Ports settled-reach's decisions_sync.py + ticket + decision scripts, Scrum-stripped. Writes to .pql/pql.db (gitignored). Verb shape mirrors the eventual `pql` subcommands so migration is a call-site find-replace once pql ships feature parity (D-040, R-011). Ticket IDs are T-NNN (TEXT PKs) — reshape from settled-reach's integer auto-increment so the stopgap's writes are compatible with pql's future reads without a data migration. No `sprints` table; the pyramid is kanban / waterfall (D-035). Verified end-to-end: sync parses 71 records (39 confirmed, 23 open questions, 9 rejected) with 62 cross-refs and zero broken links; `ticket new`, `ticket status`, `ticket board`, and `decisions show --with-refs` all round-trip correctly. Co-Authored-By: Claude <noreply@anthropic.com>
63 lines
1.6 KiB
Python
Executable File
63 lines
1.6 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""plan — clide planning stopgap.
|
|
|
|
Writes to .pql/pql.db. Replaced by `pql` subcommands when pql ships
|
|
feature parity. See tools/scripts/README.md for the sunset clause.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
# Make "from planning import ..." work when invoked as a script.
|
|
HERE = Path(__file__).resolve().parent
|
|
if str(HERE) not in sys.path:
|
|
sys.path.insert(0, str(HERE))
|
|
|
|
from planning import cmd_decisions, cmd_ticket, db # noqa: E402
|
|
|
|
|
|
def _build_parser() -> argparse.ArgumentParser:
|
|
ap = argparse.ArgumentParser(
|
|
prog="plan",
|
|
description="clide planning stopgap — decisions + tickets",
|
|
)
|
|
sub = ap.add_subparsers(dest="cmd", required=True)
|
|
|
|
cmd_decisions.add_subparsers(sub)
|
|
cmd_ticket.add_subparsers(sub)
|
|
|
|
sq = sub.add_parser("sqlite-query", help="run a raw SQL query")
|
|
sq.add_argument("sql")
|
|
|
|
return ap
|
|
|
|
|
|
def main(argv: list[str] | None = None) -> int:
|
|
ap = _build_parser()
|
|
args = ap.parse_args(argv)
|
|
|
|
if args.cmd == "decisions":
|
|
return cmd_decisions.dispatch(args)
|
|
if args.cmd == "ticket":
|
|
return cmd_ticket.dispatch(args)
|
|
if args.cmd == "sqlite-query":
|
|
conn = db.connect()
|
|
try:
|
|
cur = conn.execute(args.sql)
|
|
if cur.description:
|
|
cols = [d[0] for d in cur.description]
|
|
print("\t".join(cols))
|
|
for row in cur.fetchall():
|
|
print("\t".join(str(v) for v in row))
|
|
conn.commit()
|
|
finally:
|
|
conn.close()
|
|
return 0
|
|
return 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|