prizmkit 1.1.99 → 1.1.101

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 (321) 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 +345 -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 +147 -0
  26. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +422 -0
  27. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +552 -0
  28. package/bundled/dev-pipeline/prizmkit_runtime/status.py +71 -0
  29. package/bundled/dev-pipeline/scripts/check-session-status.py +74 -1
  30. package/bundled/dev-pipeline/scripts/continuation.py +374 -0
  31. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +64 -52
  32. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +35 -25
  33. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +2 -2
  34. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +15 -20
  35. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +185 -16
  36. package/bundled/dev-pipeline/scripts/update-bug-status.py +214 -6
  37. package/bundled/dev-pipeline/scripts/update-feature-status.py +237 -6
  38. package/bundled/dev-pipeline/scripts/update-refactor-status.py +214 -6
  39. package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +8 -2
  40. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +4 -0
  41. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +14 -5
  42. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +16 -6
  43. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +16 -6
  44. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
  45. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +3 -3
  46. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +2 -0
  47. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +13 -69
  48. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +15 -7
  49. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +42 -29
  50. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +41 -39
  51. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +4 -0
  52. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +4 -0
  53. package/bundled/dev-pipeline/templates/session-status-schema.json +1 -1
  54. package/bundled/dev-pipeline/tests/conftest.py +1 -0
  55. package/bundled/dev-pipeline/tests/test_auto_skip.py +932 -0
  56. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +207 -0
  57. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +100 -0
  58. package/bundled/dev-pipeline/tests/test_generate_refactor_prompt.py +43 -0
  59. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +1138 -0
  60. package/bundled/dev-pipeline/tests/test_unified_cli.py +1045 -0
  61. package/bundled/skills/_metadata.json +1 -1
  62. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +29 -34
  63. package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +6 -5
  64. package/bundled/skills/feature-pipeline-launcher/SKILL.md +29 -35
  65. package/bundled/skills/feature-pipeline-launcher/references/configuration.md +7 -6
  66. package/bundled/skills/feature-workflow/SKILL.md +3 -6
  67. package/bundled/skills/recovery-workflow/SKILL.md +23 -32
  68. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +29 -35
  69. package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +7 -6
  70. package/bundled/skills/refactor-workflow/SKILL.md +3 -6
  71. package/bundled/templates/hooks/commit-intent.json +2 -2
  72. package/bundled/templates/hooks/diff-prizm-docs.py +226 -0
  73. package/bundled/templates/hooks/prizm-pre-commit.py +45 -0
  74. package/bundled/templates/hooks/validate-prizm-docs.py +240 -0
  75. package/package.json +1 -1
  76. package/src/config.js +33 -12
  77. package/src/index.js +3 -6
  78. package/src/manifest.js +3 -2
  79. package/src/metadata.js +7 -18
  80. package/src/prompts.js +0 -12
  81. package/src/runtimes.js +18 -11
  82. package/src/scaffold.js +133 -116
  83. package/src/upgrade.js +1 -1
  84. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +0 -500
  85. package/bundled/dev-pipeline/launch-feature-daemon.sh +0 -657
  86. package/bundled/dev-pipeline/launch-refactor-daemon.sh +0 -502
  87. package/bundled/dev-pipeline/lib/branch.sh +0 -326
  88. package/bundled/dev-pipeline/lib/common.sh +0 -1257
  89. package/bundled/dev-pipeline/lib/heartbeat.sh +0 -469
  90. package/bundled/dev-pipeline/reset-bug.sh +0 -395
  91. package/bundled/dev-pipeline/reset-feature.sh +0 -406
  92. package/bundled/dev-pipeline/reset-refactor.sh +0 -393
  93. package/bundled/dev-pipeline/run-bugfix.sh +0 -1315
  94. package/bundled/dev-pipeline/run-feature.sh +0 -1602
  95. package/bundled/dev-pipeline/run-recovery.sh +0 -648
  96. package/bundled/dev-pipeline/run-refactor.sh +0 -1348
  97. package/bundled/dev-pipeline/scripts/monitor-log.sh +0 -104
  98. package/bundled/dev-pipeline/tests/test-path-resolution.sh +0 -100
  99. package/bundled/dev-pipeline-windows/.env.example +0 -36
  100. package/bundled/dev-pipeline-windows/README.md +0 -30
  101. package/bundled/dev-pipeline-windows/SCHEMA_ANALYSIS.md +0 -533
  102. package/bundled/dev-pipeline-windows/assets/feature-list-example.json +0 -146
  103. package/bundled/dev-pipeline-windows/assets/prizm-dev-team-integration.md +0 -137
  104. package/bundled/dev-pipeline-windows/launch-bugfix-daemon.ps1 +0 -9
  105. package/bundled/dev-pipeline-windows/launch-feature-daemon.ps1 +0 -9
  106. package/bundled/dev-pipeline-windows/launch-refactor-daemon.ps1 +0 -9
  107. package/bundled/dev-pipeline-windows/lib/branch.ps1 +0 -235
  108. package/bundled/dev-pipeline-windows/lib/common.ps1 +0 -829
  109. package/bundled/dev-pipeline-windows/lib/daemon.ps1 +0 -140
  110. package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +0 -967
  111. package/bundled/dev-pipeline-windows/lib/reset.ps1 +0 -87
  112. package/bundled/dev-pipeline-windows/reset-bug.ps1 +0 -9
  113. package/bundled/dev-pipeline-windows/reset-feature.ps1 +0 -9
  114. package/bundled/dev-pipeline-windows/reset-refactor.ps1 +0 -9
  115. package/bundled/dev-pipeline-windows/run-bugfix.ps1 +0 -9
  116. package/bundled/dev-pipeline-windows/run-feature.ps1 +0 -9
  117. package/bundled/dev-pipeline-windows/run-recovery.ps1 +0 -179
  118. package/bundled/dev-pipeline-windows/run-refactor.ps1 +0 -9
  119. package/bundled/dev-pipeline-windows/scripts/check-session-status.py +0 -228
  120. package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +0 -530
  121. package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +0 -2282
  122. package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +0 -767
  123. package/bundled/dev-pipeline-windows/scripts/generate-recovery-prompt.py +0 -805
  124. package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +0 -845
  125. package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +0 -316
  126. package/bundled/dev-pipeline-windows/scripts/init-dev-team.py +0 -134
  127. package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +0 -382
  128. package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +0 -399
  129. package/bundled/dev-pipeline-windows/scripts/monitor-log.ps1 +0 -102
  130. package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +0 -1232
  131. package/bundled/dev-pipeline-windows/scripts/patch-completion-notes.py +0 -191
  132. package/bundled/dev-pipeline-windows/scripts/prizmkit-test-gate.py +0 -446
  133. package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +0 -913
  134. package/bundled/dev-pipeline-windows/scripts/update-checkpoint.py +0 -173
  135. package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +0 -1558
  136. package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +0 -1119
  137. package/bundled/dev-pipeline-windows/scripts/utils.py +0 -542
  138. package/bundled/dev-pipeline-windows/templates/agent-prompts/critic-plan-challenge.md +0 -7
  139. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-fix.md +0 -7
  140. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +0 -65
  141. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-resume.md +0 -5
  142. package/bundled/dev-pipeline-windows/templates/agent-prompts/reviewer-review.md +0 -7
  143. package/bundled/dev-pipeline-windows/templates/bootstrap-prompt.md +0 -73
  144. package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +0 -589
  145. package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +0 -710
  146. package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +0 -791
  147. package/bundled/dev-pipeline-windows/templates/bug-fix-list-schema.json +0 -263
  148. package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +0 -326
  149. package/bundled/dev-pipeline-windows/templates/feature-list-schema.json +0 -237
  150. package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +0 -340
  151. package/bundled/dev-pipeline-windows/templates/refactor-list-schema.json +0 -270
  152. package/bundled/dev-pipeline-windows/templates/sections/ac-verification-checklist.md +0 -7
  153. package/bundled/dev-pipeline-windows/templates/sections/checkpoint-system.md +0 -91
  154. package/bundled/dev-pipeline-windows/templates/sections/context-budget-rules.md +0 -34
  155. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-agent.md +0 -10
  156. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-full.md +0 -12
  157. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-lite.md +0 -7
  158. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-agent.md +0 -8
  159. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-full.md +0 -9
  160. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-lite.md +0 -6
  161. package/bundled/dev-pipeline-windows/templates/sections/failure-capture.md +0 -21
  162. package/bundled/dev-pipeline-windows/templates/sections/feature-context.md +0 -21
  163. package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +0 -78
  164. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-auto.md +0 -283
  165. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-opencli.md +0 -112
  166. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification.md +0 -168
  167. package/bundled/dev-pipeline-windows/templates/sections/phase-commit-full.md +0 -82
  168. package/bundled/dev-pipeline-windows/templates/sections/phase-commit.md +0 -75
  169. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-agent-suffix.md +0 -23
  170. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-base.md +0 -14
  171. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-lite-suffix.md +0 -19
  172. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan-full.md +0 -63
  173. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan.md +0 -42
  174. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-agent.md +0 -44
  175. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-full.md +0 -59
  176. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-lite.md +0 -39
  177. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-agent.md +0 -27
  178. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-lite.md +0 -27
  179. package/bundled/dev-pipeline-windows/templates/sections/phase-prizmkit-test.md +0 -39
  180. package/bundled/dev-pipeline-windows/templates/sections/phase-review-agent.md +0 -35
  181. package/bundled/dev-pipeline-windows/templates/sections/phase-review-full.md +0 -35
  182. package/bundled/dev-pipeline-windows/templates/sections/phase-specify-plan-full.md +0 -73
  183. package/bundled/dev-pipeline-windows/templates/sections/phase0-init.md +0 -13
  184. package/bundled/dev-pipeline-windows/templates/sections/phase0-test-baseline.md +0 -21
  185. package/bundled/dev-pipeline-windows/templates/sections/session-context.md +0 -5
  186. package/bundled/dev-pipeline-windows/templates/sections/subagent-timeout-recovery.md +0 -6
  187. package/bundled/dev-pipeline-windows/templates/sections/task-contract.md +0 -34
  188. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-agent.md +0 -48
  189. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-lite.md +0 -48
  190. package/bundled/dev-pipeline-windows/templates/session-status-schema.json +0 -83
  191. package/bundled/skills-windows/app-planner/SKILL.md +0 -296
  192. package/bundled/skills-windows/app-planner/assets/app-design-guide.md +0 -101
  193. package/bundled/skills-windows/app-planner/references/architecture-decisions.md +0 -52
  194. package/bundled/skills-windows/app-planner/references/brainstorm-guide.md +0 -101
  195. package/bundled/skills-windows/app-planner/references/frontend-design-guide.md +0 -71
  196. package/bundled/skills-windows/app-planner/references/infrastructure-convention-discovery.md +0 -108
  197. package/bundled/skills-windows/app-planner/references/project-brief-guide.md +0 -82
  198. package/bundled/skills-windows/app-planner/references/project-conventions-discovery.md +0 -59
  199. package/bundled/skills-windows/app-planner/references/project-state-detection.md +0 -90
  200. package/bundled/skills-windows/app-planner/references/red-team-checklist.md +0 -40
  201. package/bundled/skills-windows/app-planner/references/rules/backend/derivation-rules.md +0 -619
  202. package/bundled/skills-windows/app-planner/references/rules/backend/fixed-rules.md +0 -285
  203. package/bundled/skills-windows/app-planner/references/rules/backend/question-bank.md +0 -249
  204. package/bundled/skills-windows/app-planner/references/rules/backend/question-manifest.json +0 -46
  205. package/bundled/skills-windows/app-planner/references/rules/backend/template.md +0 -173
  206. package/bundled/skills-windows/app-planner/references/rules/database/derivation-rules.md +0 -382
  207. package/bundled/skills-windows/app-planner/references/rules/database/fixed-rules.md +0 -211
  208. package/bundled/skills-windows/app-planner/references/rules/database/question-bank.md +0 -184
  209. package/bundled/skills-windows/app-planner/references/rules/database/question-manifest.json +0 -39
  210. package/bundled/skills-windows/app-planner/references/rules/database/template.md +0 -158
  211. package/bundled/skills-windows/app-planner/references/rules/frontend/derivation-rules.md +0 -820
  212. package/bundled/skills-windows/app-planner/references/rules/frontend/fixed-rules.md +0 -188
  213. package/bundled/skills-windows/app-planner/references/rules/frontend/question-bank.md +0 -319
  214. package/bundled/skills-windows/app-planner/references/rules/frontend/question-manifest.json +0 -51
  215. package/bundled/skills-windows/app-planner/references/rules/frontend/template.md +0 -339
  216. package/bundled/skills-windows/app-planner/references/rules/mobile/derivation-rules.md +0 -649
  217. package/bundled/skills-windows/app-planner/references/rules/mobile/fixed-rules.md +0 -290
  218. package/bundled/skills-windows/app-planner/references/rules/mobile/question-bank.md +0 -232
  219. package/bundled/skills-windows/app-planner/references/rules/mobile/question-manifest.json +0 -47
  220. package/bundled/skills-windows/app-planner/references/rules/mobile/template.md +0 -175
  221. package/bundled/skills-windows/app-planner/references/rules-configuration.md +0 -46
  222. package/bundled/skills-windows/bug-fix-workflow/SKILL.md +0 -379
  223. package/bundled/skills-windows/bug-fix-workflow/references/bug-diagnosis.md +0 -41
  224. package/bundled/skills-windows/bug-planner/SKILL.md +0 -402
  225. package/bundled/skills-windows/bug-planner/assets/bug-confirmation-template.md +0 -43
  226. package/bundled/skills-windows/bug-planner/references/critic-and-verification.md +0 -44
  227. package/bundled/skills-windows/bug-planner/references/error-recovery.md +0 -73
  228. package/bundled/skills-windows/bug-planner/references/input-formats.md +0 -53
  229. package/bundled/skills-windows/bug-planner/references/schema-validation.md +0 -25
  230. package/bundled/skills-windows/bug-planner/references/severity-rules.md +0 -16
  231. package/bundled/skills-windows/bug-planner/scripts/validate-bug-list.py +0 -322
  232. package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +0 -304
  233. package/bundled/skills-windows/bugfix-pipeline-launcher/references/configuration.md +0 -84
  234. package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +0 -381
  235. package/bundled/skills-windows/feature-pipeline-launcher/references/configuration.md +0 -67
  236. package/bundled/skills-windows/feature-pipeline-launcher/scripts/preflight-check.py +0 -462
  237. package/bundled/skills-windows/feature-planner/SKILL.md +0 -397
  238. package/bundled/skills-windows/feature-planner/assets/evaluation-guide.md +0 -64
  239. package/bundled/skills-windows/feature-planner/assets/planning-guide.md +0 -214
  240. package/bundled/skills-windows/feature-planner/references/browser-interaction.md +0 -59
  241. package/bundled/skills-windows/feature-planner/references/completeness-review.md +0 -57
  242. package/bundled/skills-windows/feature-planner/references/decomposition-patterns.md +0 -75
  243. package/bundled/skills-windows/feature-planner/references/error-recovery.md +0 -90
  244. package/bundled/skills-windows/feature-planner/references/incremental-feature-planning.md +0 -112
  245. package/bundled/skills-windows/feature-planner/references/new-project-planning.md +0 -85
  246. package/bundled/skills-windows/feature-planner/scripts/validate-and-generate.py +0 -1020
  247. package/bundled/skills-windows/feature-workflow/SKILL.md +0 -374
  248. package/bundled/skills-windows/feature-workflow/references/brainstorm-guide.md +0 -137
  249. package/bundled/skills-windows/prizm-kit/SKILL.md +0 -93
  250. package/bundled/skills-windows/prizmkit-code-review/SKILL.md +0 -161
  251. package/bundled/skills-windows/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
  252. package/bundled/skills-windows/prizmkit-code-review/references/review-report-template.md +0 -31
  253. package/bundled/skills-windows/prizmkit-code-review/references/reviewer-agent-prompt.md +0 -66
  254. package/bundled/skills-windows/prizmkit-code-review/scripts/check_loop.py +0 -186
  255. package/bundled/skills-windows/prizmkit-committer/SKILL.md +0 -89
  256. package/bundled/skills-windows/prizmkit-deploy/SKILL.md +0 -444
  257. package/bundled/skills-windows/prizmkit-deploy/references/ci-cd-workflows.md +0 -115
  258. package/bundled/skills-windows/prizmkit-deploy/references/cloud-platform-deploy.md +0 -93
  259. package/bundled/skills-windows/prizmkit-deploy/references/data-safety-examples.md +0 -120
  260. package/bundled/skills-windows/prizmkit-deploy/references/database-setup.md +0 -46
  261. package/bundled/skills-windows/prizmkit-deploy/references/deploy-config-schema.md +0 -148
  262. package/bundled/skills-windows/prizmkit-deploy/references/deploy-history-schema.md +0 -62
  263. package/bundled/skills-windows/prizmkit-deploy/references/deployment-modes.md +0 -50
  264. package/bundled/skills-windows/prizmkit-deploy/references/direct-upload.md +0 -26
  265. package/bundled/skills-windows/prizmkit-deploy/references/dns-setup.md +0 -42
  266. package/bundled/skills-windows/prizmkit-deploy/references/docker-deploy.md +0 -31
  267. package/bundled/skills-windows/prizmkit-deploy/references/firewall-setup.md +0 -37
  268. package/bundled/skills-windows/prizmkit-deploy/references/live-validation-notes.md +0 -21
  269. package/bundled/skills-windows/prizmkit-deploy/references/nginx-blue-green.md +0 -59
  270. package/bundled/skills-windows/prizmkit-deploy/references/ssh-bootstrap-flow.md +0 -49
  271. package/bundled/skills-windows/prizmkit-deploy/references/ssh-execution-flow.md +0 -41
  272. package/bundled/skills-windows/prizmkit-deploy/references/ssh-takeover.md +0 -20
  273. package/bundled/skills-windows/prizmkit-deploy/references/ssl-setup.md +0 -56
  274. package/bundled/skills-windows/prizmkit-implement/SKILL.md +0 -71
  275. package/bundled/skills-windows/prizmkit-init/SKILL.md +0 -356
  276. package/bundled/skills-windows/prizmkit-init/assets/project-brief-template.md +0 -82
  277. package/bundled/skills-windows/prizmkit-init/references/config-schema.md +0 -70
  278. package/bundled/skills-windows/prizmkit-init/references/rules/layer-detection.md +0 -41
  279. package/bundled/skills-windows/prizmkit-init/references/tech-stack-catalog.md +0 -13
  280. package/bundled/skills-windows/prizmkit-init/references/update-supplement.md +0 -9
  281. package/bundled/skills-windows/prizmkit-plan/SKILL.md +0 -102
  282. package/bundled/skills-windows/prizmkit-plan/assets/plan-template.md +0 -115
  283. package/bundled/skills-windows/prizmkit-plan/assets/spec-template.md +0 -73
  284. package/bundled/skills-windows/prizmkit-plan/references/clarify-guide.md +0 -67
  285. package/bundled/skills-windows/prizmkit-plan/references/examples.md +0 -85
  286. package/bundled/skills-windows/prizmkit-plan/references/verification-checklist.md +0 -60
  287. package/bundled/skills-windows/prizmkit-prizm-docs/SKILL.md +0 -129
  288. package/bundled/skills-windows/prizmkit-prizm-docs/assets/prizm-docs-format.md +0 -613
  289. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-init.md +0 -45
  290. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-rebuild.md +0 -15
  291. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-status.md +0 -14
  292. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-update.md +0 -19
  293. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-validate.md +0 -17
  294. package/bundled/skills-windows/prizmkit-retrospective/SKILL.md +0 -87
  295. package/bundled/skills-windows/prizmkit-retrospective/references/knowledge-injection-steps.md +0 -50
  296. package/bundled/skills-windows/prizmkit-retrospective/references/structural-sync-steps.md +0 -43
  297. package/bundled/skills-windows/prizmkit-test/SKILL.md +0 -227
  298. package/bundled/skills-windows/prizmkit-test/references/boundary-coverage-protocol.md +0 -220
  299. package/bundled/skills-windows/prizmkit-test/references/examples.md +0 -143
  300. package/bundled/skills-windows/prizmkit-test/references/service-boundary-test-catalog.md +0 -225
  301. package/bundled/skills-windows/prizmkit-test/references/test-generation-steps.md +0 -109
  302. package/bundled/skills-windows/prizmkit-test/references/test-report-template.md +0 -111
  303. package/bundled/skills-windows/prizmkit-test/scripts/validate_boundary_report.py +0 -347
  304. package/bundled/skills-windows/recovery-workflow/SKILL.md +0 -355
  305. package/bundled/skills-windows/recovery-workflow/evals/evals.json +0 -46
  306. package/bundled/skills-windows/recovery-workflow/references/detection.md +0 -58
  307. package/bundled/skills-windows/recovery-workflow/scripts/detect-recovery-state.py +0 -544
  308. package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +0 -346
  309. package/bundled/skills-windows/refactor-pipeline-launcher/references/configuration.md +0 -72
  310. package/bundled/skills-windows/refactor-planner/SKILL.md +0 -398
  311. package/bundled/skills-windows/refactor-planner/assets/planning-guide.md +0 -292
  312. package/bundled/skills-windows/refactor-planner/references/behavior-preservation.md +0 -301
  313. package/bundled/skills-windows/refactor-planner/references/fast-path.md +0 -59
  314. package/bundled/skills-windows/refactor-planner/references/planning-phases.md +0 -135
  315. package/bundled/skills-windows/refactor-planner/references/refactor-scoping-guide.md +0 -221
  316. package/bundled/skills-windows/refactor-planner/scripts/validate-and-generate-refactor.py +0 -858
  317. package/bundled/skills-windows/refactor-workflow/SKILL.md +0 -343
  318. package/bundled/skills-windows/refactor-workflow/references/brainstorm-guide.md +0 -116
  319. package/bundled/templates/hooks/diff-prizm-docs.sh +0 -158
  320. package/bundled/templates/hooks/prizm-pre-commit.sh +0 -108
  321. package/bundled/templates/hooks/validate-prizm-docs.sh +0 -139
@@ -0,0 +1,345 @@
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
+ strict_behavior_check: bool = True
49
+
50
+ @classmethod
51
+ def from_env(cls, env: Mapping[str, str] | None = None) -> "RunnerEnvironment":
52
+ values = dict(os.environ if env is None else env)
53
+ return cls(
54
+ stop_on_failure=_truthy(values.get("STOP_ON_FAILURE")),
55
+ auto_push=_truthy(values.get("AUTO_PUSH")),
56
+ use_worktree=not _falsey(values.get("USE_WORKTREE")),
57
+ dev_branch=values.get("DEV_BRANCH", ""),
58
+ enable_deploy=_truthy(values.get("ENABLE_DEPLOY")),
59
+ verbose=_truthy(values.get("VERBOSE")),
60
+ heartbeat_interval_seconds=_int_value(values, "HEARTBEAT_INTERVAL", 30),
61
+ heartbeat_stale_threshold_seconds=_int_value(
62
+ values,
63
+ "HEARTBEAT_STALE_THRESHOLD",
64
+ _int_value(values, "HEARTBEAT_TIMEOUT_SECONDS", 600),
65
+ ),
66
+ stale_kill_threshold_seconds=_int_value(values, "STALE_KILL_THRESHOLD", 600),
67
+ max_log_size=_optional_int(values.get("MAX_LOG_SIZE")),
68
+ strict_behavior_check=not _falsey(values.get("STRICT_BEHAVIOR_CHECK")),
69
+ )
70
+
71
+
72
+ @dataclass(frozen=True)
73
+ class RunnerInvocation:
74
+ """Normalized legacy CLI arguments for one runner invocation."""
75
+
76
+ action: str
77
+ list_path: Path
78
+ item_id: str = ""
79
+ item_filter: str = ""
80
+ max_infra_retries: int = 3
81
+ mode: str | None = None
82
+ critic: bool | None = None
83
+ dry_run: bool = False
84
+ clean: bool = False
85
+ no_reset: bool = False
86
+ resume_phase: str = "null"
87
+ help_requested: bool = False
88
+ unknown_args: tuple[str, ...] = ()
89
+ raw_args: tuple[str, ...] = ()
90
+
91
+
92
+ @dataclass(frozen=True)
93
+ class PromptGenerationResult:
94
+ """Structured output from the existing prompt generators."""
95
+
96
+ output_path: Path
97
+ model: str = ""
98
+ pipeline_mode: str = ""
99
+ agent_count: int = 0
100
+ critic_enabled: bool = False
101
+ checkpoint_path: Path | None = None
102
+ artifact_path: Path | None = None
103
+ raw: Mapping[str, object] = field(default_factory=dict)
104
+
105
+
106
+ @dataclass(frozen=True)
107
+ class SessionPaths:
108
+ """Canonical per-session runtime paths."""
109
+
110
+ session_dir: Path
111
+ prompt_path: Path
112
+ logs_dir: Path
113
+ session_log: Path
114
+ progress_json: Path
115
+ heartbeat_json: Path
116
+ session_status_json: Path
117
+
118
+ @classmethod
119
+ def for_item(cls, state_dir: Path, item_id: str, session_id: str) -> "SessionPaths":
120
+ session_dir = state_dir / item_id / "sessions" / session_id
121
+ logs_dir = session_dir / "logs"
122
+ return cls(
123
+ session_dir=session_dir,
124
+ prompt_path=session_dir / "bootstrap-prompt.md",
125
+ logs_dir=logs_dir,
126
+ session_log=logs_dir / "session.log",
127
+ progress_json=logs_dir / "progress.json",
128
+ heartbeat_json=logs_dir / "heartbeat.json",
129
+ session_status_json=session_dir / "session-status.json",
130
+ )
131
+
132
+
133
+ @dataclass(frozen=True)
134
+ class ContinuationState:
135
+ """Context-overflow continuation inputs for the next prompt/status update."""
136
+
137
+ active: bool = False
138
+ previous_session_id: str = ""
139
+ continuation_count: int = 0
140
+ context_overflow_count: int = 0
141
+ no_progress_count: int = 0
142
+ summary_path: Path | None = None
143
+ active_dev_branch: str = ""
144
+ base_branch: str = ""
145
+ fatal_error_code: str = "context_overflow"
146
+
147
+
148
+ @dataclass(frozen=True)
149
+ class SessionClassification:
150
+ """Final runner-owned session outcome before status updater mutation."""
151
+
152
+ session_status: str
153
+ reason: str = ""
154
+ fatal_error_code: str = ""
155
+ progress_fingerprint: Mapping[str, object] = field(default_factory=dict)
156
+ no_progress_count: int = 0
157
+
158
+
159
+ @dataclass(frozen=True)
160
+ class PipelineRunResult:
161
+ """Aggregated result for one foreground runner command."""
162
+
163
+ completed: bool
164
+ processed: int
165
+ stopped_reason: str = ""
166
+ last_status: str = ""
167
+ details: tuple[str, ...] = ()
168
+
169
+
170
+ FAMILY_KINDS = ("feature", "bugfix", "refactor")
171
+
172
+
173
+ def family_for(kind: str, paths: RuntimePaths) -> RunnerFamily:
174
+ """Return runner metadata for a supported pipeline family."""
175
+ script_dir = paths.pipeline_root / "scripts"
176
+ if kind == "feature":
177
+ return RunnerFamily(
178
+ kind="feature",
179
+ id_prefix="F-",
180
+ list_key="features",
181
+ list_arg="--feature-list",
182
+ item_id_arg="--feature-id",
183
+ state_dir=paths.feature_state_dir,
184
+ plan_path=paths.feature_plan,
185
+ updater_script=script_dir / "update-feature-status.py",
186
+ prompt_script=script_dir / "generate-bootstrap-prompt.py",
187
+ branch_prefix="dev",
188
+ artifact_root_name="specs",
189
+ )
190
+ if kind == "bugfix":
191
+ return RunnerFamily(
192
+ kind="bugfix",
193
+ id_prefix="B-",
194
+ list_key="bugs",
195
+ list_arg="--bug-list",
196
+ item_id_arg="--bug-id",
197
+ state_dir=paths.bugfix_state_dir,
198
+ plan_path=paths.bugfix_plan,
199
+ updater_script=script_dir / "update-bug-status.py",
200
+ prompt_script=script_dir / "generate-bugfix-prompt.py",
201
+ branch_prefix="bugfix",
202
+ artifact_root_name="bugfix",
203
+ )
204
+ if kind == "refactor":
205
+ return RunnerFamily(
206
+ kind="refactor",
207
+ id_prefix="R-",
208
+ list_key="refactors",
209
+ list_arg="--refactor-list",
210
+ item_id_arg="--refactor-id",
211
+ state_dir=paths.refactor_state_dir,
212
+ plan_path=paths.refactor_plan,
213
+ updater_script=script_dir / "update-refactor-status.py",
214
+ prompt_script=script_dir / "generate-refactor-prompt.py",
215
+ branch_prefix="refactor",
216
+ artifact_root_name="refactor",
217
+ )
218
+ raise ValueError(f"Unsupported runner family: {kind}")
219
+
220
+
221
+ def parse_invocation(
222
+ family: RunnerFamily,
223
+ action: str,
224
+ legacy_args: Sequence[str] = (),
225
+ ) -> RunnerInvocation:
226
+ """Normalize legacy shell runner arguments without redesigning the interface."""
227
+ args = tuple(str(arg) for arg in legacy_args)
228
+ list_path = family.plan_path
229
+ item_id = ""
230
+ item_filter = ""
231
+ max_infra_retries = 3
232
+ mode: str | None = None
233
+ critic: bool | None = None
234
+ dry_run = False
235
+ clean = False
236
+ no_reset = False
237
+ resume_phase = "null"
238
+ unknown: list[str] = []
239
+ positional: list[str] = []
240
+ help_requested = False
241
+
242
+ index = 0
243
+ while index < len(args):
244
+ arg = args[index]
245
+ if arg in {"--help", "-h", "help"}:
246
+ help_requested = True
247
+ elif arg == "--dry-run":
248
+ dry_run = True
249
+ elif arg == "--clean":
250
+ clean = True
251
+ elif arg == "--no-reset":
252
+ no_reset = True
253
+ elif arg == "--critic":
254
+ critic = True
255
+ elif arg == "--no-critic":
256
+ critic = False
257
+ elif arg == "--features" and index + 1 < len(args):
258
+ index += 1
259
+ item_filter = args[index]
260
+ elif arg.startswith("--features="):
261
+ item_filter = arg.split("=", 1)[1]
262
+ elif arg == "--max-infra-retries" and index + 1 < len(args):
263
+ index += 1
264
+ max_infra_retries = _safe_int(args[index], 3)
265
+ elif arg.startswith("--max-infra-retries="):
266
+ max_infra_retries = _safe_int(arg.split("=", 1)[1], 3)
267
+ elif arg == "--mode" and index + 1 < len(args):
268
+ index += 1
269
+ mode = args[index]
270
+ elif arg.startswith("--mode="):
271
+ mode = arg.split("=", 1)[1]
272
+ elif arg == "--resume-phase" and index + 1 < len(args):
273
+ index += 1
274
+ resume_phase = args[index]
275
+ elif arg.startswith("--resume-phase="):
276
+ resume_phase = arg.split("=", 1)[1]
277
+ elif arg.startswith("-"):
278
+ unknown.append(arg)
279
+ else:
280
+ positional.append(arg)
281
+ index += 1
282
+
283
+ for value in positional:
284
+ if _looks_like_item_id(value, family.id_prefix) and not item_id:
285
+ item_id = _normalize_item_id(value, family.id_prefix)
286
+ elif list_path == family.plan_path:
287
+ list_path = Path(value).expanduser()
288
+ else:
289
+ unknown.append(value)
290
+
291
+ return RunnerInvocation(
292
+ action=action,
293
+ list_path=list_path,
294
+ item_id=item_id,
295
+ item_filter=item_filter,
296
+ max_infra_retries=max_infra_retries,
297
+ mode=mode,
298
+ critic=critic,
299
+ dry_run=dry_run,
300
+ clean=clean,
301
+ no_reset=no_reset,
302
+ resume_phase=resume_phase or "null",
303
+ help_requested=help_requested,
304
+ unknown_args=tuple(unknown),
305
+ raw_args=args,
306
+ )
307
+
308
+
309
+ def _looks_like_item_id(value: str, prefix: str) -> bool:
310
+ upper = value.upper()
311
+ return upper.startswith(prefix.upper())
312
+
313
+
314
+ def _normalize_item_id(value: str, prefix: str) -> str:
315
+ upper = value.upper()
316
+ if upper.startswith(prefix.upper()):
317
+ suffix = upper[len(prefix) :]
318
+ if suffix.isdigit():
319
+ return f"{prefix}{int(suffix):03d}"
320
+ return upper
321
+
322
+
323
+ def _truthy(value: str | None) -> bool:
324
+ return str(value or "").strip().lower() in {"1", "true", "yes", "on"}
325
+
326
+
327
+ def _falsey(value: str | None) -> bool:
328
+ return str(value or "").strip().lower() in {"0", "false", "no", "off"}
329
+
330
+
331
+ def _safe_int(value: str | None, default: int) -> int:
332
+ try:
333
+ return int(str(value))
334
+ except (TypeError, ValueError):
335
+ return default
336
+
337
+
338
+ def _int_value(values: Mapping[str, str], name: str, default: int) -> int:
339
+ return _safe_int(values.get(name), default)
340
+
341
+
342
+ def _optional_int(value: str | None) -> int | None:
343
+ if value is None or str(value).strip() == "":
344
+ return None
345
+ 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"