agentic-project-kit 1.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (310) hide show
  1. agentic_project_kit/__init__.py +1 -0
  2. agentic_project_kit/absolute_path_portability_audit.py +241 -0
  3. agentic_project_kit/access_level_policy.py +14 -0
  4. agentic_project_kit/access_levels.py +22 -0
  5. agentic_project_kit/action_registry.py +195 -0
  6. agentic_project_kit/action_specs.py +286 -0
  7. agentic_project_kit/agent_command_runner.py +516 -0
  8. agentic_project_kit/audit_test_matrix.py +36 -0
  9. agentic_project_kit/audit_test_matrix_cli.py +43 -0
  10. agentic_project_kit/chat_bootloader.py +257 -0
  11. agentic_project_kit/chat_entrypoint_contract.py +297 -0
  12. agentic_project_kit/checks.py +511 -0
  13. agentic_project_kit/ci_readiness.py +211 -0
  14. agentic_project_kit/cli.py +147 -0
  15. agentic_project_kit/cli_commands/__init__.py +1 -0
  16. agentic_project_kit/cli_commands/absolute_path_audit.py +25 -0
  17. agentic_project_kit/cli_commands/actions.py +21 -0
  18. agentic_project_kit/cli_commands/artifact_gc.py +240 -0
  19. agentic_project_kit/cli_commands/boot.py +55 -0
  20. agentic_project_kit/cli_commands/chat.py +34 -0
  21. agentic_project_kit/cli_commands/checks.py +305 -0
  22. agentic_project_kit/cli_commands/cockpit.py +103 -0
  23. agentic_project_kit/cli_commands/command_taxonomy.py +25 -0
  24. agentic_project_kit/cli_commands/commands.py +129 -0
  25. agentic_project_kit/cli_commands/dev.py +23 -0
  26. agentic_project_kit/cli_commands/direction.py +92 -0
  27. agentic_project_kit/cli_commands/doc_currency_audit.py +25 -0
  28. agentic_project_kit/cli_commands/doc_registry.py +126 -0
  29. agentic_project_kit/cli_commands/docs.py +223 -0
  30. agentic_project_kit/cli_commands/dpa.py +1338 -0
  31. agentic_project_kit/cli_commands/evidence.py +251 -0
  32. agentic_project_kit/cli_commands/github.py +34 -0
  33. agentic_project_kit/cli_commands/governance.py +14 -0
  34. agentic_project_kit/cli_commands/gui.py +23 -0
  35. agentic_project_kit/cli_commands/gui_readiness_gate.py +27 -0
  36. agentic_project_kit/cli_commands/handoff.py +183 -0
  37. agentic_project_kit/cli_commands/human_workflows.py +430 -0
  38. agentic_project_kit/cli_commands/init.py +132 -0
  39. agentic_project_kit/cli_commands/instruction.py +75 -0
  40. agentic_project_kit/cli_commands/mutation_lock_audit.py +24 -0
  41. agentic_project_kit/cli_commands/ns_legacy_audit.py +25 -0
  42. agentic_project_kit/cli_commands/pass_already_done.py +66 -0
  43. agentic_project_kit/cli_commands/patch_failure_discipline_audit.py +26 -0
  44. agentic_project_kit/cli_commands/patch_preflight.py +37 -0
  45. agentic_project_kit/cli_commands/path_literal_audit.py +39 -0
  46. agentic_project_kit/cli_commands/patterns.py +40 -0
  47. agentic_project_kit/cli_commands/planning_docs_audit.py +25 -0
  48. agentic_project_kit/cli_commands/pr.py +133 -0
  49. agentic_project_kit/cli_commands/pr_hygiene.py +27 -0
  50. agentic_project_kit/cli_commands/profiles.py +26 -0
  51. agentic_project_kit/cli_commands/program_redundancy_audit.py +25 -0
  52. agentic_project_kit/cli_commands/project_direction.py +25 -0
  53. agentic_project_kit/cli_commands/release.py +392 -0
  54. agentic_project_kit/cli_commands/release_publish_orchestration.py +36 -0
  55. agentic_project_kit/cli_commands/remote_branch_hygiene.py +152 -0
  56. agentic_project_kit/cli_commands/remote_next.py +57 -0
  57. agentic_project_kit/cli_commands/removed_ns_commands.py +65 -0
  58. agentic_project_kit/cli_commands/rule_registry.py +129 -0
  59. agentic_project_kit/cli_commands/rules.py +222 -0
  60. agentic_project_kit/cli_commands/scaffold.py +46 -0
  61. agentic_project_kit/cli_commands/slice.py +21 -0
  62. agentic_project_kit/cli_commands/standard_gates_audit_suite.py +27 -0
  63. agentic_project_kit/cli_commands/state.py +51 -0
  64. agentic_project_kit/cli_commands/status_current_state_audit.py +30 -0
  65. agentic_project_kit/cli_commands/todo.py +53 -0
  66. agentic_project_kit/cli_commands/transfer.py +19 -0
  67. agentic_project_kit/cli_commands/transfer_context_flow.py +398 -0
  68. agentic_project_kit/cli_commands/transfer_context_helpers.py +398 -0
  69. agentic_project_kit/cli_commands/transfer_diagnostics.py +767 -0
  70. agentic_project_kit/cli_commands/transfer_evidence_flow.py +368 -0
  71. agentic_project_kit/cli_commands/transfer_handoff_flow.py +594 -0
  72. agentic_project_kit/cli_commands/transfer_order_contract.py +74 -0
  73. agentic_project_kit/cli_commands/transfer_post_merge_complete.py +442 -0
  74. agentic_project_kit/cli_commands/transfer_post_merge_settle.py +171 -0
  75. agentic_project_kit/cli_commands/transfer_pr_closeout_complete.py +124 -0
  76. agentic_project_kit/cli_commands/transfer_pr_create_flow.py +743 -0
  77. agentic_project_kit/cli_commands/transfer_pr_merge_flow.py +547 -0
  78. agentic_project_kit/cli_commands/transfer_repo_after_pr.py +160 -0
  79. agentic_project_kit/cli_commands/transfer_repo_pre_pr.py +664 -0
  80. agentic_project_kit/cli_commands/transfer_runner_flow.py +131 -0
  81. agentic_project_kit/cli_commands/transfer_runtime_initial.py +194 -0
  82. agentic_project_kit/cli_commands/transfer_shared.py +274 -0
  83. agentic_project_kit/cli_commands/validation.py +200 -0
  84. agentic_project_kit/cli_commands/version.py +27 -0
  85. agentic_project_kit/cli_commands/work_orders.py +219 -0
  86. agentic_project_kit/cli_commands/workflow.py +471 -0
  87. agentic_project_kit/cli_commands/workflow_guard.py +26 -0
  88. agentic_project_kit/cli_commands/workspace.py +252 -0
  89. agentic_project_kit/cockpit.py +608 -0
  90. agentic_project_kit/cockpit_readiness.py +67 -0
  91. agentic_project_kit/command_authority_audit.py +192 -0
  92. agentic_project_kit/command_inbox_check.py +103 -0
  93. agentic_project_kit/command_manifest.py +591 -0
  94. agentic_project_kit/command_queue_contract.py +161 -0
  95. agentic_project_kit/command_selector.py +245 -0
  96. agentic_project_kit/command_taxonomy.py +264 -0
  97. agentic_project_kit/commit_guard.py +67 -0
  98. agentic_project_kit/communication_artifact_gc.py +495 -0
  99. agentic_project_kit/communication_rule_context.py +437 -0
  100. agentic_project_kit/communication_state.py +115 -0
  101. agentic_project_kit/composed_wrapper_invariants.py +97 -0
  102. agentic_project_kit/composite_short_circuit.py +140 -0
  103. agentic_project_kit/contract.py +251 -0
  104. agentic_project_kit/control_state.py +83 -0
  105. agentic_project_kit/doc_currency_audit.py +536 -0
  106. agentic_project_kit/doc_lifecycle.py +1179 -0
  107. agentic_project_kit/doc_lifecycle_signals.py +446 -0
  108. agentic_project_kit/doc_lifecycle_sweep.py +639 -0
  109. agentic_project_kit/doc_mesh.py +491 -0
  110. agentic_project_kit/doctor.py +379 -0
  111. agentic_project_kit/documentation_registry.py +1122 -0
  112. agentic_project_kit/documentation_system_audit.py +310 -0
  113. agentic_project_kit/dpa_current_handoff_lifecycle.py +549 -0
  114. agentic_project_kit/dpa_dp2_decision_readiness.py +362 -0
  115. agentic_project_kit/dpa_dp3_dp4_adjudication.py +604 -0
  116. agentic_project_kit/dpa_dp5_block_new_gate.py +294 -0
  117. agentic_project_kit/dpa_dp5_stage_adoption.py +615 -0
  118. agentic_project_kit/dpa_dp5_strict_gate.py +187 -0
  119. agentic_project_kit/dpa_final_closeout.py +627 -0
  120. agentic_project_kit/dpa_fixture_evidence.py +680 -0
  121. agentic_project_kit/dpa_maintainer_record_check.py +711 -0
  122. agentic_project_kit/dpa_post_dp2_scope_assessment.py +734 -0
  123. agentic_project_kit/dpa_probe_002_readiness.py +509 -0
  124. agentic_project_kit/dpa_probe_003_readiness.py +417 -0
  125. agentic_project_kit/dpa_probe_004_readiness.py +437 -0
  126. agentic_project_kit/dpa_readiness.py +505 -0
  127. agentic_project_kit/dpa_readonly_probe_execution.py +500 -0
  128. agentic_project_kit/dpa_registry_contracts.py +312 -0
  129. agentic_project_kit/dpa_renderer_readiness.py +407 -0
  130. agentic_project_kit/dpa_repo_adoption_assessment.py +574 -0
  131. agentic_project_kit/dpa_stable_readiness.py +743 -0
  132. agentic_project_kit/dpa_successor_projection.py +168 -0
  133. agentic_project_kit/dpa_workspace_init_projection.py +93 -0
  134. agentic_project_kit/dpa_wrt_ch001_evidence.py +327 -0
  135. agentic_project_kit/entrypoint_slice_runner.py +153 -0
  136. agentic_project_kit/evidence_clean.py +152 -0
  137. agentic_project_kit/evidence_commit_paths.py +214 -0
  138. agentic_project_kit/evidence_finalize_log.py +204 -0
  139. agentic_project_kit/evidence_guard.py +114 -0
  140. agentic_project_kit/evidence_inspector.py +507 -0
  141. agentic_project_kit/evidence_state_contract.py +99 -0
  142. agentic_project_kit/execution_mode_state.py +148 -0
  143. agentic_project_kit/final_summary_contract.py +85 -0
  144. agentic_project_kit/finalize_guard.py +139 -0
  145. agentic_project_kit/gatekeeper_core.py +232 -0
  146. agentic_project_kit/github.py +25 -0
  147. agentic_project_kit/governance.py +59 -0
  148. agentic_project_kit/gui_action_execution.py +105 -0
  149. agentic_project_kit/gui_action_renderer.py +81 -0
  150. agentic_project_kit/gui_action_run_intent.py +98 -0
  151. agentic_project_kit/gui_action_views.py +195 -0
  152. agentic_project_kit/gui_activity_log.py +76 -0
  153. agentic_project_kit/gui_button_catalog.py +605 -0
  154. agentic_project_kit/gui_cockpit.py +365 -0
  155. agentic_project_kit/gui_cockpit_actions.py +695 -0
  156. agentic_project_kit/gui_cockpit_common.py +172 -0
  157. agentic_project_kit/gui_cockpit_header.py +501 -0
  158. agentic_project_kit/gui_cockpit_sidebar.py +387 -0
  159. agentic_project_kit/gui_cockpit_task.py +748 -0
  160. agentic_project_kit/gui_command_projection.py +355 -0
  161. agentic_project_kit/gui_communication_modes.py +130 -0
  162. agentic_project_kit/gui_dry_run.py +219 -0
  163. agentic_project_kit/gui_gatekeeper_status.py +259 -0
  164. agentic_project_kit/gui_layout_plan.py +148 -0
  165. agentic_project_kit/gui_open_folder.py +18 -0
  166. agentic_project_kit/gui_output_status_panel.py +61 -0
  167. agentic_project_kit/gui_panel_state.py +47 -0
  168. agentic_project_kit/gui_presenter.py +62 -0
  169. agentic_project_kit/gui_readiness_gate.py +206 -0
  170. agentic_project_kit/gui_release_flow.py +59 -0
  171. agentic_project_kit/gui_task_editor.py +1077 -0
  172. agentic_project_kit/gui_tk_widgets.py +177 -0
  173. agentic_project_kit/gui_tkinter_renderer.py +87 -0
  174. agentic_project_kit/gui_tkinter_shell.py +1176 -0
  175. agentic_project_kit/gui_transfer_contract.py +28 -0
  176. agentic_project_kit/gui_viewmodel.py +698 -0
  177. agentic_project_kit/gui_window_guard.py +46 -0
  178. agentic_project_kit/handoff_freshness.py +390 -0
  179. agentic_project_kit/handoff_prompt.py +180 -0
  180. agentic_project_kit/handoff_state.py +254 -0
  181. agentic_project_kit/instruction_lint.py +455 -0
  182. agentic_project_kit/llm_context_carriers.py +66 -0
  183. agentic_project_kit/llm_execution_context.py +285 -0
  184. agentic_project_kit/local_command_stack.py +133 -0
  185. agentic_project_kit/local_feature_gate.py +82 -0
  186. agentic_project_kit/local_garbage_collector.py +269 -0
  187. agentic_project_kit/models.py +18 -0
  188. agentic_project_kit/mutation_lock_audit.py +421 -0
  189. agentic_project_kit/next_turn_evidence.py +253 -0
  190. agentic_project_kit/next_turn_merge_if_green.py +459 -0
  191. agentic_project_kit/next_turn_pr_status.py +255 -0
  192. agentic_project_kit/next_turn_result.py +183 -0
  193. agentic_project_kit/next_turn_runner.py +159 -0
  194. agentic_project_kit/next_turn_slot.py +107 -0
  195. agentic_project_kit/next_turn_status.py +274 -0
  196. agentic_project_kit/ns_legacy_reference_audit.py +258 -0
  197. agentic_project_kit/ns_slice_runner.py +16 -0
  198. agentic_project_kit/operational_handoff_projection.py +124 -0
  199. agentic_project_kit/output_contract.py +80 -0
  200. agentic_project_kit/output_repair.py +61 -0
  201. agentic_project_kit/pass_already_done.py +216 -0
  202. agentic_project_kit/patch_artifact_preflight.py +147 -0
  203. agentic_project_kit/patch_cycle_workflow.py +440 -0
  204. agentic_project_kit/patch_failure_discipline_audit.py +223 -0
  205. agentic_project_kit/patch_preflight.py +215 -0
  206. agentic_project_kit/path_literal_audit.py +612 -0
  207. agentic_project_kit/patterns.py +99 -0
  208. agentic_project_kit/planning_docs_consolidation_audit.py +313 -0
  209. agentic_project_kit/portability_shell_gate.py +40 -0
  210. agentic_project_kit/post_merge_handoff_refresh.py +56 -0
  211. agentic_project_kit/post_release.py +252 -0
  212. agentic_project_kit/post_release_closeout.py +616 -0
  213. agentic_project_kit/pr_cleanup.py +172 -0
  214. agentic_project_kit/pr_closeout.py +50 -0
  215. agentic_project_kit/pr_closeout_complete.py +344 -0
  216. agentic_project_kit/pr_create_or_skip.py +71 -0
  217. agentic_project_kit/pr_hygiene.py +210 -0
  218. agentic_project_kit/program_redundancy_audit.py +251 -0
  219. agentic_project_kit/project_direction.py +840 -0
  220. agentic_project_kit/protected_change_planner.py +194 -0
  221. agentic_project_kit/release.py +401 -0
  222. agentic_project_kit/release_doi_safety.py +24 -0
  223. agentic_project_kit/release_gate_core.py +174 -0
  224. agentic_project_kit/release_metadata_authority_gate.py +328 -0
  225. agentic_project_kit/release_metadata_prep.py +43 -0
  226. agentic_project_kit/release_notes.py +823 -0
  227. agentic_project_kit/release_prep_core.py +204 -0
  228. agentic_project_kit/release_prepare.py +369 -0
  229. agentic_project_kit/release_process_guardrails.py +247 -0
  230. agentic_project_kit/release_publish_core.py +114 -0
  231. agentic_project_kit/release_publish_orchestration.py +469 -0
  232. agentic_project_kit/release_state.py +552 -0
  233. agentic_project_kit/release_verify_core.py +175 -0
  234. agentic_project_kit/remote_branch_hygiene.py +223 -0
  235. agentic_project_kit/remote_next.py +89 -0
  236. agentic_project_kit/remote_next_closeout.py +101 -0
  237. agentic_project_kit/remote_next_order_contract.py +391 -0
  238. agentic_project_kit/removed_ns_commands.py +458 -0
  239. agentic_project_kit/removed_source_audit.py +225 -0
  240. agentic_project_kit/rendering.py +13 -0
  241. agentic_project_kit/repair_report.py +79 -0
  242. agentic_project_kit/repo_identity.py +59 -0
  243. agentic_project_kit/result_report_classifier.py +57 -0
  244. agentic_project_kit/rule_ack.py +105 -0
  245. agentic_project_kit/rule_preservation.py +58 -0
  246. agentic_project_kit/rule_refresh.py +174 -0
  247. agentic_project_kit/rule_registry_registration.py +322 -0
  248. agentic_project_kit/rule_registry_report.py +206 -0
  249. agentic_project_kit/rule_registry_validator.py +704 -0
  250. agentic_project_kit/rule_snapshot.py +98 -0
  251. agentic_project_kit/rule_source_validator.py +133 -0
  252. agentic_project_kit/run_summary.py +68 -0
  253. agentic_project_kit/run_summary_renderer.py +238 -0
  254. agentic_project_kit/runtime_validator.py +68 -0
  255. agentic_project_kit/safe_file_replace.py +35 -0
  256. agentic_project_kit/safe_patch.py +47 -0
  257. agentic_project_kit/safe_push.py +218 -0
  258. agentic_project_kit/safe_remove_diagnostic.py +51 -0
  259. agentic_project_kit/scaffold.py +69 -0
  260. agentic_project_kit/site_claims.py +444 -0
  261. agentic_project_kit/site_generator.py +1140 -0
  262. agentic_project_kit/slice_gate.py +225 -0
  263. agentic_project_kit/slice_runner.py +75 -0
  264. agentic_project_kit/standard_gates_audit_suite.py +167 -0
  265. agentic_project_kit/state_freshness.py +135 -0
  266. agentic_project_kit/status_current_state_audit.py +762 -0
  267. agentic_project_kit/successor_handoff_package.py +1763 -0
  268. agentic_project_kit/templates.py +292 -0
  269. agentic_project_kit/terminal_block_guard.py +166 -0
  270. agentic_project_kit/terminal_logging.py +275 -0
  271. agentic_project_kit/todo.py +97 -0
  272. agentic_project_kit/transfer_closeout.py +136 -0
  273. agentic_project_kit/transfer_continue.py +215 -0
  274. agentic_project_kit/transfer_local_runner.py +101 -0
  275. agentic_project_kit/transfer_operation_monitor.py +236 -0
  276. agentic_project_kit/transfer_post_merge_lifecycle.py +356 -0
  277. agentic_project_kit/transfer_post_merge_settle.py +383 -0
  278. agentic_project_kit/transfer_pr_actions.py +164 -0
  279. agentic_project_kit/transfer_remote_next.py +959 -0
  280. agentic_project_kit/transfer_repo_actions.py +2253 -0
  281. agentic_project_kit/transfer_runner.py +347 -0
  282. agentic_project_kit/transfer_safety_context.py +291 -0
  283. agentic_project_kit/transfer_state.py +483 -0
  284. agentic_project_kit/transfer_uplink.py +471 -0
  285. agentic_project_kit/transfer_workflow_next.py +148 -0
  286. agentic_project_kit/typed_work_order_evidence.py +58 -0
  287. agentic_project_kit/typed_work_order_queue.py +166 -0
  288. agentic_project_kit/typed_work_order_runner.py +168 -0
  289. agentic_project_kit/work_cycle.py +317 -0
  290. agentic_project_kit/work_discard_changes.py +129 -0
  291. agentic_project_kit/work_order_patch.py +199 -0
  292. agentic_project_kit/work_order_runner.py +120 -0
  293. agentic_project_kit/work_order_uploader.py +220 -0
  294. agentic_project_kit/work_order_validator.py +185 -0
  295. agentic_project_kit/work_orders.py +246 -0
  296. agentic_project_kit/workflow_guard.py +262 -0
  297. agentic_project_kit/workflow_summary_runner.py +124 -0
  298. agentic_project_kit/workspace.py +665 -0
  299. agentic_project_kit/workspace_adopt.py +471 -0
  300. agentic_project_kit/workspace_dpa_intake.py +406 -0
  301. agentic_project_kit/workspace_init.py +487 -0
  302. agentic_project_kit/workspace_lock.py +129 -0
  303. agentic_project_kit/workspace_remove.py +381 -0
  304. agentic_project_kit/workspace_upgrade.py +324 -0
  305. agentic_project_kit/wrapper_live_status.py +104 -0
  306. agentic_project_kit-1.0.1.dist-info/METADATA +724 -0
  307. agentic_project_kit-1.0.1.dist-info/RECORD +310 -0
  308. agentic_project_kit-1.0.1.dist-info/WHEEL +4 -0
  309. agentic_project_kit-1.0.1.dist-info/entry_points.txt +3 -0
  310. agentic_project_kit-1.0.1.dist-info/licenses/LICENSE +10 -0
@@ -0,0 +1,55 @@
1
+ from __future__ import annotations
2
+
3
+ import typer
4
+
5
+ from agentic_project_kit.chat_bootloader import check_boot_sources
6
+ from agentic_project_kit.chat_bootloader import render_boot_report
7
+ from agentic_project_kit.chat_bootloader import render_bootloader
8
+ from agentic_project_kit.chat_bootloader import run_chat_switch_closeout
9
+ from agentic_project_kit.chat_bootloader import write_boot_report
10
+ from agentic_project_kit.chat_bootloader import write_next_chat_bootstrap
11
+
12
+ boot_app = typer.Typer(help="Render and check successor-chat boot information.")
13
+
14
+
15
+ @boot_app.command("prompt")
16
+ def prompt(root: str = ".") -> None:
17
+ typer.echo(render_bootloader(root))
18
+
19
+
20
+ @boot_app.command("check")
21
+ def check(root: str = ".") -> None:
22
+ typer.echo(render_bootloader(root))
23
+ missing = [item.source for item in check_boot_sources(root) if not item.exists]
24
+ if missing:
25
+ raise typer.Exit(code=1)
26
+
27
+
28
+ @boot_app.command("write")
29
+ def write(
30
+ path: str = "docs/handoff/NEXT_CHAT_BOOTSTRAP.md",
31
+ root: str = ".",
32
+ include_state: bool = False,
33
+ ) -> None:
34
+ output_path = write_next_chat_bootstrap(path, root, include_state=include_state)
35
+ typer.echo(f"WROTE {output_path}")
36
+
37
+
38
+ @boot_app.command("report")
39
+ def report(root: str = ".", path: str = "") -> None:
40
+ if path:
41
+ output_path = write_boot_report(path, root)
42
+ typer.echo(f"WROTE {output_path}")
43
+ else:
44
+ typer.echo(render_boot_report(root))
45
+
46
+
47
+ @boot_app.command("closeout")
48
+ def closeout(root: str = ".") -> None:
49
+ findings = run_chat_switch_closeout(root)
50
+ if findings:
51
+ typer.echo("CHAT_SWITCH_CLOSEOUT: FAIL")
52
+ for finding in findings:
53
+ typer.echo(f"- {finding}")
54
+ raise typer.Exit(code=1)
55
+ typer.echo("CHAT_SWITCH_CLOSEOUT: PASS")
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ import typer
4
+
5
+ from agentic_project_kit.chat_entrypoint_contract import (
6
+ render_chat_refresher,
7
+ render_chat_session_start,
8
+ )
9
+
10
+ chat_app = typer.Typer(help="Render command-manifest-aware chat entrypoints.")
11
+
12
+
13
+ @chat_app.command("refresher")
14
+ def chat_refresher_command(
15
+ mode: str = typer.Option("copy-paste", "--mode", help="copy-paste, remote, or file-transfer."),
16
+ ) -> None:
17
+ """Render the compact six-line command manifest refresher."""
18
+ try:
19
+ typer.echo(render_chat_refresher(mode), nl=False)
20
+ except ValueError as exc:
21
+ typer.echo(str(exc), err=True)
22
+ raise typer.Exit(2) from exc
23
+
24
+
25
+ @chat_app.command("session-start")
26
+ def chat_session_start_command(
27
+ mode: str = typer.Option("copy-paste", "--mode", help="copy-paste, remote, or file-transfer."),
28
+ ) -> None:
29
+ """Render the session-start refresher and full inline command list."""
30
+ try:
31
+ typer.echo(render_chat_session_start(mode), nl=False)
32
+ except ValueError as exc:
33
+ typer.echo(str(exc), err=True)
34
+ raise typer.Exit(2) from exc
@@ -0,0 +1,305 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Annotated
6
+
7
+ import typer
8
+ from rich.console import Console
9
+
10
+ from agentic_project_kit.checks import (
11
+ CheckContext,
12
+ build_check_context,
13
+ check_all,
14
+ check_docs,
15
+ check_todo,
16
+ )
17
+ from agentic_project_kit.doc_mesh import (
18
+ apply_doc_mesh_repair_plan,
19
+ build_doc_mesh_repair_plan,
20
+ build_doc_mesh_report,
21
+ render_doc_mesh_repair_plan,
22
+ render_doc_mesh_repair_result,
23
+ render_doc_mesh_report,
24
+ write_doc_mesh_json_report,
25
+ write_doc_mesh_repair_plan,
26
+ write_doc_mesh_repair_result,
27
+ )
28
+ from agentic_project_kit.doc_lifecycle import (
29
+ build_doc_lifecycle_report,
30
+ build_doc_lifecycle_strict_findings,
31
+ render_doc_lifecycle_report,
32
+ render_doc_lifecycle_strict_findings,
33
+ write_doc_lifecycle_json_report,
34
+ )
35
+ from agentic_project_kit.doc_lifecycle_signals import (
36
+ build_doc_orphan_report,
37
+ build_review_after_suggestions,
38
+ render_doc_orphan_report,
39
+ render_review_after_suggestions,
40
+ review_after_suggestions_to_dict,
41
+ write_doc_orphan_json_report,
42
+ )
43
+ from agentic_project_kit.documentation_registry import (
44
+ build_documentation_registry_summary,
45
+ render_documentation_registry_summary,
46
+ write_documentation_registry_summary_json,
47
+ )
48
+ from agentic_project_kit.documentation_system_audit import (
49
+ build_documentation_system_audit,
50
+ render_documentation_system_audit,
51
+ write_documentation_system_audit_json,
52
+ )
53
+ from agentic_project_kit.doctor import build_doctor_report, render_doctor_report
54
+
55
+ console = Console()
56
+
57
+
58
+ def register_check_commands(app: typer.Typer) -> None:
59
+ app.command("check")(check_command)
60
+ app.command("check-docs")(check_docs_command)
61
+ app.command("check-todo")(check_todo_command)
62
+ app.command("docs-audit")(docs_audit_command)
63
+ app.command("docs-registry")(docs_registry_command)
64
+ app.command("doc-mesh-audit")(doc_mesh_audit_command)
65
+ app.command("doc-lifecycle-audit")(doc_lifecycle_audit_command)
66
+ app.command("audit-doc-orphans")(audit_doc_orphans_command)
67
+ app.command("doc-mesh-repair")(doc_mesh_repair_command)
68
+ app.command("doctor")(doctor_command)
69
+
70
+
71
+ def check_command(
72
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
73
+ json_output: Annotated[
74
+ bool,
75
+ typer.Option("--json", help="Emit machine-readable check result with execution context."),
76
+ ] = False,
77
+ show_context: Annotated[
78
+ bool,
79
+ typer.Option("--context", help="Print check execution context before the text result."),
80
+ ] = False,
81
+ ) -> None:
82
+ root = project_root.resolve()
83
+ errors = check_all(root)
84
+ _print_result(
85
+ errors,
86
+ command="check",
87
+ project_root=root,
88
+ json_output=json_output,
89
+ show_context=show_context,
90
+ )
91
+
92
+
93
+ def check_docs_command(
94
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
95
+ json_output: Annotated[
96
+ bool,
97
+ typer.Option("--json", help="Emit machine-readable check result with execution context."),
98
+ ] = False,
99
+ show_context: Annotated[
100
+ bool,
101
+ typer.Option("--context", help="Print check execution context before the text result."),
102
+ ] = False,
103
+ ) -> None:
104
+ root = project_root.resolve()
105
+ errors = check_docs(root)
106
+ _print_result(
107
+ errors,
108
+ command="check-docs",
109
+ project_root=root,
110
+ json_output=json_output,
111
+ show_context=show_context,
112
+ )
113
+
114
+
115
+ def check_todo_command(project_root: Path = typer.Option(Path("."), "--root")) -> None:
116
+ errors = check_todo(project_root.resolve())
117
+ _print_result(errors)
118
+
119
+
120
+ def docs_audit_command(
121
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
122
+ report_path: Annotated[Path | None, typer.Option("--report")] = None,
123
+ ) -> None:
124
+ """Run the umbrella documentation-system audit."""
125
+ report = build_documentation_system_audit(project_root.resolve())
126
+ if report_path is not None:
127
+ write_documentation_system_audit_json(report, report_path)
128
+ console.print(render_documentation_system_audit(report), markup=False)
129
+ if not report.ok:
130
+ raise typer.Exit(code=1)
131
+
132
+
133
+ def docs_registry_command(
134
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
135
+ report_path: Annotated[Path | None, typer.Option("--report")] = None,
136
+ ) -> None:
137
+ """Show a read-only summary of the documentation registry."""
138
+ summary = build_documentation_registry_summary(project_root.resolve())
139
+ if report_path is not None:
140
+ write_documentation_registry_summary_json(summary, report_path)
141
+ console.print(render_documentation_registry_summary(summary), markup=False)
142
+
143
+
144
+ def doc_lifecycle_audit_command(
145
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
146
+ report_path: Annotated[Path | None, typer.Option("--report")] = None,
147
+ json_output: Annotated[bool, typer.Option("--json", help="Print JSON instead of text.")] = False,
148
+ strict: Annotated[
149
+ bool,
150
+ typer.Option("--strict", help="Fail on deterministic lifecycle blocker findings."),
151
+ ] = False,
152
+ current_version: Annotated[
153
+ str | None,
154
+ typer.Option("--current-version", help="Override the version used for release review_after checks."),
155
+ ] = None,
156
+ suggest_review_after: Annotated[
157
+ bool,
158
+ typer.Option("--suggest-review-after", help="Print report-only review_after suggestions from version target prose."),
159
+ ] = False,
160
+ ) -> None:
161
+ """Audit lifecycle status headers for planning, roadmap, strategy, and idea documents."""
162
+ if suggest_review_after:
163
+ suggestions = build_review_after_suggestions(project_root.resolve())
164
+ if json_output:
165
+ typer.echo(json.dumps(review_after_suggestions_to_dict(suggestions), indent=2, sort_keys=True))
166
+ else:
167
+ console.print(render_review_after_suggestions(suggestions), markup=False)
168
+ return
169
+
170
+ root = project_root.resolve()
171
+ report = build_doc_lifecycle_report(root, current_version=current_version)
172
+ strict_requested = strict or report.hygiene_mode == "strict"
173
+ strict_findings = (
174
+ build_doc_lifecycle_strict_findings(root, report=report)
175
+ if strict_requested
176
+ else ()
177
+ )
178
+ if report_path is not None:
179
+ write_doc_lifecycle_json_report(report, report_path)
180
+ if json_output:
181
+ payload = report.to_dict()
182
+ if strict_requested:
183
+ payload["strict"] = {
184
+ "ok": not strict_findings,
185
+ "blocker_count": len(strict_findings),
186
+ "blockers": [finding.to_dict() for finding in strict_findings],
187
+ "source": "--strict" if strict else "workspace hygiene",
188
+ }
189
+ typer.echo(json.dumps(payload, indent=2, sort_keys=True))
190
+ else:
191
+ console.print(render_doc_lifecycle_report(report), markup=False)
192
+ if strict_requested:
193
+ console.print(render_doc_lifecycle_strict_findings(strict_findings), markup=False)
194
+ if strict_requested and strict_findings:
195
+ raise typer.Exit(code=1)
196
+ if not report.ok:
197
+ raise typer.Exit(code=1)
198
+
199
+
200
+ def audit_doc_orphans_command(
201
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
202
+ report_path: Annotated[Path | None, typer.Option("--report")] = None,
203
+ json_output: Annotated[bool, typer.Option("--json", help="Print JSON instead of text.")] = False,
204
+ ) -> None:
205
+ """Report registered documents without incoming repository references."""
206
+ report = build_doc_orphan_report(project_root.resolve())
207
+ if report_path is not None:
208
+ write_doc_orphan_json_report(report, report_path)
209
+ if json_output:
210
+ typer.echo(json.dumps(report.to_dict(), indent=2, sort_keys=True))
211
+ else:
212
+ console.print(render_doc_orphan_report(report), markup=False)
213
+
214
+
215
+ def doc_mesh_audit_command(
216
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
217
+ report_path: Annotated[Path | None, typer.Option("--report")] = None,
218
+ repair_plan_path: Annotated[Path | None, typer.Option("--repair-plan")] = None,
219
+ ) -> None:
220
+ """Audit cross-document state, governance, architecture, and historical-plan drift."""
221
+ report = build_doc_mesh_report(project_root.resolve())
222
+ if report_path is not None:
223
+ write_doc_mesh_json_report(report, report_path)
224
+ if repair_plan_path is not None:
225
+ repair_plan = build_doc_mesh_repair_plan(report)
226
+ write_doc_mesh_repair_plan(repair_plan, repair_plan_path)
227
+ console.print(render_doc_mesh_repair_plan(repair_plan), markup=False)
228
+ console.print(render_doc_mesh_report(report), markup=False)
229
+ if not report.ok:
230
+ raise typer.Exit(code=1)
231
+
232
+
233
+ def doc_mesh_repair_command(
234
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
235
+ result_path: Annotated[Path | None, typer.Option("--result")] = None,
236
+ ) -> None:
237
+ """Apply safe automatic documentation mesh repairs."""
238
+ report = build_doc_mesh_report(project_root.resolve())
239
+ repair_plan = build_doc_mesh_repair_plan(report)
240
+ result = apply_doc_mesh_repair_plan(project_root.resolve(), repair_plan)
241
+ if result_path is not None:
242
+ write_doc_mesh_repair_result(result, result_path)
243
+ console.print(render_doc_mesh_repair_result(result), markup=False)
244
+
245
+
246
+ def doctor_command(project_root: Path = typer.Option(Path("."), "--root")) -> None:
247
+ """Run a compact project health check."""
248
+ report = build_doctor_report(project_root.resolve())
249
+ console.print(render_doctor_report(report), markup=False)
250
+ if not report.ok:
251
+ raise typer.Exit(code=1)
252
+
253
+
254
+ def _print_result(
255
+ errors: list[str],
256
+ *,
257
+ command: str | None = None,
258
+ project_root: Path | None = None,
259
+ json_output: bool = False,
260
+ show_context: bool = False,
261
+ ) -> None:
262
+ if json_output:
263
+ if command is None or project_root is None:
264
+ raise RuntimeError("JSON check output requires command and project root context")
265
+ payload = _check_result_payload(command, project_root, errors)
266
+ typer.echo(json.dumps(payload, indent=2, sort_keys=True))
267
+ if errors:
268
+ raise typer.Exit(code=1)
269
+ return
270
+ if show_context and project_root is not None:
271
+ _print_check_context(build_check_context(project_root))
272
+ if errors:
273
+ console.print("[bold red]Agentic project check failed[/bold red]")
274
+ for error in errors:
275
+ console.print(f"[red]- {error}[/red]")
276
+ raise typer.Exit(code=1)
277
+ console.print("[bold green]Agentic project check passed[/bold green]")
278
+
279
+
280
+ def _check_result_payload(command: str, project_root: Path, errors: list[str]) -> dict[str, object]:
281
+ return {
282
+ "schema_version": 1,
283
+ "kind": "agentic_project_check_result",
284
+ "command": command,
285
+ "status": "PASS" if not errors else "FAIL",
286
+ "error_count": len(errors),
287
+ "errors": errors,
288
+ "context": build_check_context(project_root).as_dict(),
289
+ }
290
+
291
+
292
+ def _print_check_context(context: CheckContext) -> None:
293
+ console.print("CHECK_CONTEXT", markup=False)
294
+ console.print(f"MODE={context.mode}", markup=False)
295
+ console.print(
296
+ f"EXTERNAL_MANIFEST_WORKSPACE={str(context.external_manifest_workspace).lower()}",
297
+ markup=False,
298
+ )
299
+ console.print(f"GATE_FAMILY={context.gate_family}", markup=False)
300
+ console.print(f"CHECK_RENDERS_STATUSES={str(context.check_renders_statuses).lower()}", markup=False)
301
+ console.print(f"SKIP_STATUS_RENDERER={context.skip_status_renderer}", markup=False)
302
+ if context.gate_documents:
303
+ console.print(f"GATE_DOCUMENTS={','.join(context.gate_documents)}", markup=False)
304
+ if context.invalid_manifest_error:
305
+ console.print(f"INVALID_MANIFEST_ERROR={context.invalid_manifest_error}", markup=False)
@@ -0,0 +1,103 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Annotated
6
+
7
+ import typer
8
+ from rich.console import Console
9
+
10
+ from agentic_project_kit.cockpit import (
11
+ action_inventory_as_json_data,
12
+ action_result_as_json_data,
13
+ build_cockpit_status,
14
+ cockpit_actions,
15
+ render_action_inventory,
16
+ render_action_selection,
17
+ render_cockpit_status,
18
+ run_cockpit_action,
19
+ )
20
+ from agentic_project_kit.gui_gatekeeper_status import (
21
+ build_gui_gatekeeper_status,
22
+ gui_gatekeeper_status_as_json_data,
23
+ render_gui_gatekeeper_status,
24
+ )
25
+
26
+
27
+ cockpit_app = typer.Typer(help="Inspect local cockpit status and structured project actions.")
28
+ console = Console()
29
+
30
+
31
+ @cockpit_app.command("status")
32
+ def cockpit_status_command(project_root: Annotated[Path, typer.Option("--root")] = Path(".")) -> None:
33
+ status = build_cockpit_status(project_root.resolve())
34
+ console.print(render_cockpit_status(status), markup=False)
35
+
36
+
37
+ @cockpit_app.command("gatekeeper-status")
38
+ def cockpit_gatekeeper_status_command(
39
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
40
+ json_output: Annotated[
41
+ bool,
42
+ typer.Option("--json", help="Print machine-readable JSON GUI gatekeeper status."),
43
+ ] = False,
44
+ ) -> None:
45
+ status = build_gui_gatekeeper_status(project_root.resolve())
46
+ if json_output:
47
+ typer.echo(json.dumps(gui_gatekeeper_status_as_json_data(status), indent=2, sort_keys=True))
48
+ return
49
+ console.print(render_gui_gatekeeper_status(status), markup=False)
50
+
51
+
52
+ @cockpit_app.command("actions")
53
+ def cockpit_actions_command(
54
+ json_output: Annotated[
55
+ bool,
56
+ typer.Option("--json", help="Print machine-readable JSON action inventory."),
57
+ ] = False,
58
+ ) -> None:
59
+ actions = cockpit_actions()
60
+ if json_output:
61
+ typer.echo(json.dumps(action_inventory_as_json_data(actions), indent=2, sort_keys=True))
62
+ return
63
+ console.print(render_action_inventory(actions), markup=False)
64
+
65
+
66
+ @cockpit_app.command("select")
67
+ def cockpit_select_command() -> None:
68
+ actions = cockpit_actions()
69
+ console.print(render_action_selection(actions), markup=False)
70
+
71
+
72
+ @cockpit_app.command("run")
73
+ def cockpit_run_command(
74
+ action_id: str,
75
+ project_root: Annotated[Path, typer.Option("--root")] = Path("."),
76
+ allow_bounded: Annotated[bool, typer.Option("--allow-bounded")] = False,
77
+ json_output: Annotated[bool, typer.Option("--json", help="Print machine-readable JSON action result.")] = False,
78
+ ) -> None:
79
+ result = run_cockpit_action(action_id, project_root.resolve(), allow_bounded=allow_bounded)
80
+ if json_output:
81
+ typer.echo(json.dumps(action_result_as_json_data(result), indent=2, sort_keys=True))
82
+ if not result.allowed:
83
+ raise typer.Exit(code=2)
84
+ if result.returncode not in (None, 0):
85
+ raise typer.Exit(code=result.returncode)
86
+ return
87
+ console.print(f"action_id={result.action_id}", markup=False)
88
+ console.print(f"allowed={str(result.allowed).lower()}", markup=False)
89
+ console.print(f"executed={str(result.executed).lower()}", markup=False)
90
+ console.print(f"result_status={result.result_status}", markup=False)
91
+ console.print(f"safety={result.safety}", markup=False)
92
+ console.print(f"dirty_state={result.dirty_state}", markup=False)
93
+ if result.returncode is not None:
94
+ console.print(f"returncode={result.returncode}", markup=False)
95
+ console.print(result.message, markup=False)
96
+ if result.stdout:
97
+ console.print(result.stdout, markup=False)
98
+ if result.stderr:
99
+ console.print(result.stderr, markup=False)
100
+ if not result.allowed:
101
+ raise typer.Exit(code=2)
102
+ if result.returncode not in (None, 0):
103
+ raise typer.Exit(code=result.returncode)
@@ -0,0 +1,25 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ import typer
7
+
8
+ from agentic_project_kit.command_taxonomy import (
9
+ build_command_taxonomy_report,
10
+ render_command_taxonomy_report,
11
+ )
12
+
13
+
14
+ def command_taxonomy_check_command(
15
+ root: Path = typer.Option(Path("."), "--root"),
16
+ json_output: bool = typer.Option(False, "--json"),
17
+ ) -> None:
18
+ """Check that public commands have stable GUI-usable taxonomy."""
19
+ report = build_command_taxonomy_report(root.resolve())
20
+ if json_output:
21
+ typer.echo(json.dumps(report.as_dict(), indent=2, sort_keys=True))
22
+ else:
23
+ typer.echo(render_command_taxonomy_report(report), nl=False)
24
+ if not report.ok:
25
+ raise typer.Exit(code=1)
@@ -0,0 +1,129 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ import typer
7
+
8
+ from agentic_project_kit.command_selector import (
9
+ render_command_selection,
10
+ select_for_raw,
11
+ select_for_task,
12
+ )
13
+ from agentic_project_kit.command_manifest import (
14
+ MD_PATH,
15
+ build_current_reference,
16
+ evaluate_command_manifest,
17
+ load_manifest,
18
+ render_command_manifest_audit,
19
+ render_markdown,
20
+ )
21
+ from agentic_project_kit.command_authority_audit import (
22
+ evaluate_command_authority,
23
+ render_command_authority_audit,
24
+ )
25
+ from agentic_project_kit.chat_entrypoint_contract import sync_entrypoint_files
26
+
27
+
28
+ commands_app = typer.Typer(help="Inspect and render the agentic-kit command manifest.")
29
+
30
+
31
+ @commands_app.command("render-md")
32
+ def commands_render_md_command(
33
+ root: Path = typer.Option(Path("."), "--root", help="Repository root."),
34
+ execute: bool = typer.Option(False, "--execute", help="Write generated Markdown."),
35
+ json_output: bool = typer.Option(False, "--json", help="Print machine-readable JSON."),
36
+ ) -> None:
37
+ """Render docs/reference/AGENTIC_KIT_COMMANDS.md from the JSON manifest."""
38
+ root = root.resolve()
39
+ data = load_manifest(root)
40
+ rendered = render_markdown(data)
41
+ path = root / MD_PATH
42
+ changed = path.read_text(encoding="utf-8") != rendered if path.exists() else True
43
+ if execute:
44
+ path.write_text(rendered, encoding="utf-8")
45
+ payload = {
46
+ "schema_version": 1,
47
+ "kind": "commands_render_md_result",
48
+ "result_status": "PASS",
49
+ "path": MD_PATH.as_posix(),
50
+ "changed": changed,
51
+ "written": bool(execute),
52
+ "manifest_sha": (data.get("meta") or {}).get("manifest_sha"),
53
+ }
54
+ if json_output:
55
+ typer.echo(json.dumps(payload, indent=2, sort_keys=True))
56
+ else:
57
+ if execute:
58
+ typer.echo(f"COMMANDS_RENDER_MD\nSTATUS=PASS\nWRITTEN={path.as_posix()}\n")
59
+ else:
60
+ typer.echo(rendered, nl=False)
61
+
62
+
63
+ @commands_app.command("sync-entrypoints")
64
+ def commands_sync_entrypoints_command(
65
+ root: Path = typer.Option(Path("."), "--root", help="Repository root."),
66
+ execute: bool = typer.Option(False, "--execute", help="Write synchronized entrypoint files."),
67
+ json_output: bool = typer.Option(False, "--json", help="Print machine-readable JSON."),
68
+ ) -> None:
69
+ """Synchronize command reference files and command-manifest entrypoint headers."""
70
+ root = root.resolve()
71
+ data = build_current_reference()
72
+ rendered = render_markdown(data)
73
+ payload = sync_entrypoint_files(root, manifest=data, markdown=rendered, execute=execute)
74
+ if json_output:
75
+ typer.echo(json.dumps(payload, indent=2, sort_keys=True))
76
+ return
77
+ status = "CHANGED" if payload["changed"] else "CURRENT"
78
+ typer.echo(
79
+ "COMMANDS_SYNC_ENTRYPOINTS\n"
80
+ f"STATUS=PASS\nSTATE={status}\n"
81
+ f"MANIFEST_SHA={payload['manifest_sha']}\n"
82
+ f"EXECUTE={str(execute).lower()}\n"
83
+ )
84
+
85
+
86
+ def audit_command_manifest_command(
87
+ root: Path = typer.Option(Path("."), "--root", help="Repository root."),
88
+ json_output: bool = typer.Option(False, "--json", help="Print machine-readable JSON."),
89
+ ) -> None:
90
+ """Audit command manifest hash, CLI coverage, safety metadata, and MD sync."""
91
+ audit = evaluate_command_manifest(root.resolve())
92
+ if json_output:
93
+ typer.echo(json.dumps(audit.as_dict(), indent=2, sort_keys=True))
94
+ else:
95
+ typer.echo(render_command_manifest_audit(audit), nl=False)
96
+ if not audit.ok:
97
+ raise typer.Exit(code=audit.returncode)
98
+
99
+
100
+ def audit_command_authority_command(
101
+ root: Path = typer.Option(Path("."), "--root", help="Repository root."),
102
+ json_output: bool = typer.Option(False, "--json", help="Print machine-readable JSON."),
103
+ ) -> None:
104
+ """Audit agent-facing command authority surfaces for current command-for guidance."""
105
+ audit = evaluate_command_authority(root.resolve())
106
+ if json_output:
107
+ typer.echo(json.dumps(audit.as_dict(), indent=2, sort_keys=True))
108
+ else:
109
+ typer.echo(render_command_authority_audit(audit), nl=False)
110
+ if not audit.ok:
111
+ raise typer.Exit(code=audit.returncode)
112
+
113
+
114
+ def command_for_command(
115
+ raw: str | None = typer.Option(None, "--raw", help="Raw command line to map to a wrapper."),
116
+ task: str | None = typer.Option(None, "--task", help="Task tag to list matching commands."),
117
+ root: Path = typer.Option(Path("."), "--root", help="Repository root."),
118
+ json_output: bool = typer.Option(False, "--json", help="Print machine-readable JSON."),
119
+ ) -> None:
120
+ """Select the deterministic wrapper command for a raw command or task tag."""
121
+ if bool(raw) == bool(task):
122
+ typer.echo("Provide exactly one of --raw or --task.", err=True)
123
+ raise typer.Exit(code=2)
124
+ manifest = load_manifest(root.resolve())
125
+ selection = select_for_raw(manifest, raw) if raw is not None else select_for_task(manifest, str(task))
126
+ if json_output:
127
+ typer.echo(json.dumps(selection.payload, indent=2, sort_keys=True))
128
+ else:
129
+ typer.echo(render_command_selection(selection), nl=False)
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ import typer
4
+
5
+ from agentic_project_kit.local_feature_gate import run_local_feature_gate
6
+
7
+ dev_app = typer.Typer(help="Run local developer gates without remote side effects.")
8
+
9
+
10
+ @dev_app.command("local-feature-gate", context_settings={"allow_extra_args": True, "ignore_unknown_options": True})
11
+ def local_feature_gate_command(
12
+ ctx: typer.Context,
13
+ include_pr_hygiene: bool = typer.Option(
14
+ False,
15
+ "--include-pr-hygiene",
16
+ help="Also run PR hygiene after the local feature gate.",
17
+ ),
18
+ ) -> None:
19
+ """Run the local feature gate through the supported agentic-kit CLI."""
20
+ pytest_args = list(ctx.args)
21
+ if pytest_args[:1] == ["--"]:
22
+ pytest_args = pytest_args[1:]
23
+ raise typer.Exit(code=run_local_feature_gate(pytest_args, include_pr_hygiene=include_pr_hygiene))