#!/usr/bin/env python3 """Tiny Plan F3 CLI: create/update/rebuild/sync-refs/images.""" from __future__ import annotations import sys from datetime import datetime, timezone from pathlib import Path ROOT = Path(__file__).resolve().parents[1] PLANS = ROOT / "plans" def plan_dir(product_id: str) -> Path: return PLANS / product_id def create(product_id: str, purpose: str) -> Path: d = plan_dir(product_id) d.mkdir(parents=True, exist_ok=True) md = (PLANS / "templates" / "plan.template.md").read_text(encoding="utf-8") html = (PLANS / "templates" / "plan.template.html").read_text(encoding="utf-8") for p, text in [(d / "plan.md", md), (d / "plan.html", html)]: p.write_text(text.replace("{{product_id}}", product_id).replace("{{purpose}}", purpose), encoding="utf-8") return d / "plan.md" def update(product_id: str, note: str) -> Path: p = plan_dir(product_id) / "plan.md" ts = datetime.now(timezone.utc).isoformat() with p.open("a", encoding="utf-8") as f: f.write(f"\n## Amendment {ts}\n{note}\n") return p def rebuild(product_id: str) -> Path: p = plan_dir(product_id) / "plan.md" text = p.read_text(encoding="utf-8") html = "
" + text.replace("&", "&").replace("<", "<") + "\n"
out = p.with_suffix(".html")
out.write_text(html, encoding="utf-8")
return out
def main(argv=None) -> int:
argv = argv or sys.argv[1:]
if len(argv) < 2 or argv[0] not in {"create", "update", "rebuild", "sync-refs", "images"}:
print("usage: plan_skill.py create PRODUCT PURPOSE | update PRODUCT NOTE | rebuild PRODUCT | sync-refs PRODUCT | images PRODUCT", file=sys.stderr)
return 2
cmd, product_id, *rest = argv
if cmd == "create":
print(create(product_id, " ".join(rest) or product_id))
elif cmd == "update":
print(update(product_id, " ".join(rest) or "updated"))
elif cmd == "rebuild":
print(rebuild(product_id))
else:
print(plan_dir(product_id) / "plan.md")
return 0
if __name__ == "__main__":
raise SystemExit(main())