"""Project state store for A0 Software Orchestrator.""" import json import os from datetime import datetime from typing import Any, Dict, Optional def read_json(path: str, default: Any = None) -> Any: """Read a JSON file from the project root, return default if not found.""" try: with open(path, "r") as f: return json.load(f) except (FileNotFoundError, json.JSONDecodeError): return default def write_json(path: str, data: Any) -> None: """Write data to a JSON file, creating directories if needed.""" os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, "w") as f: json.dump(data, f, indent=2, default=str) def append_markdown(path: str, line: str) -> None: """Append a line to a markdown file, creating directories if needed.""" os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, "a") as f: f.write(line + "\n") def timestamp() -> str: """Return an ISO 8601 timestamp string.""" return datetime.utcnow().isoformat() + "Z" def get_project_files(project_root: str) -> Dict[str, str]: """Return a dict of known state file paths relative to project_root.""" return { "project_state": os.path.join(project_root, ".a0", "project_state.json"), "current_status": os.path.join(project_root, ".a0", "current_status.md"), "worklog": os.path.join(project_root, ".a0", "worklog.md"), "todo": os.path.join(project_root, ".a0", "todo.md"), "known_errors": os.path.join(project_root, ".a0", "known_errors.md"), "next_steps": os.path.join(project_root, ".a0", "next_steps.md"), "task_graph": os.path.join(project_root, ".a0", "task_graph.json"), "orchestrator_mode": os.path.join(project_root, ".a0", "orchestrator_mode.json"), "tool_capabilities": os.path.join(project_root, ".a0", "tool_capabilities.json"), "resume": os.path.join(project_root, ".a0", "resume.md"), }