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,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()