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,365 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from pathlib import Path
5
+ import subprocess
6
+ from typing import Any
7
+
8
+ from agentic_project_kit.gui_action_views import (
9
+ GuiActionGroupView as GuiActionGroupView,
10
+ GuiActionView as GuiActionView,
11
+ build_gui_action_views as build_gui_action_views,
12
+ explain_safety as explain_safety,
13
+ format_action_details as format_action_details,
14
+ format_action_result as format_action_result,
15
+ grouped_action_views as grouped_action_views,
16
+ ordered_action_views as ordered_action_views,
17
+ )
18
+ from agentic_project_kit.gui_activity_log import ActivityLog
19
+ from agentic_project_kit.gui_cockpit_actions import CockpitActionsMixin
20
+ from agentic_project_kit.gui_cockpit_common import (
21
+ HEADER_TEXT,
22
+ RECOVERY_ACTION_ID as RECOVERY_ACTION_ID,
23
+ THEME,
24
+ GuiTheme as GuiTheme,
25
+ build_collapsible_group,
26
+ action_tree_columns as action_tree_columns,
27
+ action_tree_tag_colors as action_tree_tag_colors,
28
+ action_tree_tag_for_safety as action_tree_tag_for_safety,
29
+ action_tree_visible_rows as action_tree_visible_rows,
30
+ format_basic_cockpit_summary,
31
+ format_recommended_action as format_recommended_action,
32
+ format_state_details as format_state_details,
33
+ recommended_recovery_action_id,
34
+ )
35
+ from agentic_project_kit.gui_cockpit_header import CockpitHeaderMixin
36
+ from agentic_project_kit.gui_cockpit_sidebar import CockpitSidebarMixin
37
+ from agentic_project_kit.gui_cockpit_task import CockpitTaskMixin
38
+ from agentic_project_kit.gui_panel_state import read_panel_state, write_panel_state
39
+ from agentic_project_kit.gui_tk_widgets import maximize_root_window
40
+ from agentic_project_kit.gui_viewmodel import build_basic_cockpit_view_model
41
+ from agentic_project_kit.workspace_adopt import analyze_workspace_adoption
42
+
43
+
44
+ GUI_GROUP_IDS = (
45
+ "work_cycle",
46
+ "communication",
47
+ "next_step",
48
+ "task_editor",
49
+ "action_table",
50
+ "advanced_tools",
51
+ "file_browser",
52
+ "copy_paste_tools",
53
+ "output",
54
+ )
55
+ MAIN_CONTENT_GROUP_IDS = (
56
+ "communication",
57
+ "next_step",
58
+ "task_editor",
59
+ "action_table",
60
+ "advanced_tools",
61
+ "file_browser",
62
+ "copy_paste_tools",
63
+ "output",
64
+ )
65
+
66
+
67
+ class CockpitGui(CockpitHeaderMixin, CockpitSidebarMixin, CockpitActionsMixin, CockpitTaskMixin):
68
+ def __init__(self, root: Any, project_root: Path | None = None) -> None:
69
+ import tkinter as tk
70
+ from tkinter import ttk
71
+
72
+ self.root = root
73
+ self.project_root = (project_root or Path(".")).resolve()
74
+ self.activity_log = ActivityLog()
75
+ self.gui_group_frames: dict[str, Any | None] = dict.fromkeys(GUI_GROUP_IDS)
76
+ self.panel_expanded_state: dict[str, bool] = {}
77
+ self.actions: tuple[GuiActionView, ...] = ()
78
+ self.recovery_action_id = RECOVERY_ACTION_ID
79
+ self._reload_project_view_state()
80
+ self.root.title(self._window_title())
81
+ maximize_root_window(self.root, fallback_geometry=THEME.window_geometry)
82
+ if hasattr(self.root, "minsize"):
83
+ self.root.minsize(1040, 680)
84
+ self.selected_action_id_value: str | None = None
85
+ self.work_cycle_last_check_passed = False
86
+ self.work_cycle_last_check_signature = ""
87
+ self.pending_finish_preview: dict[str, object] | None = None
88
+ self.pending_discard_preview: dict[str, object] | None = None
89
+ self.pending_release_preview: dict[str, object] | None = None
90
+ self.work_finish_confirm_button: Any | None = None
91
+ self.work_discard_confirm_button: Any | None = None
92
+ self.release_confirm_button: Any | None = None
93
+ self.start_from_ref_value = tk.StringVar(value="latest main")
94
+ self.start_from_ref_picker: Any | None = None
95
+ self.project_status_var = tk.StringVar(value=self._project_status_text())
96
+ self.release_version_var = tk.StringVar(value="")
97
+
98
+ shell = tk.Frame(
99
+ root,
100
+ bg=THEME.color_shell_bg,
101
+ highlightbackground=THEME.color_border,
102
+ highlightthickness=1,
103
+ )
104
+ shell.pack(fill=tk.BOTH, expand=True, padx=14, pady=14)
105
+
106
+ self._build_work_cycle_bar(shell)
107
+
108
+ body = tk.Frame(shell, bg=THEME.color_panel_bg)
109
+ body.pack(fill=tk.BOTH, expand=True)
110
+
111
+ sidebar = tk.Frame(
112
+ body,
113
+ bg=THEME.color_panel_bg,
114
+ width=THEME.sidebar_width,
115
+ padx=THEME.frame_padding,
116
+ pady=THEME.frame_padding,
117
+ )
118
+ sidebar.pack(side=tk.LEFT, fill=tk.Y)
119
+ sidebar.pack_propagate(False)
120
+ self.sidebar = sidebar
121
+
122
+ separator = ttk.Separator(body, orient=tk.VERTICAL)
123
+ separator.pack(side=tk.LEFT, fill=tk.Y)
124
+
125
+ main_scroll_shell = tk.Frame(
126
+ body,
127
+ bg=THEME.color_panel_bg,
128
+ padx=THEME.frame_padding,
129
+ pady=THEME.frame_padding,
130
+ )
131
+ main_scroll_shell.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
132
+ main_canvas = tk.Canvas(main_scroll_shell, bg=THEME.color_panel_bg, highlightthickness=0)
133
+ main_scrollbar = ttk.Scrollbar(main_scroll_shell, orient=tk.VERTICAL, command=main_canvas.yview)
134
+ main_canvas.configure(yscrollcommand=main_scrollbar.set)
135
+ main_canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
136
+ main_scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
137
+
138
+ main_area = tk.Frame(main_canvas, bg=THEME.color_panel_bg)
139
+ main_window = main_canvas.create_window((0, 0), window=main_area, anchor=tk.NW)
140
+ main_area.bind(
141
+ "<Configure>",
142
+ lambda _event: main_canvas.configure(scrollregion=main_canvas.bbox(tk.ALL)),
143
+ )
144
+ main_canvas.bind(
145
+ "<Configure>",
146
+ lambda event: main_canvas.itemconfigure(main_window, width=event.width),
147
+ )
148
+ self.main_area = main_area
149
+
150
+ self._build_sidebar(sidebar)
151
+ self._build_main_content()
152
+
153
+ self.write_output(format_basic_cockpit_summary(self.basic_view) + "\n")
154
+
155
+ def _reload_project_view_state(
156
+ self,
157
+ *,
158
+ communication_mode: str | None = None,
159
+ access_level: str | None = None,
160
+ ) -> None:
161
+ try:
162
+ self.panel_expanded_state = read_panel_state(self.project_root)
163
+ except RuntimeError:
164
+ self.panel_expanded_state = {}
165
+ self.basic_view = build_basic_cockpit_view_model(
166
+ self.project_root,
167
+ communication_mode=communication_mode,
168
+ access_level=access_level,
169
+ )
170
+ self.actions = ordered_action_views(
171
+ build_gui_action_views(access_level=self.basic_view.access_level)
172
+ )
173
+ self.recovery_action_id = recommended_recovery_action_id(self.basic_view)
174
+
175
+ def _manifest_status(self) -> str:
176
+ try:
177
+ report = analyze_workspace_adoption(self.project_root)
178
+ except RuntimeError:
179
+ return "invalid"
180
+ return {
181
+ "already_initialized": "initialized",
182
+ "ready_for_workspace_init": "ready-for-init",
183
+ "foreign_agentic_directory": "foreign",
184
+ "invalid_workspace_manifest": "invalid",
185
+ }.get(report.agentic.status, report.agentic.status.replace("_", "-"))
186
+
187
+ def _project_branch_label(self) -> str:
188
+ try:
189
+ completed = subprocess.run(
190
+ ["git", "branch", "--show-current"],
191
+ cwd=self.project_root,
192
+ text=True,
193
+ stdout=subprocess.PIPE,
194
+ stderr=subprocess.PIPE,
195
+ check=False,
196
+ )
197
+ except OSError:
198
+ return "unknown"
199
+ branch = completed.stdout.strip() if completed.returncode == 0 else ""
200
+ return branch or "detached"
201
+
202
+ def _project_status_text(self) -> str:
203
+ return f"{self.project_root.name} | {self._project_branch_label()} | {self._manifest_status()}"
204
+
205
+ def _window_title(self) -> str:
206
+ return f"{HEADER_TEXT} - {self.project_root.name} - {self._project_branch_label()}"
207
+
208
+ def _update_project_chrome(self) -> None:
209
+ self.root.title(self._window_title())
210
+ if hasattr(self, "project_status_var"):
211
+ self.project_status_var.set(self._project_status_text())
212
+
213
+ def _is_git_repository(self, path: Path) -> bool:
214
+ try:
215
+ completed = subprocess.run(
216
+ ["git", "rev-parse", "--show-toplevel"],
217
+ cwd=path,
218
+ text=True,
219
+ stdout=subprocess.PIPE,
220
+ stderr=subprocess.PIPE,
221
+ check=False,
222
+ )
223
+ except OSError:
224
+ return False
225
+ return completed.returncode == 0
226
+
227
+ def open_project(self) -> None:
228
+ from tkinter import filedialog
229
+
230
+ selected = filedialog.askdirectory(
231
+ parent=self.root,
232
+ initialdir=str(self.project_root),
233
+ title="Open project",
234
+ )
235
+ if not selected:
236
+ return
237
+ self.switch_project_root(Path(selected))
238
+
239
+ def switch_project_root(self, path: Path | str) -> bool:
240
+ candidate = Path(path).expanduser().resolve()
241
+ if not candidate.exists() or not candidate.is_dir():
242
+ self.log_result("Open project", "BLOCKED", f"Folder does not exist: {candidate}")
243
+ return False
244
+ if not self._is_git_repository(candidate):
245
+ self.log_result("Open project", "BLOCKED", f"Selected folder is not a git repository: {candidate}")
246
+ return False
247
+ communication_mode = self.current_communication_mode() if hasattr(self, "mode_var") else None
248
+ access_level = self.basic_view.access_level
249
+ self.project_root = candidate
250
+ self._reload_project_view_state(communication_mode=communication_mode, access_level=access_level)
251
+ self._update_project_chrome()
252
+ if hasattr(self, "start_from_ref_value"):
253
+ self.start_from_ref_value.set("latest main")
254
+ if self.start_from_ref_picker is not None:
255
+ self.start_from_ref_picker.configure(values=self._start_from_ref_options())
256
+ if hasattr(self, "sidebar"):
257
+ self._rebuild_sidebar()
258
+ if hasattr(self, "main_area"):
259
+ self._rebuild_main_content()
260
+ status = self._manifest_status()
261
+ hint = " Foreign .agentic directory detected; workspace init is intentionally not run." if status == "foreign" else ""
262
+ self.log_result("Open project", "PASS", f"Project switched to {candidate}\nStatus: {status}.{hint}")
263
+ return True
264
+
265
+ def _advanced_access_visible(self) -> bool:
266
+ return self.basic_view.access_level in {"advanced", "maintainer"}
267
+
268
+ def _register_group_frame(self, group_id: str, frame: Any) -> Any:
269
+ if group_id not in self.gui_group_frames:
270
+ raise KeyError(f"unknown GUI group id: {group_id}")
271
+ self.gui_group_frames[group_id] = frame
272
+ setattr(self, f"{group_id}_frame", frame)
273
+ return frame
274
+
275
+ def _reset_main_group_frames(self) -> None:
276
+ for group_id in MAIN_CONTENT_GROUP_IDS:
277
+ self.gui_group_frames[group_id] = None
278
+ setattr(self, f"{group_id}_frame", None)
279
+ setattr(self, f"{group_id}_body", None)
280
+ setattr(self, f"{group_id}_expanded", False)
281
+
282
+ def _panel_group_expanded(self, group_id: str) -> bool:
283
+ if group_id in self.panel_expanded_state:
284
+ return bool(self.panel_expanded_state[group_id])
285
+ return group_id in set(self.basic_view.default_expanded_groups)
286
+
287
+ def _set_panel_group_expanded(self, group_id: str, expanded: bool) -> None:
288
+ self.panel_expanded_state[group_id] = bool(expanded)
289
+ write_panel_state(self.project_root, self.panel_expanded_state)
290
+
291
+ def _toggle_panel_group(self, group_id: str) -> None:
292
+ self._set_panel_group_expanded(group_id, not self._panel_group_expanded(group_id))
293
+ self._rebuild_main_content()
294
+
295
+ def _build_collapsible_group(
296
+ self,
297
+ parent: Any,
298
+ *,
299
+ group_id: str,
300
+ title: str,
301
+ subtitle: str = "",
302
+ ) -> Any:
303
+ group = build_collapsible_group(
304
+ parent,
305
+ group_id=group_id,
306
+ title=title,
307
+ subtitle=subtitle,
308
+ expanded=self._panel_group_expanded(group_id),
309
+ on_toggle=self._toggle_panel_group,
310
+ )
311
+ self._register_group_frame(group_id, group.frame)
312
+ setattr(self, f"{group_id}_body", group.body)
313
+ setattr(self, f"{group_id}_expanded", group.expanded)
314
+ return group
315
+
316
+ def _build_main_content(self) -> None:
317
+ self._reset_main_group_frames()
318
+ self._build_primary_status_row(self.main_area)
319
+ if self._advanced_access_visible():
320
+ self._build_action_cards(self.main_area)
321
+ self._build_advanced_tools(self.main_area)
322
+ self._build_file_browser(self.main_area)
323
+ self._build_task_editor(self.main_area)
324
+ self._build_copy_paste_tools(self.main_area)
325
+ self._build_output_panel(self.main_area)
326
+
327
+ def _build_primary_status_row(self, parent: Any) -> None:
328
+ import tkinter as tk
329
+
330
+ row = tk.Frame(parent, bg=THEME.color_panel_bg)
331
+ self.primary_status_row = row
332
+ row.pack(fill=tk.X, pady=(0, 10))
333
+ row.columnconfigure(0, weight=1)
334
+ row.columnconfigure(1, weight=1)
335
+
336
+ communication_column = tk.Frame(row, bg=THEME.color_panel_bg)
337
+ communication_column._primary_status_column = "communication" # type: ignore[attr-defined]
338
+ communication_column.grid(row=0, column=0, sticky="nsew", padx=(0, 8))
339
+ next_step_column = tk.Frame(row, bg=THEME.color_panel_bg)
340
+ next_step_column._primary_status_column = "next_step" # type: ignore[attr-defined]
341
+ next_step_column.grid(row=0, column=1, sticky="nsew", padx=(8, 0))
342
+
343
+ self._build_communication_panel(communication_column)
344
+ self._build_next_step_panel(next_step_column)
345
+
346
+ def _rebuild_main_content(self) -> None:
347
+ for child in self.main_area.winfo_children():
348
+ child.destroy()
349
+ self._build_main_content()
350
+
351
+ def _rebuild_sidebar(self) -> None:
352
+ for child in self.sidebar.winfo_children():
353
+ child.destroy()
354
+ self._build_sidebar(self.sidebar)
355
+
356
+
357
+ def main(argv: list[str] | None = None) -> None:
358
+ import tkinter as tk
359
+
360
+ parser = argparse.ArgumentParser(prog="agentic-kit-gui")
361
+ parser.add_argument("--root", default=".", help="Project root to open in the cockpit.")
362
+ args = parser.parse_args(argv)
363
+ root = tk.Tk()
364
+ CockpitGui(root, project_root=Path(args.root))
365
+ root.mainloop()