prizmkit 1.1.100 → 1.1.102

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (317) hide show
  1. package/bin/create-prizmkit.js +4 -4
  2. package/bundled/VERSION.json +3 -3
  3. package/bundled/dev-pipeline/.env.example +3 -3
  4. package/bundled/dev-pipeline/README.md +110 -90
  5. package/bundled/dev-pipeline/assets/prizm-dev-team-integration.md +1 -1
  6. package/bundled/dev-pipeline/cli.py +27 -0
  7. package/bundled/dev-pipeline/prizmkit_runtime/__init__.py +13 -0
  8. package/bundled/dev-pipeline/prizmkit_runtime/__main__.py +9 -0
  9. package/bundled/dev-pipeline/prizmkit_runtime/cli.py +193 -0
  10. package/bundled/dev-pipeline/prizmkit_runtime/commands.py +313 -0
  11. package/bundled/dev-pipeline/prizmkit_runtime/compat.py +32 -0
  12. package/bundled/dev-pipeline/prizmkit_runtime/config.py +410 -0
  13. package/bundled/dev-pipeline/prizmkit_runtime/daemon.py +478 -0
  14. package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +734 -0
  15. package/bundled/dev-pipeline/prizmkit_runtime/heartbeat.py +256 -0
  16. package/bundled/dev-pipeline/prizmkit_runtime/interoperability.py +109 -0
  17. package/bundled/dev-pipeline/prizmkit_runtime/paths.py +110 -0
  18. package/bundled/dev-pipeline/prizmkit_runtime/processes.py +373 -0
  19. package/bundled/dev-pipeline/prizmkit_runtime/reset.py +389 -0
  20. package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +51 -0
  21. package/bundled/dev-pipeline/prizmkit_runtime/runner_classification.py +179 -0
  22. package/bundled/dev-pipeline/prizmkit_runtime/runner_models.py +355 -0
  23. package/bundled/dev-pipeline/prizmkit_runtime/runner_prompts.py +118 -0
  24. package/bundled/dev-pipeline/prizmkit_runtime/runner_recovery.py +187 -0
  25. package/bundled/dev-pipeline/prizmkit_runtime/runner_status.py +153 -0
  26. package/bundled/dev-pipeline/prizmkit_runtime/runners.py +425 -0
  27. package/bundled/dev-pipeline/prizmkit_runtime/sessions.py +560 -0
  28. package/bundled/dev-pipeline/prizmkit_runtime/status.py +71 -0
  29. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +51 -36
  30. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +20 -5
  31. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +2 -2
  32. package/bundled/dev-pipeline/scripts/parse-stream-progress.py +39 -0
  33. package/bundled/dev-pipeline/templates/agent-prompts/dev-implement.md +8 -2
  34. package/bundled/dev-pipeline/templates/agent-prompts/reviewer-review.md +1 -1
  35. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +6 -2
  36. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +14 -6
  37. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +14 -4
  38. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +14 -4
  39. package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +2 -0
  40. package/bundled/dev-pipeline/templates/sections/log-size-awareness.md +9 -30
  41. package/bundled/dev-pipeline/templates/sections/phase-context-snapshot-agent-suffix.md +15 -7
  42. package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +42 -29
  43. package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +41 -39
  44. package/bundled/dev-pipeline/templates/sections/phase-implement-lite.md +8 -17
  45. package/bundled/dev-pipeline/templates/sections/phase-prizmkit-test.md +2 -2
  46. package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +1 -3
  47. package/bundled/dev-pipeline/templates/sections/phase-review-full.md +1 -3
  48. package/bundled/dev-pipeline/templates/sections/phase0-test-baseline.md +3 -8
  49. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +6 -2
  50. package/bundled/dev-pipeline/templates/sections/test-failure-recovery-lite.md +5 -1
  51. package/bundled/dev-pipeline/tests/test_auto_skip.py +436 -14
  52. package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +115 -7
  53. package/bundled/dev-pipeline/tests/test_generate_bugfix_prompt.py +40 -0
  54. package/bundled/dev-pipeline/tests/test_python_runner_parity.py +1226 -0
  55. package/bundled/dev-pipeline/tests/test_unified_cli.py +1045 -0
  56. package/bundled/skills/_metadata.json +1 -1
  57. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +29 -34
  58. package/bundled/skills/bugfix-pipeline-launcher/references/configuration.md +6 -5
  59. package/bundled/skills/feature-pipeline-launcher/SKILL.md +29 -35
  60. package/bundled/skills/feature-pipeline-launcher/references/configuration.md +7 -6
  61. package/bundled/skills/feature-workflow/SKILL.md +3 -6
  62. package/bundled/skills/recovery-workflow/SKILL.md +23 -32
  63. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +29 -35
  64. package/bundled/skills/refactor-pipeline-launcher/references/configuration.md +7 -6
  65. package/bundled/skills/refactor-workflow/SKILL.md +3 -6
  66. package/bundled/templates/hooks/commit-intent.json +2 -2
  67. package/bundled/templates/hooks/diff-prizm-docs.py +226 -0
  68. package/bundled/templates/hooks/prizm-pre-commit.py +45 -0
  69. package/bundled/templates/hooks/validate-prizm-docs.py +240 -0
  70. package/package.json +1 -1
  71. package/src/config.js +42 -19
  72. package/src/external-skills.js +14 -14
  73. package/src/index.js +3 -6
  74. package/src/manifest.js +11 -5
  75. package/src/metadata.js +7 -18
  76. package/src/platforms.js +25 -0
  77. package/src/prompts.js +0 -12
  78. package/src/runtimes.js +18 -11
  79. package/src/scaffold.js +144 -122
  80. package/src/upgrade.js +12 -3
  81. package/bundled/dev-pipeline/launch-bugfix-daemon.sh +0 -500
  82. package/bundled/dev-pipeline/launch-feature-daemon.sh +0 -657
  83. package/bundled/dev-pipeline/launch-refactor-daemon.sh +0 -502
  84. package/bundled/dev-pipeline/lib/branch.sh +0 -326
  85. package/bundled/dev-pipeline/lib/common.sh +0 -1476
  86. package/bundled/dev-pipeline/lib/heartbeat.sh +0 -469
  87. package/bundled/dev-pipeline/reset-bug.sh +0 -425
  88. package/bundled/dev-pipeline/reset-feature.sh +0 -436
  89. package/bundled/dev-pipeline/reset-refactor.sh +0 -423
  90. package/bundled/dev-pipeline/run-bugfix.sh +0 -1430
  91. package/bundled/dev-pipeline/run-feature.sh +0 -1718
  92. package/bundled/dev-pipeline/run-recovery.sh +0 -648
  93. package/bundled/dev-pipeline/run-refactor.sh +0 -1463
  94. package/bundled/dev-pipeline/tests/test-path-resolution.sh +0 -100
  95. package/bundled/dev-pipeline-windows/.env.example +0 -36
  96. package/bundled/dev-pipeline-windows/README.md +0 -30
  97. package/bundled/dev-pipeline-windows/SCHEMA_ANALYSIS.md +0 -533
  98. package/bundled/dev-pipeline-windows/assets/feature-list-example.json +0 -146
  99. package/bundled/dev-pipeline-windows/assets/prizm-dev-team-integration.md +0 -137
  100. package/bundled/dev-pipeline-windows/launch-bugfix-daemon.ps1 +0 -9
  101. package/bundled/dev-pipeline-windows/launch-feature-daemon.ps1 +0 -9
  102. package/bundled/dev-pipeline-windows/launch-refactor-daemon.ps1 +0 -9
  103. package/bundled/dev-pipeline-windows/lib/branch.ps1 +0 -235
  104. package/bundled/dev-pipeline-windows/lib/common.ps1 +0 -991
  105. package/bundled/dev-pipeline-windows/lib/daemon.ps1 +0 -140
  106. package/bundled/dev-pipeline-windows/lib/pipeline.ps1 +0 -1051
  107. package/bundled/dev-pipeline-windows/lib/reset.ps1 +0 -121
  108. package/bundled/dev-pipeline-windows/reset-bug.ps1 +0 -10
  109. package/bundled/dev-pipeline-windows/reset-feature.ps1 +0 -10
  110. package/bundled/dev-pipeline-windows/reset-refactor.ps1 +0 -10
  111. package/bundled/dev-pipeline-windows/run-bugfix.ps1 +0 -9
  112. package/bundled/dev-pipeline-windows/run-feature.ps1 +0 -9
  113. package/bundled/dev-pipeline-windows/run-recovery.ps1 +0 -179
  114. package/bundled/dev-pipeline-windows/run-refactor.ps1 +0 -9
  115. package/bundled/dev-pipeline-windows/scripts/check-session-status.py +0 -301
  116. package/bundled/dev-pipeline-windows/scripts/continuation.py +0 -374
  117. package/bundled/dev-pipeline-windows/scripts/detect-stuck.py +0 -530
  118. package/bundled/dev-pipeline-windows/scripts/generate-bootstrap-prompt.py +0 -2279
  119. package/bundled/dev-pipeline-windows/scripts/generate-bugfix-prompt.py +0 -763
  120. package/bundled/dev-pipeline-windows/scripts/generate-recovery-prompt.py +0 -805
  121. package/bundled/dev-pipeline-windows/scripts/generate-refactor-prompt.py +0 -841
  122. package/bundled/dev-pipeline-windows/scripts/init-bugfix-pipeline.py +0 -316
  123. package/bundled/dev-pipeline-windows/scripts/init-dev-team.py +0 -134
  124. package/bundled/dev-pipeline-windows/scripts/init-pipeline.py +0 -382
  125. package/bundled/dev-pipeline-windows/scripts/init-refactor-pipeline.py +0 -399
  126. package/bundled/dev-pipeline-windows/scripts/parse-stream-progress.py +0 -1362
  127. package/bundled/dev-pipeline-windows/scripts/patch-completion-notes.py +0 -191
  128. package/bundled/dev-pipeline-windows/scripts/prizmkit-test-gate.py +0 -446
  129. package/bundled/dev-pipeline-windows/scripts/update-bug-status.py +0 -1121
  130. package/bundled/dev-pipeline-windows/scripts/update-checkpoint.py +0 -173
  131. package/bundled/dev-pipeline-windows/scripts/update-feature-status.py +0 -1789
  132. package/bundled/dev-pipeline-windows/scripts/update-refactor-status.py +0 -1327
  133. package/bundled/dev-pipeline-windows/scripts/utils.py +0 -542
  134. package/bundled/dev-pipeline-windows/templates/agent-prompts/critic-plan-challenge.md +0 -7
  135. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-fix.md +0 -7
  136. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-implement.md +0 -65
  137. package/bundled/dev-pipeline-windows/templates/agent-prompts/dev-resume.md +0 -5
  138. package/bundled/dev-pipeline-windows/templates/agent-prompts/reviewer-review.md +0 -7
  139. package/bundled/dev-pipeline-windows/templates/bootstrap-prompt.md +0 -73
  140. package/bundled/dev-pipeline-windows/templates/bootstrap-tier1.md +0 -589
  141. package/bundled/dev-pipeline-windows/templates/bootstrap-tier2.md +0 -710
  142. package/bundled/dev-pipeline-windows/templates/bootstrap-tier3.md +0 -791
  143. package/bundled/dev-pipeline-windows/templates/bug-fix-list-schema.json +0 -263
  144. package/bundled/dev-pipeline-windows/templates/bugfix-bootstrap-prompt.md +0 -326
  145. package/bundled/dev-pipeline-windows/templates/feature-list-schema.json +0 -237
  146. package/bundled/dev-pipeline-windows/templates/refactor-bootstrap-prompt.md +0 -340
  147. package/bundled/dev-pipeline-windows/templates/refactor-list-schema.json +0 -270
  148. package/bundled/dev-pipeline-windows/templates/sections/ac-verification-checklist.md +0 -7
  149. package/bundled/dev-pipeline-windows/templates/sections/checkpoint-system.md +0 -91
  150. package/bundled/dev-pipeline-windows/templates/sections/context-budget-rules.md +0 -34
  151. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-agent.md +0 -10
  152. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-full.md +0 -12
  153. package/bundled/dev-pipeline-windows/templates/sections/critical-paths-lite.md +0 -7
  154. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-agent.md +0 -8
  155. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-full.md +0 -9
  156. package/bundled/dev-pipeline-windows/templates/sections/directory-convention-lite.md +0 -6
  157. package/bundled/dev-pipeline-windows/templates/sections/failure-capture.md +0 -21
  158. package/bundled/dev-pipeline-windows/templates/sections/feature-context.md +0 -21
  159. package/bundled/dev-pipeline-windows/templates/sections/log-size-awareness.md +0 -41
  160. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-auto.md +0 -283
  161. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification-opencli.md +0 -112
  162. package/bundled/dev-pipeline-windows/templates/sections/phase-browser-verification.md +0 -168
  163. package/bundled/dev-pipeline-windows/templates/sections/phase-commit-full.md +0 -82
  164. package/bundled/dev-pipeline-windows/templates/sections/phase-commit.md +0 -75
  165. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-agent-suffix.md +0 -23
  166. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-base.md +0 -14
  167. package/bundled/dev-pipeline-windows/templates/sections/phase-context-snapshot-lite-suffix.md +0 -19
  168. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan-full.md +0 -63
  169. package/bundled/dev-pipeline-windows/templates/sections/phase-critic-plan.md +0 -42
  170. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-agent.md +0 -44
  171. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-full.md +0 -59
  172. package/bundled/dev-pipeline-windows/templates/sections/phase-implement-lite.md +0 -39
  173. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-agent.md +0 -27
  174. package/bundled/dev-pipeline-windows/templates/sections/phase-plan-lite.md +0 -27
  175. package/bundled/dev-pipeline-windows/templates/sections/phase-prizmkit-test.md +0 -39
  176. package/bundled/dev-pipeline-windows/templates/sections/phase-review-agent.md +0 -35
  177. package/bundled/dev-pipeline-windows/templates/sections/phase-review-full.md +0 -35
  178. package/bundled/dev-pipeline-windows/templates/sections/phase-specify-plan-full.md +0 -73
  179. package/bundled/dev-pipeline-windows/templates/sections/phase0-init.md +0 -13
  180. package/bundled/dev-pipeline-windows/templates/sections/phase0-test-baseline.md +0 -21
  181. package/bundled/dev-pipeline-windows/templates/sections/session-context.md +0 -5
  182. package/bundled/dev-pipeline-windows/templates/sections/subagent-timeout-recovery.md +0 -6
  183. package/bundled/dev-pipeline-windows/templates/sections/task-contract.md +0 -34
  184. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-agent.md +0 -48
  185. package/bundled/dev-pipeline-windows/templates/sections/test-failure-recovery-lite.md +0 -48
  186. package/bundled/dev-pipeline-windows/templates/session-status-schema.json +0 -83
  187. package/bundled/skills-windows/app-planner/SKILL.md +0 -296
  188. package/bundled/skills-windows/app-planner/assets/app-design-guide.md +0 -101
  189. package/bundled/skills-windows/app-planner/references/architecture-decisions.md +0 -52
  190. package/bundled/skills-windows/app-planner/references/brainstorm-guide.md +0 -101
  191. package/bundled/skills-windows/app-planner/references/frontend-design-guide.md +0 -71
  192. package/bundled/skills-windows/app-planner/references/infrastructure-convention-discovery.md +0 -108
  193. package/bundled/skills-windows/app-planner/references/project-brief-guide.md +0 -82
  194. package/bundled/skills-windows/app-planner/references/project-conventions-discovery.md +0 -59
  195. package/bundled/skills-windows/app-planner/references/project-state-detection.md +0 -90
  196. package/bundled/skills-windows/app-planner/references/red-team-checklist.md +0 -40
  197. package/bundled/skills-windows/app-planner/references/rules/backend/derivation-rules.md +0 -619
  198. package/bundled/skills-windows/app-planner/references/rules/backend/fixed-rules.md +0 -285
  199. package/bundled/skills-windows/app-planner/references/rules/backend/question-bank.md +0 -249
  200. package/bundled/skills-windows/app-planner/references/rules/backend/question-manifest.json +0 -46
  201. package/bundled/skills-windows/app-planner/references/rules/backend/template.md +0 -173
  202. package/bundled/skills-windows/app-planner/references/rules/database/derivation-rules.md +0 -382
  203. package/bundled/skills-windows/app-planner/references/rules/database/fixed-rules.md +0 -211
  204. package/bundled/skills-windows/app-planner/references/rules/database/question-bank.md +0 -184
  205. package/bundled/skills-windows/app-planner/references/rules/database/question-manifest.json +0 -39
  206. package/bundled/skills-windows/app-planner/references/rules/database/template.md +0 -158
  207. package/bundled/skills-windows/app-planner/references/rules/frontend/derivation-rules.md +0 -820
  208. package/bundled/skills-windows/app-planner/references/rules/frontend/fixed-rules.md +0 -188
  209. package/bundled/skills-windows/app-planner/references/rules/frontend/question-bank.md +0 -319
  210. package/bundled/skills-windows/app-planner/references/rules/frontend/question-manifest.json +0 -51
  211. package/bundled/skills-windows/app-planner/references/rules/frontend/template.md +0 -339
  212. package/bundled/skills-windows/app-planner/references/rules/mobile/derivation-rules.md +0 -649
  213. package/bundled/skills-windows/app-planner/references/rules/mobile/fixed-rules.md +0 -290
  214. package/bundled/skills-windows/app-planner/references/rules/mobile/question-bank.md +0 -232
  215. package/bundled/skills-windows/app-planner/references/rules/mobile/question-manifest.json +0 -47
  216. package/bundled/skills-windows/app-planner/references/rules/mobile/template.md +0 -175
  217. package/bundled/skills-windows/app-planner/references/rules-configuration.md +0 -46
  218. package/bundled/skills-windows/bug-fix-workflow/SKILL.md +0 -379
  219. package/bundled/skills-windows/bug-fix-workflow/references/bug-diagnosis.md +0 -41
  220. package/bundled/skills-windows/bug-planner/SKILL.md +0 -402
  221. package/bundled/skills-windows/bug-planner/assets/bug-confirmation-template.md +0 -43
  222. package/bundled/skills-windows/bug-planner/references/critic-and-verification.md +0 -44
  223. package/bundled/skills-windows/bug-planner/references/error-recovery.md +0 -73
  224. package/bundled/skills-windows/bug-planner/references/input-formats.md +0 -53
  225. package/bundled/skills-windows/bug-planner/references/schema-validation.md +0 -25
  226. package/bundled/skills-windows/bug-planner/references/severity-rules.md +0 -16
  227. package/bundled/skills-windows/bug-planner/scripts/validate-bug-list.py +0 -322
  228. package/bundled/skills-windows/bugfix-pipeline-launcher/SKILL.md +0 -304
  229. package/bundled/skills-windows/bugfix-pipeline-launcher/references/configuration.md +0 -84
  230. package/bundled/skills-windows/feature-pipeline-launcher/SKILL.md +0 -381
  231. package/bundled/skills-windows/feature-pipeline-launcher/references/configuration.md +0 -67
  232. package/bundled/skills-windows/feature-pipeline-launcher/scripts/preflight-check.py +0 -462
  233. package/bundled/skills-windows/feature-planner/SKILL.md +0 -397
  234. package/bundled/skills-windows/feature-planner/assets/evaluation-guide.md +0 -64
  235. package/bundled/skills-windows/feature-planner/assets/planning-guide.md +0 -214
  236. package/bundled/skills-windows/feature-planner/references/browser-interaction.md +0 -59
  237. package/bundled/skills-windows/feature-planner/references/completeness-review.md +0 -57
  238. package/bundled/skills-windows/feature-planner/references/decomposition-patterns.md +0 -75
  239. package/bundled/skills-windows/feature-planner/references/error-recovery.md +0 -90
  240. package/bundled/skills-windows/feature-planner/references/incremental-feature-planning.md +0 -112
  241. package/bundled/skills-windows/feature-planner/references/new-project-planning.md +0 -85
  242. package/bundled/skills-windows/feature-planner/scripts/validate-and-generate.py +0 -1020
  243. package/bundled/skills-windows/feature-workflow/SKILL.md +0 -374
  244. package/bundled/skills-windows/feature-workflow/references/brainstorm-guide.md +0 -137
  245. package/bundled/skills-windows/prizm-kit/SKILL.md +0 -93
  246. package/bundled/skills-windows/prizmkit-code-review/SKILL.md +0 -161
  247. package/bundled/skills-windows/prizmkit-code-review/references/dev-agent-prompt.md +0 -30
  248. package/bundled/skills-windows/prizmkit-code-review/references/review-report-template.md +0 -31
  249. package/bundled/skills-windows/prizmkit-code-review/references/reviewer-agent-prompt.md +0 -66
  250. package/bundled/skills-windows/prizmkit-code-review/scripts/check_loop.py +0 -186
  251. package/bundled/skills-windows/prizmkit-committer/SKILL.md +0 -89
  252. package/bundled/skills-windows/prizmkit-deploy/SKILL.md +0 -444
  253. package/bundled/skills-windows/prizmkit-deploy/references/ci-cd-workflows.md +0 -115
  254. package/bundled/skills-windows/prizmkit-deploy/references/cloud-platform-deploy.md +0 -93
  255. package/bundled/skills-windows/prizmkit-deploy/references/data-safety-examples.md +0 -120
  256. package/bundled/skills-windows/prizmkit-deploy/references/database-setup.md +0 -46
  257. package/bundled/skills-windows/prizmkit-deploy/references/deploy-config-schema.md +0 -148
  258. package/bundled/skills-windows/prizmkit-deploy/references/deploy-history-schema.md +0 -62
  259. package/bundled/skills-windows/prizmkit-deploy/references/deployment-modes.md +0 -50
  260. package/bundled/skills-windows/prizmkit-deploy/references/direct-upload.md +0 -26
  261. package/bundled/skills-windows/prizmkit-deploy/references/dns-setup.md +0 -42
  262. package/bundled/skills-windows/prizmkit-deploy/references/docker-deploy.md +0 -31
  263. package/bundled/skills-windows/prizmkit-deploy/references/firewall-setup.md +0 -37
  264. package/bundled/skills-windows/prizmkit-deploy/references/live-validation-notes.md +0 -21
  265. package/bundled/skills-windows/prizmkit-deploy/references/nginx-blue-green.md +0 -59
  266. package/bundled/skills-windows/prizmkit-deploy/references/ssh-bootstrap-flow.md +0 -49
  267. package/bundled/skills-windows/prizmkit-deploy/references/ssh-execution-flow.md +0 -41
  268. package/bundled/skills-windows/prizmkit-deploy/references/ssh-takeover.md +0 -20
  269. package/bundled/skills-windows/prizmkit-deploy/references/ssl-setup.md +0 -56
  270. package/bundled/skills-windows/prizmkit-implement/SKILL.md +0 -71
  271. package/bundled/skills-windows/prizmkit-init/SKILL.md +0 -356
  272. package/bundled/skills-windows/prizmkit-init/assets/project-brief-template.md +0 -82
  273. package/bundled/skills-windows/prizmkit-init/references/config-schema.md +0 -70
  274. package/bundled/skills-windows/prizmkit-init/references/rules/layer-detection.md +0 -41
  275. package/bundled/skills-windows/prizmkit-init/references/tech-stack-catalog.md +0 -13
  276. package/bundled/skills-windows/prizmkit-init/references/update-supplement.md +0 -9
  277. package/bundled/skills-windows/prizmkit-plan/SKILL.md +0 -102
  278. package/bundled/skills-windows/prizmkit-plan/assets/plan-template.md +0 -115
  279. package/bundled/skills-windows/prizmkit-plan/assets/spec-template.md +0 -73
  280. package/bundled/skills-windows/prizmkit-plan/references/clarify-guide.md +0 -67
  281. package/bundled/skills-windows/prizmkit-plan/references/examples.md +0 -85
  282. package/bundled/skills-windows/prizmkit-plan/references/verification-checklist.md +0 -60
  283. package/bundled/skills-windows/prizmkit-prizm-docs/SKILL.md +0 -129
  284. package/bundled/skills-windows/prizmkit-prizm-docs/assets/prizm-docs-format.md +0 -613
  285. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-init.md +0 -45
  286. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-rebuild.md +0 -15
  287. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-status.md +0 -14
  288. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-update.md +0 -19
  289. package/bundled/skills-windows/prizmkit-prizm-docs/references/op-validate.md +0 -17
  290. package/bundled/skills-windows/prizmkit-retrospective/SKILL.md +0 -87
  291. package/bundled/skills-windows/prizmkit-retrospective/references/knowledge-injection-steps.md +0 -50
  292. package/bundled/skills-windows/prizmkit-retrospective/references/structural-sync-steps.md +0 -43
  293. package/bundled/skills-windows/prizmkit-test/SKILL.md +0 -227
  294. package/bundled/skills-windows/prizmkit-test/references/boundary-coverage-protocol.md +0 -220
  295. package/bundled/skills-windows/prizmkit-test/references/examples.md +0 -143
  296. package/bundled/skills-windows/prizmkit-test/references/service-boundary-test-catalog.md +0 -225
  297. package/bundled/skills-windows/prizmkit-test/references/test-generation-steps.md +0 -109
  298. package/bundled/skills-windows/prizmkit-test/references/test-report-template.md +0 -111
  299. package/bundled/skills-windows/prizmkit-test/scripts/validate_boundary_report.py +0 -347
  300. package/bundled/skills-windows/recovery-workflow/SKILL.md +0 -355
  301. package/bundled/skills-windows/recovery-workflow/evals/evals.json +0 -46
  302. package/bundled/skills-windows/recovery-workflow/references/detection.md +0 -58
  303. package/bundled/skills-windows/recovery-workflow/scripts/detect-recovery-state.py +0 -544
  304. package/bundled/skills-windows/refactor-pipeline-launcher/SKILL.md +0 -346
  305. package/bundled/skills-windows/refactor-pipeline-launcher/references/configuration.md +0 -72
  306. package/bundled/skills-windows/refactor-planner/SKILL.md +0 -398
  307. package/bundled/skills-windows/refactor-planner/assets/planning-guide.md +0 -292
  308. package/bundled/skills-windows/refactor-planner/references/behavior-preservation.md +0 -301
  309. package/bundled/skills-windows/refactor-planner/references/fast-path.md +0 -59
  310. package/bundled/skills-windows/refactor-planner/references/planning-phases.md +0 -135
  311. package/bundled/skills-windows/refactor-planner/references/refactor-scoping-guide.md +0 -221
  312. package/bundled/skills-windows/refactor-planner/scripts/validate-and-generate-refactor.py +0 -858
  313. package/bundled/skills-windows/refactor-workflow/SKILL.md +0 -343
  314. package/bundled/skills-windows/refactor-workflow/references/brainstorm-guide.md +0 -116
  315. package/bundled/templates/hooks/diff-prizm-docs.sh +0 -158
  316. package/bundled/templates/hooks/prizm-pre-commit.sh +0 -108
  317. package/bundled/templates/hooks/validate-prizm-docs.sh +0 -139
@@ -1,1430 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
-
4
- # ============================================================
5
- # dev-pipeline/run-bugfix.sh - Autonomous Bug Fix Pipeline Runner
6
- #
7
- # Drives the prizm-dev-team through iterative AI CLI sessions to
8
- # fix bugs from a .prizmkit/plans/bug-fix-list.json specification.
9
- #
10
- # Usage:
11
- # ./run-bugfix.sh run [.prizmkit/plans/bug-fix-list.json] [options] Run all bugs
12
- # ./run-bugfix.sh run <bug-id> [options] Run a single bug
13
- # ./run-bugfix.sh status [.prizmkit/plans/bug-fix-list.json] Show pipeline status
14
- # ./run-bugfix.sh reset Clear all state
15
- #
16
- # Environment Variables:
17
- # MAX_RETRIES Max code retries per bug (default: 3)
18
- # MAX_INFRA_RETRIES Max infrastructure/provider retries per bug (default: 3)
19
- # AI_CLI AI CLI command name (auto-detected: cbc, claude, or codex)
20
- # CODEBUDDY_CLI Legacy alias for AI_CLI (deprecated, use AI_CLI instead)
21
- # PRIZMKIT_PLATFORM Platform hint for custom AI_CLI wrappers: codebuddy, claude, or codex
22
- # VERBOSE Set to 1 to enable --verbose on AI CLI
23
- # HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)
24
- # STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)
25
- # HEARTBEAT_STALE_THRESHOLD Heartbeat stale threshold in seconds (default: 600)
26
- # MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)
27
- # DEV_BRANCH Custom dev branch name (default: auto-generated bugfix/pipeline-{run_id})
28
- # AUTO_PUSH Auto-push to remote after successful bug fix (default: 0). Set to 1 to enable.
29
- # STOP_ON_FAILURE Stop pipeline after a task exhausts all retries (default: 0). Set to 1 to stop.
30
- # ============================================================
31
-
32
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
33
-
34
- # Source shared common helpers (exports PIPELINE_DIR/PRIZMKIT_DIR/PROJECT_ROOT,
35
- # CLI/platform detection, logs, deps)
36
- source "$SCRIPT_DIR/lib/common.sh"
37
-
38
- STATE_DIR="${PRIZMKIT_DIR}/state/bugfix"
39
- SCRIPTS_DIR="$SCRIPT_DIR/scripts"
40
-
41
- # Configuration
42
- MAX_RETRIES=${MAX_RETRIES:-3}
43
- MAX_INFRA_RETRIES=${MAX_INFRA_RETRIES:-3}
44
- HEARTBEAT_STALE_THRESHOLD=${HEARTBEAT_STALE_THRESHOLD:-600}
45
- HEARTBEAT_INTERVAL=${HEARTBEAT_INTERVAL:-30}
46
- STALE_KILL_THRESHOLD=${STALE_KILL_THRESHOLD:-900}
47
- VERBOSE=${VERBOSE:-0}
48
- MODEL=${MODEL:-""}
49
- PRIZMKIT_EFFORT=${PRIZMKIT_EFFORT:-""}
50
- DEV_BRANCH=${DEV_BRANCH:-""}
51
- AUTO_PUSH=${AUTO_PUSH:-0}
52
- STOP_ON_FAILURE=${STOP_ON_FAILURE:-0}
53
- ENABLE_DEPLOY=${ENABLE_DEPLOY:-0}
54
-
55
- # Source shared common helpers (CLI/platform detection + logs + deps)
56
- prizm_detect_cli_and_platform
57
-
58
- # Validate PRIZMKIT_EFFORT early (fail-fast before any sessions are spawned)
59
- prizm_validate_effort
60
-
61
- # Source shared heartbeat library
62
- source "$SCRIPT_DIR/lib/heartbeat.sh"
63
-
64
- # Source shared branch library
65
- source "$SCRIPT_DIR/lib/branch.sh"
66
-
67
- # Detect stream-json support
68
- detect_stream_json_support "$CLI_CMD"
69
-
70
- # Bug list path (set in main, used by cleanup trap)
71
- BUG_LIST=""
72
-
73
- # Branch tracking (for cleanup on interrupt)
74
- _ORIGINAL_BRANCH=""
75
- _DEV_BRANCH_NAME=""
76
-
77
- # ============================================================
78
- # Shared: Spawn AI CLI session and wait for result
79
- # ============================================================
80
-
81
- spawn_and_wait_session() {
82
- local bug_id="$1"
83
- local bug_list="$2"
84
- local session_id="$3"
85
- local bootstrap_prompt="$4"
86
- local session_dir="$5"
87
- local max_retries="$6"
88
- local max_infra_retries="$7"
89
- local item_model="${8:-}"
90
- local base_branch="${9:-main}"
91
-
92
- local session_log="$session_dir/logs/session.log"
93
- local progress_json="$session_dir/logs/progress.json"
94
-
95
- local effective_model=""
96
- if [[ -n "$item_model" ]]; then
97
- effective_model="$item_model"
98
- elif [[ -n "${MODEL:-}" ]]; then
99
- effective_model="$MODEL"
100
- fi
101
-
102
- # Log bootstrap prompt in test mode
103
- prizm_log_bootstrap_prompt "$bootstrap_prompt" "$bug_id"
104
-
105
- local cli_pid
106
- prizm_start_ai_session "$bootstrap_prompt" "$session_log" "$effective_model"
107
- cli_pid="$PRIZM_AI_PID"
108
-
109
- # Start progress parser (no-op if stream-json not supported)
110
- start_progress_parser "$session_log" "$progress_json" "$SCRIPTS_DIR"
111
- local parser_pid="${_PARSER_PID:-}"
112
-
113
- # Heartbeat monitor (with stale-kill protection)
114
- start_heartbeat "$cli_pid" "$session_log" "$progress_json" "$HEARTBEAT_INTERVAL" "$STALE_KILL_THRESHOLD"
115
- local heartbeat_pid="${_HEARTBEAT_PID:-}"
116
-
117
- # Wait for AI CLI to finish
118
- local exit_code=0
119
- if wait "$cli_pid" 2>/dev/null; then
120
- exit_code=0
121
- else
122
- exit_code=$?
123
- fi
124
-
125
- # Clean up heartbeat and parser
126
- stop_heartbeat "$heartbeat_pid"
127
- stop_progress_parser "$parser_pid"
128
-
129
- # Recover session log from backup if truncated by subagent stdout redirection
130
- prizm_recover_session_log "$session_log"
131
-
132
-
133
- # Check for stale-kill marker (heartbeat killed the process due to no progress)
134
- local stale_kill_marker="$session_dir/logs/stale-kill.json"
135
- local was_stale_killed=false
136
- if [[ -f "$stale_kill_marker" ]]; then
137
- was_stale_killed=true
138
- log_warn "Session was stale-killed by heartbeat monitor (no progress for too long)"
139
- fi
140
-
141
- local was_context_overflow=false
142
- if prizm_detect_context_overflow_error "$session_log" "$progress_json"; then
143
- was_context_overflow=true
144
- fi
145
-
146
- local was_ai_runtime_error=false
147
- if prizm_detect_ai_runtime_error "$session_log" "$progress_json"; then
148
- was_ai_runtime_error=true
149
- fi
150
-
151
- local was_infra_error=false
152
- if [[ $exit_code -ne 0 ]] && prizm_detect_infra_error "$session_log" "$progress_json"; then
153
- was_infra_error=true
154
- fi
155
-
156
- # Session summary
157
- if [[ -f "$session_log" ]]; then
158
- local final_size=$(wc -c < "$session_log" 2>/dev/null | tr -d ' ')
159
- local final_lines=$(wc -l < "$session_log" 2>/dev/null | tr -d ' ')
160
- log_info "Session log: $final_lines lines, $((final_size / 1024))KB"
161
- if [[ "$final_size" -lt 1024 && "$exit_code" -eq 0 ]]; then
162
- log_warn "Session log was truncated during execution (subagent stdout redirection may have severed it)"
163
- log_warn "Proceeding with exit-code-only outcome detection — child transcripts and git state are still valid"
164
- fi
165
- fi
166
- log_info "exit_code=$exit_code"
167
-
168
- # ── Determine session outcome from observable signals ──────────────
169
- local session_status
170
- local project_root
171
- project_root="$PROJECT_ROOT"
172
- local default_branch="$base_branch"
173
-
174
- local has_commits=""
175
- if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
176
- has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
177
- fi
178
-
179
- if [[ -n "$has_commits" ]]; then
180
- session_status="success"
181
- elif [[ "$was_context_overflow" == true ]]; then
182
- log_warn "Session failed because the AI CLI exceeded the model context window"
183
- log_warn "Context overflow is retried without consuming code retry budget"
184
- session_status="context_overflow"
185
- elif [[ "$was_ai_runtime_error" == true ]]; then
186
- log_warn "Session failed due to structured AI runtime error"
187
- log_warn "AI runtime errors are retried without consuming code retry budget"
188
- session_status="infra_error"
189
- elif [[ "$was_infra_error" == true ]]; then
190
- log_warn "Session failed due to AI CLI/provider infrastructure error"
191
- log_warn "Infrastructure errors are retried without consuming code retry budget"
192
- session_status="infra_error"
193
- elif [[ "$was_stale_killed" == true ]]; then
194
- log_warn "Session stale-killed (no progress for ${STALE_KILL_THRESHOLD}s)"
195
- log_warn "Stale-killed sessions are treated as failed; dev branch is preserved for inspection"
196
- session_status="crashed"
197
- elif [[ $exit_code -ne 0 ]]; then
198
- log_warn "Session exited with code $exit_code"
199
- session_status="crashed"
200
- else
201
- # Exit code 0 — check if the session actually produced commits
202
- local has_commits=""
203
- if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
204
- has_commits=$(git -C "$project_root" log "${default_branch}..HEAD" --oneline 2>/dev/null | head -1)
205
- fi
206
-
207
- if [[ -n "$has_commits" ]]; then
208
- session_status="success"
209
- else
210
- local uncommitted=""
211
- uncommitted=$(prizm_git_status_safe "$project_root" | head -1 || true)
212
- if [[ -n "$uncommitted" ]]; then
213
- log_warn "Session exited cleanly but produced no commits (uncommitted changes found) — auto-committing..."
214
- prizm_git_add_all_safe "$project_root" || true
215
- if git -C "$project_root" commit --no-verify -m "chore($bug_id): auto-commit session work" 2>/dev/null; then
216
- log_info "Auto-commit succeeded"
217
- session_status="success"
218
- else
219
- log_warn "Auto-commit failed — no changes to commit"
220
- session_status="crashed"
221
- fi
222
- else
223
- log_warn "Session exited cleanly but produced no commits and no changes"
224
- session_status="crashed"
225
- fi
226
- fi
227
- fi
228
-
229
- # ── Post-success validation ──────────────────────────────────────────
230
- if [[ "$session_status" == "success" ]]; then
231
- if git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
232
- local dirty_files=""
233
- dirty_files=$(prizm_git_status_safe "$project_root" || true)
234
- if [[ -n "$dirty_files" ]]; then
235
- log_info "Auto-committing remaining session artifacts..."
236
- prizm_git_add_all_safe "$project_root" || true
237
- git -C "$project_root" commit --no-verify --amend --no-edit 2>/dev/null \
238
- || git -C "$project_root" commit --no-verify -m "chore($bug_id): include remaining session artifacts" 2>/dev/null \
239
- || true
240
- fi
241
- fi
242
- fi
243
-
244
- log_info "Session result: $session_status"
245
-
246
- # Validate checkpoint completeness after successful session
247
- if [[ "$session_status" == "success" ]]; then
248
- local checkpoint_file="$PRIZMKIT_DIR/bugfix/${bug_id}/workflow-checkpoint.json"
249
- if [[ -f "$checkpoint_file" ]]; then
250
- local checkpoint_result
251
- checkpoint_result=$(python3 -c "
252
- import json, sys
253
- try:
254
- with open(sys.argv[1]) as f:
255
- data = json.load(f)
256
- except json.JSONDecodeError as e:
257
- print('CORRUPTED: {}'.format(e))
258
- sys.exit(2)
259
- incomplete = [s for s in data['steps'] if s['status'] not in ('completed', 'skipped')]
260
- if incomplete:
261
- for s in incomplete:
262
- print('INCOMPLETE: {} {} = {}'.format(s['id'], s['skill'], s['status']))
263
- sys.exit(1)
264
- print('ALL_COMPLETE')
265
- sys.exit(0)
266
- " "$checkpoint_file" 2>&1) || checkpoint_result="CHECK_FAILED"
267
- local check_exit=$?
268
- if [[ "$checkpoint_result" == "CHECK_FAILED" ]]; then
269
- check_exit=2
270
- elif [[ "$checkpoint_result" == *"INCOMPLETE"* ]]; then
271
- check_exit=1
272
- else
273
- check_exit=0
274
- fi
275
- if [[ $check_exit -eq 2 ]]; then
276
- log_warn "CHECKPOINT_CORRUPTED: workflow-checkpoint.json is not valid JSON"
277
- elif [[ $check_exit -eq 1 ]]; then
278
- log_warn "CHECKPOINT_INCOMPLETE: Not all workflow steps completed:"
279
- echo "$checkpoint_result" | while read -r line; do log_warn " $line"; done
280
- else
281
- log_info "CHECKPOINT: All workflow steps completed"
282
- fi
283
- fi
284
- fi
285
-
286
- # Subagent detection
287
- prizm_detect_subagents "$session_log"
288
-
289
- # Final status updates happen after the caller returns to the original branch.
290
- _SPAWN_RESULT="$session_status"
291
- }
292
-
293
- finalize_bug_status_after_branch_return() {
294
- local bug_id="$1"
295
- local bug_list="$2"
296
- local session_id="$3"
297
- local session_status="$4"
298
- local max_retries="$5"
299
- local max_infra_retries="$6"
300
- local base_branch="${7:-main}"
301
- local active_dev_branch="${8:-}"
302
- local fatal_error_code="${9:-}"
303
- local continuation_summary_path="${10:-}"
304
- local no_progress_count="${11:-0}"
305
- local progress_fingerprint="${12:-}"
306
-
307
- # Update bug status on the original branch. The caller commits the resulting
308
- # bug-list diff immediately after this helper returns.
309
- local update_output
310
- update_output=$(python3 "$SCRIPTS_DIR/update-bug-status.py" \
311
- --bug-list "$bug_list" \
312
- --state-dir "$STATE_DIR" \
313
- --bug-id "$bug_id" \
314
- --session-status "$session_status" \
315
- --session-id "$session_id" \
316
- --max-retries "$max_retries" \
317
- --max-infra-retries "$max_infra_retries" \
318
- --active-dev-branch "$active_dev_branch" \
319
- --base-branch "$base_branch" \
320
- --last-fatal-error-code "$fatal_error_code" \
321
- --continuation-summary-path "$continuation_summary_path" \
322
- --no-progress-count "$no_progress_count" \
323
- --progress-fingerprint "$progress_fingerprint" \
324
- --action update) || {
325
- log_error "Failed to update bug status: $update_output"
326
- update_output=""
327
- }
328
-
329
- _SPAWN_ITEM_STATUS="$(printf '%s' "$update_output" | prizm_extract_update_new_status)"
330
- }
331
-
332
- # ============================================================
333
- # Graceful Shutdown
334
- # ============================================================
335
-
336
- cleanup() {
337
- echo ""
338
- log_warn "Received interrupt signal. Saving state..."
339
-
340
- # Kill all child processes (claude-internal, heartbeat, progress parser, etc.)
341
- kill 0 2>/dev/null || true
342
-
343
- # Log current branch info for recovery
344
- if [[ -n "$_DEV_BRANCH_NAME" ]]; then
345
- log_info "Development was on branch: $_DEV_BRANCH_NAME"
346
- log_info "Original branch was: $_ORIGINAL_BRANCH"
347
- fi
348
-
349
- # Update status of currently in-progress bug to interrupted
350
- if [[ -n "$BUG_LIST" && -f "$BUG_LIST" ]]; then
351
- # Find any in-progress bug and mark it as failed
352
- local _interrupted_id
353
- _interrupted_id=$(python3 -c "
354
- import json, sys
355
- with open(sys.argv[1]) as f:
356
- data = json.load(f)
357
- for bug in data.get('bugs', []):
358
- if bug.get('status') == 'in_progress':
359
- print(bug['id'])
360
- break
361
- " "$BUG_LIST" 2>/dev/null || echo "")
362
-
363
- if [[ -n "$_interrupted_id" ]]; then
364
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
365
- --bug-list "$BUG_LIST" \
366
- --state-dir "$STATE_DIR" \
367
- --bug-id "$_interrupted_id" \
368
- --session-status "failed" \
369
- --max-retries "$MAX_RETRIES" \
370
- --max-infra-retries "$MAX_INFRA_RETRIES" \
371
- --action update 2>/dev/null || true
372
- log_info "Bug $_interrupted_id marked as failed due to interrupt"
373
- fi
374
-
375
- # Pause the pipeline
376
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
377
- --bug-list "$BUG_LIST" \
378
- --state-dir "$STATE_DIR" \
379
- --action pause 2>/dev/null || true
380
- fi
381
-
382
- # GUARANTEED: always return to original branch (save WIP on dev branch first)
383
- branch_ensure_return "$PROJECT_ROOT" "$_ORIGINAL_BRANCH" "$_DEV_BRANCH_NAME"
384
-
385
- log_info "Bug fix pipeline paused. Run './run-bugfix.sh run' to resume."
386
- exit 130
387
- }
388
- trap cleanup SIGINT SIGTERM
389
-
390
- # ============================================================
391
- # Dependency Check
392
- # ============================================================
393
-
394
- check_dependencies() {
395
- prizm_check_common_dependencies "$CLI_CMD"
396
- local _project_root
397
- _project_root="$PROJECT_ROOT"
398
- prizm_ensure_git_repo "$_project_root"
399
- }
400
-
401
-
402
- # ============================================================
403
- # run-one: Run a single bug fix
404
- # ============================================================
405
-
406
- run_one() {
407
- local bug_id=""
408
- local bug_list=""
409
- local dry_run=false
410
- local do_clean=false
411
- local no_reset=false
412
- local mode_override=""
413
- local critic_override=""
414
-
415
- while [[ $# -gt 0 ]]; do
416
- case "$1" in
417
- --dry-run) dry_run=true; shift ;;
418
- --clean) do_clean=true; shift ;;
419
- --no-reset) no_reset=true; shift ;;
420
- --max-infra-retries)
421
- shift
422
- if [[ $# -eq 0 ]]; then
423
- log_error "--max-infra-retries requires a value"
424
- exit 1
425
- fi
426
- prizm_require_positive_int "--max-infra-retries" "$1"
427
- MAX_INFRA_RETRIES="$1"
428
- shift
429
- ;;
430
- --mode)
431
- shift
432
- if [[ $# -eq 0 ]]; then
433
- log_error "--mode requires a value (lite|standard|full)"
434
- exit 1
435
- fi
436
- case "$1" in
437
- lite|standard|full) mode_override="$1" ;;
438
- *) log_error "Invalid mode: $1 (must be lite, standard, or full)"; exit 1 ;;
439
- esac
440
- shift
441
- ;;
442
- --critic) critic_override="true"; shift ;;
443
- --no-critic) critic_override="false"; shift ;;
444
- B-*|b-*) bug_id="$1"; shift ;;
445
- *) bug_list="$1"; shift ;;
446
- esac
447
- done
448
-
449
- if [[ -z "$bug_id" ]]; then
450
- log_error "Bug ID is required (e.g. B-001)"
451
- echo ""
452
- show_help
453
- exit 1
454
- fi
455
-
456
- if [[ -z "$bug_list" ]]; then
457
- bug_list="$PRIZMKIT_DIR/plans/bug-fix-list.json"
458
- fi
459
- if [[ ! "$bug_list" = /* ]]; then
460
- bug_list="$(pwd)/$bug_list"
461
- fi
462
- BUG_LIST="$bug_list"
463
-
464
- if [[ ! -f "$bug_list" ]]; then
465
- log_error "Bug fix list not found: $bug_list"
466
- exit 1
467
- fi
468
-
469
- check_dependencies
470
-
471
- # Initialize state if needed
472
- if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
473
- log_info "Initializing bugfix pipeline state..."
474
- local init_result init_stderr init_tmpstderr
475
- init_tmpstderr=$(mktemp)
476
- if ! init_result=$(python3 "$SCRIPTS_DIR/init-bugfix-pipeline.py" \
477
- --bug-list "$bug_list" \
478
- --state-dir "$STATE_DIR" 2>"$init_tmpstderr"); then
479
- init_stderr=$(cat "$init_tmpstderr" 2>/dev/null || true)
480
- rm -f "$init_tmpstderr"
481
- if [[ -n "$init_stderr" ]]; then
482
- log_warn "$init_stderr"
483
- fi
484
- log_error "Bugfix pipeline initialization failed (script error)"
485
- exit 1
486
- fi
487
- init_stderr=$(cat "$init_tmpstderr" 2>/dev/null || true)
488
- rm -f "$init_tmpstderr"
489
-
490
- if [[ -n "$init_stderr" ]]; then
491
- log_warn "$init_stderr"
492
- fi
493
-
494
- local init_valid
495
- init_valid=$(echo "$init_result" | python3 -c "import sys,json; print(json.load(sys.stdin).get('valid', False))" 2>/dev/null || echo "False")
496
-
497
- if [[ "$init_valid" != "True" ]]; then
498
- log_error "Bugfix pipeline initialization failed:"
499
- echo "$init_result"
500
- exit 1
501
- fi
502
-
503
- local bugs_count
504
- bugs_count=$(echo "$init_result" | python3 -c "import sys,json; print(json.load(sys.stdin).get('bugs_count', 0))" 2>/dev/null || echo "0")
505
- log_success "Bugfix pipeline initialized with $bugs_count bugs"
506
- fi
507
-
508
- # Verify bug exists
509
- local bug_title
510
- bug_title=$(python3 -c "
511
- import json, sys
512
- with open(sys.argv[1]) as f:
513
- data = json.load(f)
514
- for bug in data.get('bugs', []):
515
- if bug.get('id') == sys.argv[2]:
516
- print(bug.get('title', ''))
517
- sys.exit(0)
518
- sys.exit(1)
519
- " "$bug_list" "$bug_id" 2>/dev/null) || {
520
- log_error "Bug $bug_id not found in $bug_list"
521
- exit 1
522
- }
523
-
524
- local bug_severity
525
- bug_severity=$(python3 -c "
526
- import json, sys
527
- with open(sys.argv[1]) as f:
528
- data = json.load(f)
529
- for bug in data.get('bugs', []):
530
- if bug.get('id') == sys.argv[2]:
531
- print(bug.get('severity', 'medium'))
532
- sys.exit(0)
533
- sys.exit(1)
534
- " "$bug_list" "$bug_id" 2>/dev/null) || bug_severity="medium"
535
-
536
- # Optional Clean
537
- if [[ "$do_clean" == true ]]; then
538
- if [[ "$dry_run" == true ]]; then
539
- log_warn "Dry-run mode: --clean ignored (no artifacts will be deleted)"
540
- else
541
- log_info "Cleaning artifacts for $bug_id..."
542
-
543
- local project_root
544
- project_root="$PROJECT_ROOT"
545
-
546
- local bugfix_dir="$PRIZMKIT_DIR/bugfix/$bug_id"
547
- if [[ -d "$bugfix_dir" ]]; then
548
- rm -rf "$bugfix_dir"
549
- log_info "Removed $bugfix_dir"
550
- fi
551
-
552
- local dev_team_dir="$project_root/.dev-team"
553
- if [[ -d "$dev_team_dir" ]]; then
554
- rm -rf "$dev_team_dir"
555
- log_info "Removed $dev_team_dir"
556
- fi
557
-
558
- local bug_state_dir="$STATE_DIR/$bug_id"
559
- if [[ -d "$bug_state_dir" ]]; then
560
- rm -rf "$bug_state_dir"
561
- log_info "Removed $bug_state_dir"
562
- fi
563
- fi
564
- fi
565
-
566
- # Reset bug status (conditional)
567
- if [[ "$no_reset" == false && "$dry_run" == false ]]; then
568
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
569
- --bug-list "$bug_list" \
570
- --state-dir "$STATE_DIR" \
571
- --bug-id "$bug_id" \
572
- --action reset >/dev/null 2>&1 || {
573
- log_warn "Failed to reset bug status (may already be pending)"
574
- }
575
- elif [[ "$dry_run" == true && "$no_reset" == false ]]; then
576
- log_info "Dry-run mode: skipping status reset"
577
- fi
578
-
579
- # Generate bootstrap prompt
580
- local run_id session_id session_dir bootstrap_prompt
581
- run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
582
- session_id="${bug_id}-$(date +%Y%m%d%H%M%S)"
583
- session_dir="$STATE_DIR/$bug_id/sessions/$session_id"
584
- mkdir -p "$session_dir/logs"
585
-
586
- bootstrap_prompt="$session_dir/bootstrap-prompt.md"
587
-
588
- # Read retry count from status.json
589
- local retry_count
590
- retry_count=$(python3 -c "
591
- import json, os
592
- status_path = os.path.join('$STATE_DIR', '$bug_id', 'status.json')
593
- if os.path.isfile(status_path):
594
- with open(status_path) as f:
595
- d = json.load(f)
596
- print(d.get('retry_count', 0))
597
- else:
598
- print(0)
599
- " 2>/dev/null || echo "0")
600
- local resume_phase
601
- resume_phase=$(python3 -c "
602
- import json, os
603
- status_path = os.path.join('$STATE_DIR', '$bug_id', 'status.json')
604
- if os.path.isfile(status_path):
605
- with open(status_path) as f:
606
- d = json.load(f)
607
- print(d.get('resume_from_phase') or 'null')
608
- else:
609
- print('null')
610
- " 2>/dev/null || echo "null")
611
-
612
- log_info "Generating bugfix bootstrap prompt..."
613
- local prompt_args=(
614
- --bug-list "$bug_list"
615
- --bug-id "$bug_id"
616
- --session-id "$session_id"
617
- --run-id "$run_id"
618
- --retry-count "$retry_count"
619
- --resume-phase "$resume_phase"
620
- --state-dir "$STATE_DIR"
621
- --output "$bootstrap_prompt"
622
- )
623
-
624
- if [[ -n "$mode_override" ]]; then
625
- prompt_args+=(--mode "$mode_override")
626
- elif [[ -n "${PIPELINE_MODE:-}" ]]; then
627
- prompt_args+=(--mode "$PIPELINE_MODE")
628
- fi
629
-
630
- if [[ -n "${critic_override:-}" ]]; then
631
- prompt_args+=(--critic "$critic_override")
632
- elif [[ "${ENABLE_CRITIC:-}" == "true" || "${ENABLE_CRITIC:-}" == "1" ]]; then
633
- prompt_args+=(--critic "true")
634
- elif [[ "${ENABLE_CRITIC:-}" == "false" || "${ENABLE_CRITIC:-}" == "0" ]]; then
635
- prompt_args+=(--critic "false")
636
- fi
637
-
638
- local gen_output
639
- gen_output=$(python3 "$SCRIPTS_DIR/generate-bugfix-prompt.py" "${prompt_args[@]}" 2>/dev/null) || {
640
- log_error "Failed to generate bootstrap prompt for $bug_id"
641
- return 1
642
- }
643
- local bug_model pipeline_mode agent_count critic_enabled
644
- bug_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
645
- pipeline_mode=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('pipeline_mode','standard'))" 2>/dev/null || echo "standard")
646
- agent_count=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('agent_count',3))" 2>/dev/null || echo "3")
647
- critic_enabled=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('critic_enabled','false'))" 2>/dev/null || echo "false")
648
-
649
- if [[ "$dry_run" == true ]]; then
650
- echo ""
651
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
652
- echo -e "${BOLD} Dry Run: $bug_id — $bug_title${NC}"
653
- echo -e "${BOLD} Severity: $bug_severity${NC}"
654
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
655
- echo ""
656
- log_info "Session ID: $session_id"
657
- if [[ -n "$mode_override" ]]; then
658
- log_info "Mode Override: $mode_override"
659
- fi
660
- log_info "Pipeline mode: $pipeline_mode"
661
- log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
662
- if [[ -n "$bug_model" ]]; then
663
- log_info "Bug Model: $bug_model"
664
- elif [[ -n "$MODEL" ]]; then
665
- log_info "Model (env): $MODEL"
666
- else
667
- log_info "Model: (CLI default)"
668
- fi
669
- echo ""
670
- log_info "Bootstrap prompt written to:"
671
- echo " $bootstrap_prompt"
672
- echo ""
673
- log_success "Dry run complete. Inspect full prompt with:"
674
- echo " cat $bootstrap_prompt"
675
- return 0
676
- fi
677
-
678
- echo ""
679
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
680
- echo -e "${BOLD} Bug Fix: $bug_id — $bug_title${NC}"
681
- echo -e "${BOLD} Severity: $bug_severity${NC}"
682
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
683
- log_info "Session ID: $session_id"
684
- log_info "Prompt: $bootstrap_prompt"
685
- log_info "Log: $session_dir/logs/session.log"
686
- local _run_one_mode_desc
687
- case "$pipeline_mode" in
688
- lite) _run_one_mode_desc="Tier 1 — Single Agent" ;;
689
- standard) _run_one_mode_desc="Tier 2 — Orchestrator + Dev + Reviewer" ;;
690
- full) _run_one_mode_desc="Tier 3 — Full Team (+ Multi-Critic)" ;;
691
- *) _run_one_mode_desc="$pipeline_mode" ;;
692
- esac
693
- log_info "Pipeline mode: ${BOLD}$pipeline_mode${NC} ($_run_one_mode_desc)"
694
- log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
695
- if [[ -n "$bug_model" ]]; then
696
- log_info "Bug model: $bug_model"
697
- fi
698
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
699
- echo ""
700
-
701
- cleanup_single_bug() {
702
- echo ""
703
- log_warn "Interrupted. Killing session..."
704
- kill 0 2>/dev/null || true
705
- # Log current branch info
706
- if [[ -n "$_DEV_BRANCH_NAME" ]]; then
707
- log_info "Development was on branch: $_DEV_BRANCH_NAME"
708
- fi
709
- log_info "Session log: $session_dir/logs/session.log"
710
-
711
- # Update bug status to failed on interrupt
712
- if [[ -n "$bug_list" && -f "$bug_list" ]]; then
713
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
714
- --bug-list "$bug_list" \
715
- --state-dir "$STATE_DIR" \
716
- --bug-id "$bug_id" \
717
- --session-status "failed" \
718
- --max-retries "$MAX_RETRIES" \
719
- --max-infra-retries "$MAX_INFRA_RETRIES" \
720
- --action update 2>/dev/null || true
721
- log_info "Bug $bug_id marked as failed due to interrupt"
722
- fi
723
-
724
- # GUARANTEED: always return to original branch (save WIP on dev branch first)
725
- branch_ensure_return "$PROJECT_ROOT" "$_ORIGINAL_BRANCH" "$_DEV_BRANCH_NAME"
726
- exit 130
727
- }
728
- trap cleanup_single_bug SIGINT SIGTERM
729
-
730
- _SPAWN_RESULT=""
731
- _SPAWN_ITEM_STATUS=""
732
-
733
- # Branch lifecycle: create and checkout bugfix branch
734
- local _proj_root
735
- _proj_root="$PROJECT_ROOT"
736
- local _source_branch
737
- _source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
738
- _ORIGINAL_BRANCH="$_source_branch"
739
-
740
- # Mark bug as in-progress (update JSON for runtime monitoring, no commit)
741
- # The status change will be committed together with the final status update
742
- # after the session completes, avoiding an extra noise commit per bug.
743
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
744
- --bug-list "$bug_list" \
745
- --state-dir "$STATE_DIR" \
746
- --bug-id "$bug_id" \
747
- --action start >/dev/null 2>&1 || true
748
-
749
- local _branch_name="${DEV_BRANCH:-bugfix/${bug_id}-$(date +%s)}"
750
- if branch_create "$_proj_root" "$_branch_name" "$_source_branch"; then
751
- _DEV_BRANCH_NAME="$_branch_name"
752
- else
753
- log_error "Failed to create branch: $_branch_name from $_source_branch — aborting to avoid running on $_source_branch"
754
- return 1
755
- fi
756
-
757
- spawn_and_wait_session \
758
- "$bug_id" "$bug_list" "$session_id" \
759
- "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$bug_model" "$_ORIGINAL_BRANCH"
760
- local session_status="$_SPAWN_RESULT"
761
-
762
- local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
763
- local continuation_summary_path=""
764
- local no_progress_count=0
765
- local progress_after=""
766
-
767
- # Merge dev branch back to original on success
768
- if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
769
- if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
770
- _DEV_BRANCH_NAME=""
771
- else
772
- log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
773
- log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
774
- session_status="merge_conflict"
775
- fi
776
- elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
777
- # Session failed — preserve dev branch for inspection
778
- log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
779
- _DEV_BRANCH_NAME=""
780
- fi
781
-
782
- # GUARANTEED: always return to original branch regardless of success/failure/merge outcome
783
- branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
784
-
785
- finalize_bug_status_after_branch_return \
786
- "$bug_id" "$bug_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "${progress_after:-}"
787
-
788
- # Commit bug status update on the original branch (after guaranteed return)
789
- if ! git -C "$_proj_root" diff --quiet "$bug_list" 2>/dev/null; then
790
- prizm_git_commit_paths "$_proj_root" "chore($bug_id): update bug status" "$bug_list"
791
- fi
792
-
793
- echo ""
794
- if [[ "$session_status" == "success" ]]; then
795
- log_success "════════════════════════════════════════════════════"
796
- log_success " $bug_id fixed successfully!"
797
- log_success "════════════════════════════════════════════════════"
798
- else
799
- log_error "════════════════════════════════════════════════════"
800
- log_error " $bug_id result: $session_status"
801
- log_error " Review log: $session_dir/logs/session.log"
802
- log_error "════════════════════════════════════════════════════"
803
- fi
804
- }
805
-
806
- # ============================================================
807
- # Main Loop: Run all bugs
808
- # ============================================================
809
-
810
- main() {
811
- local bug_list="$PRIZMKIT_DIR/plans/bug-fix-list.json"
812
-
813
- while [[ $# -gt 0 ]]; do
814
- case "$1" in
815
- --max-infra-retries)
816
- shift
817
- if [[ $# -eq 0 ]]; then
818
- log_error "--max-infra-retries requires a value"
819
- exit 1
820
- fi
821
- prizm_require_positive_int "--max-infra-retries" "$1"
822
- MAX_INFRA_RETRIES="$1"
823
- shift
824
- ;;
825
- --)
826
- shift
827
- break
828
- ;;
829
- -*)
830
- log_error "Unknown option: $1"
831
- show_help
832
- exit 1
833
- ;;
834
- *)
835
- bug_list="$1"
836
- shift
837
- ;;
838
- esac
839
- done
840
-
841
- if [[ $# -gt 0 ]]; then
842
- log_error "Unexpected arguments: $*"
843
- show_help
844
- exit 1
845
- fi
846
-
847
- if [[ ! "$bug_list" = /* ]]; then
848
- bug_list="$(pwd)/$bug_list"
849
- fi
850
- BUG_LIST="$bug_list"
851
-
852
- if [[ ! -f "$bug_list" ]]; then
853
- log_error "Bug fix list not found: $bug_list"
854
- log_info "Create a bug fix list first using the bug-planner skill,"
855
- log_info "or provide a path: ./run-bugfix.sh run <path-to-.prizmkit/plans/bug-fix-list.json>"
856
- exit 1
857
- fi
858
-
859
- check_dependencies
860
-
861
- # Initialize pipeline state if needed
862
- if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
863
- log_info "Initializing bugfix pipeline state..."
864
- local init_result init_stderr init_tmpstderr
865
- init_tmpstderr=$(mktemp)
866
- if ! init_result=$(python3 "$SCRIPTS_DIR/init-bugfix-pipeline.py" \
867
- --bug-list "$bug_list" \
868
- --state-dir "$STATE_DIR" 2>"$init_tmpstderr"); then
869
- init_stderr=$(cat "$init_tmpstderr" 2>/dev/null || true)
870
- rm -f "$init_tmpstderr"
871
- if [[ -n "$init_stderr" ]]; then
872
- log_warn "$init_stderr"
873
- fi
874
- log_error "Bugfix pipeline initialization failed (script error)"
875
- exit 1
876
- fi
877
- init_stderr=$(cat "$init_tmpstderr" 2>/dev/null || true)
878
- rm -f "$init_tmpstderr"
879
-
880
- if [[ -n "$init_stderr" ]]; then
881
- log_warn "$init_stderr"
882
- fi
883
-
884
- local init_valid
885
- init_valid=$(echo "$init_result" | python3 -c "import sys,json; print(json.load(sys.stdin).get('valid', False))" 2>/dev/null || echo "False")
886
-
887
- if [[ "$init_valid" != "True" ]]; then
888
- log_error "Bugfix pipeline initialization failed:"
889
- echo "$init_result"
890
- exit 1
891
- fi
892
-
893
- local bugs_count
894
- bugs_count=$(echo "$init_result" | python3 -c "import sys,json; print(json.load(sys.stdin).get('bugs_count', 0))" 2>/dev/null || echo "0")
895
- log_success "Bugfix pipeline initialized with $bugs_count bugs"
896
- else
897
- log_info "Resuming existing bugfix pipeline..."
898
- fi
899
-
900
- # Print header
901
- echo ""
902
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
903
- echo -e "${BOLD} Bug-Fix Pipeline Runner Started${NC}"
904
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
905
- log_info "Bug fix list: $bug_list"
906
- log_info "Max code retries per bug: $MAX_RETRIES"
907
- log_info "Max infrastructure retries per bug: $MAX_INFRA_RETRIES"
908
- log_info "AI CLI: $CLI_CMD (platform: $PLATFORM)"
909
- if [[ -n "${MODEL:-}" ]]; then
910
- log_info "Default Model: $MODEL"
911
- fi
912
- if [[ "$STOP_ON_FAILURE" == "1" ]]; then
913
- log_info "Stop on failure: enabled"
914
- fi
915
- echo -e "${BOLD}════════════════════════════════════════════════════${NC}"
916
- echo ""
917
-
918
- # Branch lifecycle: per-bug branches (like feature pipeline)
919
- local _proj_root
920
- _proj_root="$PROJECT_ROOT"
921
- local _source_branch
922
- _source_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "main")
923
- _ORIGINAL_BRANCH="$_source_branch"
924
-
925
- local session_count=0
926
- local total_subagent_calls=0
927
-
928
- while true; do
929
- # Safety net: ensure we're on the original branch at the start of each iteration.
930
- # If a previous iteration's `continue` skipped branch_ensure_return, we could
931
- # still be on a dev branch. This prevents cascading branch confusion.
932
- if [[ -n "$_ORIGINAL_BRANCH" ]]; then
933
- local _cur_branch
934
- _cur_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || true)
935
- if [[ -n "$_cur_branch" && "$_cur_branch" != "$_ORIGINAL_BRANCH" ]]; then
936
- log_warn "Still on branch $_cur_branch at loop start — returning to $_ORIGINAL_BRANCH"
937
- branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
938
- fi
939
- fi
940
-
941
- # Find next bug to process
942
- local next_bug
943
- if ! next_bug=$(python3 "$SCRIPTS_DIR/update-bug-status.py" \
944
- --bug-list "$bug_list" \
945
- --state-dir "$STATE_DIR" \
946
- --max-retries "$MAX_RETRIES" \
947
- --max-infra-retries "$MAX_INFRA_RETRIES" \
948
- --action get_next 2>/dev/null); then
949
- log_error "Failed to get next bug"
950
- break
951
- fi
952
-
953
- if [[ "$next_bug" == "PIPELINE_COMPLETE" ]]; then
954
- echo ""
955
- log_success "════════════════════════════════════════════════════"
956
- log_success " All bugs processed! Bug fix pipeline finished."
957
- log_success " Total sessions: $session_count"
958
- log_success " Total subagent calls: $total_subagent_calls"
959
- log_success "════════════════════════════════════════════════════"
960
-
961
- # ── Deploy session (only if ENABLE_DEPLOY=1 and all bugs fixed) ──
962
- if [[ "$ENABLE_DEPLOY" == "1" ]]; then
963
- local incomplete_count
964
- incomplete_count=$({ python3 -c "
965
- import json, sys
966
- with open(sys.argv[1]) as f:
967
- data = json.load(f)
968
- bad = [b for b in data.get('bugs', [])
969
- if b.get('status') not in ('completed', 'skipped', 'needs_info')]
970
- for b in bad:
971
- print(f\" {b['id']}: {b.get('status', 'unknown')} — {b.get('title', '')}\")
972
- print(len(bad))
973
- " "$bug_list" 2>/dev/null || echo "0"; } | tee /dev/stderr | tail -1)
974
-
975
- if [[ "$incomplete_count" -gt 0 ]]; then
976
- echo ""
977
- log_warn "DEPLOY BLOCKED: $incomplete_count bug(s) not fixed successfully."
978
- log_warn "Fix failed bugs and re-run, or manually run /prizmkit-deploy."
979
- else
980
- echo ""
981
- log_info "All bugs fixed — starting deploy session..."
982
- log_info "ENABLE_DEPLOY=1"
983
-
984
- local deploy_session_id="deploy-$(date +%Y%m%d%H%M%S)"
985
- local deploy_session_dir="$STATE_DIR/deploy/$deploy_session_id"
986
- mkdir -p "$deploy_session_dir/logs"
987
-
988
- local deploy_prompt="$deploy_session_dir/bootstrap-prompt.md"
989
- local _deploy_branch _deploy_commit
990
- _deploy_branch=$(git -C "$_proj_root" rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
991
- _deploy_commit=$(git -C "$_proj_root" rev-parse --short HEAD 2>/dev/null || echo "unknown")
992
- cat > "$deploy_prompt" << DEPLOY_PROMPT_EOF
993
- ## Deploy
994
-
995
- All bugs have been fixed successfully.
996
-
997
- - Branch: $_deploy_branch
998
- - Commit: $_deploy_commit
999
-
1000
- Run /prizmkit-deploy to deploy the project. Read .prizmkit/deploy/deploy.config.json
1001
- for deployment configuration. If no deploy config exists, guide the user through
1002
- setting one up before deploying.
1003
- DEPLOY_PROMPT_EOF
1004
-
1005
- log_info "Deploy prompt: $deploy_prompt"
1006
- log_info "Deploy log: $deploy_session_dir/logs/session.log"
1007
-
1008
- prizm_run_ai_session "$deploy_prompt" "$deploy_session_dir/logs/session.log"
1009
- local deploy_exit=$?
1010
-
1011
- # Recover log from backup if truncated
1012
- prizm_recover_session_log "$deploy_session_dir/logs/session.log"
1013
-
1014
- if [[ $deploy_exit -eq 0 ]]; then
1015
- log_success "Deploy session completed (exit 0)"
1016
- else
1017
- log_warn "Deploy session exited with code $deploy_exit"
1018
- log_warn "Review log: $deploy_session_dir/logs/session.log"
1019
- fi
1020
- fi
1021
- fi
1022
-
1023
- break
1024
- fi
1025
-
1026
- if [[ "$next_bug" == "PIPELINE_BLOCKED" ]]; then
1027
- log_warn "All remaining bugs are blocked (needs_info/failed)."
1028
- log_warn "Run './run-bugfix.sh status' to see details."
1029
- log_warn "Waiting 60s before re-checking... (Ctrl+C to stop)"
1030
- sleep 60
1031
- continue
1032
- fi
1033
-
1034
- # Parse bug info
1035
- local bug_id bug_title bug_severity retry_count infra_error_count resume_phase active_dev_branch base_branch continuation_pending continuation_reason context_overflow_count continuation_count previous_session_id no_progress_count
1036
- bug_id=$(echo "$next_bug" | jq -r '.bug_id')
1037
- bug_title=$(echo "$next_bug" | jq -r '.title')
1038
- bug_severity=$(echo "$next_bug" | jq -r '.severity')
1039
- retry_count=$(echo "$next_bug" | jq -r '.retry_count // 0')
1040
- infra_error_count=$(echo "$next_bug" | jq -r '.infra_error_count // 0')
1041
- resume_phase=$(echo "$next_bug" | jq -r '.resume_from_phase // "null"')
1042
- active_dev_branch=$(echo "$next_bug" | jq -r '.active_dev_branch // ""')
1043
- base_branch=$(echo "$next_bug" | jq -r '.base_branch // ""')
1044
- continuation_pending=$(echo "$next_bug" | jq -r '.continuation_pending // false')
1045
- continuation_reason=$(echo "$next_bug" | jq -r '.continuation_reason // ""')
1046
- context_overflow_count=$(echo "$next_bug" | jq -r '.context_overflow_count // 0')
1047
- continuation_count=$(echo "$next_bug" | jq -r '.continuation_count // 0')
1048
- previous_session_id=$(echo "$next_bug" | jq -r '.last_context_overflow_session_id // ""')
1049
- no_progress_count=$(echo "$next_bug" | jq -r '.no_progress_count // 0')
1050
-
1051
- echo ""
1052
- echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
1053
- log_info "Bug: ${BOLD}$bug_id${NC} — $bug_title"
1054
- log_info "Severity: $bug_severity"
1055
- log_info "Code retry: $retry_count / $MAX_RETRIES"
1056
- log_info "Infrastructure retry: $infra_error_count / $MAX_INFRA_RETRIES"
1057
- if [[ "$resume_phase" != "null" ]]; then
1058
- log_info "Resuming from Phase $resume_phase"
1059
- fi
1060
- if [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
1061
- log_info "Continuation pending (${continuation_reason:-context_overflow}); reusing dev branch: $active_dev_branch"
1062
- log_info "Continuation count: $continuation_count (context overflows: $context_overflow_count)"
1063
- fi
1064
- echo -e "${BOLD}────────────────────────────────────────────────────${NC}"
1065
-
1066
- # Auto-commit any uncommitted workspace changes before starting the pipeline.
1067
- # This ensures a clean baseline without blocking execution.
1068
- local _dirty_files=""
1069
- _dirty_files=$(prizm_git_status_non_bookkeeping "$_proj_root" "$STATE_DIR" "$bug_list" || true)
1070
- if [[ -n "$_dirty_files" ]]; then
1071
- log_info "Auto-committing workspace changes before $bug_id..."
1072
- prizm_git_add_all_safe "$_proj_root"
1073
- git -C "$_proj_root" commit --no-verify -m "chore: workspace snapshot ready for run $bug_id" 2>/dev/null || true
1074
- fi
1075
-
1076
- local _bookkeeping_dirty=""
1077
- _bookkeeping_dirty=$(prizm_git_status_bookkeeping "$_proj_root" "$STATE_DIR" "$bug_list" || true)
1078
- if [[ -n "$_bookkeeping_dirty" ]]; then
1079
- log_info "Committing pending pipeline bookkeeping before $bug_id..."
1080
- prizm_git_commit_paths "$_proj_root" "chore($bug_id): include pipeline bookkeeping" "$bug_list" "$STATE_DIR"
1081
- fi
1082
-
1083
- # Mark bug as in-progress BEFORE creating dev branch
1084
- # This ensures the in_progress status commit lands on the original branch,
1085
- # not the dev branch — preventing rebase conflicts in branch_merge later.
1086
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
1087
- --bug-list "$bug_list" \
1088
- --state-dir "$STATE_DIR" \
1089
- --bug-id "$bug_id" \
1090
- --action start >/dev/null 2>&1 || true
1091
- # Commit the in_progress status on the original branch
1092
- if ! git -C "$_proj_root" diff --quiet "$bug_list" 2>/dev/null; then
1093
- prizm_git_commit_paths "$_proj_root" "chore($bug_id): mark in_progress" "$bug_list"
1094
- fi
1095
-
1096
- # Continuation base branch from runtime state is authoritative for branch reuse.
1097
- if [[ "$continuation_pending" == "true" && -n "$base_branch" ]]; then
1098
- _ORIGINAL_BRANCH="$base_branch"
1099
- fi
1100
-
1101
- # Create or reuse per-bug dev branch (from the now-updated original branch)
1102
- local _bug_branch
1103
- if [[ -n "$DEV_BRANCH" ]]; then
1104
- _bug_branch="$DEV_BRANCH"
1105
- elif [[ "$continuation_pending" == "true" && -n "$active_dev_branch" ]]; then
1106
- _bug_branch="$active_dev_branch"
1107
- else
1108
- _bug_branch="bugfix/${bug_id}-$(date +%Y%m%d%H%M)"
1109
- fi
1110
- if branch_create "$_proj_root" "$_bug_branch" "$_ORIGINAL_BRANCH"; then
1111
- _DEV_BRANCH_NAME="$_bug_branch"
1112
- log_info "Dev branch: $_bug_branch"
1113
- else
1114
- log_error "Failed to create dev branch: $_bug_branch from $_ORIGINAL_BRANCH — aborting to avoid running on $_ORIGINAL_BRANCH"
1115
- _DEV_BRANCH_NAME=""
1116
- break
1117
- fi
1118
-
1119
- while true; do
1120
- # Generate session
1121
- local session_id run_id
1122
- run_id=$(jq -r '.run_id' "$STATE_DIR/pipeline.json")
1123
- session_id="${bug_id}-$(date +%Y%m%d%H%M%S)"
1124
-
1125
- local session_dir="$STATE_DIR/$bug_id/sessions/$session_id"
1126
- mkdir -p "$session_dir/logs"
1127
-
1128
- local bootstrap_prompt="$session_dir/bootstrap-prompt.md"
1129
- local continuation_summary_path=".prizmkit/bugfix/${bug_id}/continuation-summary.md"
1130
-
1131
- local main_prompt_args=(
1132
- --bug-list "$bug_list"
1133
- --bug-id "$bug_id"
1134
- --session-id "$session_id"
1135
- --run-id "$run_id"
1136
- --retry-count "$retry_count"
1137
- --resume-phase "$resume_phase"
1138
- --state-dir "$STATE_DIR"
1139
- --output "$bootstrap_prompt"
1140
- )
1141
-
1142
- if [[ "$continuation_pending" == "true" ]]; then
1143
- main_prompt_args+=(
1144
- --continuation-mode "${continuation_reason:-context_overflow}"
1145
- --previous-session-id "$previous_session_id"
1146
- --continuation-count "$continuation_count"
1147
- --context-overflow-count "$context_overflow_count"
1148
- --task-type "bugfix"
1149
- --active-dev-branch "$active_dev_branch"
1150
- --base-branch "$base_branch"
1151
- --continuation-summary-path "$continuation_summary_path"
1152
- )
1153
- fi
1154
-
1155
- # Support PIPELINE_MODE env var (set by launch-bugfix-daemon.sh --mode)
1156
- if [[ -n "${PIPELINE_MODE:-}" ]]; then
1157
- main_prompt_args+=(--mode "$PIPELINE_MODE")
1158
- fi
1159
-
1160
- # Support ENABLE_CRITIC env var (set by launch-bugfix-daemon.sh --critic)
1161
- if [[ "${ENABLE_CRITIC:-}" == "true" || "${ENABLE_CRITIC:-}" == "1" ]]; then
1162
- main_prompt_args+=(--critic "true")
1163
- elif [[ "${ENABLE_CRITIC:-}" == "false" || "${ENABLE_CRITIC:-}" == "0" ]]; then
1164
- main_prompt_args+=(--critic "false")
1165
- fi
1166
-
1167
- local gen_output
1168
- gen_output=$(python3 "$SCRIPTS_DIR/generate-bugfix-prompt.py" "${main_prompt_args[@]}" 2>/dev/null) || {
1169
- log_error "Failed to generate bootstrap prompt for $bug_id"
1170
- branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
1171
- _DEV_BRANCH_NAME=""
1172
- continue 2
1173
- }
1174
- local bug_model pipeline_mode agent_count critic_enabled
1175
- bug_model=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('model',''))" 2>/dev/null || echo "")
1176
- pipeline_mode=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('pipeline_mode','standard'))" 2>/dev/null || echo "standard")
1177
- agent_count=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('agent_count',3))" 2>/dev/null || echo "3")
1178
- critic_enabled=$(echo "$gen_output" | python3 -c "import json,sys; print(json.load(sys.stdin).get('critic_enabled','false'))" 2>/dev/null || echo "false")
1179
-
1180
- # Log pipeline mode and agent configuration
1181
- local _mode_desc
1182
- case "$pipeline_mode" in
1183
- lite) _mode_desc="Tier 1 — Single Agent" ;;
1184
- standard) _mode_desc="Tier 2 — Orchestrator + Dev + Reviewer" ;;
1185
- full) _mode_desc="Tier 3 — Full Team (+ Multi-Critic)" ;;
1186
- *) _mode_desc="$pipeline_mode" ;;
1187
- esac
1188
- log_info "Pipeline mode: ${BOLD}$pipeline_mode${NC} ($_mode_desc)"
1189
- log_info "Agents: $agent_count (critic: $([ "$critic_enabled" = "true" ] && echo "enabled" || echo "disabled"))"
1190
- if [[ -n "$bug_model" ]]; then
1191
- log_info "Bug model: $bug_model"
1192
- fi
1193
-
1194
- local continuation_artifact_dir=".prizmkit/bugfix/${bug_id}"
1195
- local continuation_checkpoint_path="$continuation_artifact_dir/workflow-checkpoint.json"
1196
- local progress_before progress_after
1197
- progress_before=$(prizm_context_progress_fingerprint "$_proj_root" "bugfix" "$bug_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
1198
-
1199
- # Spawn session
1200
- log_info "Spawning AI CLI session: $session_id"
1201
- _SPAWN_RESULT=""
1202
- _SPAWN_ITEM_STATUS=""
1203
-
1204
- spawn_and_wait_session \
1205
- "$bug_id" "$bug_list" "$session_id" \
1206
- "$bootstrap_prompt" "$session_dir" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$bug_model" "$_ORIGINAL_BRANCH"
1207
-
1208
- local session_status="$_SPAWN_RESULT"
1209
-
1210
- # Merge per-bug dev branch back to original on success
1211
- local active_dev_branch_for_status="$_DEV_BRANCH_NAME"
1212
- if [[ "$session_status" == "context_overflow" ]]; then
1213
- progress_after=$(prizm_context_progress_fingerprint "$_proj_root" "bugfix" "$bug_id" "$continuation_artifact_dir" "$continuation_checkpoint_path")
1214
- if prizm_context_progress_changed "$progress_before" "$progress_after"; then
1215
- no_progress_count=0
1216
- log_info "Context-overflow session made observable progress; continuing on $_DEV_BRANCH_NAME"
1217
- else
1218
- no_progress_count=$((no_progress_count + 1))
1219
- log_warn "Context-overflow session made no observable progress ($no_progress_count consecutive)"
1220
- fi
1221
- if [[ "$no_progress_count" -ge 2 ]]; then
1222
- log_warn "Pausing automatic continuation: context_overflow_without_git_checkpoint_or_artifact_progress"
1223
- session_status="stalled_context_continuation"
1224
- else
1225
- finalize_bug_status_after_branch_return \
1226
- "$bug_id" "$bug_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "$progress_after"
1227
- session_count=$((session_count + 1))
1228
- total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
1229
- continuation_pending="true"
1230
- continuation_reason="context_overflow"
1231
- previous_session_id="$session_id"
1232
- active_dev_branch="$_DEV_BRANCH_NAME"
1233
- base_branch="$_ORIGINAL_BRANCH"
1234
- context_overflow_count=$((context_overflow_count + 1))
1235
- continuation_count=$((continuation_count + 1))
1236
- log_info "Launching automatic continuation for $bug_id on same branch/worktree"
1237
- continue
1238
- fi
1239
- fi
1240
-
1241
- if [[ "$session_status" == "success" && -n "$_DEV_BRANCH_NAME" ]]; then
1242
- if branch_merge "$_proj_root" "$_DEV_BRANCH_NAME" "$_ORIGINAL_BRANCH" "$AUTO_PUSH"; then
1243
- _DEV_BRANCH_NAME=""
1244
- else
1245
- log_warn "Auto-merge failed — dev branch preserved: $_DEV_BRANCH_NAME"
1246
- log_warn "Merge manually: git checkout $_ORIGINAL_BRANCH && git rebase $_DEV_BRANCH_NAME"
1247
- session_status="merge_conflict"
1248
- fi
1249
- elif [[ -n "$_DEV_BRANCH_NAME" ]]; then
1250
- # Session failed — preserve dev branch for inspection
1251
- log_warn "Session failed — dev branch preserved for inspection: $_DEV_BRANCH_NAME"
1252
- fi
1253
-
1254
- # GUARANTEED: always return to original branch regardless of success/failure/merge outcome
1255
- branch_ensure_return "$_proj_root" "$_ORIGINAL_BRANCH"
1256
-
1257
- finalize_bug_status_after_branch_return \
1258
- "$bug_id" "$bug_list" "$session_id" "$session_status" "$MAX_RETRIES" "$MAX_INFRA_RETRIES" "$_ORIGINAL_BRANCH" "$active_dev_branch_for_status" "context_overflow" "$continuation_summary_path" "$no_progress_count" "${progress_after:-}"
1259
- local item_status_after_session="${_SPAWN_ITEM_STATUS:-}"
1260
-
1261
- # Commit bug status update on the original branch (after guaranteed return)
1262
- if ! git -C "$_proj_root" diff --quiet "$bug_list" 2>/dev/null; then
1263
- prizm_git_commit_paths "$_proj_root" "chore($bug_id): update bug status" "$bug_list"
1264
- fi
1265
-
1266
- session_count=$((session_count + 1))
1267
- total_subagent_calls=$((total_subagent_calls + _SUBAGENT_COUNT))
1268
- break
1269
- done
1270
-
1271
- # Stop-on-failure: abort only after the task is actually marked failed.
1272
- # Pending retry outcomes, including infrastructure errors, keep running.
1273
- if [[ "$session_status" != "success" && "$STOP_ON_FAILURE" == "1" && "$item_status_after_session" == "failed" ]]; then
1274
- echo ""
1275
- log_error "════════════════════════════════════════════════════"
1276
- log_error " STOP_ON_FAILURE: Pipeline halted after $bug_id exhausted retries."
1277
- log_error " Total sessions completed: $session_count"
1278
- log_error " Set STOP_ON_FAILURE=0 to continue past failures."
1279
- log_error "════════════════════════════════════════════════════"
1280
- break
1281
- elif [[ "$session_status" != "success" && "$STOP_ON_FAILURE" == "1" ]]; then
1282
- log_info "STOP_ON_FAILURE: $bug_id is ${item_status_after_session:-unknown}; code/infra retry budget not exhausted, continuing."
1283
- fi
1284
-
1285
- # Stuck detection
1286
- if python3 "$SCRIPTS_DIR/detect-stuck.py" \
1287
- --state-dir "$STATE_DIR" \
1288
- --pipeline-type bugfix \
1289
- --bug-list "$bug_list" \
1290
- --max-retries "$MAX_RETRIES" \
1291
- 2>/dev/null | jq -e '.stuck_count > 0' >/dev/null 2>&1; then
1292
- log_warn "STUCK_DETECTED: Some bugs may be stuck — run detect-stuck.py for details"
1293
- fi
1294
-
1295
- # Completion notes propagation (on success)
1296
- if [ "$_SPAWN_RESULT" = "success" ]; then
1297
- local _summary_path="$PRIZMKIT_DIR/bugfix/${bug_id}/completion-summary.json"
1298
- if [ -f "$_summary_path" ]; then
1299
- python3 "$SCRIPTS_DIR/patch-completion-notes.py" \
1300
- --bug-list "$bug_list" \
1301
- --bug-id "$bug_id" \
1302
- --summary "$_summary_path" 2>/dev/null || true
1303
- fi
1304
- fi
1305
-
1306
- log_info "Pausing 5s before next bug..."
1307
- sleep 5
1308
- done
1309
- }
1310
-
1311
- # ============================================================
1312
- # Entry Point
1313
- # ============================================================
1314
-
1315
- show_help() {
1316
- echo "Usage: $0 <command> [options]"
1317
- echo ""
1318
- echo "Commands:"
1319
- echo " run [.prizmkit/plans/bug-fix-list.json] [options] Run all bugs by severity/priority order"
1320
- echo " run <bug-id> [options] Run a single bug fix"
1321
- echo " status [.prizmkit/plans/bug-fix-list.json] Show bug fix pipeline status"
1322
- echo " reset Clear all bugfix state"
1323
- echo " help Show this help message"
1324
- echo ""
1325
- echo "Single Bug Options (run <bug-id>):"
1326
- echo " --dry-run Generate bootstrap prompt only, don't spawn session"
1327
- echo " --clean Delete artifacts and reset before running"
1328
- echo " --no-reset Skip status reset (preserve retry count)"
1329
- echo " --max-infra-retries N Max infrastructure/provider retries (default: 3)"
1330
- echo " --mode <lite|standard|full> Override pipeline mode"
1331
- echo " --critic Enable adversarial critic review"
1332
- echo " --no-critic Disable adversarial critic review"
1333
- echo ""
1334
- echo "Pipeline Options (run all):"
1335
- echo " --max-infra-retries N Max infrastructure/provider retries (default: 3)"
1336
- echo ""
1337
- echo "Environment Variables:"
1338
- echo " MAX_RETRIES Max code retries per bug (default: 3)"
1339
- echo " MAX_INFRA_RETRIES Max infrastructure/provider retries per bug (default: 3)"
1340
- echo " MODEL Default AI model (overridden by per-bug model in bug list)"
1341
- echo " PRIZMKIT_EFFORT AI reasoning effort (low|medium|high|xhigh|max; max is Claude Code only)"
1342
- echo " PIPELINE_MODE Default pipeline mode: lite|standard|full (overridden by --mode)"
1343
- echo " ENABLE_CRITIC Enable/disable critic: true|false|1|0 (overridden by --critic/--no-critic)"
1344
- echo " AI_CLI AI CLI command name (auto-detected: cbc, claude, or codex)"
1345
- echo " VERBOSE Set to 1 for verbose AI CLI output"
1346
- echo " HEARTBEAT_INTERVAL Heartbeat log interval in seconds (default: 30)"
1347
- echo " STALE_KILL_THRESHOLD Auto-kill session after N seconds of no progress (default: 900)"
1348
- echo " MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)"
1349
- echo " STOP_ON_FAILURE Stop pipeline when a task exhausts retries: 0|1 (default: 0)"
1350
- echo ""
1351
- echo "Examples:"
1352
- echo " ./run-bugfix.sh run # Run all bugs"
1353
- echo " ./run-bugfix.sh run .prizmkit/plans/bug-fix-list.json # Custom bug list"
1354
- echo " ./run-bugfix.sh run B-001 --dry-run # Inspect generated prompt"
1355
- echo " ./run-bugfix.sh run B-001 --clean # Clean artifacts + reset + run"
1356
- echo " ./run-bugfix.sh run B-001 --no-reset # Retry without resetting status"
1357
- echo " ./run-bugfix.sh status # Show status"
1358
- echo " MAX_RETRIES=5 ./run-bugfix.sh run # Custom retries"
1359
- }
1360
-
1361
- case "${1:-run}" in
1362
- run|resume)
1363
- shift || true
1364
- if [[ "${1:-}" =~ ^[Bb]-[0-9]+ ]]; then
1365
- run_one "$@"
1366
- else
1367
- main "$@"
1368
- fi
1369
- ;;
1370
- status)
1371
- check_dependencies
1372
- if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
1373
- log_error "No bugfix pipeline state found. Run './run-bugfix.sh run' first."
1374
- exit 1
1375
- fi
1376
- python3 "$SCRIPTS_DIR/update-bug-status.py" \
1377
- --bug-list "${2:-$PRIZMKIT_DIR/plans/bug-fix-list.json}" \
1378
- --state-dir "$STATE_DIR" \
1379
- --max-retries "$MAX_RETRIES" \
1380
- --max-infra-retries "$MAX_INFRA_RETRIES" \
1381
- --action status
1382
- ;;
1383
- reset)
1384
- log_warn "Resetting bugfix pipeline state..."
1385
- rm -rf "$STATE_DIR"
1386
- log_success "Bugfix state cleared. Run './run-bugfix.sh run' to start fresh."
1387
- ;;
1388
- unskip)
1389
- check_dependencies
1390
- if [[ ! -f "$STATE_DIR/pipeline.json" ]]; then
1391
- log_error "No bugfix pipeline state found. Run './run-bugfix.sh run' first."
1392
- exit 1
1393
- fi
1394
- _unskip_bug_list="$PRIZMKIT_DIR/plans/bug-fix-list.json"
1395
- _unskip_bug_id=""
1396
- shift || true
1397
- # Parse arguments: optional bug-id and bug-list path
1398
- while [[ $# -gt 0 ]]; do
1399
- if [[ "$1" =~ ^[Bb]-[0-9]+ ]]; then
1400
- _unskip_bug_id="$1"
1401
- else
1402
- _unskip_bug_list="$1"
1403
- fi
1404
- shift
1405
- done
1406
- _unskip_args=(
1407
- --bug-list "$_unskip_bug_list"
1408
- --state-dir "$STATE_DIR"
1409
- --action unskip
1410
- )
1411
- if [[ -n "$_unskip_bug_id" ]]; then
1412
- _unskip_args+=(--bug-id "$_unskip_bug_id")
1413
- fi
1414
- python3 "$SCRIPTS_DIR/update-bug-status.py" "${_unskip_args[@]}"
1415
-
1416
- # Commit the status change
1417
- if ! git diff --quiet "$_unskip_bug_list" 2>/dev/null; then
1418
- git add "$_unskip_bug_list"
1419
- git commit -m "chore: unskip skipped bugs" 2>/dev/null || true
1420
- fi
1421
- ;;
1422
- help|--help|-h)
1423
- show_help
1424
- ;;
1425
- *)
1426
- log_error "Unknown command: $1"
1427
- show_help
1428
- exit 1
1429
- ;;
1430
- esac