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,251 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ import typer
6
+
7
+ from agentic_project_kit.evidence_clean import check_clean_except_expected_log, clean_local_evidence
8
+ from agentic_project_kit.evidence_commit_paths import commit_paths
9
+ from agentic_project_kit.evidence_commit_paths import render_commit_paths_result
10
+ from agentic_project_kit.evidence_finalize_log import finalize_log
11
+ from agentic_project_kit.evidence_finalize_log import render_finalize_log_error
12
+ from agentic_project_kit.evidence_finalize_log import render_finalize_log_result
13
+ from agentic_project_kit.evidence_guard import check_change_scope
14
+ from agentic_project_kit.evidence_guard import check_terminal_log
15
+ from agentic_project_kit.evidence_inspector import classify_log
16
+ from agentic_project_kit.evidence_inspector import inspect_evidence
17
+ from agentic_project_kit.evidence_inspector import render_evidence_inspection
18
+ from agentic_project_kit.evidence_inspector import render_log_classification
19
+
20
+ app = typer.Typer(help="Validate terminal evidence logs.")
21
+
22
+
23
+ @app.command("guard")
24
+ def guard(logfile: Path) -> None:
25
+ """Fail if a terminal evidence log has contradictory final state."""
26
+ result = check_terminal_log(logfile)
27
+ status = "PASS" if result.ok else "FAIL"
28
+ typer.echo(f"{status}: {result.path} final_result={result.final_result}")
29
+ for finding in result.findings:
30
+ typer.echo(f" - {finding}")
31
+ if not result.ok:
32
+ raise typer.Exit(1)
33
+
34
+
35
+ @app.command("inspect")
36
+ def inspect(
37
+ path: Path | None = typer.Argument(None),
38
+ root: Path = typer.Option(Path("."), "--root"),
39
+ require_summary: bool = typer.Option(False, "--require-summary"),
40
+ ) -> None:
41
+ """Inspect explicit or latest terminal evidence before continuing after chat control signals."""
42
+ result = inspect_evidence(path, root=root, require_summary=require_summary)
43
+ typer.echo(render_evidence_inspection(result))
44
+ if not result.success:
45
+ raise typer.Exit(code=1)
46
+
47
+
48
+ @app.command("classify-log")
49
+ def classify_log_command(
50
+ path: Path | None = typer.Argument(None),
51
+ root: Path = typer.Option(Path("."), "--root"),
52
+ require_summary: bool = typer.Option(False, "--require-summary"),
53
+ ignore_git_status: bool = typer.Option(False, "--ignore-git-status"),
54
+ ) -> None:
55
+ """Classify a terminal/evidence log for deterministic gatekeeper decisions."""
56
+ result = classify_log(
57
+ path,
58
+ root=root,
59
+ require_summary=require_summary,
60
+ check_git_status=not ignore_git_status,
61
+ )
62
+ typer.echo(render_log_classification(result))
63
+ if not result.success:
64
+ raise typer.Exit(code=1)
65
+
66
+
67
+ @app.command("finalize-log")
68
+ def finalize_log_command(
69
+ run_log: Path = typer.Option(..., "--run-log"),
70
+ remote_log: Path = typer.Option(..., "--remote-log"),
71
+ slice_name: str = typer.Option(..., "--slice"),
72
+ scope: str = typer.Option(..., "--scope"),
73
+ mode_check: str = typer.Option(..., "--mode-check"),
74
+ work: str = typer.Option("PASS", "--work"),
75
+ evidence: str = typer.Option("PASS", "--evidence"),
76
+ overall: str = typer.Option("PASS", "--overall"),
77
+ remote_evidence: str = typer.Option("NOT_REQUIRED", "--remote-evidence"),
78
+ pr: str = typer.Option("NONE", "--pr"),
79
+ ci: str = typer.Option("not-required", "--ci"),
80
+ merge: str = typer.Option("not-required", "--merge"),
81
+ command_report: str = typer.Option(..., "--command-report"),
82
+ interpretation: str = typer.Option(..., "--interpretation"),
83
+ safe_step: str = typer.Option(..., "--safe-step"),
84
+ chat_reply: str = typer.Option("d", "--next"),
85
+ origin: str = typer.Option("local", "--origin"),
86
+ state_mode: str = typer.Option("local", "--state-mode"),
87
+ comm_id: str = typer.Option("COMM-LOCAL", "--comm-id"),
88
+ commit_message: str | None = typer.Option(None, "--commit-message"),
89
+ push: bool = typer.Option(False, "--push"),
90
+ required_branch: str = typer.Option("", "--branch", help="Expected branch for finalize-log commits."),
91
+ allow_main: bool = typer.Option(False, "--allow-main", help="Allow finalize-log to commit on main."),
92
+ root: Path = typer.Option(Path("."), "--root"),
93
+ ) -> None:
94
+ """Append a canonical summary, require strict inspection, then upload the evidence log."""
95
+ try:
96
+ result = finalize_log(
97
+ root=root,
98
+ run_log=run_log,
99
+ remote_log=remote_log,
100
+ slice_name=slice_name,
101
+ scope=scope,
102
+ mode_check=mode_check,
103
+ work=work,
104
+ evidence=evidence,
105
+ overall=overall,
106
+ remote_evidence=remote_evidence,
107
+ pr=pr,
108
+ ci=ci,
109
+ merge=merge,
110
+ command_report=command_report,
111
+ interpretation=interpretation,
112
+ safe_step=safe_step,
113
+ chat_reply=chat_reply,
114
+ origin=origin,
115
+ state_mode=state_mode,
116
+ comm_id=comm_id,
117
+ commit_message=commit_message,
118
+ push=push,
119
+ required_branch=required_branch,
120
+ allow_main=allow_main,
121
+ )
122
+ except (ValueError, FileNotFoundError) as exc:
123
+ typer.echo(render_finalize_log_error(str(exc)))
124
+ raise typer.Exit(code=1) from None
125
+ typer.echo(render_finalize_log_result(result))
126
+ if not result.success:
127
+ raise typer.Exit(code=1)
128
+
129
+
130
+ @app.command("commit-paths")
131
+ def commit_paths_command(
132
+ path: list[str] = typer.Option([], "--path", help="Repository-relative path to commit. Repeat for multiple paths."),
133
+ message: str = typer.Option(..., "--message"),
134
+ log_path: str | None = typer.Option(None, "--log-path"),
135
+ push: bool = typer.Option(False, "--push"),
136
+ required_branch: str = typer.Option("", "--branch", help="Expected branch for evidence commit-paths commits."),
137
+ allow_main: bool = typer.Option(False, "--allow-main", help="Allow evidence commit-paths to commit on main."),
138
+ root: Path = typer.Option(Path("."), "--root"),
139
+ ) -> None:
140
+ """Commit an explicit evidence path set and verify the worktree is clean afterwards."""
141
+ try:
142
+ result = commit_paths(
143
+ root=root,
144
+ paths=tuple(path),
145
+ message=message,
146
+ log_path=log_path,
147
+ push=push,
148
+ required_branch=required_branch,
149
+ allow_main=allow_main,
150
+ )
151
+ except ValueError as exc:
152
+ typer.echo("EVIDENCE_COMMIT_PATHS")
153
+ typer.echo("success=no")
154
+ typer.echo(f"finding={exc}")
155
+ typer.echo("### RESULT: FAIL ###")
156
+ raise typer.Exit(code=1) from None
157
+ typer.echo(render_commit_paths_result(result))
158
+ if not result.success:
159
+ raise typer.Exit(code=1)
160
+
161
+
162
+ @app.command("scope-check")
163
+ def scope_check(
164
+ changed: list[str] = typer.Option([], "--changed", help="Changed repository path. Repeat for multiple paths."),
165
+ expected: list[str] = typer.Option([], "--expected", help="Expected target path. Repeat for multiple paths."),
166
+ ) -> None:
167
+ """Fail if expected target paths are missing from a change set."""
168
+ result = check_change_scope(changed_paths=changed, expected_paths=expected)
169
+ status = "PASS" if result.ok else "FAIL"
170
+ typer.echo(f"{status}: change scope check")
171
+ typer.echo("changed_paths=" + ", ".join(result.changed_paths))
172
+ typer.echo("expected_paths=" + ", ".join(result.expected_paths))
173
+ for finding in result.findings:
174
+ typer.echo(f" - {finding}")
175
+ if not result.ok:
176
+ raise typer.Exit(1)
177
+
178
+
179
+ @app.command("clean-check")
180
+ def clean_check(expected_log: str = typer.Argument(...), root: Path = typer.Option(Path("."), "--root")) -> None:
181
+ """Pass when git status is clean except one expected in-progress log."""
182
+ result = check_clean_except_expected_log(root.resolve(), expected_log)
183
+ if result.ok:
184
+ typer.echo("PASS: worktree clean except expected log: " + result.expected_log)
185
+ return
186
+ typer.echo("FAIL: worktree dirty beyond expected log: " + result.expected_log)
187
+ for line in result.unexpected_lines:
188
+ typer.echo(line)
189
+ raise typer.Exit(code=1)
190
+
191
+
192
+ @app.command("clean")
193
+ def clean(root: Path = typer.Option(Path("."), "--root")) -> None:
194
+ """Clean local evidence according to repo policy."""
195
+ result = clean_local_evidence(root.resolve())
196
+
197
+ typer.echo("\n\n\n")
198
+ typer.echo("-------------------------------------------------------------------------")
199
+ typer.echo("-------------------------------------------------------------------------")
200
+ typer.echo("-------------------------------------------------------------------------")
201
+ typer.echo("\n\n\n")
202
+ typer.echo("NS CLEAN EVIDENCE")
203
+
204
+ typer.echo("\n### SAFETY ###")
205
+ typer.echo(
206
+ "Safety: removes ignored tmp evidence and restores known tracked workflow evidence only; "
207
+ "does not delete arbitrary docs/reports files."
208
+ )
209
+
210
+ typer.echo("\n### BEFORE STATUS ###")
211
+ if result.before_status:
212
+ for line in result.before_status:
213
+ typer.echo(line)
214
+ else:
215
+ typer.echo("clean")
216
+
217
+ typer.echo("\n### RESTORE KNOWN TRACKED WORKFLOW EVIDENCE ###")
218
+ for line in result.restore_lines:
219
+ typer.echo(line)
220
+
221
+ typer.echo("\n### REMOVE IGNORED TMP EVIDENCE ###")
222
+ if result.removed_tmp_evidence:
223
+ typer.echo("remove_ignored_dir=tmp/agent-evidence")
224
+ else:
225
+ typer.echo("no_ignored_tmp_evidence=tmp/agent-evidence")
226
+
227
+ typer.echo("\n### UNTRACKED DOC REPORTS REVIEW ###")
228
+ if result.untracked_doc_reports:
229
+ for line in result.untracked_doc_reports:
230
+ typer.echo(line)
231
+ typer.echo("NEEDS_HUMAN_REVIEW: untracked docs/reports files were not deleted automatically.")
232
+ else:
233
+ typer.echo("No untracked docs/reports files found.")
234
+
235
+ if result.errors:
236
+ typer.echo("\n### ERRORS ###")
237
+ for line in result.errors:
238
+ typer.echo(line)
239
+
240
+ typer.echo("\n### AFTER STATUS ###")
241
+ if result.after_status:
242
+ for line in result.after_status:
243
+ typer.echo(line)
244
+ else:
245
+ typer.echo("clean")
246
+
247
+ if result.ok:
248
+ typer.echo("\n### RESULT: PASS ###")
249
+ return
250
+ typer.echo("\n### RESULT: FAIL ###")
251
+ raise typer.Exit(code=1)
@@ -0,0 +1,34 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+
5
+ import typer
6
+ from rich.console import Console
7
+ from rich.prompt import Confirm
8
+
9
+ from agentic_project_kit.github import create_github_repo
10
+
11
+ console = Console()
12
+
13
+
14
+ def register_github_commands(app: typer.Typer) -> None:
15
+ app.command(
16
+ "github-create",
17
+ help="Create and push a GitHub repository for an initialized project.",
18
+ )(github_create_command)
19
+
20
+
21
+ def github_create_command(
22
+ project_root: Path = typer.Option(Path("."), "--root"),
23
+ owner: str | None = typer.Option(None, "--owner"),
24
+ visibility: str = typer.Option("private", "--visibility"),
25
+ ) -> None:
26
+ if visibility not in {"private", "public"}:
27
+ raise typer.BadParameter("visibility must be private or public")
28
+ if visibility == "public":
29
+ console.print("[bold yellow]Public repository selected. Check for secrets before continuing.[/bold yellow]")
30
+ if not Confirm.ask("Continue?", default=False):
31
+ raise typer.Exit(code=1)
32
+
33
+ create_github_repo(project_root.resolve(), owner=owner, visibility=visibility, push=True)
34
+ console.print("[green]GitHub repository created and pushed.[/green]")
@@ -0,0 +1,14 @@
1
+ from __future__ import annotations
2
+
3
+ import typer
4
+
5
+ from agentic_project_kit.governance import governance_check, render_governance_check
6
+
7
+ governance_app = typer.Typer(help="Run deterministic project governance checks.")
8
+
9
+ @governance_app.command("check")
10
+ def check_command() -> None:
11
+ errors = governance_check()
12
+ typer.echo(render_governance_check(errors))
13
+ if errors:
14
+ raise typer.Exit(code=1)
@@ -0,0 +1,23 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ import typer
7
+
8
+ from agentic_project_kit.gui_task_editor import build_initial_llm_prompt
9
+
10
+
11
+ gui_app = typer.Typer(help="Render GUI-facing prompts and helper metadata.")
12
+
13
+
14
+ @gui_app.command("initial-llm-prompt")
15
+ def initial_llm_prompt(
16
+ root: Path = typer.Option(Path("."), "--root", help="Project root whose GUI prompt should be rendered."),
17
+ json_output: bool = typer.Option(False, "--json", help="Print machine-readable JSON."),
18
+ ) -> None:
19
+ result = build_initial_llm_prompt(project_root=root)
20
+ if json_output:
21
+ typer.echo(json.dumps(result.as_json_data(), indent=2, sort_keys=True))
22
+ else:
23
+ typer.echo(result.prompt_text)
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+
6
+ import typer
7
+
8
+ from agentic_project_kit import __version__ as PACKAGE_VERSION
9
+ from agentic_project_kit.gui_readiness_gate import (
10
+ evaluate_gui_readiness,
11
+ render_gui_readiness_gate,
12
+ )
13
+
14
+
15
+ def gui_readiness_gate_command(
16
+ root: Path = typer.Option(Path("."), "--root"),
17
+ version: str = typer.Option(PACKAGE_VERSION, "--version"),
18
+ json_output: bool = typer.Option(False, "--json"),
19
+ ) -> None:
20
+ """Run the pre-GUI readiness gate."""
21
+ result = evaluate_gui_readiness(root.resolve(), version=version)
22
+ if json_output:
23
+ typer.echo(json.dumps(result.as_dict(), indent=2, sort_keys=True))
24
+ else:
25
+ typer.echo(render_gui_readiness_gate(result), nl=False)
26
+ if not result.ok:
27
+ raise typer.Exit(code=result.returncode)
@@ -0,0 +1,183 @@
1
+ from __future__ import annotations
2
+
3
+ import subprocess
4
+
5
+ from pathlib import Path
6
+ from typing import Annotated, Any
7
+
8
+ import typer
9
+
10
+ from agentic_project_kit.documentation_registry import build_documentation_registry_summary
11
+ from agentic_project_kit.handoff_freshness import (
12
+ assess_handoff_prompt_freshness,
13
+ render_freshness_guard,
14
+ )
15
+ from agentic_project_kit.handoff_prompt import render_handoff_prompt
16
+ from agentic_project_kit.handoff_state import (
17
+ current_git_safe_state,
18
+ load_handoff_state,
19
+ refresh_handoff_safe_state,
20
+ save_handoff_state,
21
+ summarize_handoff_state,
22
+ validate_handoff_state,
23
+ )
24
+
25
+ from agentic_project_kit.post_merge_handoff_refresh import evaluate_post_merge_handoff_refresh, render_post_merge_handoff_refresh_status
26
+
27
+ handoff_app = typer.Typer(help="Read-only persistent handoff state commands.")
28
+
29
+
30
+ @handoff_app.command("show")
31
+ def show(path: str = ".agentic/handoff_state.yaml") -> None:
32
+ data = load_handoff_state(path)
33
+ typer.echo(summarize_handoff_state(data))
34
+
35
+
36
+ @handoff_app.command("check")
37
+ def check(path: str = ".agentic/handoff_state.yaml") -> None:
38
+ data = load_handoff_state(path)
39
+ errors = validate_handoff_state(data)
40
+ if errors:
41
+ for error in errors:
42
+ typer.echo(f"[FAIL] {error}")
43
+ raise typer.Exit(code=1)
44
+ typer.echo("Persistent handoff state check passed")
45
+ registry_lines = _render_registry_summary(path)
46
+ if registry_lines:
47
+ typer.echo(registry_lines)
48
+
49
+
50
+ @handoff_app.command("prompt")
51
+ def prompt(
52
+ path: str = ".agentic/handoff_state.yaml",
53
+ intended_output: Annotated[
54
+ str | None,
55
+ typer.Option(
56
+ "--intended-output",
57
+ help="Prompt path that this render will write after generation.",
58
+ ),
59
+ ] = None,
60
+ ) -> None:
61
+ data = load_handoff_state(path)
62
+ errors = validate_handoff_state(data)
63
+ if errors:
64
+ for error in errors:
65
+ typer.echo(f"[FAIL] {error}")
66
+ raise typer.Exit(code=1)
67
+ rendered_prompt = render_handoff_prompt(data)
68
+ guard = render_freshness_guard(
69
+ assess_handoff_prompt_freshness(
70
+ data,
71
+ path,
72
+ successor_prompt_text=rendered_prompt,
73
+ intended_successor_prompt_path=intended_output,
74
+ )
75
+ )
76
+ if guard:
77
+ typer.echo(guard, nl=False)
78
+ typer.echo(rendered_prompt, nl=False)
79
+
80
+
81
+ @handoff_app.command("refresh")
82
+ def refresh(
83
+ path: Annotated[str, typer.Argument()] = ".agentic/handoff_state.yaml",
84
+ write: bool = typer.Option(False, "--write", help="Write refreshed safe_state to YAML."),
85
+ ) -> None:
86
+ data = load_handoff_state(path)
87
+ git_state = current_git_safe_state()
88
+ refreshed = refresh_handoff_safe_state(
89
+ data,
90
+ git_state["commit"],
91
+ git_state["commit_subject"],
92
+ )
93
+ errors = validate_handoff_state(refreshed)
94
+ if errors:
95
+ for error in errors:
96
+ typer.echo(f"[FAIL] {error}")
97
+ raise typer.Exit(code=1)
98
+ current = data.get("safe_state", {})
99
+ updated = refreshed.get("safe_state", {})
100
+ typer.echo(f"Current safe_state: {current.get('commit')} {current.get('commit_subject')}")
101
+ typer.echo(f"Refreshed safe_state: {updated.get('commit')} {updated.get('commit_subject')}")
102
+ if write:
103
+ save_handoff_state(refreshed, path)
104
+ typer.echo(f"Updated {path}")
105
+ else:
106
+ typer.echo("Dry run only. Use --write to update the YAML file.")
107
+
108
+
109
+ def _render_registry_summary(handoff_path: str) -> str:
110
+ summary = _load_registry_summary(handoff_path)
111
+ if summary is None:
112
+ return ""
113
+ lines = [
114
+ "Documentation registry:",
115
+ f"- registry: {summary['registry_path']}",
116
+ f"- version: {summary['version']}",
117
+ f"- documents: {summary['document_count']}",
118
+ f"- broad_migration_allowed: {summary['broad_migration_allowed']}",
119
+ ]
120
+ class_counts = summary.get("class_counts", {})
121
+ if isinstance(class_counts, dict):
122
+ for class_name, count in class_counts.items():
123
+ lines.append(f"- class:{class_name}: {count}")
124
+ return "\n".join(lines)
125
+
126
+
127
+ def _load_registry_summary(handoff_path: str) -> dict[str, Any] | None:
128
+ project_root = _project_root_for_handoff_path(Path(handoff_path))
129
+ try:
130
+ return build_documentation_registry_summary(project_root)
131
+ except (OSError, ValueError):
132
+ return None
133
+
134
+
135
+ def _project_root_for_handoff_path(path: Path) -> Path:
136
+ if path.name == "handoff_state.yaml" and path.parent.name == ".agentic":
137
+ return path.parent.parent
138
+ return Path.cwd()
139
+
140
+
141
+
142
+ def _current_head_is_refresh_only_merge_commit() -> bool:
143
+ """Return true when current HEAD is a merged successor handoff refresh PR."""
144
+
145
+ completed = subprocess.run(
146
+ ["git", "log", "-1", "--pretty=%s"],
147
+ text=True,
148
+ stdout=subprocess.PIPE,
149
+ stderr=subprocess.PIPE,
150
+ check=False,
151
+ )
152
+ if completed.returncode != 0:
153
+ return False
154
+ subject = completed.stdout.strip()
155
+ return (
156
+ (
157
+ subject.startswith("Refresh successor handoff after PR")
158
+ or subject.startswith("Refresh handoff state after PR")
159
+ )
160
+ and "(#" in subject
161
+ and subject.endswith(")")
162
+ )
163
+
164
+ @handoff_app.command("post-merge-refresh-status")
165
+ def post_merge_refresh_status() -> None:
166
+ status = evaluate_post_merge_handoff_refresh(Path("."))
167
+ refresh_only_merge_commit_is_fresh = (
168
+ status.refresh_required and _current_head_is_refresh_only_merge_commit()
169
+ )
170
+ if refresh_only_merge_commit_is_fresh:
171
+ typer.echo("POST_MERGE_HANDOFF_REFRESH")
172
+ typer.echo(f"current_head={status.current_head}")
173
+ typer.echo(f"freshness_warning_present={status.freshness_warning_present}")
174
+ typer.echo("refresh_required=False")
175
+ typer.echo(f"latest_successor_prompt={status.latest_successor_prompt}")
176
+ typer.echo("result=NOOP")
177
+ typer.echo("next_safe_action=none")
178
+ typer.echo("refresh_only_merge_commit_is_fresh=True")
179
+ return
180
+
181
+ typer.echo(render_post_merge_handoff_refresh_status(status), nl=False)
182
+ if status.refresh_required:
183
+ raise typer.Exit(1)