prizmkit 1.1.100 → 1.1.102

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 (317) hide show
  1. package/bin/create-prizmkit.js +4 -4
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/dev-pipeline/.env.example +3 -3
  4. package/bundled/dev-pipeline/README.md +110 -90
  5. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +1 -1
  6. package/bundled/dev-pipeline/cli.py +27 -0
  7. package/bundled/dev-pipeline/prizmkit_runtime/__init__.py +13 -0
  8. package/bundled/dev-pipeline/prizmkit_runtime/__main__.py +9 -0
  9. package/bundled/dev-pipeline/prizmkit_runtime/cli.py +193 -0
  10. package/bundled/dev-pipeline/prizmkit_runtime/commands.py +313 -0
  11. package/bundled/dev-pipeline/prizmkit_runtime/compat.py +32 -0
  12. package/bundled/dev-pipeline/prizmkit_runtime/config.py +410 -0
  13. package/bundled/dev-pipeline/prizmkit_runtime/daemon.py +478 -0
  14. package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +734 -0
  15. package/bundled/dev-pipeline/prizmkit_runtime/heartbeat.py +256 -0
  16. package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +109 -0
  17. package/bundled/dev-pipeline/prizmkit_runtime/paths.py +110 -0
  18. package/bundled/dev-pipeline/prizmkit_runtime/processes.py +373 -0
  19. package/bundled/dev-pipeline/prizmkit_runtime/reset.py +389 -0
  20. package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +51 -0
  21. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +179 -0
  22. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +355 -0
  23. package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +118 -0
  24. package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +187 -0
  25. package/bundled/dev-pipeline/prizmkit_runtime/runner_status.py +153 -0
  26. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +425 -0
  27. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +560 -0
  28. package/bundled/dev-pipeline/prizmkit_runtime/status.py +71 -0
  29. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +51 -36
  30. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +20 -5
  31. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +2 -2
  32. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +39 -0
  33. package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +8 -2
  34. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +1 -1
  35. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +6 -2
  36. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +14 -6
  37. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +14 -4
  38. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +14 -4
  39. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +2 -0
  40. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +9 -30
  41. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +15 -7
  42. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +42 -29
  43. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +41 -39
  44. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +8 -17
  45. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +2 -2
  46. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +1 -3
  47. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +1 -3
  48. package/bundled/dev-pipeline/templates/sections/phase0-test-baseline.md +3 -8
  49. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +6 -2
  50. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +5 -1
  51. package/bundled/dev-pipeline/tests/test_auto_skip.py +436 -14
  52. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +115 -7
  53. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +40 -0
  54. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +1226 -0
  55. package/bundled/dev-pipeline/tests/test_unified_cli.py +1045 -0
  56. package/bundled/skills/_metadata.json +1 -1
  57. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +29 -34
  58. package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +6 -5
  59. package/bundled/skills/feature-pipeline-launcher/SKILL.md +29 -35
  60. package/bundled/skills/feature-pipeline-launcher/references/configuration.md +7 -6
  61. package/bundled/skills/feature-workflow/SKILL.md +3 -6
  62. package/bundled/skills/recovery-workflow/SKILL.md +23 -32
  63. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +29 -35
  64. package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +7 -6
  65. package/bundled/skills/refactor-workflow/SKILL.md +3 -6
  66. package/bundled/templates/hooks/commit-intent.json +2 -2
  67. package/bundled/templates/hooks/diff-prizm-docs.py +226 -0
  68. package/bundled/templates/hooks/prizm-pre-commit.py +45 -0
  69. package/bundled/templates/hooks/validate-prizm-docs.py +240 -0
  70. package/package.json +1 -1
  71. package/src/config.js +42 -19
  72. package/src/external-skills.js +14 -14
  73. package/src/index.js +3 -6
  74. package/src/manifest.js +11 -5
  75. package/src/metadata.js +7 -18
  76. package/src/platforms.js +25 -0
  77. package/src/prompts.js +0 -12
  78. package/src/runtimes.js +18 -11
  79. package/src/scaffold.js +144 -122
  80. package/src/upgrade.js +12 -3
  81. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +0 -500
  82. package/bundled/dev-pipeline/launch-feature-daemon.sh +0 -657
  83. package/bundled/dev-pipeline/launch-refactor-daemon.sh +0 -502
  84. package/bundled/dev-pipeline/lib/branch.sh +0 -326
  85. package/bundled/dev-pipeline/lib/common.sh +0 -1476
  86. package/bundled/dev-pipeline/lib/heartbeat.sh +0 -469
  87. package/bundled/dev-pipeline/reset-bug.sh +0 -425
  88. package/bundled/dev-pipeline/reset-feature.sh +0 -436
  89. package/bundled/dev-pipeline/reset-refactor.sh +0 -423
  90. package/bundled/dev-pipeline/run-bugfix.sh +0 -1430
  91. package/bundled/dev-pipeline/run-feature.sh +0 -1718
  92. package/bundled/dev-pipeline/run-recovery.sh +0 -648
  93. package/bundled/dev-pipeline/run-refactor.sh +0 -1463
  94. package/bundled/dev-pipeline/tests/test-path-resolution.sh +0 -100
  95. package/bundled/dev-pipeline-windows/.env.example +0 -36
  96. package/bundled/dev-pipeline-windows/README.md +0 -30
  97. package/bundled/dev-pipeline-windows/SCHEMA_ANALYSIS.md +0 -533
  98. package/bundled/dev-pipeline-windows/assets/feature-list-example.json +0 -146
  99. package/bundled/dev-pipeline-windows/assets/prizm-dev-team-integration.md +0 -137
  100. package/bundled/dev-pipeline-windows/launch-bugfix-daemon.ps1 +0 -9
  101. package/bundled/dev-pipeline-windows/launch-feature-daemon.ps1 +0 -9
  102. package/bundled/dev-pipeline-windows/launch-refactor-daemon.ps1 +0 -9
  103. package/bundled/dev-pipeline-windows/lib/branch.ps1 +0 -235
  104. package/bundled/dev-pipeline-windows/lib/common.ps1 +0 -991
  105. package/bundled/dev-pipeline-windows/lib/daemon.ps1 +0 -140
  106. package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +0 -1051
  107. package/bundled/dev-pipeline-windows/lib/reset.ps1 +0 -121
  108. package/bundled/dev-pipeline-windows/reset-bug.ps1 +0 -10
  109. package/bundled/dev-pipeline-windows/reset-feature.ps1 +0 -10
  110. package/bundled/dev-pipeline-windows/reset-refactor.ps1 +0 -10
  111. package/bundled/dev-pipeline-windows/run-bugfix.ps1 +0 -9
  112. package/bundled/dev-pipeline-windows/run-feature.ps1 +0 -9
  113. package/bundled/dev-pipeline-windows/run-recovery.ps1 +0 -179
  114. package/bundled/dev-pipeline-windows/run-refactor.ps1 +0 -9
  115. package/bundled/dev-pipeline-windows/scripts/check-session-status.py +0 -301
  116. package/bundled/dev-pipeline-windows/scripts/continuation.py +0 -374
  117. package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +0 -530
  118. package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +0 -2279
  119. package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +0 -763
  120. package/bundled/dev-pipeline-windows/scripts/generate-recovery-prompt.py +0 -805
  121. package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +0 -841
  122. package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +0 -316
  123. package/bundled/dev-pipeline-windows/scripts/init-dev-team.py +0 -134
  124. package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +0 -382
  125. package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +0 -399
  126. package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +0 -1362
  127. package/bundled/dev-pipeline-windows/scripts/patch-completion-notes.py +0 -191
  128. package/bundled/dev-pipeline-windows/scripts/prizmkit-test-gate.py +0 -446
  129. package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +0 -1121
  130. package/bundled/dev-pipeline-windows/scripts/update-checkpoint.py +0 -173
  131. package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +0 -1789
  132. package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +0 -1327
  133. package/bundled/dev-pipeline-windows/scripts/utils.py +0 -542
  134. package/bundled/dev-pipeline-windows/templates/agent-prompts/critic-plan-challenge.md +0 -7
  135. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-fix.md +0 -7
  136. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +0 -65
  137. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-resume.md +0 -5
  138. package/bundled/dev-pipeline-windows/templates/agent-prompts/reviewer-review.md +0 -7
  139. package/bundled/dev-pipeline-windows/templates/bootstrap-prompt.md +0 -73
  140. package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +0 -589
  141. package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +0 -710
  142. package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +0 -791
  143. package/bundled/dev-pipeline-windows/templates/bug-fix-list-schema.json +0 -263
  144. package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +0 -326
  145. package/bundled/dev-pipeline-windows/templates/feature-list-schema.json +0 -237
  146. package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +0 -340
  147. package/bundled/dev-pipeline-windows/templates/refactor-list-schema.json +0 -270
  148. package/bundled/dev-pipeline-windows/templates/sections/ac-verification-checklist.md +0 -7
  149. package/bundled/dev-pipeline-windows/templates/sections/checkpoint-system.md +0 -91
  150. package/bundled/dev-pipeline-windows/templates/sections/context-budget-rules.md +0 -34
  151. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-agent.md +0 -10
  152. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-full.md +0 -12
  153. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-lite.md +0 -7
  154. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-agent.md +0 -8
  155. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-full.md +0 -9
  156. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-lite.md +0 -6
  157. package/bundled/dev-pipeline-windows/templates/sections/failure-capture.md +0 -21
  158. package/bundled/dev-pipeline-windows/templates/sections/feature-context.md +0 -21
  159. package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +0 -41
  160. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-auto.md +0 -283
  161. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-opencli.md +0 -112
  162. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification.md +0 -168
  163. package/bundled/dev-pipeline-windows/templates/sections/phase-commit-full.md +0 -82
  164. package/bundled/dev-pipeline-windows/templates/sections/phase-commit.md +0 -75
  165. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-agent-suffix.md +0 -23
  166. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-base.md +0 -14
  167. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-lite-suffix.md +0 -19
  168. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan-full.md +0 -63
  169. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan.md +0 -42
  170. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-agent.md +0 -44
  171. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-full.md +0 -59
  172. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-lite.md +0 -39
  173. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-agent.md +0 -27
  174. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-lite.md +0 -27
  175. package/bundled/dev-pipeline-windows/templates/sections/phase-prizmkit-test.md +0 -39
  176. package/bundled/dev-pipeline-windows/templates/sections/phase-review-agent.md +0 -35
  177. package/bundled/dev-pipeline-windows/templates/sections/phase-review-full.md +0 -35
  178. package/bundled/dev-pipeline-windows/templates/sections/phase-specify-plan-full.md +0 -73
  179. package/bundled/dev-pipeline-windows/templates/sections/phase0-init.md +0 -13
  180. package/bundled/dev-pipeline-windows/templates/sections/phase0-test-baseline.md +0 -21
  181. package/bundled/dev-pipeline-windows/templates/sections/session-context.md +0 -5
  182. package/bundled/dev-pipeline-windows/templates/sections/subagent-timeout-recovery.md +0 -6
  183. package/bundled/dev-pipeline-windows/templates/sections/task-contract.md +0 -34
  184. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-agent.md +0 -48
  185. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-lite.md +0 -48
  186. package/bundled/dev-pipeline-windows/templates/session-status-schema.json +0 -83
  187. package/bundled/skills-windows/app-planner/SKILL.md +0 -296
  188. package/bundled/skills-windows/app-planner/assets/app-design-guide.md +0 -101
  189. package/bundled/skills-windows/app-planner/references/architecture-decisions.md +0 -52
  190. package/bundled/skills-windows/app-planner/references/brainstorm-guide.md +0 -101
  191. package/bundled/skills-windows/app-planner/references/frontend-design-guide.md +0 -71
  192. package/bundled/skills-windows/app-planner/references/infrastructure-convention-discovery.md +0 -108
  193. package/bundled/skills-windows/app-planner/references/project-brief-guide.md +0 -82
  194. package/bundled/skills-windows/app-planner/references/project-conventions-discovery.md +0 -59
  195. package/bundled/skills-windows/app-planner/references/project-state-detection.md +0 -90
  196. package/bundled/skills-windows/app-planner/references/red-team-checklist.md +0 -40
  197. package/bundled/skills-windows/app-planner/references/rules/backend/derivation-rules.md +0 -619
  198. package/bundled/skills-windows/app-planner/references/rules/backend/fixed-rules.md +0 -285
  199. package/bundled/skills-windows/app-planner/references/rules/backend/question-bank.md +0 -249
  200. package/bundled/skills-windows/app-planner/references/rules/backend/question-manifest.json +0 -46
  201. package/bundled/skills-windows/app-planner/references/rules/backend/template.md +0 -173
  202. package/bundled/skills-windows/app-planner/references/rules/database/derivation-rules.md +0 -382
  203. package/bundled/skills-windows/app-planner/references/rules/database/fixed-rules.md +0 -211
  204. package/bundled/skills-windows/app-planner/references/rules/database/question-bank.md +0 -184
  205. package/bundled/skills-windows/app-planner/references/rules/database/question-manifest.json +0 -39
  206. package/bundled/skills-windows/app-planner/references/rules/database/template.md +0 -158
  207. package/bundled/skills-windows/app-planner/references/rules/frontend/derivation-rules.md +0 -820
  208. package/bundled/skills-windows/app-planner/references/rules/frontend/fixed-rules.md +0 -188
  209. package/bundled/skills-windows/app-planner/references/rules/frontend/question-bank.md +0 -319
  210. package/bundled/skills-windows/app-planner/references/rules/frontend/question-manifest.json +0 -51
  211. package/bundled/skills-windows/app-planner/references/rules/frontend/template.md +0 -339
  212. package/bundled/skills-windows/app-planner/references/rules/mobile/derivation-rules.md +0 -649
  213. package/bundled/skills-windows/app-planner/references/rules/mobile/fixed-rules.md +0 -290
  214. package/bundled/skills-windows/app-planner/references/rules/mobile/question-bank.md +0 -232
  215. package/bundled/skills-windows/app-planner/references/rules/mobile/question-manifest.json +0 -47
  216. package/bundled/skills-windows/app-planner/references/rules/mobile/template.md +0 -175
  217. package/bundled/skills-windows/app-planner/references/rules-configuration.md +0 -46
  218. package/bundled/skills-windows/bug-fix-workflow/SKILL.md +0 -379
  219. package/bundled/skills-windows/bug-fix-workflow/references/bug-diagnosis.md +0 -41
  220. package/bundled/skills-windows/bug-planner/SKILL.md +0 -402
  221. package/bundled/skills-windows/bug-planner/assets/bug-confirmation-template.md +0 -43
  222. package/bundled/skills-windows/bug-planner/references/critic-and-verification.md +0 -44
  223. package/bundled/skills-windows/bug-planner/references/error-recovery.md +0 -73
  224. package/bundled/skills-windows/bug-planner/references/input-formats.md +0 -53
  225. package/bundled/skills-windows/bug-planner/references/schema-validation.md +0 -25
  226. package/bundled/skills-windows/bug-planner/references/severity-rules.md +0 -16
  227. package/bundled/skills-windows/bug-planner/scripts/validate-bug-list.py +0 -322
  228. package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +0 -304
  229. package/bundled/skills-windows/bugfix-pipeline-launcher/references/configuration.md +0 -84
  230. package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +0 -381
  231. package/bundled/skills-windows/feature-pipeline-launcher/references/configuration.md +0 -67
  232. package/bundled/skills-windows/feature-pipeline-launcher/scripts/preflight-check.py +0 -462
  233. package/bundled/skills-windows/feature-planner/SKILL.md +0 -397
  234. package/bundled/skills-windows/feature-planner/assets/evaluation-guide.md +0 -64
  235. package/bundled/skills-windows/feature-planner/assets/planning-guide.md +0 -214
  236. package/bundled/skills-windows/feature-planner/references/browser-interaction.md +0 -59
  237. package/bundled/skills-windows/feature-planner/references/completeness-review.md +0 -57
  238. package/bundled/skills-windows/feature-planner/references/decomposition-patterns.md +0 -75
  239. package/bundled/skills-windows/feature-planner/references/error-recovery.md +0 -90
  240. package/bundled/skills-windows/feature-planner/references/incremental-feature-planning.md +0 -112
  241. package/bundled/skills-windows/feature-planner/references/new-project-planning.md +0 -85
  242. package/bundled/skills-windows/feature-planner/scripts/validate-and-generate.py +0 -1020
  243. package/bundled/skills-windows/feature-workflow/SKILL.md +0 -374
  244. package/bundled/skills-windows/feature-workflow/references/brainstorm-guide.md +0 -137
  245. package/bundled/skills-windows/prizm-kit/SKILL.md +0 -93
  246. package/bundled/skills-windows/prizmkit-code-review/SKILL.md +0 -161
  247. package/bundled/skills-windows/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
  248. package/bundled/skills-windows/prizmkit-code-review/references/review-report-template.md +0 -31
  249. package/bundled/skills-windows/prizmkit-code-review/references/reviewer-agent-prompt.md +0 -66
  250. package/bundled/skills-windows/prizmkit-code-review/scripts/check_loop.py +0 -186
  251. package/bundled/skills-windows/prizmkit-committer/SKILL.md +0 -89
  252. package/bundled/skills-windows/prizmkit-deploy/SKILL.md +0 -444
  253. package/bundled/skills-windows/prizmkit-deploy/references/ci-cd-workflows.md +0 -115
  254. package/bundled/skills-windows/prizmkit-deploy/references/cloud-platform-deploy.md +0 -93
  255. package/bundled/skills-windows/prizmkit-deploy/references/data-safety-examples.md +0 -120
  256. package/bundled/skills-windows/prizmkit-deploy/references/database-setup.md +0 -46
  257. package/bundled/skills-windows/prizmkit-deploy/references/deploy-config-schema.md +0 -148
  258. package/bundled/skills-windows/prizmkit-deploy/references/deploy-history-schema.md +0 -62
  259. package/bundled/skills-windows/prizmkit-deploy/references/deployment-modes.md +0 -50
  260. package/bundled/skills-windows/prizmkit-deploy/references/direct-upload.md +0 -26
  261. package/bundled/skills-windows/prizmkit-deploy/references/dns-setup.md +0 -42
  262. package/bundled/skills-windows/prizmkit-deploy/references/docker-deploy.md +0 -31
  263. package/bundled/skills-windows/prizmkit-deploy/references/firewall-setup.md +0 -37
  264. package/bundled/skills-windows/prizmkit-deploy/references/live-validation-notes.md +0 -21
  265. package/bundled/skills-windows/prizmkit-deploy/references/nginx-blue-green.md +0 -59
  266. package/bundled/skills-windows/prizmkit-deploy/references/ssh-bootstrap-flow.md +0 -49
  267. package/bundled/skills-windows/prizmkit-deploy/references/ssh-execution-flow.md +0 -41
  268. package/bundled/skills-windows/prizmkit-deploy/references/ssh-takeover.md +0 -20
  269. package/bundled/skills-windows/prizmkit-deploy/references/ssl-setup.md +0 -56
  270. package/bundled/skills-windows/prizmkit-implement/SKILL.md +0 -71
  271. package/bundled/skills-windows/prizmkit-init/SKILL.md +0 -356
  272. package/bundled/skills-windows/prizmkit-init/assets/project-brief-template.md +0 -82
  273. package/bundled/skills-windows/prizmkit-init/references/config-schema.md +0 -70
  274. package/bundled/skills-windows/prizmkit-init/references/rules/layer-detection.md +0 -41
  275. package/bundled/skills-windows/prizmkit-init/references/tech-stack-catalog.md +0 -13
  276. package/bundled/skills-windows/prizmkit-init/references/update-supplement.md +0 -9
  277. package/bundled/skills-windows/prizmkit-plan/SKILL.md +0 -102
  278. package/bundled/skills-windows/prizmkit-plan/assets/plan-template.md +0 -115
  279. package/bundled/skills-windows/prizmkit-plan/assets/spec-template.md +0 -73
  280. package/bundled/skills-windows/prizmkit-plan/references/clarify-guide.md +0 -67
  281. package/bundled/skills-windows/prizmkit-plan/references/examples.md +0 -85
  282. package/bundled/skills-windows/prizmkit-plan/references/verification-checklist.md +0 -60
  283. package/bundled/skills-windows/prizmkit-prizm-docs/SKILL.md +0 -129
  284. package/bundled/skills-windows/prizmkit-prizm-docs/assets/prizm-docs-format.md +0 -613
  285. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-init.md +0 -45
  286. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-rebuild.md +0 -15
  287. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-status.md +0 -14
  288. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-update.md +0 -19
  289. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-validate.md +0 -17
  290. package/bundled/skills-windows/prizmkit-retrospective/SKILL.md +0 -87
  291. package/bundled/skills-windows/prizmkit-retrospective/references/knowledge-injection-steps.md +0 -50
  292. package/bundled/skills-windows/prizmkit-retrospective/references/structural-sync-steps.md +0 -43
  293. package/bundled/skills-windows/prizmkit-test/SKILL.md +0 -227
  294. package/bundled/skills-windows/prizmkit-test/references/boundary-coverage-protocol.md +0 -220
  295. package/bundled/skills-windows/prizmkit-test/references/examples.md +0 -143
  296. package/bundled/skills-windows/prizmkit-test/references/service-boundary-test-catalog.md +0 -225
  297. package/bundled/skills-windows/prizmkit-test/references/test-generation-steps.md +0 -109
  298. package/bundled/skills-windows/prizmkit-test/references/test-report-template.md +0 -111
  299. package/bundled/skills-windows/prizmkit-test/scripts/validate_boundary_report.py +0 -347
  300. package/bundled/skills-windows/recovery-workflow/SKILL.md +0 -355
  301. package/bundled/skills-windows/recovery-workflow/evals/evals.json +0 -46
  302. package/bundled/skills-windows/recovery-workflow/references/detection.md +0 -58
  303. package/bundled/skills-windows/recovery-workflow/scripts/detect-recovery-state.py +0 -544
  304. package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +0 -346
  305. package/bundled/skills-windows/refactor-pipeline-launcher/references/configuration.md +0 -72
  306. package/bundled/skills-windows/refactor-planner/SKILL.md +0 -398
  307. package/bundled/skills-windows/refactor-planner/assets/planning-guide.md +0 -292
  308. package/bundled/skills-windows/refactor-planner/references/behavior-preservation.md +0 -301
  309. package/bundled/skills-windows/refactor-planner/references/fast-path.md +0 -59
  310. package/bundled/skills-windows/refactor-planner/references/planning-phases.md +0 -135
  311. package/bundled/skills-windows/refactor-planner/references/refactor-scoping-guide.md +0 -221
  312. package/bundled/skills-windows/refactor-planner/scripts/validate-and-generate-refactor.py +0 -858
  313. package/bundled/skills-windows/refactor-workflow/SKILL.md +0 -343
  314. package/bundled/skills-windows/refactor-workflow/references/brainstorm-guide.md +0 -116
  315. package/bundled/templates/hooks/diff-prizm-docs.sh +0 -158
  316. package/bundled/templates/hooks/prizm-pre-commit.sh +0 -108
  317. package/bundled/templates/hooks/validate-prizm-docs.sh +0 -139
@@ -0,0 +1,355 @@
1
+ """Data models and legacy argument normalization for Python pipeline runners."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ from collections.abc import Mapping, Sequence
7
+ from dataclasses import dataclass, field
8
+ from pathlib import Path
9
+
10
+ from .paths import RuntimePaths
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class RunnerFamily:
15
+ """Static metadata for one foreground pipeline family."""
16
+
17
+ kind: str
18
+ id_prefix: str
19
+ list_key: str
20
+ list_arg: str
21
+ item_id_arg: str
22
+ state_dir: Path
23
+ plan_path: Path
24
+ updater_script: Path
25
+ prompt_script: Path
26
+ branch_prefix: str
27
+ artifact_root_name: str
28
+
29
+ @property
30
+ def task_type(self) -> str:
31
+ return self.kind
32
+
33
+
34
+ @dataclass(frozen=True)
35
+ class RunnerEnvironment:
36
+ """Legacy runner environment controls modeled as one cohesive unit."""
37
+
38
+ stop_on_failure: bool = False
39
+ auto_push: bool = False
40
+ use_worktree: bool = True
41
+ dev_branch: str = ""
42
+ enable_deploy: bool = False
43
+ verbose: bool = False
44
+ heartbeat_interval_seconds: int = 30
45
+ heartbeat_stale_threshold_seconds: int = 600
46
+ stale_kill_threshold_seconds: int = 600
47
+ max_log_size: int | None = None
48
+ max_retries: int = 3
49
+ strict_behavior_check: bool = True
50
+
51
+ @classmethod
52
+ def from_env(cls, env: Mapping[str, str] | None = None) -> "RunnerEnvironment":
53
+ values = dict(os.environ if env is None else env)
54
+ return cls(
55
+ stop_on_failure=_truthy(values.get("STOP_ON_FAILURE")),
56
+ auto_push=_truthy(values.get("AUTO_PUSH")),
57
+ use_worktree=not _falsey(values.get("USE_WORKTREE")),
58
+ dev_branch=values.get("DEV_BRANCH", ""),
59
+ enable_deploy=_truthy(values.get("ENABLE_DEPLOY")),
60
+ verbose=_truthy(values.get("VERBOSE")),
61
+ heartbeat_interval_seconds=_int_value(values, "HEARTBEAT_INTERVAL", 30),
62
+ heartbeat_stale_threshold_seconds=_int_value(
63
+ values,
64
+ "HEARTBEAT_STALE_THRESHOLD",
65
+ _int_value(values, "HEARTBEAT_TIMEOUT_SECONDS", 600),
66
+ ),
67
+ stale_kill_threshold_seconds=_int_value(values, "STALE_KILL_THRESHOLD", 600),
68
+ max_log_size=_optional_int(values.get("MAX_LOG_SIZE")),
69
+ max_retries=max(0, _int_value(values, "MAX_RETRIES", 3)),
70
+ strict_behavior_check=not _falsey(values.get("STRICT_BEHAVIOR_CHECK")),
71
+ )
72
+
73
+
74
+ @dataclass(frozen=True)
75
+ class RunnerInvocation:
76
+ """Normalized legacy CLI arguments for one runner invocation."""
77
+
78
+ action: str
79
+ list_path: Path
80
+ item_id: str = ""
81
+ item_filter: str = ""
82
+ max_retries: int | None = None
83
+ max_infra_retries: int = 3
84
+ mode: str | None = None
85
+ critic: bool | None = None
86
+ dry_run: bool = False
87
+ clean: bool = False
88
+ no_reset: bool = False
89
+ resume_phase: str = "null"
90
+ help_requested: bool = False
91
+ unknown_args: tuple[str, ...] = ()
92
+ raw_args: tuple[str, ...] = ()
93
+
94
+
95
+ @dataclass(frozen=True)
96
+ class PromptGenerationResult:
97
+ """Structured output from the existing prompt generators."""
98
+
99
+ output_path: Path
100
+ model: str = ""
101
+ pipeline_mode: str = ""
102
+ agent_count: int = 0
103
+ critic_enabled: bool = False
104
+ checkpoint_path: Path | None = None
105
+ artifact_path: Path | None = None
106
+ raw: Mapping[str, object] = field(default_factory=dict)
107
+
108
+
109
+ @dataclass(frozen=True)
110
+ class SessionPaths:
111
+ """Canonical per-session runtime paths."""
112
+
113
+ session_dir: Path
114
+ prompt_path: Path
115
+ logs_dir: Path
116
+ session_log: Path
117
+ progress_json: Path
118
+ heartbeat_json: Path
119
+ session_status_json: Path
120
+
121
+ @classmethod
122
+ def for_item(cls, state_dir: Path, item_id: str, session_id: str) -> "SessionPaths":
123
+ session_dir = state_dir / item_id / "sessions" / session_id
124
+ logs_dir = session_dir / "logs"
125
+ return cls(
126
+ session_dir=session_dir,
127
+ prompt_path=session_dir / "bootstrap-prompt.md",
128
+ logs_dir=logs_dir,
129
+ session_log=logs_dir / "session.log",
130
+ progress_json=logs_dir / "progress.json",
131
+ heartbeat_json=logs_dir / "heartbeat.json",
132
+ session_status_json=session_dir / "session-status.json",
133
+ )
134
+
135
+
136
+ @dataclass(frozen=True)
137
+ class ContinuationState:
138
+ """Context-overflow continuation inputs for the next prompt/status update."""
139
+
140
+ active: bool = False
141
+ previous_session_id: str = ""
142
+ continuation_count: int = 0
143
+ context_overflow_count: int = 0
144
+ no_progress_count: int = 0
145
+ summary_path: Path | None = None
146
+ active_dev_branch: str = ""
147
+ base_branch: str = ""
148
+ fatal_error_code: str = "context_overflow"
149
+
150
+
151
+ @dataclass(frozen=True)
152
+ class SessionClassification:
153
+ """Final runner-owned session outcome before status updater mutation."""
154
+
155
+ session_status: str
156
+ reason: str = ""
157
+ fatal_error_code: str = ""
158
+ progress_fingerprint: Mapping[str, object] = field(default_factory=dict)
159
+ no_progress_count: int = 0
160
+
161
+
162
+ @dataclass(frozen=True)
163
+ class PipelineRunResult:
164
+ """Aggregated result for one foreground runner command."""
165
+
166
+ completed: bool
167
+ processed: int
168
+ stopped_reason: str = ""
169
+ last_status: str = ""
170
+ details: tuple[str, ...] = ()
171
+
172
+
173
+ FAMILY_KINDS = ("feature", "bugfix", "refactor")
174
+
175
+
176
+ def family_for(kind: str, paths: RuntimePaths) -> RunnerFamily:
177
+ """Return runner metadata for a supported pipeline family."""
178
+ script_dir = paths.pipeline_root / "scripts"
179
+ if kind == "feature":
180
+ return RunnerFamily(
181
+ kind="feature",
182
+ id_prefix="F-",
183
+ list_key="features",
184
+ list_arg="--feature-list",
185
+ item_id_arg="--feature-id",
186
+ state_dir=paths.feature_state_dir,
187
+ plan_path=paths.feature_plan,
188
+ updater_script=script_dir / "update-feature-status.py",
189
+ prompt_script=script_dir / "generate-bootstrap-prompt.py",
190
+ branch_prefix="dev",
191
+ artifact_root_name="specs",
192
+ )
193
+ if kind == "bugfix":
194
+ return RunnerFamily(
195
+ kind="bugfix",
196
+ id_prefix="B-",
197
+ list_key="bugs",
198
+ list_arg="--bug-list",
199
+ item_id_arg="--bug-id",
200
+ state_dir=paths.bugfix_state_dir,
201
+ plan_path=paths.bugfix_plan,
202
+ updater_script=script_dir / "update-bug-status.py",
203
+ prompt_script=script_dir / "generate-bugfix-prompt.py",
204
+ branch_prefix="bugfix",
205
+ artifact_root_name="bugfix",
206
+ )
207
+ if kind == "refactor":
208
+ return RunnerFamily(
209
+ kind="refactor",
210
+ id_prefix="R-",
211
+ list_key="refactors",
212
+ list_arg="--refactor-list",
213
+ item_id_arg="--refactor-id",
214
+ state_dir=paths.refactor_state_dir,
215
+ plan_path=paths.refactor_plan,
216
+ updater_script=script_dir / "update-refactor-status.py",
217
+ prompt_script=script_dir / "generate-refactor-prompt.py",
218
+ branch_prefix="refactor",
219
+ artifact_root_name="refactor",
220
+ )
221
+ raise ValueError(f"Unsupported runner family: {kind}")
222
+
223
+
224
+ def parse_invocation(
225
+ family: RunnerFamily,
226
+ action: str,
227
+ legacy_args: Sequence[str] = (),
228
+ ) -> RunnerInvocation:
229
+ """Normalize legacy shell runner arguments without redesigning the interface."""
230
+ args = tuple(str(arg) for arg in legacy_args)
231
+ list_path = family.plan_path
232
+ item_id = ""
233
+ item_filter = ""
234
+ max_retries: int | None = None
235
+ max_infra_retries = 3
236
+ mode: str | None = None
237
+ critic: bool | None = None
238
+ dry_run = False
239
+ clean = False
240
+ no_reset = False
241
+ resume_phase = "null"
242
+ unknown: list[str] = []
243
+ positional: list[str] = []
244
+ help_requested = False
245
+
246
+ index = 0
247
+ while index < len(args):
248
+ arg = args[index]
249
+ if arg in {"--help", "-h", "help"}:
250
+ help_requested = True
251
+ elif arg == "--dry-run":
252
+ dry_run = True
253
+ elif arg == "--clean":
254
+ clean = True
255
+ elif arg == "--no-reset":
256
+ no_reset = True
257
+ elif arg == "--critic":
258
+ critic = True
259
+ elif arg == "--no-critic":
260
+ critic = False
261
+ elif arg == "--features" and index + 1 < len(args):
262
+ index += 1
263
+ item_filter = args[index]
264
+ elif arg.startswith("--features="):
265
+ item_filter = arg.split("=", 1)[1]
266
+ elif arg == "--max-retries" and index + 1 < len(args):
267
+ index += 1
268
+ max_retries = max(0, _safe_int(args[index], 3))
269
+ elif arg.startswith("--max-retries="):
270
+ max_retries = max(0, _safe_int(arg.split("=", 1)[1], 3))
271
+ elif arg == "--max-infra-retries" and index + 1 < len(args):
272
+ index += 1
273
+ max_infra_retries = _safe_int(args[index], 3)
274
+ elif arg.startswith("--max-infra-retries="):
275
+ max_infra_retries = _safe_int(arg.split("=", 1)[1], 3)
276
+ elif arg == "--mode" and index + 1 < len(args):
277
+ index += 1
278
+ mode = args[index]
279
+ elif arg.startswith("--mode="):
280
+ mode = arg.split("=", 1)[1]
281
+ elif arg == "--resume-phase" and index + 1 < len(args):
282
+ index += 1
283
+ resume_phase = args[index]
284
+ elif arg.startswith("--resume-phase="):
285
+ resume_phase = arg.split("=", 1)[1]
286
+ elif arg.startswith("-"):
287
+ unknown.append(arg)
288
+ else:
289
+ positional.append(arg)
290
+ index += 1
291
+
292
+ for value in positional:
293
+ if _looks_like_item_id(value, family.id_prefix) and not item_id:
294
+ item_id = _normalize_item_id(value, family.id_prefix)
295
+ elif list_path == family.plan_path:
296
+ list_path = Path(value).expanduser()
297
+ else:
298
+ unknown.append(value)
299
+
300
+ return RunnerInvocation(
301
+ action=action,
302
+ list_path=list_path,
303
+ item_id=item_id,
304
+ item_filter=item_filter,
305
+ max_retries=max_retries,
306
+ max_infra_retries=max_infra_retries,
307
+ mode=mode,
308
+ critic=critic,
309
+ dry_run=dry_run,
310
+ clean=clean,
311
+ no_reset=no_reset,
312
+ resume_phase=resume_phase or "null",
313
+ help_requested=help_requested,
314
+ unknown_args=tuple(unknown),
315
+ raw_args=args,
316
+ )
317
+
318
+
319
+ def _looks_like_item_id(value: str, prefix: str) -> bool:
320
+ upper = value.upper()
321
+ return upper.startswith(prefix.upper())
322
+
323
+
324
+ def _normalize_item_id(value: str, prefix: str) -> str:
325
+ upper = value.upper()
326
+ if upper.startswith(prefix.upper()):
327
+ suffix = upper[len(prefix) :]
328
+ if suffix.isdigit():
329
+ return f"{prefix}{int(suffix):03d}"
330
+ return upper
331
+
332
+
333
+ def _truthy(value: str | None) -> bool:
334
+ return str(value or "").strip().lower() in {"1", "true", "yes", "on"}
335
+
336
+
337
+ def _falsey(value: str | None) -> bool:
338
+ return str(value or "").strip().lower() in {"0", "false", "no", "off"}
339
+
340
+
341
+ def _safe_int(value: str | None, default: int) -> int:
342
+ try:
343
+ return int(str(value))
344
+ except (TypeError, ValueError):
345
+ return default
346
+
347
+
348
+ def _int_value(values: Mapping[str, str], name: str, default: int) -> int:
349
+ return _safe_int(values.get(name), default)
350
+
351
+
352
+ def _optional_int(value: str | None) -> int | None:
353
+ if value is None or str(value).strip() == "":
354
+ return None
355
+ return _safe_int(value, 0)
@@ -0,0 +1,118 @@
1
+ """Prompt generator bridge for Python foreground runners."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import subprocess
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from .runner_models import PromptGenerationResult, RunnerFamily, RunnerInvocation, SessionPaths
11
+
12
+
13
+ def generate_prompt(
14
+ family: RunnerFamily,
15
+ invocation: RunnerInvocation,
16
+ *,
17
+ item_id: str,
18
+ session_id: str,
19
+ run_id: str,
20
+ retry_count: int,
21
+ session_paths: SessionPaths,
22
+ project_root: Path,
23
+ execution_root: Path | None = None,
24
+ continuation: dict[str, object] | None = None,
25
+ ) -> PromptGenerationResult:
26
+ """Run the existing prompt generator and return its structured JSON result."""
27
+ visible_root = execution_root or project_root
28
+ command = [
29
+ sys.executable,
30
+ str(family.prompt_script),
31
+ family.list_arg,
32
+ str(invocation.list_path),
33
+ family.item_id_arg,
34
+ item_id,
35
+ "--session-id",
36
+ session_id,
37
+ "--run-id",
38
+ run_id,
39
+ "--retry-count",
40
+ str(retry_count),
41
+ "--resume-phase",
42
+ invocation.resume_phase,
43
+ "--state-dir",
44
+ str(family.state_dir),
45
+ "--project-root",
46
+ str(visible_root),
47
+ "--output",
48
+ str(session_paths.prompt_path),
49
+ ]
50
+ if invocation.mode:
51
+ command.extend(["--mode", invocation.mode])
52
+ if invocation.critic is not None:
53
+ command.extend(["--critic", "true" if invocation.critic else "false"])
54
+ if continuation:
55
+ command.extend(["--continuation-mode", "context_overflow"])
56
+ for flag, key in (
57
+ ("--previous-session-id", "previous_session_id"),
58
+ ("--continuation-count", "continuation_count"),
59
+ ("--context-overflow-count", "context_overflow_count"),
60
+ ("--task-type", "task_type"),
61
+ ("--active-dev-branch", "active_dev_branch"),
62
+ ("--base-branch", "base_branch"),
63
+ ("--continuation-summary-path", "continuation_summary_path"),
64
+ ):
65
+ value = continuation.get(key)
66
+ if value not in (None, ""):
67
+ command.extend([flag, str(value)])
68
+
69
+ completed = subprocess.run(
70
+ command,
71
+ cwd=str(project_root),
72
+ stdout=subprocess.PIPE,
73
+ stderr=subprocess.PIPE,
74
+ text=True,
75
+ check=False,
76
+ )
77
+ if completed.returncode != 0:
78
+ raise RuntimeError(completed.stdout.strip() or completed.stderr.strip() or "prompt generation failed")
79
+ try:
80
+ data = json.loads(completed.stdout)
81
+ except json.JSONDecodeError as exc:
82
+ raise RuntimeError(f"prompt generator returned non-JSON output: {completed.stdout[:500]}") from exc
83
+ if not data.get("success"):
84
+ raise RuntimeError(str(data.get("error") or "prompt generation failed"))
85
+
86
+ checkpoint = data.get("checkpoint_path")
87
+ output_path = Path(str(data.get("output_path") or session_paths.prompt_path))
88
+ return PromptGenerationResult(
89
+ output_path=output_path,
90
+ model=str(data.get("model") or ""),
91
+ pipeline_mode=str(data.get("pipeline_mode") or ""),
92
+ agent_count=int(data.get("agent_count") or 0),
93
+ critic_enabled=_truthy(data.get("critic_enabled")),
94
+ checkpoint_path=Path(str(checkpoint)) if checkpoint else None,
95
+ artifact_path=_artifact_path(family, visible_root, item_id, data),
96
+ raw=data,
97
+ )
98
+
99
+
100
+ def _artifact_path(
101
+ family: RunnerFamily,
102
+ project_root: Path,
103
+ item_id: str,
104
+ data: dict[str, object],
105
+ ) -> Path:
106
+ if family.kind == "feature" and data.get("checkpoint_path"):
107
+ return Path(str(data["checkpoint_path"])).parent
108
+ if family.kind == "bugfix":
109
+ return project_root / ".prizmkit" / "bugfix" / item_id
110
+ if family.kind == "refactor":
111
+ return project_root / ".prizmkit" / "refactor" / item_id
112
+ return project_root / ".prizmkit" / family.artifact_root_name / item_id
113
+
114
+
115
+ def _truthy(value: object) -> bool:
116
+ if isinstance(value, bool):
117
+ return value
118
+ return str(value or "").strip().lower() in {"1", "true", "yes", "on"}
@@ -0,0 +1,187 @@
1
+ """Recovery detection and execution for Python foreground runner commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import subprocess
7
+ import sys
8
+ import time
9
+ from dataclasses import dataclass
10
+ from pathlib import Path
11
+
12
+ from .config import load_runtime_config
13
+ from .paths import RuntimePaths
14
+ from .runner_models import RunnerEnvironment, SessionPaths
15
+ from .sessions import AISessionConfig, AISessionLauncher
16
+
17
+
18
+ @dataclass(frozen=True)
19
+ class RecoveryDetectorResolver:
20
+ """Resolve recovery detector sources without coupling to one platform copy."""
21
+
22
+ paths: RuntimePaths
23
+
24
+ def candidates(self) -> tuple[Path, ...]:
25
+ project = self.paths.project_root
26
+ return (
27
+ project / ".agents" / "skills" / "recovery-workflow" / "scripts" / "detect-recovery-state.py",
28
+ project / ".claude" / "command-assets" / "recovery-workflow" / "scripts" / "detect-recovery-state.py",
29
+ project / ".codebuddy" / "skills" / "recovery-workflow" / "scripts" / "detect-recovery-state.py",
30
+ project
31
+ / "core"
32
+ / "skills"
33
+ / "orchestration-skill"
34
+ / "workflows"
35
+ / "recovery-workflow"
36
+ / "scripts"
37
+ / "detect-recovery-state.py",
38
+ )
39
+
40
+ def resolve(self) -> Path:
41
+ for candidate in self.candidates():
42
+ if candidate.is_file():
43
+ return candidate
44
+ raise FileNotFoundError("recovery detector script not found")
45
+
46
+
47
+ def run_recovery_detect(paths: RuntimePaths) -> tuple[int, str, str, dict[str, object] | None]:
48
+ """Run recovery state detection and parse the JSON report."""
49
+ detector = RecoveryDetectorResolver(paths).resolve()
50
+ completed = subprocess.run(
51
+ [sys.executable, str(detector), "--project-root", str(paths.project_root)],
52
+ cwd=str(paths.project_root),
53
+ stdout=subprocess.PIPE,
54
+ stderr=subprocess.PIPE,
55
+ text=True,
56
+ check=False,
57
+ )
58
+ data = None
59
+ if completed.stdout.strip():
60
+ try:
61
+ data = json.loads(completed.stdout)
62
+ except json.JSONDecodeError:
63
+ data = None
64
+ return completed.returncode, completed.stdout, completed.stderr, data
65
+
66
+
67
+ def run_recovery(paths: RuntimePaths, legacy_args: tuple[str, ...] = ()) -> tuple[int, str, str]:
68
+ """Detect recovery state, render a prompt, launch an AI session, and classify."""
69
+ dry_run = "--dry-run" in legacy_args
70
+ model_override = _option_value(legacy_args, "--model")
71
+ code, stdout, stderr, detection = run_recovery_detect(paths)
72
+ if code != 0 or not detection:
73
+ return code or 1, stdout, stderr
74
+ if not detection.get("detected"):
75
+ return 0, stdout, stderr
76
+
77
+ session_id = "recovery-{}-{}".format(
78
+ str(detection.get("workflow_type") or "workflow"),
79
+ time.strftime("%Y%m%d-%H%M%S"),
80
+ )
81
+ session_dir = paths.recovery_state_dir / session_id
82
+ session_paths = SessionPaths(
83
+ session_dir=session_dir,
84
+ prompt_path=session_dir / "bootstrap-prompt.md",
85
+ logs_dir=session_dir / "logs",
86
+ session_log=session_dir / "logs" / "session.log",
87
+ progress_json=session_dir / "logs" / "progress.json",
88
+ heartbeat_json=session_dir / "logs" / "heartbeat.json",
89
+ session_status_json=session_dir / "session-status.json",
90
+ )
91
+ detection_json = session_paths.session_dir / "detection.json"
92
+ session_paths.session_dir.mkdir(parents=True, exist_ok=True)
93
+ detection_json.write_text(json.dumps(detection, indent=2, ensure_ascii=False), encoding="utf-8")
94
+ prompt_output = session_paths.prompt_path
95
+ generator = paths.pipeline_root / "scripts" / "generate-recovery-prompt.py"
96
+ prompt_cmd = [
97
+ sys.executable,
98
+ str(generator),
99
+ "--detection-json",
100
+ str(detection_json),
101
+ "--output",
102
+ str(prompt_output),
103
+ "--project-root",
104
+ str(paths.project_root),
105
+ "--session-id",
106
+ session_id,
107
+ ]
108
+ prompt_result = subprocess.run(
109
+ prompt_cmd,
110
+ cwd=str(paths.project_root),
111
+ stdout=subprocess.PIPE,
112
+ stderr=subprocess.PIPE,
113
+ text=True,
114
+ check=False,
115
+ )
116
+ if prompt_result.returncode != 0:
117
+ return prompt_result.returncode, prompt_result.stdout, prompt_result.stderr
118
+ if dry_run:
119
+ return 0, prompt_result.stdout, prompt_result.stderr
120
+
121
+ config = load_runtime_config(paths)
122
+ if not config.ai_client.command:
123
+ return 1, "", "No supported AI CLI command was found for recovery\n"
124
+ env = RunnerEnvironment.from_env()
125
+ launcher = AISessionLauncher(
126
+ AISessionConfig(
127
+ cli_command=config.ai_client.command,
128
+ platform=config.ai_client.platform or "codebuddy",
129
+ model=model_override or config.model,
130
+ prompt_path=prompt_output,
131
+ cwd=paths.project_root,
132
+ log_path=session_paths.session_log,
133
+ progress_path=session_paths.progress_json,
134
+ heartbeat_path=session_paths.heartbeat_json,
135
+ effort=config.effort,
136
+ verbose=env.verbose,
137
+ stale_kill_threshold_seconds=env.stale_kill_threshold_seconds,
138
+ )
139
+ )
140
+ result = launcher.run()
141
+ outcome = _recovery_outcome(paths.project_root, result.exit_code)
142
+ session_paths.session_status_json.write_text(
143
+ json.dumps({"session_id": session_id, "outcome": outcome}, indent=2) + "\n",
144
+ encoding="utf-8",
145
+ )
146
+ return 0 if outcome in {"success", "success_wip", "no_changes"} else 1, outcome + "\n", ""
147
+
148
+
149
+ def _option_value(args: tuple[str, ...], flag: str) -> str | None:
150
+ for index, arg in enumerate(args):
151
+ if arg == flag and index + 1 < len(args):
152
+ return args[index + 1]
153
+ if arg.startswith(flag + "="):
154
+ return arg.split("=", 1)[1]
155
+ return None
156
+
157
+
158
+ def _recovery_outcome(project_root: Path, exit_code: int | None) -> str:
159
+ commits = subprocess.run(
160
+ ["git", "-C", str(project_root), "rev-list", "--count", "HEAD", "^main"],
161
+ stdout=subprocess.PIPE,
162
+ stderr=subprocess.DEVNULL,
163
+ text=True,
164
+ check=False,
165
+ )
166
+ if commits.returncode == 0 and commits.stdout.strip() not in {"", "0"}:
167
+ return "success"
168
+ status = subprocess.run(
169
+ ["git", "-C", str(project_root), "status", "--porcelain"],
170
+ stdout=subprocess.PIPE,
171
+ stderr=subprocess.DEVNULL,
172
+ text=True,
173
+ check=False,
174
+ )
175
+ has_changes = bool(status.stdout.strip())
176
+ if exit_code == 0 and has_changes:
177
+ subprocess.run(["git", "-C", str(project_root), "add", "-A"], check=False)
178
+ subprocess.run(
179
+ ["git", "-C", str(project_root), "commit", "--no-verify", "-m", "chore: save recovery work"],
180
+ stdout=subprocess.DEVNULL,
181
+ stderr=subprocess.DEVNULL,
182
+ check=False,
183
+ )
184
+ return "success_wip"
185
+ if exit_code == 0:
186
+ return "no_changes"
187
+ return "partial" if has_changes else "failed"