main.py python
208 lines 8.6 KB
Raw
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 58 days ago
1 """Overseer CLI entrypoint and argument parsing (§K4.1)."""
2
3 from __future__ import annotations
4
5 import argparse
6 import sys
7 from pathlib import Path
8
9 from cli.args import extract_global_args
10
11 COMMANDS = frozenset({"init", "sync", "status", "review", "governance-sync", "verify-step", "honesty-status", "ledger"})
12 from cli.commands.governance_sync import run_governance_sync_command
13 from cli.commands.honesty_status import run_honesty_status_command
14 from cli.commands.init import run_init
15 from cli.commands.ledger import run_ledger_command
16 from cli.commands.review import run_review
17 from cli.commands.status import run_status
18 from cli.commands.sync import run_sync
19 from cli.commands.verify_step import run_verify_step_command
20 from cli.context import CliContext
21 from cli.kit_root import kit_version
22 from cli.output import OutputContext
23
24
25 def build_parser() -> argparse.ArgumentParser:
26 """Construct the frozen argument parser."""
27 parser = argparse.ArgumentParser(prog="overseer", description="Overseer Kit vendoring CLI")
28 parser.add_argument("--version", action="store_true", help="Print kit version and exit")
29 parser.add_argument("-C", "--repo", metavar="PATH", help="Repo root")
30 parser.add_argument("--config", metavar="PATH", help="Config file path")
31 parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON")
32 parser.add_argument("-q", "--quiet", action="store_true", help="Suppress non-essential stdout")
33 parser.add_argument("-v", "--verbose", action="store_true", help="Verbose diagnostics on stderr")
34 parser.add_argument("--no-color", action="store_true", help="Disable ANSI color")
35
36 subparsers = parser.add_subparsers(dest="command")
37
38 init_parser = subparsers.add_parser("init", help="First install into a repo")
39 init_parser.add_argument("--regime", choices=["muse+git-mirror", "muse-only", "git-only"])
40 init_parser.add_argument("--repo-name", metavar="NAME")
41 init_parser.add_argument("--docs-dir", metavar="PATH", default="docs")
42 init_parser.add_argument("--from-config", metavar="PATH")
43 init_parser.add_argument("--force", action="store_true")
44 init_parser.add_argument("--non-interactive", action="store_true")
45 init_parser.add_argument("--dry-run", action="store_true")
46 init_parser.add_argument(
47 "--migrate",
48 action="store_true",
49 help="Preserve existing living docs; lock origin:preserved (K6)",
50 )
51 init_parser.add_argument(
52 "--include-preserved",
53 action="store_true",
54 help="With --force: promote living docs to origin:kit (pilot-forbidden)",
55 )
56
57 sync_parser = subparsers.add_parser("sync", help="Update vendored footprint")
58 sync_parser.add_argument("--dry-run", action="store_true")
59 sync_parser.add_argument("--diff", action="store_true", default=None)
60 sync_parser.add_argument("--no-diff", action="store_false", dest="diff")
61 sync_parser.add_argument("--only", action="append", metavar="GLOB")
62 sync_parser.add_argument("--force", action="store_true")
63 sync_parser.add_argument("-y", "--yes", action="store_true")
64 sync_parser.add_argument(
65 "--include-preserved",
66 action="store_true",
67 help="With --force: promote living docs to origin:kit (pilot-forbidden)",
68 )
69
70 status_parser = subparsers.add_parser("status", help="Read-only status report")
71 status_parser.add_argument("--exit-code", action="store_true")
72 status_parser.add_argument("--check-footprint", action="store_true")
73
74 review_parser = subparsers.add_parser("review", help="Freeze-contract review")
75 review_parser.add_argument("--freeze", required=True, dest="freeze_path", metavar="PATH")
76 review_parser.add_argument("--dry-run", action="store_true")
77 review_parser.add_argument("--mode", choices=["agent", "human"])
78 review_parser.add_argument("--provider", choices=["local", "api"])
79 review_parser.add_argument("--model", metavar="LABEL")
80 review_parser.add_argument("--no-stamp", action="store_true")
81 review_parser.add_argument("--checklist", metavar="PATH")
82
83 gs_parser = subparsers.add_parser(
84 "governance-sync",
85 help="Governance hygiene agent (default dry-run)",
86 )
87 gs_parser.add_argument(
88 "--write",
89 action="store_true",
90 help="Apply doc patches, commit on feature branch, and push (default is dry-run)",
91 )
92 gs_parser.add_argument(
93 "--dry-run",
94 action="store_true",
95 help="Explicit dry-run (default when --write is absent)",
96 )
97 gs_parser.add_argument(
98 "--lane",
99 metavar="NAME",
100 help="Sync only this configured docs lane (requires docs.lanes in config)",
101 )
102 gs_parser.add_argument(
103 "--all-lanes",
104 action="store_true",
105 help="Sync every configured lane; skip lanes with missing doc files",
106 )
107
108 vs_parser = subparsers.add_parser("verify-step", help="L1 checkpoint orchestrator (K9b)")
109 vs_parser.add_argument("--manifest", metavar="PATH", help="Active manifest path")
110 vs_parser.add_argument("--step", metavar="ID", help="Verify one step")
111 vs_parser.add_argument(
112 "--through",
113 metavar="TOKEN",
114 help="Verify through current step (only 'current' accepted)",
115 )
116 vs_parser.add_argument("--all", action="store_true", help="Verify full template order")
117 vs_parser.add_argument("--policy", metavar="PATH", help="Policy file override")
118 vs_parser.add_argument(
119 "--dry-run",
120 action="store_true",
121 help="Plan only; no script invoke or manifest writes",
122 )
123
124 hs_parser = subparsers.add_parser("honesty-status", help="L2 co-requirement check (K10)")
125 hs_parser.add_argument("--hook", metavar="HOOK")
126 hs_parser.add_argument("--artifact", metavar="PATH")
127 hs_parser.add_argument("--producer-session", metavar="ID")
128
129 ledger_parser = subparsers.add_parser("ledger", help="L2 verdict ledger (K10)")
130 ledger_sub = ledger_parser.add_subparsers(dest="ledger_action", required=True)
131
132 append_parser = ledger_sub.add_parser("append", help="Append a ledger entry")
133 append_parser.add_argument("--kind", metavar="KIND", required=True)
134 append_parser.add_argument("--file", metavar="JSON_PATH")
135 append_parser.add_argument("--stdin", action="store_true")
136
137 ledger_sub.add_parser("verify", help="Verify ledger hash chain")
138
139 show_parser = ledger_sub.add_parser("show", help="Show recent ledger entries")
140 show_parser.add_argument("--last", type=int, metavar="N")
141
142 return parser
143
144
145 def main(argv: list[str] | None = None, *, ctx: CliContext | None = None) -> int:
146 """CLI main; return exit code."""
147 parser = build_parser()
148 raw_argv = list(argv) if argv is not None else sys.argv[1:]
149 global_argv, rest_argv = extract_global_args(raw_argv)
150 if rest_argv and rest_argv[0] not in COMMANDS:
151 print(f"unknown command: {rest_argv[0]}", file=sys.stderr)
152 return 1
153 try:
154 args = parser.parse_args(global_argv + rest_argv)
155 except SystemExit as exc:
156 code = exc.code
157 return 1 if code == 2 else (int(code) if isinstance(code, int) else 1)
158
159 if args.version:
160 print(kit_version())
161 return 0
162
163 if args.command is None:
164 parser.print_help()
165 return 0
166
167 runtime = ctx or CliContext.create()
168 if ctx is None:
169 runtime = CliContext.create(
170 output=OutputContext(
171 json_mode=args.json,
172 quiet=args.quiet,
173 verbose=args.verbose,
174 no_color=args.no_color,
175 ),
176 cwd=Path.cwd(),
177 )
178 else:
179 runtime.output.json_mode = args.json or runtime.output.json_mode
180 runtime.output.quiet = args.quiet or runtime.output.quiet
181 runtime.output.verbose = args.verbose or runtime.output.verbose
182 runtime.output.no_color = args.no_color or runtime.output.no_color
183
184 if args.command == "init":
185 return run_init(args, runtime)
186 if args.command == "sync":
187 if args.diff is None:
188 args.diff = sys.stdout.isatty()
189 return run_sync(args, runtime)
190 if args.command == "status":
191 return run_status(args, runtime)
192 if args.command == "review":
193 return run_review(args, runtime, raw_argv=rest_argv)
194 if args.command == "governance-sync":
195 return run_governance_sync_command(args, runtime)
196 if args.command == "verify-step":
197 return run_verify_step_command(args, runtime)
198 if args.command == "honesty-status":
199 return run_honesty_status_command(args, runtime)
200 if args.command == "ledger":
201 return run_ledger_command(args, runtime)
202
203 parser.error(f"unknown command: {args.command}")
204 return 1
205
206
207 if __name__ == "__main__":
208 raise SystemExit(main())
File History 1 commit
sha256:4671b7f787ddbe63ced31c895b688c77ab495653b65a730b423329f26b3c1439 feat: K1-P1 complete — agent provenance, build-verification… Sonnet 4.6 patch 58 days ago