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
@@ -1,1121 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Core state machine for updating bug status in the bug-fix pipeline.
3
-
4
- Handles eight actions:
5
- - get_next: Find the next bug to process based on priority and severity
6
- - start: Mark a bug as fixing when a session starts
7
- - update: Update a bug's status based on session outcome
8
- - status: Print a formatted overview of all bugs
9
- - pause: Save pipeline state for graceful shutdown
10
- - reset: Reset a bug to pending (status + retry count)
11
- - clean: Reset + delete session history + delete bugfix artifacts
12
- - unskip: Reset skipped bugs back to pending
13
-
14
- Usage:
15
- python3 update-bug-status.py \
16
- --bug-list <path> --state-dir <path> \
17
- --action <get_next|start|update|status|pause|reset|clean|unskip> \
18
- [--bug-id <id>] [--session-status <status>] \
19
- [--session-id <id>] [--max-retries <n>] [--max-infra-retries <n>]
20
- """
21
-
22
- import argparse
23
- import json
24
- import os
25
- import shutil
26
- from datetime import datetime, timezone
27
-
28
- from utils import (
29
- load_json_file,
30
- write_json_file,
31
- error_out,
32
- pad_right,
33
- _build_progress_bar,
34
- )
35
-
36
-
37
- SESSION_STATUS_VALUES = [
38
- "success",
39
- "partial_resumable",
40
- "partial_not_resumable",
41
- "failed",
42
- "crashed",
43
- "timed_out",
44
- "infra_error",
45
- "context_overflow",
46
- "stalled_context_continuation",
47
- "commit_missing",
48
- "docs_missing",
49
- "merge_conflict",
50
- ]
51
-
52
- TERMINAL_STATUSES = {"completed", "failed", "skipped", "needs_info"}
53
-
54
- # Severity priority (lower value = higher priority)
55
- SEVERITY_PRIORITY = {
56
- "critical": 0,
57
- "high": 1,
58
- "medium": 2,
59
- "low": 3,
60
- }
61
-
62
-
63
- def parse_args():
64
- parser = argparse.ArgumentParser(
65
- description="Core state machine for bug-fix pipeline bug status management."
66
- )
67
- parser.add_argument("--bug-list", required=True, help="Path to the .prizmkit/plans/bug-fix-list.json file")
68
- parser.add_argument("--state-dir", required=True, help="Path to the state directory (default: .prizmkit/state/bugfix)")
69
- parser.add_argument(
70
- "--action", required=True,
71
- choices=["get_next", "start", "update", "status", "pause", "reset", "clean", "unskip", "complete"],
72
- help="Action to perform",
73
- )
74
- parser.add_argument("--bug-id", default=None, help="Bug ID (required for 'update'/'reset'/'clean' actions)")
75
- parser.add_argument(
76
- "--session-status", default=None, choices=SESSION_STATUS_VALUES,
77
- help="Session outcome status (required for 'update' action)",
78
- )
79
- parser.add_argument("--session-id", default=None, help="Session ID (optional, for 'update' action)")
80
- parser.add_argument("--max-retries", type=int, default=3, help="Maximum code retry count (default: 3)")
81
- parser.add_argument("--max-infra-retries", type=int, default=3, help="Maximum infrastructure retry count (default: 3)")
82
- parser.add_argument("--project-root", default=None, help="Project root directory. Required for 'clean' action.")
83
- parser.add_argument("--active-dev-branch", default=None, help="Development branch preserved for continuation after context overflow.")
84
- parser.add_argument("--base-branch", default=None, help="Original/base branch for continuation branch reuse.")
85
- parser.add_argument("--last-fatal-error-code", default=None, help="Fatal runtime error code associated with continuation.")
86
- parser.add_argument("--continuation-summary-path", default=None, help="Optional continuation summary artifact path.")
87
- parser.add_argument("--no-progress-count", type=int, default=None, help="Consecutive context-overflow sessions without objective progress.")
88
- parser.add_argument("--progress-fingerprint", default=None, help="JSON progress fingerprint captured after the session.")
89
- return parser.parse_args()
90
-
91
-
92
- def now_iso():
93
- return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
94
-
95
-
96
- def load_bug_status(state_dir, bug_id):
97
- """Load runtime state from status.json for a bug.
98
-
99
- Returns runtime fields only (retry_count, sessions, etc.).
100
- The 'status' field is NOT included — status lives exclusively
101
- in bug-fix-list.json.
102
- """
103
- status_path = os.path.join(state_dir, bug_id, "status.json")
104
- if not os.path.isfile(status_path):
105
- now = now_iso()
106
- return {
107
- "bug_id": bug_id,
108
- "retry_count": 0,
109
- "max_retries": 3,
110
- "max_infra_retries": 3,
111
- "infra_error_count": 0,
112
- "last_infra_error_session_id": None,
113
- "sessions": [],
114
- "last_session_id": None,
115
- "resume_from_phase": None,
116
- "created_at": now,
117
- "updated_at": now,
118
- }
119
- data, err = load_json_file(status_path)
120
- if err:
121
- now = now_iso()
122
- return {
123
- "bug_id": bug_id,
124
- "retry_count": 0,
125
- "max_retries": 3,
126
- "max_infra_retries": 3,
127
- "infra_error_count": 0,
128
- "last_infra_error_session_id": None,
129
- "sessions": [],
130
- "last_session_id": None,
131
- "resume_from_phase": None,
132
- "created_at": now,
133
- "updated_at": now,
134
- }
135
- # Defensively remove status if present (legacy data)
136
- data.pop("status", None)
137
- return data
138
-
139
-
140
- def save_bug_status(state_dir, bug_id, status_data):
141
- """Write the status.json for a bug (runtime fields only)."""
142
- # Defensively strip status — it belongs in bug-fix-list.json
143
- status_data.pop("status", None)
144
- status_path = os.path.join(state_dir, bug_id, "status.json")
145
- return write_json_file(status_path, status_data)
146
-
147
-
148
- def get_bug_status_from_list(bug_list_path, bug_id):
149
- """Read a single bug's status from bug-fix-list.json."""
150
- data, err = load_json_file(bug_list_path)
151
- if err:
152
- return "pending"
153
- for b in data.get("bugs", []):
154
- if isinstance(b, dict) and b.get("id") == bug_id:
155
- return b.get("status", "pending")
156
- return "pending"
157
-
158
-
159
- def update_bug_in_list(bug_list_path, bug_id, new_status):
160
- data, err = load_json_file(bug_list_path)
161
- if err:
162
- return err
163
- bugs = data.get("bugs", [])
164
- found = False
165
- for bug in bugs:
166
- if isinstance(bug, dict) and bug.get("id") == bug_id:
167
- bug["status"] = new_status
168
- found = True
169
- break
170
- if not found:
171
- return "Bug '{}' not found in .prizmkit/plans/bug-fix-list.json".format(bug_id)
172
- return write_json_file(bug_list_path, data)
173
-
174
-
175
- CONTINUATION_PENDING_FIELDS = [
176
- "active_dev_branch",
177
- "base_branch",
178
- "continuation_pending",
179
- "continuation_reason",
180
- "last_context_overflow_session_id",
181
- "previous_session_id",
182
- "last_fatal_error_code",
183
- "continuation_summary_path",
184
- "no_progress_count",
185
- "last_progress_fingerprint",
186
- "needs_attention",
187
- "stalled_context_continuation",
188
- "stalled_reason",
189
- ]
190
-
191
- CONTINUATION_COUNTER_FIELDS = [
192
- "context_overflow_count",
193
- "continuation_count",
194
- ]
195
-
196
-
197
- def has_pending_continuation_metadata(status_data):
198
- """Return True when runtime state still has pending continuation metadata."""
199
- return any(key in status_data for key in CONTINUATION_PENDING_FIELDS)
200
-
201
-
202
- def clear_pending_continuation_metadata(status_data):
203
- """Clear branch/pending continuation fields while preserving observability counters."""
204
- for key in CONTINUATION_PENDING_FIELDS:
205
- status_data.pop(key, None)
206
-
207
-
208
- def reset_continuation_metadata(status_data):
209
- """Clear all continuation runtime metadata, including manual-reset counters."""
210
- clear_pending_continuation_metadata(status_data)
211
- for key in CONTINUATION_COUNTER_FIELDS:
212
- status_data.pop(key, None)
213
-
214
-
215
- STALL_REASON = "context_overflow_without_git_checkpoint_or_artifact_progress"
216
-
217
-
218
- def _load_progress_fingerprint(raw):
219
- if not raw:
220
- return None
221
- try:
222
- return json.loads(raw)
223
- except (TypeError, ValueError):
224
- return {"unparsed": str(raw)}
225
-
226
-
227
- def _set_continuation_common(status_data, args, session_id):
228
- if args.active_dev_branch:
229
- status_data["active_dev_branch"] = args.active_dev_branch
230
- if args.base_branch:
231
- status_data["base_branch"] = args.base_branch
232
- status_data["last_context_overflow_session_id"] = session_id
233
- status_data["previous_session_id"] = session_id
234
- status_data["last_fatal_error_code"] = args.last_fatal_error_code or "context_overflow"
235
- if args.continuation_summary_path:
236
- status_data["continuation_summary_path"] = args.continuation_summary_path
237
- else:
238
- status_data.pop("continuation_summary_path", None)
239
- if args.no_progress_count is not None:
240
- status_data["no_progress_count"] = max(0, args.no_progress_count)
241
- fingerprint = _load_progress_fingerprint(args.progress_fingerprint)
242
- if fingerprint is not None:
243
- status_data["last_progress_fingerprint"] = fingerprint
244
- status_data["last_infra_error_session_id"] = None
245
- status_data["resume_from_phase"] = None
246
- if session_id:
247
- status_data["last_session_id"] = session_id
248
-
249
-
250
- def set_context_overflow_continuation_metadata(status_data, args, session_id):
251
- """Record continuation metadata for a context-overflow outcome in status.json."""
252
- status_data["context_overflow_count"] = status_data.get("context_overflow_count", 0) + 1
253
- status_data["continuation_count"] = status_data.get("continuation_count", 0) + 1
254
- status_data["continuation_pending"] = True
255
- status_data["continuation_reason"] = "context_overflow"
256
- status_data.pop("needs_attention", None)
257
- status_data.pop("stalled_context_continuation", None)
258
- status_data.pop("stalled_reason", None)
259
- _set_continuation_common(status_data, args, session_id)
260
-
261
-
262
- def set_stalled_context_continuation_metadata(status_data, args, session_id):
263
- """Record no-progress context-overflow stall without consuming retry budgets."""
264
- status_data["context_overflow_count"] = status_data.get("context_overflow_count", 0) + 1
265
- status_data["continuation_count"] = status_data.get("continuation_count", 0) + 1
266
- _set_continuation_common(status_data, args, session_id)
267
- status_data["continuation_pending"] = False
268
- status_data["continuation_reason"] = STALL_REASON
269
- status_data["needs_attention"] = True
270
- status_data["stalled_context_continuation"] = True
271
- status_data["stalled_reason"] = STALL_REASON
272
- if args.no_progress_count is None or args.no_progress_count < 2:
273
- status_data["no_progress_count"] = 2
274
-
275
-
276
- def continuation_metadata_summary(status_data):
277
- """Return additive continuation fields for CLI JSON outputs."""
278
- return {
279
- "active_dev_branch": status_data.get("active_dev_branch"),
280
- "base_branch": status_data.get("base_branch"),
281
- "continuation_pending": status_data.get("continuation_pending", False),
282
- "continuation_reason": status_data.get("continuation_reason"),
283
- "last_context_overflow_session_id": status_data.get("last_context_overflow_session_id"),
284
- "last_fatal_error_code": status_data.get("last_fatal_error_code"),
285
- "previous_session_id": status_data.get("previous_session_id"),
286
- "context_overflow_count": status_data.get("context_overflow_count", 0),
287
- "continuation_count": status_data.get("continuation_count", 0),
288
- "no_progress_count": status_data.get("no_progress_count", 0),
289
- "last_progress_fingerprint": status_data.get("last_progress_fingerprint"),
290
- "needs_attention": status_data.get("needs_attention", False),
291
- "stalled_context_continuation": status_data.get("stalled_context_continuation", False),
292
- "stalled_reason": status_data.get("stalled_reason"),
293
- "continuation_summary_path": status_data.get("continuation_summary_path"),
294
- }
295
-
296
-
297
- # ---------------------------------------------------------------------------
298
- # Action: get_next
299
- # ---------------------------------------------------------------------------
300
-
301
- def action_get_next(bug_list_data, state_dir):
302
- """Find the next bug to process.
303
-
304
- Priority logic:
305
- 1. Skip terminal statuses (completed, failed, skipped, needs_info)
306
- 2. Prefer in_progress bugs (interrupted session resume) over pending
307
- 3. Sort by: severity (critical > high > medium > low), then by priority (high > medium > low)
308
- """
309
- bugs = bug_list_data.get("bugs", [])
310
- if not bugs:
311
- print("PIPELINE_COMPLETE")
312
- return
313
-
314
- # Build status map from bug-fix-list.json (single source of truth)
315
- status_map = {}
316
- status_data_map = {}
317
- for bug in bugs:
318
- if not isinstance(bug, dict):
319
- continue
320
- bid = bug.get("id")
321
- if not bid:
322
- continue
323
- status_map[bid] = bug.get("status", "pending")
324
- bs = load_bug_status(state_dir, bid)
325
- status_data_map[bid] = bs
326
-
327
- # Check if all bugs are terminal
328
- non_terminal = [
329
- b for b in bugs
330
- if isinstance(b, dict) and b.get("id")
331
- and status_map.get(b["id"], "pending") not in TERMINAL_STATUSES
332
- ]
333
- if not non_terminal:
334
- print("PIPELINE_COMPLETE")
335
- return
336
-
337
- # Separate in_progress from pending
338
- in_progress_bugs = []
339
- pending_bugs = []
340
- for bug in non_terminal:
341
- bid = bug.get("id")
342
- bstatus = status_map.get(bid, "pending")
343
- if bstatus == "in_progress":
344
- in_progress_bugs.append(bug)
345
- elif bstatus == "pending":
346
- pending_bugs.append(bug)
347
-
348
- _PRIORITY_ORDER = {"high": 0, "medium": 1, "low": 2}
349
-
350
- def sort_key(b):
351
- severity = b.get("severity", "medium")
352
- sev_order = SEVERITY_PRIORITY.get(severity, 2)
353
- priority = _PRIORITY_ORDER.get(b.get("priority", "low"), 2)
354
- return (sev_order, priority)
355
-
356
- if in_progress_bugs:
357
- candidates = sorted(in_progress_bugs, key=sort_key)
358
- elif pending_bugs:
359
- candidates = sorted(pending_bugs, key=sort_key)
360
- else:
361
- # All remaining bugs are in non-terminal but also non-pending/in_progress states
362
- print("PIPELINE_BLOCKED")
363
- return
364
-
365
- chosen = candidates[0]
366
- chosen_id = chosen["id"]
367
- chosen_status_data = status_data_map.get(chosen_id, {})
368
-
369
- result = {
370
- "bug_id": chosen_id,
371
- "title": chosen.get("title", ""),
372
- "severity": chosen.get("severity", "medium"),
373
- "retry_count": chosen_status_data.get("retry_count", 0),
374
- "infra_error_count": chosen_status_data.get("infra_error_count", 0),
375
- "resume_from_phase": chosen_status_data.get("resume_from_phase", None),
376
- }
377
- result.update(continuation_metadata_summary(chosen_status_data))
378
- print(json.dumps(result, indent=2, ensure_ascii=False))
379
-
380
-
381
- # ---------------------------------------------------------------------------
382
- # Action: update
383
- # ---------------------------------------------------------------------------
384
-
385
- def action_update(args, bug_list_path, state_dir):
386
- bug_id = args.bug_id
387
- session_status = args.session_status
388
- session_id = args.session_id
389
- max_retries = args.max_retries
390
- max_infra_retries = args.max_infra_retries
391
-
392
- if not bug_id:
393
- error_out("--bug-id is required for 'update' action")
394
- return
395
- if not session_status:
396
- error_out("--session-status is required for 'update' action")
397
- return
398
-
399
- bs = load_bug_status(state_dir, bug_id)
400
-
401
- current_list_status = get_bug_status_from_list(bug_list_path, bug_id)
402
-
403
- # Track what status we write to bug-fix-list.json
404
- new_status = current_list_status
405
-
406
- if session_status == "success":
407
- bs["infra_error_count"] = 0
408
- bs["last_infra_error_session_id"] = None
409
- clear_pending_continuation_metadata(bs)
410
- new_status = "completed"
411
- bs["resume_from_phase"] = None
412
- err = update_bug_in_list(bug_list_path, bug_id, "completed")
413
- if err:
414
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
415
- return
416
- elif session_status in ("commit_missing", "docs_missing", "merge_conflict"):
417
- bs["retry_count"] = bs.get("retry_count", 0) + 1
418
-
419
- if bs["retry_count"] >= max_retries:
420
- new_status = "failed"
421
- else:
422
- new_status = "pending"
423
-
424
- bs["degraded_reason"] = session_status
425
- bs["resume_from_phase"] = None
426
- bs["sessions"] = []
427
- bs["last_session_id"] = None
428
-
429
- err = update_bug_in_list(bug_list_path, bug_id, new_status)
430
- if err:
431
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
432
- return
433
- elif session_status == "infra_error":
434
- # AI CLI/provider outage, auth failure, gateway error, etc.
435
- # Infra failures do not consume the code retry budget, but they still
436
- # need their own bounded budget so a flaky provider cannot loop forever.
437
- infra_error_count = bs.get("infra_error_count", 0) + 1
438
- bs["infra_error_count"] = infra_error_count
439
- bs["last_infra_error_session_id"] = session_id
440
- bs["max_infra_retries"] = max_infra_retries
441
- bs["degraded_reason"] = session_status
442
- if session_id:
443
- bs["last_session_id"] = session_id
444
- bs["resume_from_phase"] = None
445
-
446
- if infra_error_count >= max_infra_retries:
447
- new_status = "failed"
448
- if session_id:
449
- bs["last_failed_session_id"] = session_id
450
- else:
451
- new_status = "pending"
452
-
453
- err = update_bug_in_list(bug_list_path, bug_id, new_status)
454
- if err:
455
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
456
- return
457
- elif session_status == "context_overflow":
458
- # Context overflow is continuation state, not code or infra retry state.
459
- set_context_overflow_continuation_metadata(bs, args, session_id)
460
- new_status = "in_progress"
461
- if current_list_status != "in_progress":
462
- err = update_bug_in_list(bug_list_path, bug_id, "in_progress")
463
- if err:
464
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
465
- return
466
- elif session_status == "stalled_context_continuation":
467
- # No-progress context-overflow stall pauses automation without consuming retry budgets.
468
- set_stalled_context_continuation_metadata(bs, args, session_id)
469
- new_status = "needs_info"
470
- err = update_bug_in_list(bug_list_path, bug_id, new_status)
471
- if err:
472
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
473
- return
474
- else:
475
- bs["retry_count"] = bs.get("retry_count", 0) + 1
476
-
477
- cleaned = cleanup_bug_artifacts(
478
- state_dir=state_dir,
479
- bug_id=bug_id,
480
- project_root=args.project_root,
481
- )
482
-
483
- if bs["retry_count"] >= max_retries:
484
- new_status = "failed"
485
- else:
486
- new_status = "pending"
487
-
488
- bs["resume_from_phase"] = None
489
- bs["sessions"] = []
490
- bs["last_session_id"] = None
491
-
492
- err = update_bug_in_list(bug_list_path, bug_id, new_status)
493
- if err:
494
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
495
- return
496
-
497
- if session_status == "success" and session_id:
498
- sessions = bs.get("sessions", [])
499
- if session_id not in sessions:
500
- sessions.append(session_id)
501
- bs["sessions"] = sessions
502
- bs["last_session_id"] = session_id
503
-
504
- bs["updated_at"] = now_iso()
505
-
506
- err = save_bug_status(state_dir, bug_id, bs)
507
- if err:
508
- error_out("Failed to save bug status: {}".format(err))
509
- return
510
-
511
- summary = {
512
- "action": "update",
513
- "bug_id": bug_id,
514
- "session_status": session_status,
515
- "new_status": new_status,
516
- "retry_count": bs["retry_count"],
517
- "infra_error_count": bs.get("infra_error_count", 0),
518
- "max_infra_retries": max_infra_retries,
519
- "resume_from_phase": bs.get("resume_from_phase"),
520
- "updated_at": bs["updated_at"],
521
- }
522
- if session_status in ("commit_missing", "docs_missing", "merge_conflict"):
523
- summary["degraded_reason"] = session_status
524
- summary["restart_policy"] = "finalization_retry"
525
- elif session_status == "infra_error":
526
- summary["restart_policy"] = "infra_retry"
527
- summary["infra_error_count"] = bs.get("infra_error_count", 0)
528
- summary["artifacts_preserved"] = True
529
- elif session_status == "context_overflow":
530
- summary["restart_policy"] = "context_overflow_continuation"
531
- summary.update(continuation_metadata_summary(bs))
532
- summary["artifacts_preserved"] = True
533
- elif session_status == "stalled_context_continuation":
534
- summary["restart_policy"] = "needs_attention"
535
- summary.update(continuation_metadata_summary(bs))
536
- summary["artifacts_preserved"] = True
537
- elif session_status != "success":
538
- summary["restart_policy"] = "full_restart"
539
- summary["cleanup_performed"] = cleaned
540
-
541
- print(json.dumps(summary, indent=2, ensure_ascii=False))
542
-
543
-
544
- def _default_project_root():
545
- env = os.environ.get("PROJECT_ROOT")
546
- if env:
547
- return os.path.abspath(env)
548
- script_dir = os.path.dirname(os.path.abspath(__file__))
549
- pipeline_dir = os.path.dirname(script_dir)
550
- pipeline_parent = os.path.dirname(pipeline_dir)
551
- if os.path.basename(pipeline_parent) == ".prizmkit":
552
- return os.path.dirname(pipeline_parent)
553
- return pipeline_parent
554
-
555
-
556
- def cleanup_bug_artifacts(state_dir, bug_id, project_root=None):
557
- """Delete intermediate artifacts for a failed bug run."""
558
- if not project_root:
559
- project_root = _default_project_root()
560
-
561
- cleaned = []
562
-
563
- # 1) Remove all session history
564
- sessions_dir = os.path.join(state_dir, bug_id, "sessions")
565
- sessions_deleted = 0
566
- if os.path.isdir(sessions_dir):
567
- for entry in os.listdir(sessions_dir):
568
- entry_path = os.path.join(sessions_dir, entry)
569
- if os.path.isdir(entry_path):
570
- shutil.rmtree(entry_path)
571
- sessions_deleted += 1
572
- cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
573
-
574
- # 2) Remove transient files under bug dir (keep status.json)
575
- bug_dir = os.path.join(state_dir, bug_id)
576
- if os.path.isdir(bug_dir):
577
- for entry in os.listdir(bug_dir):
578
- if entry == "status.json" or entry == "sessions":
579
- continue
580
- entry_path = os.path.join(bug_dir, entry)
581
- if os.path.isdir(entry_path):
582
- shutil.rmtree(entry_path)
583
- cleaned.append("Deleted directory {}".format(entry_path))
584
- elif os.path.isfile(entry_path):
585
- os.remove(entry_path)
586
- cleaned.append("Deleted file {}".format(entry_path))
587
-
588
- # 3) Remove bugfix artifacts
589
- bugfix_dir = os.path.join(project_root, ".prizmkit", "bugfix", bug_id)
590
- if os.path.isdir(bugfix_dir):
591
- file_count = sum(len(files) for _, _, files in os.walk(bugfix_dir))
592
- shutil.rmtree(bugfix_dir)
593
- cleaned.append("Deleted {} ({} files)".format(bugfix_dir, file_count))
594
-
595
- # 4) Remove shared dev-team workspace
596
- dev_team_dir = os.path.join(project_root, ".dev-team")
597
- if os.path.isdir(dev_team_dir):
598
- file_count = sum(len(files) for _, _, files in os.walk(dev_team_dir))
599
- shutil.rmtree(dev_team_dir)
600
- cleaned.append("Deleted {} ({} files)".format(dev_team_dir, file_count))
601
-
602
- # 5) (removed: current-session.json no longer used)
603
-
604
- return cleaned
605
-
606
-
607
- def _resolve_project_file(project_root, path):
608
- if not path:
609
- return None
610
- if os.path.isabs(path):
611
- target = os.path.abspath(path)
612
- else:
613
- target = os.path.abspath(os.path.join(project_root, path))
614
- root = os.path.abspath(project_root)
615
- try:
616
- rel = os.path.relpath(target, root)
617
- except ValueError:
618
- return None
619
- if rel == os.pardir or rel.startswith(os.pardir + os.sep):
620
- return None
621
- return target
622
-
623
-
624
- def cleanup_continuation_artifacts(project_root, status_data, candidate_paths=None):
625
- """Delete durable continuation handoff files for a manual clean reset."""
626
- candidates = []
627
- if isinstance(status_data, dict):
628
- candidates.append(status_data.get("continuation_summary_path"))
629
- candidates.extend(candidate_paths or [])
630
-
631
- cleaned = []
632
- seen = set()
633
- for candidate in candidates:
634
- target = _resolve_project_file(project_root, candidate)
635
- if not target or target in seen:
636
- continue
637
- seen.add(target)
638
- if os.path.basename(target) != "continuation-summary.md":
639
- continue
640
- if os.path.isfile(target):
641
- os.remove(target)
642
- cleaned.append("Deleted continuation artifact {}".format(target))
643
- return cleaned
644
-
645
-
646
- def load_session_status(state_dir, bug_id, session_id):
647
- session_status_path = os.path.join(state_dir, bug_id, "sessions",
648
- session_id, "session-status.json"
649
- )
650
- data, err = load_json_file(session_status_path)
651
- if err:
652
- return None, err
653
- return data, None
654
-
655
-
656
- # ---------------------------------------------------------------------------
657
- # Action: status
658
- # ---------------------------------------------------------------------------
659
-
660
- COLOR_GREEN = "\033[92m"
661
- COLOR_YELLOW = "\033[93m"
662
- COLOR_RED = "\033[91m"
663
- COLOR_GRAY = "\033[90m"
664
- COLOR_MAGENTA = "\033[95m"
665
- COLOR_BOLD = "\033[1m"
666
- COLOR_RESET = "\033[0m"
667
-
668
- BOX_WIDTH = 68
669
-
670
-
671
- SEVERITY_ICONS = {
672
- "critical": COLOR_RED + "🔴" + COLOR_RESET,
673
- "high": COLOR_MAGENTA + "🟠" + COLOR_RESET,
674
- "medium": COLOR_YELLOW + "🟡" + COLOR_RESET,
675
- "low": COLOR_GRAY + "🟢" + COLOR_RESET,
676
- }
677
-
678
-
679
- def action_status(bug_list_data, state_dir):
680
- bugs = bug_list_data.get("bugs", [])
681
- project_name = bug_list_data.get("project_name", "Unknown")
682
-
683
- counts = {"completed": 0, "in_progress": 0, "failed": 0, "pending": 0, "needs_info": 0, "skipped": 0}
684
- bug_lines = []
685
-
686
- for bug in bugs:
687
- if not isinstance(bug, dict):
688
- continue
689
- bid = bug.get("id")
690
- title = bug.get("title", "Untitled")
691
- severity = bug.get("severity", "medium")
692
- if not bid:
693
- continue
694
-
695
- bstatus = bug.get("status", "pending")
696
- bs = load_bug_status(state_dir, bid)
697
- retry_count = bs.get("retry_count", 0)
698
- max_retries_val = bs.get("max_retries", 3)
699
- resume_phase = bs.get("resume_from_phase")
700
-
701
- if bstatus in counts:
702
- counts[bstatus] += 1
703
- else:
704
- counts["pending"] += 1
705
-
706
- # Status icon
707
- if bstatus == "completed":
708
- icon = COLOR_GREEN + "[✓]" + COLOR_RESET
709
- elif bstatus == "in_progress":
710
- icon = COLOR_YELLOW + "[→]" + COLOR_RESET
711
- elif bstatus == "failed":
712
- icon = COLOR_RED + "[✗]" + COLOR_RESET
713
- elif bstatus == "needs_info":
714
- icon = COLOR_MAGENTA + "[?]" + COLOR_RESET
715
- elif bstatus == "skipped":
716
- icon = COLOR_GRAY + "[—]" + COLOR_RESET
717
- else:
718
- icon = COLOR_GRAY + "[ ]" + COLOR_RESET
719
-
720
- # Severity badge
721
- sev_badge = "[{}]".format(severity[:4].upper())
722
-
723
- # Detail
724
- detail = ""
725
- if bstatus == "in_progress":
726
- parts = []
727
- if retry_count > 0:
728
- parts.append("retry {}/{}".format(retry_count, max_retries_val))
729
- if resume_phase is not None:
730
- parts.append("CP-BF-{}".format(resume_phase))
731
- if parts:
732
- detail = " ({})".format(", ".join(parts))
733
- elif bstatus == "failed":
734
- detail = " (failed after {} retries)".format(retry_count)
735
- elif bstatus == "needs_info":
736
- detail = " (needs more info)"
737
-
738
- # Colorize
739
- if bstatus == "completed":
740
- line_content = "{} {} {} {} {}{}".format(
741
- bid, icon, sev_badge, COLOR_GREEN + title + COLOR_RESET, "", detail
742
- )
743
- elif bstatus == "in_progress":
744
- line_content = "{} {} {} {} {}{}".format(
745
- bid, icon, sev_badge, COLOR_YELLOW + title + COLOR_RESET, "", detail
746
- )
747
- elif bstatus == "failed":
748
- line_content = "{} {} {} {} {}{}".format(
749
- bid, icon, sev_badge, COLOR_RED + title + COLOR_RESET, "", detail
750
- )
751
- elif bstatus == "needs_info":
752
- line_content = "{} {} {} {} {}{}".format(
753
- bid, icon, sev_badge, COLOR_MAGENTA + title + COLOR_RESET, "", detail
754
- )
755
- else:
756
- line_content = "{} {} {} {} {}{}".format(
757
- bid, icon, sev_badge, COLOR_GRAY + title + COLOR_RESET, "", detail
758
- )
759
-
760
- bug_lines.append(line_content)
761
-
762
- total = len(bugs)
763
- completed = counts["completed"]
764
- percent = round(completed / total * 100, 1) if total > 0 else 0.0
765
- progress_bar = _build_progress_bar(percent, width=24)
766
-
767
- summary_line = "Total: {} bugs | Completed: {} | In Progress: {}".format(
768
- total, completed, counts["in_progress"]
769
- )
770
- summary_line2 = "Failed: {} | Pending: {} | Needs Info: {} | Skipped: {}".format(
771
- counts["failed"], counts["pending"], counts["needs_info"], counts["skipped"]
772
- )
773
-
774
- inner = BOX_WIDTH - 2
775
- print("╔" + "═" * BOX_WIDTH + "╗")
776
- print("║" + pad_right(COLOR_BOLD + " Bug-Fix Pipeline Status" + COLOR_RESET, inner) + " ║")
777
- print("╠" + "═" * BOX_WIDTH + "╣")
778
- print("║" + pad_right(" Project: {}".format(project_name), inner) + " ║")
779
- print("║" + pad_right(" {}".format(summary_line), inner) + " ║")
780
- print("║" + pad_right(" {}".format(summary_line2), inner) + " ║")
781
- print("╠" + "─" * BOX_WIDTH + "╣")
782
- print("║" + pad_right(" Progress: {}".format(progress_bar), inner) + " ║")
783
- print("╠" + "═" * BOX_WIDTH + "╣")
784
- for line in bug_lines:
785
- print("║" + pad_right(" {}".format(line), inner) + " ║")
786
- print("╚" + "═" * BOX_WIDTH + "╝")
787
-
788
-
789
- # ---------------------------------------------------------------------------
790
- # Action: reset
791
- # ---------------------------------------------------------------------------
792
-
793
- def action_reset(args, bug_list_path, state_dir):
794
- bug_id = args.bug_id
795
- if not bug_id:
796
- error_out("--bug-id is required for 'reset' action")
797
- return
798
-
799
- bs = load_bug_status(state_dir, bug_id)
800
- old_status = get_bug_status_from_list(bug_list_path, bug_id)
801
- old_retry = bs.get("retry_count", 0)
802
-
803
- bs["retry_count"] = 0
804
- bs["infra_error_count"] = 0
805
- bs["last_infra_error_session_id"] = None
806
- bs["sessions"] = []
807
- bs["last_session_id"] = None
808
- bs["resume_from_phase"] = None
809
- reset_continuation_metadata(bs)
810
- bs["updated_at"] = now_iso()
811
-
812
- err = save_bug_status(state_dir, bug_id, bs)
813
- if err:
814
- error_out("Failed to save bug status: {}".format(err))
815
- return
816
-
817
- err = update_bug_in_list(bug_list_path, bug_id, "pending")
818
- if err:
819
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
820
- return
821
-
822
- result = {
823
- "action": "reset",
824
- "bug_id": bug_id,
825
- "old_status": old_status,
826
- "old_retry_count": old_retry,
827
- "new_status": "pending",
828
- }
829
- print(json.dumps(result, indent=2, ensure_ascii=False))
830
-
831
-
832
- # ---------------------------------------------------------------------------
833
- # Action: clean
834
- # ---------------------------------------------------------------------------
835
-
836
- def action_clean(args, bug_list_path, state_dir):
837
- bug_id = args.bug_id
838
- project_root = args.project_root
839
-
840
- if not bug_id:
841
- error_out("--bug-id is required for 'clean' action")
842
- return
843
- if not project_root:
844
- error_out("--project-root is required for 'clean' action")
845
- return
846
-
847
- cleaned = []
848
-
849
- # 1. Delete session history
850
- sessions_dir = os.path.join(state_dir, bug_id, "sessions")
851
- sessions_deleted = 0
852
- if os.path.isdir(sessions_dir):
853
- for entry in os.listdir(sessions_dir):
854
- entry_path = os.path.join(sessions_dir, entry)
855
- if os.path.isdir(entry_path):
856
- shutil.rmtree(entry_path)
857
- sessions_deleted += 1
858
- cleaned.append("Deleted {} session(s) from {}".format(sessions_deleted, sessions_dir))
859
-
860
- # 2. Delete bugfix artifacts for this bug
861
- bugfix_dir = os.path.join(project_root, ".prizmkit", "bugfix", bug_id)
862
- if os.path.isdir(bugfix_dir):
863
- file_count = sum(len(files) for _, _, files in os.walk(bugfix_dir))
864
- shutil.rmtree(bugfix_dir)
865
- cleaned.append("Deleted {} ({} files)".format(bugfix_dir, file_count))
866
-
867
- # 3. Delete shared dev-team workspace
868
- dev_team_dir = os.path.join(project_root, ".dev-team")
869
- if os.path.isdir(dev_team_dir):
870
- file_count = sum(len(files) for _, _, files in os.walk(dev_team_dir))
871
- shutil.rmtree(dev_team_dir)
872
- cleaned.append("Deleted {} ({} files)".format(dev_team_dir, file_count))
873
-
874
- # 4. (removed: current-session.json no longer used)
875
-
876
- # 5. Reset status
877
- bs = load_bug_status(state_dir, bug_id)
878
- old_status = get_bug_status_from_list(bug_list_path, bug_id)
879
- old_retry = bs.get("retry_count", 0)
880
-
881
- continuation_candidates = [
882
- os.path.join(".prizmkit", "bugfix", bug_id, "continuation-summary.md"),
883
- os.path.join(".prizmkit", "specs", bug_id, "continuation-summary.md"),
884
- ]
885
- cleaned.extend(cleanup_continuation_artifacts(project_root, bs, continuation_candidates))
886
-
887
- bs["retry_count"] = 0
888
- bs["infra_error_count"] = 0
889
- bs["last_infra_error_session_id"] = None
890
- bs["sessions"] = []
891
- bs["last_session_id"] = None
892
- bs["resume_from_phase"] = None
893
- reset_continuation_metadata(bs)
894
- bs["updated_at"] = now_iso()
895
-
896
- err = save_bug_status(state_dir, bug_id, bs)
897
- if err:
898
- error_out("Failed to save bug status: {}".format(err))
899
- return
900
-
901
- err = update_bug_in_list(bug_list_path, bug_id, "pending")
902
- if err:
903
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
904
- return
905
-
906
- result = {
907
- "action": "clean",
908
- "bug_id": bug_id,
909
- "old_status": old_status,
910
- "old_retry_count": old_retry,
911
- "new_status": "pending",
912
- "sessions_deleted": sessions_deleted,
913
- "cleaned": cleaned,
914
- }
915
- print(json.dumps(result, indent=2, ensure_ascii=False))
916
-
917
-
918
- # ---------------------------------------------------------------------------
919
- # Action: pause
920
- # ---------------------------------------------------------------------------
921
-
922
- def action_pause(state_dir):
923
- pipeline_path = os.path.join(state_dir, "pipeline.json")
924
- data, err = load_json_file(pipeline_path)
925
- if err:
926
- data = {"status": "paused", "paused_at": now_iso()}
927
- else:
928
- data["status"] = "paused"
929
- data["paused_at"] = now_iso()
930
-
931
- err = write_json_file(pipeline_path, data)
932
- if err:
933
- error_out("Failed to write pipeline.json: {}".format(err))
934
- return
935
-
936
- result = {
937
- "action": "pause",
938
- "status": "paused",
939
- "paused_at": data["paused_at"],
940
- }
941
- print(json.dumps(result, indent=2, ensure_ascii=False))
942
-
943
-
944
- # ---------------------------------------------------------------------------
945
- # Action: start
946
- # ---------------------------------------------------------------------------
947
-
948
- def action_start(args, bug_list_path, state_dir):
949
- """Mark a bug as in_progress when a session starts.
950
-
951
- This keeps bug-fix-list.json/state status in sync during execution,
952
- instead of only updating after session end.
953
- """
954
- bug_id = args.bug_id
955
- if not bug_id:
956
- error_out("--bug-id is required for 'start' action")
957
- return
958
-
959
- bs = load_bug_status(state_dir, bug_id)
960
- old_status = get_bug_status_from_list(bug_list_path, bug_id)
961
-
962
- bs["updated_at"] = now_iso()
963
-
964
- err = save_bug_status(state_dir, bug_id, bs)
965
- if err:
966
- error_out("Failed to save bug status: {}".format(err))
967
- return
968
-
969
- if old_status != "in_progress":
970
- err = update_bug_in_list(bug_list_path, bug_id, "in_progress")
971
- if err:
972
- error_out("Failed to update .prizmkit/plans/bug-fix-list.json: {}".format(err))
973
- return
974
-
975
- result = {
976
- "action": "start",
977
- "bug_id": bug_id,
978
- "old_status": old_status,
979
- "new_status": "in_progress",
980
- "retry_count": bs.get("retry_count", 0),
981
- "infra_error_count": bs.get("infra_error_count", 0),
982
- "updated_at": bs["updated_at"],
983
- }
984
- print(json.dumps(result, indent=2, ensure_ascii=False))
985
-
986
-
987
- # ---------------------------------------------------------------------------
988
- # Action: unskip
989
- # ---------------------------------------------------------------------------
990
-
991
- def action_unskip(args, bug_list_path, state_dir):
992
- """Reset skipped bugs back to pending.
993
-
994
- Two modes:
995
- - --bug-id B-001: Reset the specified skipped bug to pending.
996
- - No --bug-id: Reset ALL skipped bugs to pending.
997
- """
998
- bug_id = args.bug_id
999
-
1000
- data, err = load_json_file(bug_list_path)
1001
- if err:
1002
- error_out("Cannot load bug fix list: {}".format(err))
1003
- return
1004
- bugs = data.get("bugs", [])
1005
-
1006
- to_reset = set()
1007
-
1008
- if bug_id:
1009
- # Find the target bug
1010
- target = None
1011
- for b in bugs:
1012
- if isinstance(b, dict) and b.get("id") == bug_id:
1013
- target = b
1014
- break
1015
- if not target:
1016
- error_out("Bug '{}' not found in .prizmkit/plans/bug-fix-list.json".format(bug_id))
1017
- return
1018
- if target.get("status") not in ("failed", "skipped", "needs_info"):
1019
- error_out(
1020
- "Bug '{}' has status '{}', expected 'failed', 'skipped', or 'needs_info'".format(
1021
- bug_id, target.get("status", "unknown")
1022
- )
1023
- )
1024
- return
1025
- to_reset.add(bug_id)
1026
- else:
1027
- # No bug-id: reset ALL skipped/failed/needs_info bugs
1028
- for b in bugs:
1029
- if isinstance(b, dict) and b.get("id"):
1030
- if b.get("status") in ("failed", "skipped", "needs_info"):
1031
- to_reset.add(b["id"])
1032
-
1033
- if not to_reset:
1034
- error_out("No bugs to unskip")
1035
- return
1036
-
1037
- # Reset all collected bugs in bug-fix-list.json
1038
- reset_details = []
1039
- for b in bugs:
1040
- if isinstance(b, dict) and b.get("id") in to_reset:
1041
- old_status = b.get("status", "unknown")
1042
- b["status"] = "pending"
1043
- reset_details.append({
1044
- "bug_id": b["id"],
1045
- "title": b.get("title", ""),
1046
- "old_status": old_status,
1047
- })
1048
-
1049
- err = write_json_file(bug_list_path, data)
1050
- if err:
1051
- error_out("Failed to write .prizmkit/plans/bug-fix-list.json: {}".format(err))
1052
- return
1053
-
1054
- # Reset runtime fields in status.json for each bug
1055
- for bid in to_reset:
1056
- bs = load_bug_status(state_dir, bid)
1057
- bs["retry_count"] = 0
1058
- bs["infra_error_count"] = 0
1059
- bs["last_infra_error_session_id"] = None
1060
- bs["sessions"] = []
1061
- bs["last_session_id"] = None
1062
- bs["resume_from_phase"] = None
1063
- reset_continuation_metadata(bs)
1064
- bs["updated_at"] = now_iso()
1065
- save_bug_status(state_dir, bid, bs)
1066
-
1067
- result = {
1068
- "action": "unskip",
1069
- "reset_count": len(to_reset),
1070
- "bugs": reset_details,
1071
- }
1072
- print(json.dumps(result, indent=2, ensure_ascii=False))
1073
-
1074
-
1075
- # ---------------------------------------------------------------------------
1076
- # Main
1077
- # ---------------------------------------------------------------------------
1078
-
1079
- def main():
1080
- args = parse_args()
1081
-
1082
- if args.action == "update":
1083
- if not args.bug_id:
1084
- error_out("--bug-id is required for 'update' action")
1085
- if not args.session_status:
1086
- error_out("--session-status is required for 'update' action")
1087
- if args.action in ("start", "reset", "clean", "complete"):
1088
- if not args.bug_id:
1089
- error_out("--bug-id is required for '{}' action".format(args.action))
1090
- if args.action == "clean":
1091
- if not args.project_root:
1092
- error_out("--project-root is required for 'clean' action")
1093
-
1094
- bug_list_data, err = load_json_file(args.bug_list)
1095
- if err:
1096
- error_out("Cannot load bug fix list: {}".format(err))
1097
-
1098
- if args.action == "get_next":
1099
- action_get_next(bug_list_data, args.state_dir)
1100
- elif args.action == "start":
1101
- action_start(args, args.bug_list, args.state_dir)
1102
- elif args.action == "update":
1103
- action_update(args, args.bug_list, args.state_dir)
1104
- elif args.action == "status":
1105
- action_status(bug_list_data, args.state_dir)
1106
- elif args.action == "reset":
1107
- action_reset(args, args.bug_list, args.state_dir)
1108
- elif args.action == "clean":
1109
- action_clean(args, args.bug_list, args.state_dir)
1110
- elif args.action == "pause":
1111
- action_pause(args.state_dir)
1112
- elif args.action == "unskip":
1113
- action_unskip(args, args.bug_list, args.state_dir)
1114
- elif args.action == "complete":
1115
- # Shortcut: 'complete' is equivalent to 'update --session-status success'
1116
- args.session_status = "success"
1117
- action_update(args, args.bug_list, args.state_dir)
1118
-
1119
-
1120
- if __name__ == "__main__":
1121
- main()