prizmkit 1.1.100 → 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 (309) 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/generate-bootstrap-prompt.py +38 -23
  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 +7 -1
  34. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +4 -0
  35. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +12 -3
  36. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +13 -3
  37. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +13 -3
  38. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +2 -0
  39. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +9 -30
  40. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +15 -7
  41. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +42 -29
  42. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +41 -39
  43. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +4 -0
  44. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +4 -0
  45. package/bundled/dev-pipeline/tests/test_auto_skip.py +436 -14
  46. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +104 -0
  47. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +40 -0
  48. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +1138 -0
  49. package/bundled/dev-pipeline/tests/test_unified_cli.py +1045 -0
  50. package/bundled/skills/_metadata.json +1 -1
  51. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +29 -34
  52. package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +6 -5
  53. package/bundled/skills/feature-pipeline-launcher/SKILL.md +29 -35
  54. package/bundled/skills/feature-pipeline-launcher/references/configuration.md +7 -6
  55. package/bundled/skills/feature-workflow/SKILL.md +3 -6
  56. package/bundled/skills/recovery-workflow/SKILL.md +23 -32
  57. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +29 -35
  58. package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +7 -6
  59. package/bundled/skills/refactor-workflow/SKILL.md +3 -6
  60. package/bundled/templates/hooks/commit-intent.json +2 -2
  61. package/bundled/templates/hooks/diff-prizm-docs.py +226 -0
  62. package/bundled/templates/hooks/prizm-pre-commit.py +45 -0
  63. package/bundled/templates/hooks/validate-prizm-docs.py +240 -0
  64. package/package.json +1 -1
  65. package/src/config.js +33 -12
  66. package/src/index.js +3 -6
  67. package/src/manifest.js +3 -2
  68. package/src/metadata.js +7 -18
  69. package/src/prompts.js +0 -12
  70. package/src/runtimes.js +18 -11
  71. package/src/scaffold.js +133 -116
  72. package/src/upgrade.js +1 -1
  73. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +0 -500
  74. package/bundled/dev-pipeline/launch-feature-daemon.sh +0 -657
  75. package/bundled/dev-pipeline/launch-refactor-daemon.sh +0 -502
  76. package/bundled/dev-pipeline/lib/branch.sh +0 -326
  77. package/bundled/dev-pipeline/lib/common.sh +0 -1476
  78. package/bundled/dev-pipeline/lib/heartbeat.sh +0 -469
  79. package/bundled/dev-pipeline/reset-bug.sh +0 -425
  80. package/bundled/dev-pipeline/reset-feature.sh +0 -436
  81. package/bundled/dev-pipeline/reset-refactor.sh +0 -423
  82. package/bundled/dev-pipeline/run-bugfix.sh +0 -1430
  83. package/bundled/dev-pipeline/run-feature.sh +0 -1718
  84. package/bundled/dev-pipeline/run-recovery.sh +0 -648
  85. package/bundled/dev-pipeline/run-refactor.sh +0 -1463
  86. package/bundled/dev-pipeline/tests/test-path-resolution.sh +0 -100
  87. package/bundled/dev-pipeline-windows/.env.example +0 -36
  88. package/bundled/dev-pipeline-windows/README.md +0 -30
  89. package/bundled/dev-pipeline-windows/SCHEMA_ANALYSIS.md +0 -533
  90. package/bundled/dev-pipeline-windows/assets/feature-list-example.json +0 -146
  91. package/bundled/dev-pipeline-windows/assets/prizm-dev-team-integration.md +0 -137
  92. package/bundled/dev-pipeline-windows/launch-bugfix-daemon.ps1 +0 -9
  93. package/bundled/dev-pipeline-windows/launch-feature-daemon.ps1 +0 -9
  94. package/bundled/dev-pipeline-windows/launch-refactor-daemon.ps1 +0 -9
  95. package/bundled/dev-pipeline-windows/lib/branch.ps1 +0 -235
  96. package/bundled/dev-pipeline-windows/lib/common.ps1 +0 -991
  97. package/bundled/dev-pipeline-windows/lib/daemon.ps1 +0 -140
  98. package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +0 -1051
  99. package/bundled/dev-pipeline-windows/lib/reset.ps1 +0 -121
  100. package/bundled/dev-pipeline-windows/reset-bug.ps1 +0 -10
  101. package/bundled/dev-pipeline-windows/reset-feature.ps1 +0 -10
  102. package/bundled/dev-pipeline-windows/reset-refactor.ps1 +0 -10
  103. package/bundled/dev-pipeline-windows/run-bugfix.ps1 +0 -9
  104. package/bundled/dev-pipeline-windows/run-feature.ps1 +0 -9
  105. package/bundled/dev-pipeline-windows/run-recovery.ps1 +0 -179
  106. package/bundled/dev-pipeline-windows/run-refactor.ps1 +0 -9
  107. package/bundled/dev-pipeline-windows/scripts/check-session-status.py +0 -301
  108. package/bundled/dev-pipeline-windows/scripts/continuation.py +0 -374
  109. package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +0 -530
  110. package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +0 -2279
  111. package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +0 -763
  112. package/bundled/dev-pipeline-windows/scripts/generate-recovery-prompt.py +0 -805
  113. package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +0 -841
  114. package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +0 -316
  115. package/bundled/dev-pipeline-windows/scripts/init-dev-team.py +0 -134
  116. package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +0 -382
  117. package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +0 -399
  118. package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +0 -1362
  119. package/bundled/dev-pipeline-windows/scripts/patch-completion-notes.py +0 -191
  120. package/bundled/dev-pipeline-windows/scripts/prizmkit-test-gate.py +0 -446
  121. package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +0 -1121
  122. package/bundled/dev-pipeline-windows/scripts/update-checkpoint.py +0 -173
  123. package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +0 -1789
  124. package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +0 -1327
  125. package/bundled/dev-pipeline-windows/scripts/utils.py +0 -542
  126. package/bundled/dev-pipeline-windows/templates/agent-prompts/critic-plan-challenge.md +0 -7
  127. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-fix.md +0 -7
  128. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +0 -65
  129. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-resume.md +0 -5
  130. package/bundled/dev-pipeline-windows/templates/agent-prompts/reviewer-review.md +0 -7
  131. package/bundled/dev-pipeline-windows/templates/bootstrap-prompt.md +0 -73
  132. package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +0 -589
  133. package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +0 -710
  134. package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +0 -791
  135. package/bundled/dev-pipeline-windows/templates/bug-fix-list-schema.json +0 -263
  136. package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +0 -326
  137. package/bundled/dev-pipeline-windows/templates/feature-list-schema.json +0 -237
  138. package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +0 -340
  139. package/bundled/dev-pipeline-windows/templates/refactor-list-schema.json +0 -270
  140. package/bundled/dev-pipeline-windows/templates/sections/ac-verification-checklist.md +0 -7
  141. package/bundled/dev-pipeline-windows/templates/sections/checkpoint-system.md +0 -91
  142. package/bundled/dev-pipeline-windows/templates/sections/context-budget-rules.md +0 -34
  143. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-agent.md +0 -10
  144. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-full.md +0 -12
  145. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-lite.md +0 -7
  146. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-agent.md +0 -8
  147. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-full.md +0 -9
  148. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-lite.md +0 -6
  149. package/bundled/dev-pipeline-windows/templates/sections/failure-capture.md +0 -21
  150. package/bundled/dev-pipeline-windows/templates/sections/feature-context.md +0 -21
  151. package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +0 -41
  152. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-auto.md +0 -283
  153. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-opencli.md +0 -112
  154. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification.md +0 -168
  155. package/bundled/dev-pipeline-windows/templates/sections/phase-commit-full.md +0 -82
  156. package/bundled/dev-pipeline-windows/templates/sections/phase-commit.md +0 -75
  157. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-agent-suffix.md +0 -23
  158. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-base.md +0 -14
  159. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-lite-suffix.md +0 -19
  160. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan-full.md +0 -63
  161. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan.md +0 -42
  162. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-agent.md +0 -44
  163. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-full.md +0 -59
  164. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-lite.md +0 -39
  165. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-agent.md +0 -27
  166. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-lite.md +0 -27
  167. package/bundled/dev-pipeline-windows/templates/sections/phase-prizmkit-test.md +0 -39
  168. package/bundled/dev-pipeline-windows/templates/sections/phase-review-agent.md +0 -35
  169. package/bundled/dev-pipeline-windows/templates/sections/phase-review-full.md +0 -35
  170. package/bundled/dev-pipeline-windows/templates/sections/phase-specify-plan-full.md +0 -73
  171. package/bundled/dev-pipeline-windows/templates/sections/phase0-init.md +0 -13
  172. package/bundled/dev-pipeline-windows/templates/sections/phase0-test-baseline.md +0 -21
  173. package/bundled/dev-pipeline-windows/templates/sections/session-context.md +0 -5
  174. package/bundled/dev-pipeline-windows/templates/sections/subagent-timeout-recovery.md +0 -6
  175. package/bundled/dev-pipeline-windows/templates/sections/task-contract.md +0 -34
  176. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-agent.md +0 -48
  177. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-lite.md +0 -48
  178. package/bundled/dev-pipeline-windows/templates/session-status-schema.json +0 -83
  179. package/bundled/skills-windows/app-planner/SKILL.md +0 -296
  180. package/bundled/skills-windows/app-planner/assets/app-design-guide.md +0 -101
  181. package/bundled/skills-windows/app-planner/references/architecture-decisions.md +0 -52
  182. package/bundled/skills-windows/app-planner/references/brainstorm-guide.md +0 -101
  183. package/bundled/skills-windows/app-planner/references/frontend-design-guide.md +0 -71
  184. package/bundled/skills-windows/app-planner/references/infrastructure-convention-discovery.md +0 -108
  185. package/bundled/skills-windows/app-planner/references/project-brief-guide.md +0 -82
  186. package/bundled/skills-windows/app-planner/references/project-conventions-discovery.md +0 -59
  187. package/bundled/skills-windows/app-planner/references/project-state-detection.md +0 -90
  188. package/bundled/skills-windows/app-planner/references/red-team-checklist.md +0 -40
  189. package/bundled/skills-windows/app-planner/references/rules/backend/derivation-rules.md +0 -619
  190. package/bundled/skills-windows/app-planner/references/rules/backend/fixed-rules.md +0 -285
  191. package/bundled/skills-windows/app-planner/references/rules/backend/question-bank.md +0 -249
  192. package/bundled/skills-windows/app-planner/references/rules/backend/question-manifest.json +0 -46
  193. package/bundled/skills-windows/app-planner/references/rules/backend/template.md +0 -173
  194. package/bundled/skills-windows/app-planner/references/rules/database/derivation-rules.md +0 -382
  195. package/bundled/skills-windows/app-planner/references/rules/database/fixed-rules.md +0 -211
  196. package/bundled/skills-windows/app-planner/references/rules/database/question-bank.md +0 -184
  197. package/bundled/skills-windows/app-planner/references/rules/database/question-manifest.json +0 -39
  198. package/bundled/skills-windows/app-planner/references/rules/database/template.md +0 -158
  199. package/bundled/skills-windows/app-planner/references/rules/frontend/derivation-rules.md +0 -820
  200. package/bundled/skills-windows/app-planner/references/rules/frontend/fixed-rules.md +0 -188
  201. package/bundled/skills-windows/app-planner/references/rules/frontend/question-bank.md +0 -319
  202. package/bundled/skills-windows/app-planner/references/rules/frontend/question-manifest.json +0 -51
  203. package/bundled/skills-windows/app-planner/references/rules/frontend/template.md +0 -339
  204. package/bundled/skills-windows/app-planner/references/rules/mobile/derivation-rules.md +0 -649
  205. package/bundled/skills-windows/app-planner/references/rules/mobile/fixed-rules.md +0 -290
  206. package/bundled/skills-windows/app-planner/references/rules/mobile/question-bank.md +0 -232
  207. package/bundled/skills-windows/app-planner/references/rules/mobile/question-manifest.json +0 -47
  208. package/bundled/skills-windows/app-planner/references/rules/mobile/template.md +0 -175
  209. package/bundled/skills-windows/app-planner/references/rules-configuration.md +0 -46
  210. package/bundled/skills-windows/bug-fix-workflow/SKILL.md +0 -379
  211. package/bundled/skills-windows/bug-fix-workflow/references/bug-diagnosis.md +0 -41
  212. package/bundled/skills-windows/bug-planner/SKILL.md +0 -402
  213. package/bundled/skills-windows/bug-planner/assets/bug-confirmation-template.md +0 -43
  214. package/bundled/skills-windows/bug-planner/references/critic-and-verification.md +0 -44
  215. package/bundled/skills-windows/bug-planner/references/error-recovery.md +0 -73
  216. package/bundled/skills-windows/bug-planner/references/input-formats.md +0 -53
  217. package/bundled/skills-windows/bug-planner/references/schema-validation.md +0 -25
  218. package/bundled/skills-windows/bug-planner/references/severity-rules.md +0 -16
  219. package/bundled/skills-windows/bug-planner/scripts/validate-bug-list.py +0 -322
  220. package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +0 -304
  221. package/bundled/skills-windows/bugfix-pipeline-launcher/references/configuration.md +0 -84
  222. package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +0 -381
  223. package/bundled/skills-windows/feature-pipeline-launcher/references/configuration.md +0 -67
  224. package/bundled/skills-windows/feature-pipeline-launcher/scripts/preflight-check.py +0 -462
  225. package/bundled/skills-windows/feature-planner/SKILL.md +0 -397
  226. package/bundled/skills-windows/feature-planner/assets/evaluation-guide.md +0 -64
  227. package/bundled/skills-windows/feature-planner/assets/planning-guide.md +0 -214
  228. package/bundled/skills-windows/feature-planner/references/browser-interaction.md +0 -59
  229. package/bundled/skills-windows/feature-planner/references/completeness-review.md +0 -57
  230. package/bundled/skills-windows/feature-planner/references/decomposition-patterns.md +0 -75
  231. package/bundled/skills-windows/feature-planner/references/error-recovery.md +0 -90
  232. package/bundled/skills-windows/feature-planner/references/incremental-feature-planning.md +0 -112
  233. package/bundled/skills-windows/feature-planner/references/new-project-planning.md +0 -85
  234. package/bundled/skills-windows/feature-planner/scripts/validate-and-generate.py +0 -1020
  235. package/bundled/skills-windows/feature-workflow/SKILL.md +0 -374
  236. package/bundled/skills-windows/feature-workflow/references/brainstorm-guide.md +0 -137
  237. package/bundled/skills-windows/prizm-kit/SKILL.md +0 -93
  238. package/bundled/skills-windows/prizmkit-code-review/SKILL.md +0 -161
  239. package/bundled/skills-windows/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
  240. package/bundled/skills-windows/prizmkit-code-review/references/review-report-template.md +0 -31
  241. package/bundled/skills-windows/prizmkit-code-review/references/reviewer-agent-prompt.md +0 -66
  242. package/bundled/skills-windows/prizmkit-code-review/scripts/check_loop.py +0 -186
  243. package/bundled/skills-windows/prizmkit-committer/SKILL.md +0 -89
  244. package/bundled/skills-windows/prizmkit-deploy/SKILL.md +0 -444
  245. package/bundled/skills-windows/prizmkit-deploy/references/ci-cd-workflows.md +0 -115
  246. package/bundled/skills-windows/prizmkit-deploy/references/cloud-platform-deploy.md +0 -93
  247. package/bundled/skills-windows/prizmkit-deploy/references/data-safety-examples.md +0 -120
  248. package/bundled/skills-windows/prizmkit-deploy/references/database-setup.md +0 -46
  249. package/bundled/skills-windows/prizmkit-deploy/references/deploy-config-schema.md +0 -148
  250. package/bundled/skills-windows/prizmkit-deploy/references/deploy-history-schema.md +0 -62
  251. package/bundled/skills-windows/prizmkit-deploy/references/deployment-modes.md +0 -50
  252. package/bundled/skills-windows/prizmkit-deploy/references/direct-upload.md +0 -26
  253. package/bundled/skills-windows/prizmkit-deploy/references/dns-setup.md +0 -42
  254. package/bundled/skills-windows/prizmkit-deploy/references/docker-deploy.md +0 -31
  255. package/bundled/skills-windows/prizmkit-deploy/references/firewall-setup.md +0 -37
  256. package/bundled/skills-windows/prizmkit-deploy/references/live-validation-notes.md +0 -21
  257. package/bundled/skills-windows/prizmkit-deploy/references/nginx-blue-green.md +0 -59
  258. package/bundled/skills-windows/prizmkit-deploy/references/ssh-bootstrap-flow.md +0 -49
  259. package/bundled/skills-windows/prizmkit-deploy/references/ssh-execution-flow.md +0 -41
  260. package/bundled/skills-windows/prizmkit-deploy/references/ssh-takeover.md +0 -20
  261. package/bundled/skills-windows/prizmkit-deploy/references/ssl-setup.md +0 -56
  262. package/bundled/skills-windows/prizmkit-implement/SKILL.md +0 -71
  263. package/bundled/skills-windows/prizmkit-init/SKILL.md +0 -356
  264. package/bundled/skills-windows/prizmkit-init/assets/project-brief-template.md +0 -82
  265. package/bundled/skills-windows/prizmkit-init/references/config-schema.md +0 -70
  266. package/bundled/skills-windows/prizmkit-init/references/rules/layer-detection.md +0 -41
  267. package/bundled/skills-windows/prizmkit-init/references/tech-stack-catalog.md +0 -13
  268. package/bundled/skills-windows/prizmkit-init/references/update-supplement.md +0 -9
  269. package/bundled/skills-windows/prizmkit-plan/SKILL.md +0 -102
  270. package/bundled/skills-windows/prizmkit-plan/assets/plan-template.md +0 -115
  271. package/bundled/skills-windows/prizmkit-plan/assets/spec-template.md +0 -73
  272. package/bundled/skills-windows/prizmkit-plan/references/clarify-guide.md +0 -67
  273. package/bundled/skills-windows/prizmkit-plan/references/examples.md +0 -85
  274. package/bundled/skills-windows/prizmkit-plan/references/verification-checklist.md +0 -60
  275. package/bundled/skills-windows/prizmkit-prizm-docs/SKILL.md +0 -129
  276. package/bundled/skills-windows/prizmkit-prizm-docs/assets/prizm-docs-format.md +0 -613
  277. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-init.md +0 -45
  278. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-rebuild.md +0 -15
  279. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-status.md +0 -14
  280. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-update.md +0 -19
  281. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-validate.md +0 -17
  282. package/bundled/skills-windows/prizmkit-retrospective/SKILL.md +0 -87
  283. package/bundled/skills-windows/prizmkit-retrospective/references/knowledge-injection-steps.md +0 -50
  284. package/bundled/skills-windows/prizmkit-retrospective/references/structural-sync-steps.md +0 -43
  285. package/bundled/skills-windows/prizmkit-test/SKILL.md +0 -227
  286. package/bundled/skills-windows/prizmkit-test/references/boundary-coverage-protocol.md +0 -220
  287. package/bundled/skills-windows/prizmkit-test/references/examples.md +0 -143
  288. package/bundled/skills-windows/prizmkit-test/references/service-boundary-test-catalog.md +0 -225
  289. package/bundled/skills-windows/prizmkit-test/references/test-generation-steps.md +0 -109
  290. package/bundled/skills-windows/prizmkit-test/references/test-report-template.md +0 -111
  291. package/bundled/skills-windows/prizmkit-test/scripts/validate_boundary_report.py +0 -347
  292. package/bundled/skills-windows/recovery-workflow/SKILL.md +0 -355
  293. package/bundled/skills-windows/recovery-workflow/evals/evals.json +0 -46
  294. package/bundled/skills-windows/recovery-workflow/references/detection.md +0 -58
  295. package/bundled/skills-windows/recovery-workflow/scripts/detect-recovery-state.py +0 -544
  296. package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +0 -346
  297. package/bundled/skills-windows/refactor-pipeline-launcher/references/configuration.md +0 -72
  298. package/bundled/skills-windows/refactor-planner/SKILL.md +0 -398
  299. package/bundled/skills-windows/refactor-planner/assets/planning-guide.md +0 -292
  300. package/bundled/skills-windows/refactor-planner/references/behavior-preservation.md +0 -301
  301. package/bundled/skills-windows/refactor-planner/references/fast-path.md +0 -59
  302. package/bundled/skills-windows/refactor-planner/references/planning-phases.md +0 -135
  303. package/bundled/skills-windows/refactor-planner/references/refactor-scoping-guide.md +0 -221
  304. package/bundled/skills-windows/refactor-planner/scripts/validate-and-generate-refactor.py +0 -858
  305. package/bundled/skills-windows/refactor-workflow/SKILL.md +0 -343
  306. package/bundled/skills-windows/refactor-workflow/references/brainstorm-guide.md +0 -116
  307. package/bundled/templates/hooks/diff-prizm-docs.sh +0 -158
  308. package/bundled/templates/hooks/prizm-pre-commit.sh +0 -108
  309. 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"