chore: push all design docs, V2 plan specs, and current working state
Includes AirPlan design documents, AircOding-alpha1-plan, AirPlanV2, AirPlan-ParaV2, AirPlan-Para V1 reference docs, and all working code changes across packages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
191
AirPlan/docs/spec/AirPlan-ParaV2/plugins/airarc/scripts/airarc_mode.py
Executable file
191
AirPlan/docs/spec/AirPlan-ParaV2/plugins/airarc/scripts/airarc_mode.py
Executable file
@@ -0,0 +1,191 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user