from __future__ import annotations import argparse import json from pathlib import Path from typing import Any PRIORITY = { "named_range_presence_probe": 110, "named_range_rectangular_area": 100, "named_range_horizontal_resize": 90, "named_range_vertical_resize": 80, "cell_horizontal_align": 70, "cell_vertical_align": 60, } def read_json(path: Path) -> dict[str, Any]: return json.loads(path.read_text(encoding="utf-8")) def choose_action(plan: dict[str, Any], target: str | None = None) -> dict[str, Any] | None: experiments = [item for item in plan.get("experiments") or [] if isinstance(item, dict)] if target: experiments = [item for item in experiments if item.get("target") == target or item.get("id") == target] if not experiments: return None return sorted(experiments, key=lambda item: (-PRIORITY.get(str(item.get("id") or ""), 0), str(item.get("id") or "")))[0] def render_markdown(action: dict[str, Any] | None) -> str: if not action: return "# 1C MOXCEL Next Action\n\nNo pending action found.\n" lines = ["# 1C MOXCEL Next Action", ""] lines.append(f"- Experiment: `{action.get('id')}`") lines.append(f"- Target: `{action.get('target')}`") lines.append(f"- Goal: {action.get('goal')}") lines.append("") lines.append("## Manual Action") lines.append("") lines.append(str(action.get("manual_action") or "")) lines.append("") lines.append("## Watch Command") lines.append("") lines.append("```powershell") command = str(action.get("capture_command") or "") if "--run-pipeline-after" not in command: command = f"{command} --run-pipeline-after".strip() lines.append(command) lines.append("```") lines.append("") lines.append("## Expected Signal") lines.append("") lines.append(str(action.get("expected_signal") or "")) lines.append("") return "\n".join(lines) def build_payload(action: dict[str, Any] | None) -> dict[str, Any]: command = str((action or {}).get("capture_command") or "") if command and "--run-pipeline-after" not in command: command = f"{command} --run-pipeline-after".strip() return { "schema": "codex_1c_moxel_next_action.v1", "status": "ok" if action else "empty", "action": { **(action or {}), **({"capture_command_with_pipeline": command} if command else {}), } if action else None, } def main() -> int: parser = argparse.ArgumentParser(description="Print the highest-priority next 1C MOXCEL experiment action.") parser.add_argument("--plan", default="reports/1c-template-baselines/moxel-next-experiments.json") parser.add_argument("--target", help="Optional target or experiment id filter.") parser.add_argument("--output-json", default="reports/1c-template-baselines/moxel-next-action.json") parser.add_argument("--output-markdown", default="reports/1c-template-baselines/moxel-next-action.md") args = parser.parse_args() action = choose_action(read_json(Path(args.plan)), args.target) payload = build_payload(action) markdown = render_markdown(action) json_path = Path(args.output_json) output_path = Path(args.output_markdown) json_path.parent.mkdir(parents=True, exist_ok=True) output_path.parent.mkdir(parents=True, exist_ok=True) json_path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") output_path.write_text(markdown, encoding="utf-8") print(markdown) return 0 if action else 1 if __name__ == "__main__": raise SystemExit(main())