# src/native_orchestrator.py # DEPRECATED: This module is legacy and is being replaced by src/orchestrator_pm.py # and the MMA multi-agent conductor system. Avoid using this for new features. from pathlib import Path from typing import Optional import json import re from src import paths def read_plan(track_id: str, base_dir: str = ".") -> str: """ Reads the implementation plan (plan.md) for a track. [C: tests/test_native_orchestrator.py:test_read_plan_nonexistent, tests/test_native_orchestrator.py:test_write_and_read_plan] """ plan_path = paths.get_track_state_dir(track_id, base_dir) / "plan.md" if not plan_path.exists(): return "" return plan_path.read_text(encoding="utf-8") def write_plan(track_id: str, content: str, base_dir: str = ".") -> None: """ Writes the implementation plan (plan.md) for a track. [C: tests/test_native_orchestrator.py:test_write_and_read_plan] """ plan_path = paths.get_track_state_dir(track_id, base_dir) / "plan.md" plan_path.parent.mkdir(parents=True, exist_ok=True) plan_path.write_text(content, encoding="utf-8") def parse_plan_tasks(content: str) -> list[dict[str, str]]: """ Parses the tasks from a plan.md file. [C: tests/test_native_orchestrator.py:test_parse_plan_tasks] """ tasks = [] for line in content.split("\n"): stripped = line.strip() if stripped.startswith("- ["): checked = "[x]" in stripped text = stripped[4:] if len(stripped) > 4 else "" tasks.append({"text": text, "completed": checked}) return tasks def read_metadata(track_id: str, base_dir: str = ".") -> dict: """ Reads the metadata (metadata.json) for a track. [C: tests/test_native_orchestrator.py:test_read_metadata_nonexistent, tests/test_native_orchestrator.py:test_write_and_read_metadata] """ meta_path = paths.get_track_state_dir(track_id, base_dir) / "metadata.json" if not meta_path.exists(): return {} return json.loads(meta_path.read_text(encoding="utf-8")) def write_metadata(track_id: str, data: dict, base_dir: str = ".") -> None: """ Writes the metadata (metadata.json) for a track. [C: tests/test_native_orchestrator.py:test_write_and_read_metadata] """ meta_path = paths.get_track_state_dir(track_id, base_dir) / "metadata.json" meta_path.parent.mkdir(parents=True, exist_ok=True) meta_path.write_text(json.dumps(data, indent=2), encoding="utf-8") def get_track_dir(track_id: str, base_dir: str = ".") -> Path: """ Returns the state directory for a specific track. [C: tests/test_native_orchestrator.py:test_get_track_dir] """ return paths.get_track_state_dir(track_id, base_dir) def get_archive_dir(base_dir: str = ".") -> Path: """ Returns the central archive directory for completed tracks. [C: src/orchestrator_pm.py:get_track_history_summary, tests/test_native_orchestrator.py:test_get_archive_dir, tests/test_paths.py:test_conductor_dir_project_relative] """ return paths.get_archive_dir(base_dir) class NativeOrchestrator: def __init__(self, base_dir: str = "."): self.base_dir = Path(base_dir) self._conductor = None def load_track(self, track_id: str) -> dict: """ Load track from metadata.json [C: tests/test_native_orchestrator.py:test_native_orchestrator_class] """ return read_metadata(track_id, str(self.base_dir)) def save_track(self, track_id: str, data: dict) -> None: """ Persist track metadata [C: tests/test_native_orchestrator.py:test_native_orchestrator_class] """ write_metadata(track_id, data, str(self.base_dir)) def load_plan(self, track_id: str) -> str: """ Load plan.md content [C: tests/test_native_orchestrator.py:test_native_orchestrator_class] """ return read_plan(track_id, str(self.base_dir)) def save_plan(self, track_id: str, content: str) -> None: """ Persist plan.md content [C: tests/test_native_orchestrator.py:test_native_orchestrator_class] """ write_plan(track_id, content, str(self.base_dir)) def get_track_tasks(self, track_id: str) -> list[dict]: """ Get parsed task list from plan.md [C: tests/test_native_orchestrator.py:test_native_orchestrator_class] """ content = self.load_plan(track_id) return parse_plan_tasks(content) def generate_tickets(self, brief: str, module_skeletons: str = "") -> list[dict]: """ Tier 2: Generate tickets from brief [C: tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_failure, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_retry_success, tests/test_conductor_tech_lead.py:TestConductorTechLead.test_generate_tickets_success, tests/test_orchestration_logic.py:test_generate_tickets] """ from src import conductor_tech_lead return conductor_tech_lead.generate_tickets(brief, module_skeletons) def execute_ticket(self, ticket: dict, context: str) -> str: """Tier 3: Execute single ticket""" from src import ai_client return ai_client.send(context, ticket.get("description", ""), str(self.base_dir)) def analyze_error(self, error: str) -> str: """Tier 4: Analyze error""" from src import ai_client return ai_client.run_tier4_analysis(error) def run_tier4_patch(self, error: str, file_context: str) -> str: """Tier 4: Generate patch for error""" from src import ai_client return ai_client.run_tier4_patch_generation(error, file_context)