#!/usr/bin/env python3 """Complete ready statehub-bootstrap workplans (T01–T03) for attached repos.""" from __future__ import annotations import re import sys from pathlib import Path HOME = Path("/home/worsch") REGISTRY_STACK = """## Stack - **Language:** Markdown-first registry and planning repo (no application runtime yet) - **Key deps:** State Hub ADR-001 workplans, `registry/indexes/capabilities.yaml` ## Dev Commands ```bash # Orient (offline-safe) cat .custodian-brief.md cat INTENT.md cat SCOPE.md ls workplans/ # After workplan or registry edits — from ~/state-hub make fix-consistency REPO={repo_slug} # Sanity-check markdown / registry edits git diff --check ``` """ DOCS_STACK = """## Stack - **Language:** Markdown-first control/planning repository (no application runtime) - **Key deps:** State Hub workplans, agent instructions, optional `registry/` scaffold ## Dev Commands ```bash cat .custodian-brief.md cat INTENT.md ls workplans/ # After workplan edits — from ~/state-hub make fix-consistency REPO={repo_slug} ``` """ def wp0002_template( *, prefix: str, num: str, slug: str, title: str, domain: str, repo: str, topic_slug: str, summary: str, task_title: str, task_body: str, ) -> str: wid = f"{prefix}-{num}" return f"""--- id: {wid} type: workplan title: "{title}" domain: {domain} repo: {repo} status: ready owner: codex topic_slug: {topic_slug} created: "2026-06-22" updated: "2026-06-22" --- # {title} {summary} ## {task_title} ```task id: {wid}-T01 status: todo priority: high ``` {task_body} """ def close_wp0001(path: Path, *, t01_note: str, t02_note: str, t03_note: str) -> None: text = path.read_text(encoding="utf-8") text = re.sub(r"^status: ready$", "status: finished", text, count=1, flags=re.M) text = re.sub(r"^(updated: ).*$", r'\1"2026-06-22"', text, count=1, flags=re.M) for tid, note in [ ("T01", t01_note), ("T02", t02_note), ("T03", t03_note), ]: text = re.sub( rf"(id: [A-Z0-9-]+-{tid}\nstatus: )todo", r"\1done", text, count=1, ) pattern = rf"(```task\nid: [A-Z0-9-]+-{tid}\nstatus: done\n.*?```)" block = re.search(pattern, text, re.DOTALL) if block and note: after = f"{block.group(1)}\n\nResult 2026-06-22: {note}" if note not in text: text = text.replace(block.group(1), after, 1) path.write_text(text, encoding="utf-8") def fill_scope_template(path: Path, *, oneliner: str, core: str, in_scope: list[str], out_scope: list[str]) -> None: text = path.read_text(encoding="utf-8") if "