#!/usr/bin/env python3 from __future__ import annotations import argparse import json import sys from pathlib import Path def _add_lib_path() -> None: root = Path(__file__).resolve().parents[3] lib_path = root / "lib" if str(lib_path) not in sys.path: sys.path.insert(0, str(lib_path)) _add_lib_path() from air_runtime.contracts import now_iso from air_runtime.paths import airarc_root, required_project_artifacts, todo_path as workflow_todo_path from air_runtime.project_bootstrap import ensure_project_bootstrap from air_runtime.review import build_parallel_review, render_review_markdown REQUIRED_ARTIFACTS = required_project_artifacts() def _paths(project_root: Path) -> dict[str, Path]: root = airarc_root(project_root) return { "root": root, "state": root / "state.json", "reviews": root / "reviews", "execution_plan_json": root / "reviews" / "execution-plan.json", "execution_plan_md": root / "reviews" / "execution-plan.md", } def _ensure_layout(project_root: Path) -> dict[str, Path]: paths = _paths(project_root) paths["reviews"].mkdir(parents=True, exist_ok=True) return paths def _artifact_health(project_root: Path) -> dict[str, bool]: return { relative: (project_root / relative).exists() for relative in REQUIRED_ARTIFACTS } def _write_state(project_root: Path, enabled: bool) -> Path: paths = _ensure_layout(project_root) payload = { "enabled": enabled, "updatedAt": now_iso(), "projectRoot": str(project_root), "artifactHealth": _artifact_health(project_root), } paths["state"].write_text(json.dumps(payload, indent=2) + "\n", encoding="utf-8") return paths["state"] def enter_mode(project_root: Path) -> dict[str, object]: state_path = _write_state(project_root, True) return { "statePath": str(state_path), "artifactHealth": _artifact_health(project_root), } def status_mode(project_root: Path) -> dict[str, object]: paths = _ensure_layout(project_root) if paths["state"].exists(): payload = json.loads(paths["state"].read_text(encoding="utf-8-sig")) else: payload = { "enabled": False, "projectRoot": str(project_root), "artifactHealth": _artifact_health(project_root), } payload["artifactHealth"] = _artifact_health(project_root) return payload def parallel_review_mode(project_root: Path, todo_path: Path) -> dict[str, object]: paths = _ensure_layout(project_root) review = build_parallel_review(todo_path) json_path = paths["reviews"] / "parallel-review.json" markdown_path = paths["reviews"] / "parallel-review.md" json_path.write_text(json.dumps(review.to_dict(), indent=2) + "\n", encoding="utf-8") markdown_path.write_text(render_review_markdown(review), encoding="utf-8") selected_tasks = review.parallel_groups[0].task_ids if review.parallel_groups else [] execution_plan_payload = { "generatedAt": now_iso(), "projectRoot": str(project_root), "todoPath": str(todo_path), "planSource": "airarc-post-plan-review", "parallelReview": review.to_dict(), "selectedTasks": selected_tasks, "parallelGroups": [group.to_dict() for group in review.parallel_groups], "conflicts": [conflict.to_dict() for conflict in review.conflicts], "serializationPoints": review.serialization_points, } paths["execution_plan_json"].write_text( json.dumps(execution_plan_payload, indent=2) + "\n", encoding="utf-8", ) execution_lines = [ "# AirArc Execution Plan", "", f"- Generated At: `{execution_plan_payload['generatedAt']}`", f"- Todo Path: `{todo_path}`", f"- Plan Source: `{execution_plan_payload['planSource']}`", "", "## Selected Tasks", ] if selected_tasks: for task_id in selected_tasks: execution_lines.append(f"- `{task_id}`") else: execution_lines.append("- No selected tasks.") execution_lines.extend(["", "## Parallel Groups"]) if review.parallel_groups: for group in review.parallel_groups: execution_lines.append(f"- `{group.name}`: {', '.join(group.task_ids)}") execution_lines.append(f" Reason: {group.reason}") else: execution_lines.append("- No parallel groups.") execution_lines.extend(["", "## Serialization Points"]) if review.serialization_points: for item in review.serialization_points: execution_lines.append(f"- `{item['taskId']}`: {'; '.join(item['reasons'])}") else: execution_lines.append("- No serialization points.") paths["execution_plan_md"].write_text("\n".join(execution_lines) + "\n", encoding="utf-8") _write_state(project_root, True) return { "jsonPath": str(json_path), "markdownPath": str(markdown_path), "executionPlanJsonPath": str(paths["execution_plan_json"]), "executionPlanMarkdownPath": str(paths["execution_plan_md"]), "parallelGroupCount": len(review.parallel_groups), "conflictCount": len(review.conflicts), } def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser(description="Upgraded AirArc prototype runtime") parser.add_argument("--mode", choices=["enter", "status", "parallel-review"], default="status") parser.add_argument("--project", default=".") parser.add_argument("--todo", default="") return parser.parse_args() def main() -> None: args = parse_args() project_root = Path(args.project).expanduser().resolve() ensure_project_bootstrap(project_root) if args.mode == "enter": result = enter_mode(project_root) print("airarc_mode=enabled") print(f"project_root={project_root}") print(f"state_path={result['statePath']}") for key, value in result["artifactHealth"].items(): print(f"{key}={'ok' if value else 'missing'}") return if args.mode == "status": result = status_mode(project_root) print(f"airarc_mode={'enabled' if result.get('enabled') else 'disabled'}") print(f"project_root={project_root}") for key, value in result["artifactHealth"].items(): print(f"{key}={'ok' if value else 'missing'}") return current_todo_path = Path(args.todo).expanduser().resolve() if args.todo else workflow_todo_path(project_root) result = parallel_review_mode(project_root, current_todo_path) print("airarc_mode=parallel-reviewed") print(f"project_root={project_root}") print(f"todo_path={current_todo_path}") print(f"json_path={result['jsonPath']}") print(f"markdown_path={result['markdownPath']}") print(f"execution_plan_json_path={result['executionPlanJsonPath']}") print(f"execution_plan_markdown_path={result['executionPlanMarkdownPath']}") print(f"parallel_group_count={result['parallelGroupCount']}") print(f"conflict_count={result['conflictCount']}") if __name__ == "__main__": main()