50 lines
1.9 KiB
Python
50 lines
1.9 KiB
Python
|
|
"""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"),
|
||
|
|
}
|