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,1051 +0,0 @@
1
- . "$PSScriptRoot\common.ps1"
2
- . "$PSScriptRoot\branch.ps1"
3
- $global:PRIZM_EXIT_CODE = 0
4
-
5
- function Invoke-PrizmPipeline {
6
- param(
7
- [ValidateSet('feature','bugfix','refactor')][string]$Kind,
8
- [string]$ScriptRoot,
9
- [string[]]$Args
10
- )
11
-
12
- $paths = Initialize-PrizmPaths $ScriptRoot
13
- Import-PrizmEnv (Join-Path $paths.PrizmkitDir '.env')
14
- Set-Location $paths.ProjectRoot
15
- $python = Resolve-PrizmPython
16
-
17
- $command = if ($Args.Count -gt 0) { $Args[0] } else { 'help' }
18
- $remaining = if ($Args.Count -gt 1) { $Args[1..($Args.Count - 1)] } else { @() }
19
-
20
- $idName = @{ feature = 'feature'; bugfix = 'bug'; refactor = 'refactor' }[$Kind]
21
- $idOption = @{ feature = '--feature-id'; bugfix = '--bug-id'; refactor = '--refactor-id' }[$Kind]
22
- $listOption = @{ feature = '--feature-list'; bugfix = '--bug-list'; refactor = '--refactor-list' }[$Kind]
23
- $initScript = @{ feature = 'init-pipeline.py'; bugfix = 'init-bugfix-pipeline.py'; refactor = 'init-refactor-pipeline.py' }[$Kind]
24
- $updateScript = @{ feature = 'update-feature-status.py'; bugfix = 'update-bug-status.py'; refactor = 'update-refactor-status.py' }[$Kind]
25
- $promptScript = @{ feature = 'generate-bootstrap-prompt.py'; bugfix = 'generate-bugfix-prompt.py'; refactor = 'generate-refactor-prompt.py' }[$Kind]
26
- $defaultList = Get-PrizmListDefault $Kind $paths.ProjectRoot
27
- $stateDir = Get-PrizmStateDir $Kind $paths.ProjectRoot
28
- $envMaxRetryArgs = @()
29
- if ($env:MAX_RETRIES) {
30
- $parsedEnvMaxRetries = 0
31
- if (-not [int]::TryParse($env:MAX_RETRIES, [ref]$parsedEnvMaxRetries) -or $parsedEnvMaxRetries -lt 1) {
32
- throw "MAX_RETRIES must be a positive integer: $($env:MAX_RETRIES)"
33
- }
34
- $envMaxRetryArgs = @('--max-retries', [string]$parsedEnvMaxRetries)
35
- }
36
-
37
- $envMaxInfraRetryArgs = @()
38
- if ($env:MAX_INFRA_RETRIES) {
39
- $parsedEnvMaxInfraRetries = 0
40
- if (-not [int]::TryParse($env:MAX_INFRA_RETRIES, [ref]$parsedEnvMaxInfraRetries) -or $parsedEnvMaxInfraRetries -lt 1) {
41
- throw "MAX_INFRA_RETRIES must be a positive integer: $($env:MAX_INFRA_RETRIES)"
42
- }
43
- $envMaxInfraRetryArgs = @('--max-infra-retries', [string]$parsedEnvMaxInfraRetries)
44
- }
45
-
46
- if ($command -in @('help','--help','-h')) {
47
- Write-Host "Usage: .\run-$Kind.ps1 run [item-id] [list-path] [--dry-run] [--mode lite|standard|full] [--critic] [--max-retries N] [--max-infra-retries N]"
48
- Write-Host " .\run-$Kind.ps1 status [list-path]"
49
- Write-Host " .\run-$Kind.ps1 reset"
50
- Write-Host ""
51
- Write-Host "Environment Variables:"
52
- Write-Host " PRIZMKIT_EFFORT AI reasoning effort (low|medium|high|xhigh|max; max is Claude Code only)"
53
- Write-Host " MAX_LOG_SIZE Include passive log-size checkpoint guidance above this threshold (default: 2097152 = 2MB, set 0 to disable)"
54
- $global:PRIZM_EXIT_CODE = 0
55
- return
56
- }
57
-
58
- if ($command -eq 'reset') {
59
- if (Test-Path $stateDir) { Remove-Item -Recurse -Force $stateDir }
60
- New-Item -ItemType Directory -Force -Path $stateDir | Out-Null
61
- Write-PrizmSuccess "State reset: $stateDir"
62
- $global:PRIZM_EXIT_CODE = 0
63
- return
64
- }
65
-
66
- if ($command -eq 'status') {
67
- $listPath = if ($remaining.Count -gt 0) { $remaining[0] } else { $defaultList }
68
- Invoke-PrizmPythonText $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'status') + $envMaxRetryArgs + $envMaxInfraRetryArgs)
69
- $global:PRIZM_EXIT_CODE = $LASTEXITCODE
70
- return
71
- }
72
-
73
- if ($command -ne 'run') { throw "Unknown command: $command" }
74
-
75
- $itemId = $null
76
- $listPath = $defaultList
77
- $dryRun = $false
78
- $mode = $null
79
- if ($env:PIPELINE_MODE) { $mode = $env:PIPELINE_MODE.Trim() }
80
- $critic = $null
81
- $criticEnv = if ($env:ENABLE_CRITIC) { $env:ENABLE_CRITIC.Trim().ToLowerInvariant() } else { '' }
82
- if ($criticEnv -in @('true','1','yes','on')) {
83
- $critic = 'true'
84
- } elseif ($criticEnv -in @('false','0','no','off')) {
85
- $critic = 'false'
86
- } elseif ($criticEnv) {
87
- Write-PrizmWarn "Ignoring unsupported ENABLE_CRITIC value: $($env:ENABLE_CRITIC)"
88
- }
89
- $maxRetries = $null
90
- if ($envMaxRetryArgs.Count -gt 0) { $maxRetries = [int]$envMaxRetryArgs[1] }
91
- $maxInfraRetries = $null
92
- if ($envMaxInfraRetryArgs.Count -gt 0) { $maxInfraRetries = [int]$envMaxInfraRetryArgs[1] }
93
- $verboseEnabled = $env:VERBOSE -in @('1','true','yes','on')
94
- $heartbeatInterval = 30
95
- if ($env:HEARTBEAT_INTERVAL) {
96
- $parsedHeartbeatInterval = 0
97
- if (-not [int]::TryParse($env:HEARTBEAT_INTERVAL, [ref]$parsedHeartbeatInterval) -or $parsedHeartbeatInterval -lt 1) {
98
- throw "HEARTBEAT_INTERVAL must be a positive integer: $($env:HEARTBEAT_INTERVAL)"
99
- }
100
- $heartbeatInterval = $parsedHeartbeatInterval
101
- }
102
- $staleKillThreshold = 900
103
- if ($env:STALE_KILL_THRESHOLD) {
104
- $parsedStaleKillThreshold = 0
105
- if (-not [int]::TryParse($env:STALE_KILL_THRESHOLD, [ref]$parsedStaleKillThreshold) -or $parsedStaleKillThreshold -lt 0) {
106
- throw "STALE_KILL_THRESHOLD must be a non-negative integer: $($env:STALE_KILL_THRESHOLD)"
107
- }
108
- $staleKillThreshold = $parsedStaleKillThreshold
109
- }
110
- $staleKillGraceSeconds = 10
111
- if ($env:STALE_KILL_GRACE_SECONDS) {
112
- $parsedStaleKillGraceSeconds = 0
113
- if (-not [int]::TryParse($env:STALE_KILL_GRACE_SECONDS, [ref]$parsedStaleKillGraceSeconds) -or $parsedStaleKillGraceSeconds -lt 0) {
114
- throw "STALE_KILL_GRACE_SECONDS must be a non-negative integer: $($env:STALE_KILL_GRACE_SECONDS)"
115
- }
116
- $staleKillGraceSeconds = $parsedStaleKillGraceSeconds
117
- }
118
- $autoPush = $env:AUTO_PUSH -in @('1','true','yes','on')
119
- $enableDeploy = $env:ENABLE_DEPLOY -in @('1','true','yes','on')
120
- $stopOnFailure = $env:STOP_ON_FAILURE -in @('1','true','yes','on')
121
- $devBranchOverride = if ($env:DEV_BRANCH) { $env:DEV_BRANCH.Trim() } else { '' }
122
- $featuresFilter = $null
123
-
124
- for ($i = 0; $i -lt $remaining.Count; $i++) {
125
- $arg = $remaining[$i]
126
- switch -Regex ($arg) {
127
- '^--dry-run$' { $dryRun = $true; continue }
128
- '^--critic$' { $critic = 'true'; continue }
129
- '^--no-critic$' { $critic = 'false'; continue }
130
- '^--mode$' { $i++; $mode = $remaining[$i]; continue }
131
- '^--max-retries$' {
132
- $i++
133
- $parsedMaxRetries = 0
134
- if (-not [int]::TryParse($remaining[$i], [ref]$parsedMaxRetries) -or $parsedMaxRetries -lt 1) {
135
- throw "--max-retries must be a positive integer: $($remaining[$i])"
136
- }
137
- $maxRetries = $parsedMaxRetries
138
- continue
139
- }
140
- '^--max-infra-retries$' {
141
- $i++
142
- $parsedMaxInfraRetries = 0
143
- if (-not [int]::TryParse($remaining[$i], [ref]$parsedMaxInfraRetries) -or $parsedMaxInfraRetries -lt 1) {
144
- throw "--max-infra-retries must be a positive integer: $($remaining[$i])"
145
- }
146
- $maxInfraRetries = $parsedMaxInfraRetries
147
- continue
148
- }
149
- '^--features$' { $i++; $featuresFilter = $remaining[$i]; continue }
150
- '^-' { Write-PrizmWarn "Ignoring unsupported option: $arg"; continue }
151
- default {
152
- if (-not $itemId -and $arg -match '^[FBR]-\d+') { $itemId = $arg; continue }
153
- $listPath = $arg
154
- }
155
- }
156
- }
157
-
158
- if ($mode -and $mode -notin @('lite','standard','full')) {
159
- throw "PIPELINE_MODE/--mode must be one of: lite, standard, full. Got: $mode"
160
- }
161
- $maxRetryArgs = @()
162
- if ($maxRetries -ne $null) { $maxRetryArgs = @('--max-retries', [string]$maxRetries) }
163
- $maxInfraRetryArgs = @()
164
- if ($maxInfraRetries -ne $null) { $maxInfraRetryArgs = @('--max-infra-retries', [string]$maxInfraRetries) }
165
- if ($verboseEnabled) {
166
- $modeLabel = if ($mode) { $mode } else { 'auto' }
167
- $criticLabel = if ($critic) { $critic } else { 'plan-default' }
168
- $retryLabel = if ($maxRetries -ne $null) { [string]$maxRetries } else { 'default' }
169
- $infraRetryLabel = if ($maxInfraRetries -ne $null) { [string]$maxInfraRetries } else { 'default' }
170
- Write-PrizmInfo "Verbose mode enabled."
171
- Write-PrizmInfo "Effective options: mode=$modeLabel critic=$criticLabel maxRetries=$retryLabel maxInfraRetries=$infraRetryLabel staleKillThreshold=$staleKillThreshold dryRun=$dryRun"
172
- }
173
-
174
- # Validate PRIZMKIT_EFFORT early (fail-fast before any sessions are spawned)
175
- $cli = Resolve-PrizmAiCli $paths.ProjectRoot $paths.PrizmkitDir
176
- Test-PrizmEffort $cli
177
-
178
- if (-not (Test-Path $listPath)) { throw "List file not found: $listPath" }
179
- $pipelineStatePath = Join-Path $stateDir 'pipeline.json'
180
- if (-not $dryRun) {
181
- New-Item -ItemType Directory -Force -Path $stateDir | Out-Null
182
- if (-not (Test-Path $pipelineStatePath)) {
183
- Invoke-PrizmPythonText $python @((Join-Path $paths.ScriptsDir $initScript), $listOption, $listPath, '--state-dir', $stateDir)
184
- } else {
185
- Write-PrizmInfo "Using existing pipeline state: $pipelineStatePath"
186
- }
187
- } elseif (-not (Test-Path $pipelineStatePath)) {
188
- Write-PrizmInfo "Dry-run mode: not initializing pipeline state."
189
- }
190
-
191
- function Test-PrizmGitRepository {
192
- param([string]$ProjectRoot)
193
- & git -C $ProjectRoot rev-parse --is-inside-work-tree *> $null
194
- return $LASTEXITCODE -eq 0
195
- }
196
-
197
- function Get-PrizmGitHead {
198
- param([string]$ProjectRoot)
199
- $head = & git -C $ProjectRoot rev-parse HEAD 2>$null
200
- if ($LASTEXITCODE -eq 0 -and $head) { return ($head | Select-Object -First 1) }
201
- return ''
202
- }
203
-
204
- function Test-PrizmGitCommitsSince {
205
- param([string]$ProjectRoot, [string]$BaseCommit)
206
- if (-not $BaseCommit) {
207
- return -not [string]::IsNullOrWhiteSpace([string](Get-PrizmGitHead $ProjectRoot))
208
- }
209
- $commit = & git -C $ProjectRoot log "$BaseCommit..HEAD" --oneline 2>$null | Select-Object -First 1
210
- return -not [string]::IsNullOrWhiteSpace([string]$commit)
211
- }
212
-
213
- function ConvertTo-PrizmGitRelativePath {
214
- param([string]$ProjectRoot, [string]$Path)
215
- if (-not $Path) { return '' }
216
- try {
217
- $rootFull = [System.IO.Path]::GetFullPath($ProjectRoot).TrimEnd([char[]]@('\', '/')) + [System.IO.Path]::DirectorySeparatorChar
218
- $pathInput = if ([System.IO.Path]::IsPathRooted($Path)) { $Path } else { Join-Path $ProjectRoot $Path }
219
- $pathFull = [System.IO.Path]::GetFullPath($pathInput)
220
- $rootUri = [System.Uri]::new($rootFull)
221
- $pathUri = [System.Uri]::new($pathFull)
222
- return ([System.Uri]::UnescapeDataString($rootUri.MakeRelativeUri($pathUri).ToString()) -replace '\\', '/').TrimStart([char[]]@('.', '/'))
223
- } catch {
224
- return ($Path -replace '\\', '/').TrimStart([char[]]@('.', '/'))
225
- }
226
- }
227
-
228
- function Get-PrizmGitDirtyPaths {
229
- param([string]$ProjectRoot)
230
- $hiddenToolWorktreeExcludes = Get-PrizmHiddenToolWorktreeExcludes
231
- $lines = & git -C $ProjectRoot status --porcelain -- . @hiddenToolWorktreeExcludes 2>$null
232
- $paths = @()
233
- foreach ($line in $lines) {
234
- if ([string]::IsNullOrWhiteSpace($line) -or $line.Length -lt 4) { continue }
235
- $path = $line.Substring(3).Trim()
236
- if ($path -match ' -> ') { $path = ($path -split ' -> ')[-1].Trim() }
237
- $paths += (($path -replace '\\', '/').Trim('"').TrimStart([char[]]@('/')))
238
- }
239
- return @($paths)
240
- }
241
-
242
- function Test-PrizmPipelineIgnoredPath {
243
- param([string]$Path)
244
- $normalizedPath = (($Path -replace '\\', '/').Trim('"').TrimStart([char[]]@('/')))
245
- $segments = @($normalizedPath -split '/' | Where-Object { -not [string]::IsNullOrWhiteSpace($_) })
246
- if ($segments.Count -lt 2) { return $false }
247
- if (-not $segments[0].StartsWith('.')) { return $false }
248
- return $segments[1] -in @('worktree', 'worktrees')
249
- }
250
-
251
- function Test-PrizmPipelineBookkeepingPath {
252
- param(
253
- [string]$ProjectRoot,
254
- [string]$Path,
255
- [string]$StateDir,
256
- [string]$ListPath
257
- )
258
- $normalizedPath = (($Path -replace '\\', '/').Trim('"').TrimStart([char[]]@('.', '/')))
259
- $stateRel = ConvertTo-PrizmGitRelativePath $ProjectRoot $StateDir
260
- $listRel = ConvertTo-PrizmGitRelativePath $ProjectRoot $ListPath
261
- if ($stateRel -and ($normalizedPath -eq $stateRel -or $normalizedPath.StartsWith("$stateRel/"))) { return $true }
262
- if ($listRel -and $normalizedPath -eq $listRel) { return $true }
263
- return $false
264
- }
265
-
266
- function Test-PrizmGitWorkDirty {
267
- param([string]$ProjectRoot, [string]$StateDir, [string]$ListPath)
268
- foreach ($path in (Get-PrizmGitDirtyPaths $ProjectRoot)) {
269
- if (Test-PrizmPipelineIgnoredPath $path) { continue }
270
- if (-not (Test-PrizmPipelineBookkeepingPath $ProjectRoot $path $StateDir $ListPath)) {
271
- return $true
272
- }
273
- }
274
- return $false
275
- }
276
-
277
- function Test-PrizmGitDirty {
278
- param([string]$ProjectRoot)
279
- $hiddenToolWorktreeExcludes = Get-PrizmHiddenToolWorktreeExcludes
280
- $dirty = & git -C $ProjectRoot status --porcelain -- . @hiddenToolWorktreeExcludes 2>$null | Select-Object -First 1
281
- return -not [string]::IsNullOrWhiteSpace([string]$dirty)
282
- }
283
-
284
- function Stop-PrizmSessionProcess {
285
- param([string]$PidPath)
286
- if (-not (Test-Path $PidPath)) { return }
287
- $rawPid = Get-Content $PidPath -ErrorAction SilentlyContinue | Select-Object -First 1
288
- $aiPid = 0
289
- if ([int]::TryParse($rawPid, [ref]$aiPid)) {
290
- Stop-PrizmProcessTreeById -ProcessId $aiPid
291
- }
292
- }
293
-
294
- function Write-PrizmStaleKillMarker {
295
- param([string]$MarkerPath, [int]$StaleSeconds, [int]$Threshold)
296
- $markerDir = Split-Path $MarkerPath -Parent
297
- if ($markerDir) { New-Item -ItemType Directory -Force -Path $markerDir | Out-Null }
298
- [ordered]@{
299
- killed_at = (Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ')
300
- reason = 'stale_session'
301
- stale_seconds = $StaleSeconds
302
- threshold = $Threshold
303
- } | ConvertTo-Json -Compress | Set-Content -Path $MarkerPath -Encoding UTF8
304
- }
305
-
306
- function Invoke-PrizmGitAutoCommit {
307
- param([string]$ProjectRoot, [string]$Message)
308
- $hiddenToolWorktreeExcludes = Get-PrizmHiddenToolWorktreeExcludes
309
- & git -C $ProjectRoot add -A -- . @hiddenToolWorktreeExcludes *> $null
310
- & git -C $ProjectRoot commit --no-verify -m $Message *> $null
311
- return $LASTEXITCODE -eq 0
312
- }
313
-
314
- function Invoke-PrizmGitIncludeRemainingArtifacts {
315
- param([string]$ProjectRoot, [string]$ItemId)
316
- $hiddenToolWorktreeExcludes = Get-PrizmHiddenToolWorktreeExcludes
317
- & git -C $ProjectRoot add -A -- . @hiddenToolWorktreeExcludes *> $null
318
- & git -C $ProjectRoot commit --no-verify --amend --no-edit *> $null
319
- if ($LASTEXITCODE -eq 0) { return }
320
- & git -C $ProjectRoot commit --no-verify -m "chore($ItemId): include remaining session artifacts" *> $null
321
- }
322
-
323
- function Invoke-PrizmGitIncludeBookkeepingArtifacts {
324
- param([string]$ProjectRoot, [string]$StateDir, [string]$ListPath)
325
- $listRel = ConvertTo-PrizmGitRelativePath $ProjectRoot $ListPath
326
- if (-not $listRel) { return }
327
- & git -C $ProjectRoot ls-files --error-unmatch -- $listRel *> $null
328
- if ($LASTEXITCODE -ne 0) { return }
329
- & git -C $ProjectRoot commit --no-verify --amend --no-edit --only -- $listRel *> $null
330
- }
331
-
332
- function Invoke-PrizmGitCommitPath {
333
- param([string]$ProjectRoot, [string]$Path, [string]$Message)
334
- if (-not $Path) { return $false }
335
- $relPath = ConvertTo-PrizmGitRelativePath $ProjectRoot $Path
336
- if (-not $relPath) { return $false }
337
- & git -C $ProjectRoot diff --quiet -- $relPath 2>$null
338
- if ($LASTEXITCODE -eq 0) { return $false }
339
- & git -C $ProjectRoot add -- $relPath *> $null
340
- if ($LASTEXITCODE -ne 0) { return $false }
341
- & git -C $ProjectRoot commit --no-verify -m $Message *> $null
342
- return $LASTEXITCODE -eq 0
343
- }
344
-
345
- function Get-PrizmFeatureSlugFromList {
346
- param([string]$ListPath, [string]$FeatureId)
347
- if (-not (Test-Path $ListPath)) { return '' }
348
- try { $data = Get-Content $ListPath -Raw | ConvertFrom-Json } catch { return '' }
349
- foreach ($feature in @($data.features)) {
350
- if ($feature.id -eq $FeatureId) {
351
- $number = ([string]$feature.id).Replace('F-', '').Replace('f-', '').PadLeft(3, '0')
352
- $title = ([string]$feature.title).ToLowerInvariant()
353
- $title = [regex]::Replace($title, '[^a-z0-9\s-]', '')
354
- $title = [regex]::Replace($title.Trim(), '[\s]+', '-')
355
- $title = [regex]::Replace($title, '-+', '-').Trim('-')
356
- if ($title) { return "$number-$title" }
357
- return $number
358
- }
359
- }
360
- return ''
361
- }
362
-
363
- function Test-PrizmCheckpointComplete {
364
- param([string]$CheckpointPath)
365
- if (-not (Test-Path $CheckpointPath)) { return $false }
366
- try { $checkpoint = Get-Content $CheckpointPath -Raw | ConvertFrom-Json } catch { return $false }
367
- if (-not $checkpoint.steps) { return $false }
368
- foreach ($step in @($checkpoint.steps)) {
369
- if ($step.status -notin @('completed', 'skipped')) { return $false }
370
- }
371
- return $true
372
- }
373
-
374
- function Get-PrizmFeatureTitleFromList {
375
- param([string]$ListPath, [string]$FeatureId)
376
- if (-not (Test-Path $ListPath)) { return '' }
377
- try { $data = Get-Content $ListPath -Raw | ConvertFrom-Json } catch { return '' }
378
- foreach ($feature in @($data.features)) {
379
- if ($feature.id -eq $FeatureId) { return [string]$feature.title }
380
- }
381
- return ''
382
- }
383
-
384
- function Get-PrizmTitleWords {
385
- param([string]$Text)
386
- $matches = [regex]::Matches(([string]$Text).ToLowerInvariant(), '[a-z0-9]{3,}')
387
- $words = @()
388
- foreach ($match in $matches) { $words += [string]$match.Value }
389
- return @($words)
390
- }
391
-
392
- function Test-PrizmCommitMatchesFeatureTitle {
393
- param([string]$Subject, [string]$FeatureTitle)
394
- $titleWords = @(Get-PrizmTitleWords $FeatureTitle)
395
- if ($titleWords.Count -eq 0) { return $false }
396
- $subjectWords = @(Get-PrizmTitleWords $Subject)
397
- $subjectSet = @{}
398
- foreach ($word in $subjectWords) { $subjectSet[$word] = $true }
399
- $required = if ($titleWords.Count -le 3) { $titleWords.Count } else { [Math]::Max(3, [int][Math]::Ceiling($titleWords.Count * 0.75)) }
400
- $matched = 0
401
- foreach ($word in $titleWords) {
402
- if ($subjectSet.ContainsKey($word)) { $matched++ }
403
- }
404
- return $matched -ge $required
405
- }
406
-
407
- function Get-PrizmFeatureCommit {
408
- param([string]$ProjectRoot, [string]$BaseCommit, [string]$FeatureId, [bool]$AllowFallback = $false, [string]$FeatureTitle = '')
409
- $range = if ($BaseCommit) { "$BaseCommit..HEAD" } else { 'HEAD' }
410
- $lines = & git -C $ProjectRoot log $range '--format=%H%x09%s' 2>$null
411
- if ($LASTEXITCODE -ne 0) { return '' }
412
- foreach ($line in @($lines)) {
413
- $parts = ([string]$line).Split("`t", 2)
414
- if ($parts.Count -lt 2) { continue }
415
- $subject = $parts[1]
416
- if ($subject.Contains($FeatureId) -and $subject -notmatch '^wip(\(|:)') { return $parts[0] }
417
- }
418
- if ($AllowFallback -and $FeatureTitle) {
419
- foreach ($line in @($lines)) {
420
- $parts = ([string]$line).Split("`t", 2)
421
- if ($parts.Count -lt 2) { continue }
422
- $subject = $parts[1]
423
- if ($subject -notmatch '^wip(\(|:)' -and (Test-PrizmCommitMatchesFeatureTitle $subject $FeatureTitle)) { return $parts[0] }
424
- }
425
- }
426
- return ''
427
- }
428
-
429
- function Get-PrizmFeatureSemanticCompletion {
430
- param([string]$ProjectRoot, [string]$ListPath, [string]$FeatureId, [string]$BaseCommit, [string]$PrizmkitDir)
431
- $slug = Get-PrizmFeatureSlugFromList $ListPath $FeatureId
432
- if (-not $slug) { return $null }
433
- $checkpointPath = Join-Path $PrizmkitDir "specs\$slug\workflow-checkpoint.json"
434
- if (-not (Test-PrizmCheckpointComplete $checkpointPath)) { return $null }
435
- $featureTitle = Get-PrizmFeatureTitleFromList $ListPath $FeatureId
436
- $commitSha = Get-PrizmFeatureCommit $ProjectRoot $BaseCommit $FeatureId $true $featureTitle
437
- if (-not $commitSha) { return $null }
438
- return [pscustomobject]@{ Slug = $slug; CommitSha = $commitSha; CheckpointPath = $checkpointPath }
439
- }
440
-
441
- function Write-PrizmRuntimeFailureLog {
442
- param(
443
- [string]$FailureLog,
444
- [string]$FeatureId,
445
- [string]$SessionId,
446
- [string]$SessionStatus,
447
- [int]$ExitCode,
448
- [string]$StaleKillMarker,
449
- [string]$ProgressJson,
450
- [string]$CheckpointPath,
451
- [string]$ProjectRoot,
452
- [string]$BaseCommit
453
- )
454
- if (-not $FailureLog -or (Test-Path $FailureLog)) { return }
455
- $dir = Split-Path $FailureLog -Parent
456
- if ($dir) { New-Item -ItemType Directory -Force -Path $dir | Out-Null }
457
- $stale = if (Test-Path $StaleKillMarker) { Get-Content $StaleKillMarker -Raw } else { 'No stale-kill marker.' }
458
- $progressLines = @('Progress data unavailable.')
459
- if (Test-Path $ProgressJson) {
460
- try {
461
- $progress = Get-Content $ProgressJson -Raw | ConvertFrom-Json
462
- $progressLines = @()
463
- foreach ($key in @('fatal_error_code','api_error_status','api_error_code','current_phase','current_tool','last_text_snippet','terminal_result_text')) {
464
- if ($progress.PSObject.Properties[$key] -and $progress.$key) { $progressLines += "- ${key}: $($progress.$key)" }
465
- }
466
- if ($progressLines.Count -eq 0) { $progressLines = @('Progress data contained no terminal fields.') }
467
- } catch { $progressLines = @("Progress parse error: $($_.Exception.Message)") }
468
- }
469
- $checkpointLines = @('No checkpoint file found.')
470
- if (Test-Path $CheckpointPath) {
471
- try {
472
- $checkpoint = Get-Content $CheckpointPath -Raw | ConvertFrom-Json
473
- $steps = @($checkpoint.steps)
474
- $complete = @($steps | Where-Object { $_.status -in @('completed','skipped') }).Count
475
- $checkpointLines = @("$complete/$($steps.Count) steps completed_or_skipped")
476
- foreach ($step in $steps) {
477
- if ($step.status -notin @('completed','skipped')) { $checkpointLines += "- incomplete: $($step.id) $($step.skill) = $($step.status)" }
478
- }
479
- } catch { $checkpointLines = @("Checkpoint parse error: $($_.Exception.Message)") }
480
- }
481
- $latestCommit = (& git -C $ProjectRoot rev-parse --short HEAD 2>$null | Select-Object -First 1)
482
- if (-not $latestCommit) { $latestCommit = 'unavailable' }
483
- $featureCommit = if (Get-PrizmFeatureCommit $ProjectRoot $BaseCommit $FeatureId $false) { 'yes' } else { 'no' }
484
- $dirty = & git -C $ProjectRoot status --short 2>$null
485
- if ([string]::IsNullOrWhiteSpace(($dirty -join "`n"))) { $dirty = @('clean') }
486
- @(
487
- '# Runtime-synthesized failure log',
488
- '',
489
- '## Session',
490
- '',
491
- "- feature_id: $FeatureId",
492
- "- session_id: $SessionId",
493
- "- session_status: $SessionStatus",
494
- "- exit_code: $ExitCode",
495
- '',
496
- '## Stale kill marker',
497
- '',
498
- '```json',
499
- $stale,
500
- '```',
501
- '',
502
- '## Progress',
503
- '',
504
- $progressLines,
505
- '',
506
- '## Checkpoint',
507
- '',
508
- $checkpointLines,
509
- '',
510
- '## Git state',
511
- '',
512
- "- feature_commit_exists: $featureCommit",
513
- "- latest_commit: $latestCommit",
514
- '',
515
- '```text',
516
- $dirty,
517
- '```',
518
- '',
519
- '## Recommended recovery action',
520
- '',
521
- '- If this is an AI runtime/provider error before checkpoint completion, retry the session with a fresh context.',
522
- '- If the working tree is dirty, preserve or review those changes before any reset or merge.'
523
- ) | Set-Content -Path $FailureLog -Encoding UTF8
524
- }
525
-
526
- function New-PrizmDefaultDevBranchName {
527
- param([string]$Kind, [string]$CurrentItemId)
528
- $timestamp = Get-Date -Format 'yyyyMMddHHmm'
529
- switch ($Kind) {
530
- 'feature' { return "dev/$CurrentItemId-$timestamp" }
531
- 'bugfix' { return "bugfix/$CurrentItemId-$timestamp" }
532
- 'refactor' { return "refactor/$CurrentItemId-$timestamp" }
533
- default { return "dev/$CurrentItemId-$timestamp" }
534
- }
535
- }
536
-
537
- function Get-PrizmDeployIncompleteItems {
538
- param([string]$Kind, [string]$ListPath)
539
-
540
- if (-not (Test-Path $ListPath)) { return @("List file not found: $ListPath") }
541
- try {
542
- $data = Get-Content -Raw $ListPath | ConvertFrom-Json
543
- } catch {
544
- return @("List file is not valid JSON: $ListPath")
545
- }
546
-
547
- $collectionName = @{ feature = 'features'; bugfix = 'bugs'; refactor = 'refactors' }[$Kind]
548
- $allowedStatuses = @{
549
- feature = @('completed', 'skipped')
550
- bugfix = @('completed', 'skipped', 'needs_info')
551
- refactor = @('completed', 'skipped')
552
- }[$Kind]
553
-
554
- $items = @()
555
- $property = $data.PSObject.Properties[$collectionName]
556
- if ($property -and $property.Value) { $items = @($property.Value) }
557
-
558
- $bad = @()
559
- foreach ($item in $items) {
560
- $status = if ($item.PSObject.Properties['status']) { [string]$item.status } else { 'unknown' }
561
- if ($status -notin $allowedStatuses) {
562
- $itemIdText = if ($item.PSObject.Properties['id']) { [string]$item.id } else { 'unknown' }
563
- $titleText = if ($item.PSObject.Properties['title']) { [string]$item.title } else { '' }
564
- $bad += " ${itemIdText}: $status - $titleText"
565
- }
566
- }
567
- return @($bad)
568
- }
569
-
570
- function Invoke-PrizmDeploySession {
571
- param([string]$Kind, [string]$ListPath)
572
-
573
- if (-not $enableDeploy) { return 0 }
574
-
575
- $incomplete = @(Get-PrizmDeployIncompleteItems $Kind $ListPath)
576
- if ($incomplete.Count -gt 0) {
577
- Write-PrizmWarn "DEPLOY BLOCKED: $($incomplete.Count) task(s) not completed successfully."
578
- foreach ($line in $incomplete) { Write-PrizmWarn $line }
579
- Write-PrizmWarn "Fix failed tasks and re-run, or manually run /prizmkit-deploy."
580
- return 1
581
- }
582
-
583
- Write-PrizmInfo "All tasks completed - starting deploy session..."
584
- Write-PrizmInfo "ENABLE_DEPLOY=1"
585
-
586
- $deploySessionId = "deploy-$(Get-Date -Format 'yyyyMMddHHmmss')"
587
- $deploySessionDir = Join-Path $stateDir "deploy\$deploySessionId"
588
- $deployLogsDir = Join-Path $deploySessionDir 'logs'
589
- New-Item -ItemType Directory -Force -Path $deployLogsDir | Out-Null
590
-
591
- $deployPrompt = Join-Path $deploySessionDir 'bootstrap-prompt.md'
592
- $deployLog = Join-Path $deployLogsDir 'session.log'
593
- $deployPidPath = Join-Path $deployLogsDir 'ai.pid'
594
- $deployBranch = Get-PrizmCurrentBranch $paths.ProjectRoot
595
- if (-not $deployBranch) { $deployBranch = 'unknown' }
596
- $deployCommit = & git -C $paths.ProjectRoot rev-parse --short HEAD 2>$null
597
- if ($LASTEXITCODE -ne 0 -or -not $deployCommit) { $deployCommit = 'unknown' }
598
- $deployCommit = [string]($deployCommit | Select-Object -First 1)
599
-
600
- @(
601
- '## Deploy',
602
- '',
603
- "All $Kind tasks in the pipeline completed successfully.",
604
- '',
605
- "- Branch: $deployBranch",
606
- "- Commit: $deployCommit",
607
- '',
608
- 'Run /prizmkit-deploy to deploy the project. Read .prizmkit/deploy/deploy.config.json',
609
- 'for deployment configuration. If no deploy config exists, guide the user through',
610
- 'setting one up before deploying.'
611
- ) | Set-Content -Path $deployPrompt -Encoding UTF8
612
-
613
- Write-PrizmInfo "Deploy prompt: $deployPrompt"
614
- Write-PrizmInfo "Deploy log: $deployLog"
615
-
616
- $cli = Resolve-PrizmAiCli $paths.ProjectRoot $paths.PrizmkitDir
617
- $env:PRIZMKIT_PLATFORM = Get-PrizmPlatformFromProject $paths.ProjectRoot $paths.PrizmkitDir $cli
618
- $exitCode = Invoke-PrizmAiSession -CliCommand $cli -PromptPath $deployPrompt -LogPath $deployLog -ProjectRoot $paths.ProjectRoot -Model $env:MODEL -PidPath $deployPidPath
619
- if ($exitCode -eq 0) {
620
- Write-PrizmSuccess "Deploy session completed"
621
- } else {
622
- Write-PrizmWarn "Deploy session failed with exit code $exitCode"
623
- }
624
- return $exitCode
625
- }
626
-
627
- function Invoke-PrizmPipelineItem {
628
- param(
629
- [string]$CurrentItemId,
630
- [object]$ContinuationState = $null
631
- )
632
- $script:PRIZM_ITEM_EXIT_CODE = 0
633
-
634
- $sessionId = New-PrizmSessionId $Kind
635
- $runId = "run-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
636
- $retryCount = '0'
637
- $resumePhase = 'null'
638
- $isGitRepository = if (-not $dryRun) { Test-PrizmGitRepository $paths.ProjectRoot } else { $false }
639
- $originalBranch = if ($isGitRepository) { Get-PrizmCurrentBranch $paths.ProjectRoot } else { '' }
640
- $devBranchName = ''
641
- $activeDevBranch = ''
642
- $continuationPending = $false
643
- $continuationReason = ''
644
- $contextOverflowCount = 0
645
- $continuationCount = 0
646
- $previousSessionId = ''
647
- $noProgressCount = 0
648
- if ($ContinuationState) {
649
- if ($ContinuationState.PSObject.Properties['active_dev_branch'] -and $ContinuationState.active_dev_branch) { $activeDevBranch = [string]$ContinuationState.active_dev_branch }
650
- if ($ContinuationState.PSObject.Properties['base_branch'] -and $ContinuationState.base_branch) { $originalBranch = [string]$ContinuationState.base_branch }
651
- if ($ContinuationState.PSObject.Properties['continuation_pending']) { $continuationPending = [bool]$ContinuationState.continuation_pending }
652
- if ($ContinuationState.PSObject.Properties['continuation_reason'] -and $ContinuationState.continuation_reason) { $continuationReason = [string]$ContinuationState.continuation_reason }
653
- if ($ContinuationState.PSObject.Properties['context_overflow_count'] -and $ContinuationState.context_overflow_count -ne $null) { $contextOverflowCount = [int]$ContinuationState.context_overflow_count }
654
- if ($ContinuationState.PSObject.Properties['continuation_count'] -and $ContinuationState.continuation_count -ne $null) { $continuationCount = [int]$ContinuationState.continuation_count }
655
- if ($ContinuationState.PSObject.Properties['last_context_overflow_session_id'] -and $ContinuationState.last_context_overflow_session_id) { $previousSessionId = [string]$ContinuationState.last_context_overflow_session_id }
656
- if ($ContinuationState.PSObject.Properties['no_progress_count'] -and $ContinuationState.no_progress_count -ne $null) { $noProgressCount = [int]$ContinuationState.no_progress_count }
657
- }
658
- if ($continuationPending -and $activeDevBranch) {
659
- Write-PrizmInfo "Continuation pending ($continuationReason); reusing dev branch: $activeDevBranch"
660
- Write-PrizmInfo "Continuation count: $continuationCount (context overflows: $contextOverflowCount)"
661
- }
662
- $hadDirtyBaseline = if ($isGitRepository) { Test-PrizmGitWorkDirty $paths.ProjectRoot $stateDir $listPath } else { $false }
663
- if ($hadDirtyBaseline) {
664
- if ($dryRun) {
665
- Write-PrizmWarn "Dirty working tree detected before $CurrentItemId; would auto-commit snapshot in real run."
666
- } else {
667
- Write-PrizmInfo "Dirty working tree detected before $CurrentItemId; auto-committing snapshot."
668
- Invoke-PrizmGitAutoCommit $paths.ProjectRoot "chore: workspace snapshot ready for run $CurrentItemId" | Out-Null
669
- }
670
- }
671
-
672
- if ($dryRun) {
673
- $statusPath = Join-Path $stateDir "$CurrentItemId\status.json"
674
- if (Test-Path $statusPath) {
675
- try {
676
- $itemStatus = Get-Content -Raw $statusPath | ConvertFrom-Json
677
- if ($itemStatus.retry_count -ne $null) { $retryCount = [string]$itemStatus.retry_count }
678
- if ($itemStatus.resume_from_phase -ne $null) { $resumePhase = [string]$itemStatus.resume_from_phase }
679
- } catch {
680
- Write-PrizmWarn "Could not read dry-run status file: $statusPath"
681
- }
682
- }
683
- } else {
684
- $start = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'start', $idOption, $CurrentItemId, '--session-id', $sessionId) + $maxRetryArgs + $maxInfraRetryArgs)
685
- if ($start.retry_count -ne $null) { $retryCount = [string]$start.retry_count }
686
- if ($start.resume_from_phase -ne $null) { $resumePhase = [string]$start.resume_from_phase }
687
-
688
- if ($isGitRepository -and $originalBranch) {
689
- Invoke-PrizmGitCommitPath $paths.ProjectRoot $listPath "chore($CurrentItemId): mark in_progress" | Out-Null
690
- $candidateBranch = if ($devBranchOverride) { $devBranchOverride } elseif ($continuationPending -and $activeDevBranch) { $activeDevBranch } else { New-PrizmDefaultDevBranchName $Kind $CurrentItemId }
691
- if (New-PrizmDevBranch $paths.ProjectRoot $candidateBranch $originalBranch) {
692
- $devBranchName = $candidateBranch
693
- Write-PrizmInfo "Dev branch: $devBranchName"
694
- } else {
695
- Write-PrizmError "Failed to create dev branch: $candidateBranch from $originalBranch - aborting to avoid running on $originalBranch"
696
- $script:PRIZM_ITEM_LIST_STATUS = ''
697
- $script:PRIZM_ITEM_EXIT_CODE = 1
698
- return
699
- }
700
- }
701
- }
702
-
703
- $baseCommit = if ($isGitRepository) { Get-PrizmGitHead $paths.ProjectRoot } else { '' }
704
-
705
- while ($true) {
706
- $sessionDir = if ($dryRun) {
707
- Join-Path ([System.IO.Path]::GetTempPath()) "prizmkit-dry-run\$sessionId"
708
- } else {
709
- Join-Path $stateDir "$CurrentItemId\sessions\$sessionId"
710
- }
711
- $logsDir = Join-Path $sessionDir 'logs'
712
- New-Item -ItemType Directory -Force -Path $logsDir | Out-Null
713
- $promptPath = Join-Path $sessionDir 'bootstrap-prompt.md'
714
- $sessionLog = Join-Path $logsDir 'session.log'
715
- $pidPath = Join-Path $logsDir 'ai.pid'
716
-
717
- $cli = $null
718
- if (-not $dryRun) {
719
- $cli = Resolve-PrizmAiCli $paths.ProjectRoot $paths.PrizmkitDir
720
- $env:PRIZMKIT_PLATFORM = Get-PrizmPlatformFromProject $paths.ProjectRoot $paths.PrizmkitDir $cli
721
- }
722
-
723
- $promptArgs = @((Join-Path $paths.ScriptsDir $promptScript), $listOption, $listPath, $idOption, $CurrentItemId, '--session-id', $sessionId, '--run-id', $runId, '--retry-count', $retryCount, '--resume-phase', $resumePhase, '--state-dir', $stateDir, '--output', $promptPath)
724
- $continuationSummaryPath = ".prizmkit/$Kind/$CurrentItemId/continuation-summary.md"
725
- if ($Kind -eq 'feature') {
726
- $featureSlug = Get-PrizmFeatureSlugFromList $listPath $CurrentItemId
727
- if ($featureSlug) { $continuationSummaryPath = ".prizmkit/specs/$featureSlug/continuation-summary.md" }
728
- }
729
- if ($continuationPending) {
730
- $modeForContinuation = if ($continuationReason) { $continuationReason } else { 'context_overflow' }
731
- $promptArgs += @('--continuation-mode', $modeForContinuation, '--previous-session-id', $previousSessionId, '--continuation-count', [string]$continuationCount, '--context-overflow-count', [string]$contextOverflowCount, '--task-type', $Kind, '--active-dev-branch', $activeDevBranch, '--base-branch', $originalBranch, '--continuation-summary-path', $continuationSummaryPath)
732
- }
733
- if ($mode) { $promptArgs += @('--mode', $mode) }
734
- if ($critic) { $promptArgs += @('--critic', $critic) }
735
- if ($dryRun) { $promptArgs += '--no-checkpoint' }
736
- if ($verboseEnabled) { Write-PrizmInfo "Prompt args: $($promptArgs -join ' ')" }
737
- $promptResult = Invoke-PrizmPythonJson $python $promptArgs
738
- $itemModel = ''
739
- if ($promptResult -and $promptResult.PSObject.Properties['model'] -and $promptResult.model) {
740
- $itemModel = [string]$promptResult.model
741
- }
742
- $effectiveModel = if ($itemModel) { $itemModel } else { $env:MODEL }
743
- Write-PrizmSuccess "Generated prompt: $promptPath"
744
-
745
- if ($dryRun) {
746
- Get-Content $promptPath
747
- $script:PRIZM_ITEM_EXIT_CODE = 0
748
- return
749
- }
750
-
751
- Write-PrizmInfo "Starting $cli session for $CurrentItemId ($sessionId)"
752
-
753
- $artifactDirForFingerprint = if ($Kind -eq 'feature') { Split-Path $continuationSummaryPath -Parent } else { ".prizmkit/$Kind/$CurrentItemId" }
754
- $checkpointForFingerprint = Join-Path $artifactDirForFingerprint 'workflow-checkpoint.json'
755
- $progressBefore = Get-PrizmContextProgressFingerprint -ProjectRoot $paths.ProjectRoot -TaskType $Kind -TaskId $CurrentItemId -ArtifactDir $artifactDirForFingerprint -CheckpointFile $checkpointForFingerprint
756
-
757
- $progressJson = Join-Path $logsDir 'progress.json'
758
- $parserProcess = Start-PrizmProgressParser -PythonCommand $python -ScriptsDir $paths.ScriptsDir -SessionLog $sessionLog -ProgressFile $progressJson -CliCommand $cli
759
-
760
- $job = Start-Job -ScriptBlock {
761
- param($commonPath, $cli, $promptPath, $sessionLog, $projectRoot, $model, $pidPath)
762
- . $commonPath
763
- Invoke-PrizmAiSession -CliCommand $cli -PromptPath $promptPath -LogPath $sessionLog -ProjectRoot $projectRoot -Model $model -PidPath $pidPath
764
- } -ArgumentList (Join-Path $paths.PipelineDir 'lib\common.ps1'), $cli, $promptPath, $sessionLog, $paths.ProjectRoot, $effectiveModel, $pidPath
765
-
766
- $elapsedSeconds = 0
767
- $staleSeconds = 0
768
- $previousLogSize = 0
769
- $previousProgressSignature = ''
770
- $previousChildActivitySignature = ''
771
- $staleKillMarker = Join-Path $logsDir 'stale-kill.json'
772
- $wasStaleKilled = $false
773
- while ($true) {
774
- $completed = Wait-Job $job -Timeout $heartbeatInterval
775
- if ($completed) { break }
776
-
777
- $elapsedSeconds += $heartbeatInterval
778
- $currentLogSize = 0
779
- if (Test-Path $sessionLog) {
780
- $currentLogSize = [int64](Get-Item $sessionLog).Length
781
- }
782
- $growth = $currentLogSize - $previousLogSize
783
- $previousLogSize = $currentLogSize
784
-
785
- $progressActivity = Get-PrizmProgressActivity -ProgressFile $progressJson
786
- $progressSignature = [string]$progressActivity.ProgressSignature
787
- $progressAdvanced = ($progressSignature -and $progressSignature -ne $previousProgressSignature)
788
- $previousProgressSignature = $progressSignature
789
- $childSignature = [string]$progressActivity.ChildSignature
790
- $childAdvanced = ($childSignature -and $childSignature -ne $previousChildActivitySignature)
791
- $previousChildActivitySignature = $childSignature
792
-
793
- $effectiveStaleKillThreshold = Get-PrizmEffectiveStaleKillThreshold -ProgressFile $progressJson -BaseThreshold $staleKillThreshold
794
-
795
- if ($growth -gt 0 -or $childAdvanced -or $progressAdvanced) {
796
- $staleSeconds = 0
797
- } else {
798
- $staleSeconds += $heartbeatInterval
799
- }
800
-
801
- $fatalErrorCode = Get-PrizmProgressFatalErrorCode -ProgressFile $progressJson
802
- if ($fatalErrorCode) {
803
- $wasStaleKilled = $true
804
- Write-PrizmWarn "Session hit fatal AI runtime error: $fatalErrorCode"
805
- $fatalErrorMarker = Join-Path $logsDir 'fatal-error.json'
806
- Write-PrizmFatalErrorMarker $fatalErrorMarker $fatalErrorCode $staleSeconds $effectiveStaleKillThreshold
807
- Write-PrizmFatalErrorMarker $staleKillMarker $fatalErrorCode $staleSeconds $effectiveStaleKillThreshold
808
- Stop-PrizmSessionProcess $pidPath
809
- if ($staleKillGraceSeconds -gt 0) { Start-Sleep -Seconds $staleKillGraceSeconds }
810
- break
811
- }
812
- if ($effectiveStaleKillThreshold -gt 0 -and $staleSeconds -ge $effectiveStaleKillThreshold) {
813
- $wasStaleKilled = $true
814
- Write-PrizmWarn "Session stale-killed (no progress for ${effectiveStaleKillThreshold}s)"
815
- Write-PrizmStaleKillMarker $staleKillMarker $staleSeconds $effectiveStaleKillThreshold
816
- Stop-PrizmSessionProcess $pidPath
817
- if ($staleKillGraceSeconds -gt 0) { Start-Sleep -Seconds $staleKillGraceSeconds }
818
- break
819
- }
820
- }
821
-
822
- $exitCode = 0
823
- if ($wasStaleKilled) {
824
- Stop-Job $job
825
- Remove-Job $job
826
- $exitCode = 143
827
- } else {
828
- try {
829
- $exitCode = [int](Receive-Job $job)
830
- } catch {
831
- Write-PrizmWarn "AI session job failed: $($_.Exception.Message)"
832
- $exitCode = 1
833
- }
834
- Remove-Job $job
835
- }
836
- Stop-PrizmProgressParser $parserProcess
837
-
838
- $wasContextOverflow = Test-PrizmContextOverflowError -SessionLog $sessionLog -ProgressJson $progressJson
839
- $wasInfraError = ($exitCode -ne 0 -and (Test-PrizmInfraError -SessionLog $sessionLog -ProgressJson $progressJson))
840
- $wasAiRuntimeError = Test-PrizmAiRuntimeError -SessionLog $sessionLog -ProgressJson $progressJson
841
- $semanticCompletion = if ($Kind -eq 'feature' -and $isGitRepository) {
842
- Get-PrizmFeatureSemanticCompletion $paths.ProjectRoot $listPath $CurrentItemId $baseCommit $paths.PrizmkitDir
843
- } else { $null }
844
-
845
- $hasSuccessfulCommit = $false
846
- if ($Kind -ne 'feature' -and $isGitRepository) {
847
- $hasSuccessfulCommit = Test-PrizmGitCommitsSince $paths.ProjectRoot $baseCommit
848
- }
849
-
850
- $status = 'crashed'
851
- if ($semanticCompletion) {
852
- $status = 'success'
853
- if ($exitCode -ne 0 -or $wasStaleKilled -or $wasContextOverflow -or $wasAiRuntimeError) {
854
- Write-PrizmWarn "Session ended with a failure signal after semantic completion; treating as finalized success"
855
- Write-PrizmWarn "Semantic completion commit: $($semanticCompletion.CommitSha)"
856
- }
857
- } elseif ($hasSuccessfulCommit) {
858
- $status = 'success'
859
- } elseif ($wasContextOverflow) {
860
- $status = 'context_overflow'
861
- Write-PrizmWarn "AI session failed because the AI CLI exceeded the model context window"
862
- Write-PrizmWarn "Context overflow is retried without consuming code retry budget"
863
- } elseif ($wasAiRuntimeError) {
864
- $status = 'infra_error'
865
- Write-PrizmWarn "AI session failed due to structured AI runtime error"
866
- Write-PrizmWarn "AI runtime errors are retried without consuming code retry budget"
867
- } elseif ($wasInfraError) {
868
- $status = 'infra_error'
869
- Write-PrizmWarn "AI session failed due to AI CLI/provider infrastructure error"
870
- Write-PrizmWarn "Infrastructure errors are retried without consuming code retry budget"
871
- } elseif ($wasStaleKilled -or (Test-Path $staleKillMarker)) {
872
- Write-PrizmWarn "Session was stale-killed by heartbeat monitor (no progress for too long)"
873
- Write-PrizmWarn "Heartbeat-killed sessions are treated as failed; dev branch is preserved for inspection"
874
- } elseif ($exitCode -ne 0) {
875
- Write-PrizmWarn "AI session exited with code $exitCode"
876
- } elseif (-not $isGitRepository) {
877
- Write-PrizmWarn "AI session exited cleanly, but project is not a git repository; cannot verify work was committed."
878
- } elseif (Test-PrizmGitCommitsSince $paths.ProjectRoot $baseCommit) {
879
- $status = 'success'
880
- } elseif (Test-PrizmGitWorkDirty $paths.ProjectRoot $stateDir $listPath) {
881
- Write-PrizmWarn "AI session exited cleanly but produced no commits; auto-committing dirty work tree."
882
- if (Invoke-PrizmGitAutoCommit $paths.ProjectRoot "chore($CurrentItemId): auto-commit session work") {
883
- $status = 'success'
884
- } else {
885
- Write-PrizmWarn "Auto-commit failed; treating session as crashed."
886
- }
887
- } else {
888
- Write-PrizmWarn "AI session exited cleanly but produced no commits and no changes."
889
- }
890
-
891
- $mergeSucceeded = $true
892
- $itemListStatus = ''
893
- $activeDevBranchForStatus = $devBranchName
894
- $progressAfter = ''
895
- $statusContinuationArgs = @('--active-dev-branch', $activeDevBranchForStatus, '--base-branch', $originalBranch, '--last-fatal-error-code', 'context_overflow', '--continuation-summary-path', $continuationSummaryPath)
896
- if ($status -eq 'context_overflow') {
897
- $progressAfter = Get-PrizmContextProgressFingerprint -ProjectRoot $paths.ProjectRoot -TaskType $Kind -TaskId $CurrentItemId -ArtifactDir $artifactDirForFingerprint -CheckpointFile $checkpointForFingerprint
898
- if (Test-PrizmContextProgressChanged -BeforeJson $progressBefore -AfterJson $progressAfter) {
899
- $noProgressCount = 0
900
- Write-PrizmInfo "Context-overflow session made observable progress; continuing on $devBranchName"
901
- } else {
902
- $noProgressCount++
903
- Write-PrizmWarn "Context-overflow session made no observable progress ($noProgressCount consecutive)"
904
- }
905
- $statusContinuationArgs = @('--active-dev-branch', $activeDevBranchForStatus, '--base-branch', $originalBranch, '--last-fatal-error-code', 'context_overflow', '--continuation-summary-path', $continuationSummaryPath, '--no-progress-count', [string]$noProgressCount, '--progress-fingerprint', $progressAfter)
906
- if ($noProgressCount -ge 2) {
907
- Write-PrizmWarn 'Pausing automatic continuation: context_overflow_without_git_checkpoint_or_artifact_progress'
908
- $status = 'stalled_context_continuation'
909
- } else {
910
- $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', 'context_overflow') + $maxRetryArgs + $maxInfraRetryArgs + $statusContinuationArgs)
911
- if ($updateResult -and $updateResult.PSObject.Properties['new_status']) { $itemListStatus = [string]$updateResult.new_status }
912
- $continuationPending = $true
913
- $continuationReason = 'context_overflow'
914
- $previousSessionId = $sessionId
915
- $activeDevBranch = $devBranchName
916
- $contextOverflowCount++
917
- $continuationCount++
918
- $sessionId = New-PrizmSessionId $Kind
919
- $runId = "run-$(Get-Date -Format 'yyyyMMdd-HHmmss')"
920
- Write-PrizmInfo "Launching automatic continuation for $CurrentItemId on same branch/worktree"
921
- continue
922
- }
923
- }
924
-
925
- if ($status -eq 'success') {
926
- if (Test-PrizmGitDirty $paths.ProjectRoot) {
927
- Write-PrizmInfo "Auto-committing remaining session artifacts."
928
- Invoke-PrizmGitIncludeRemainingArtifacts $paths.ProjectRoot $CurrentItemId
929
- }
930
-
931
- if ($status -eq 'success') {
932
- $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', $status) + $maxRetryArgs + $maxInfraRetryArgs + $statusContinuationArgs)
933
- if ($updateResult -and $updateResult.PSObject.Properties['new_status']) {
934
- $itemListStatus = [string]$updateResult.new_status
935
- }
936
-
937
- if ($isGitRepository -and $devBranchName) {
938
- if (Merge-PrizmDevBranch $paths.ProjectRoot $devBranchName $originalBranch $autoPush) {
939
- $devBranchName = ''
940
- } else {
941
- $mergeSucceeded = $false
942
- $status = 'merge_conflict'
943
- Write-PrizmWarn "Auto-merge failed - dev branch preserved for inspection"
944
- }
945
- }
946
- }
947
- } elseif ($isGitRepository -and $devBranchName) {
948
- Write-PrizmWarn "Session failed - dev branch preserved for inspection: $devBranchName"
949
- }
950
-
951
- if ($isGitRepository -and $originalBranch) {
952
- Restore-PrizmOriginalBranch $paths.ProjectRoot $originalBranch $devBranchName | Out-Null
953
- }
954
-
955
- if ($status -eq 'success' -and $mergeSucceeded -and $isGitRepository) {
956
- Invoke-PrizmGitCommitPath $paths.ProjectRoot $listPath "chore($CurrentItemId): update $idName status" | Out-Null
957
- }
958
-
959
- if ($status -ne 'success') {
960
- if ($Kind -eq 'feature') {
961
- $failureSlug = if ($semanticCompletion) { [string]$semanticCompletion.Slug } else { Get-PrizmFeatureSlugFromList $listPath $CurrentItemId }
962
- if ($failureSlug) {
963
- $featureArtifactDir = Join-Path $paths.PrizmkitDir "specs\$failureSlug"
964
- $failureLog = Join-Path $featureArtifactDir 'failure-log.md'
965
- $checkpointPath = Join-Path $featureArtifactDir 'workflow-checkpoint.json'
966
- Write-PrizmRuntimeFailureLog $failureLog $CurrentItemId $sessionId $status $exitCode $staleKillMarker $progressJson $checkpointPath $paths.ProjectRoot $baseCommit
967
- }
968
- }
969
- $updateResult = Invoke-PrizmPythonJson $python (@((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'update', $idOption, $CurrentItemId, '--session-id', $sessionId, '--session-status', $status) + $maxRetryArgs + $maxInfraRetryArgs + $statusContinuationArgs)
970
- if ($updateResult -and $updateResult.PSObject.Properties['new_status']) {
971
- $itemListStatus = [string]$updateResult.new_status
972
- }
973
- if ($isGitRepository) {
974
- Invoke-PrizmGitCommitPath $paths.ProjectRoot $listPath "chore($CurrentItemId): update $idName status" | Out-Null
975
- }
976
- }
977
-
978
- break
979
- }
980
-
981
- if ($status -eq 'success' -and $mergeSucceeded) {
982
- Write-PrizmSuccess "$Kind item completed: $CurrentItemId"
983
- } else {
984
- Write-PrizmError "$Kind item failed: $CurrentItemId. Log: $sessionLog"
985
- }
986
- $script:PRIZM_ITEM_LIST_STATUS = $itemListStatus
987
- $script:PRIZM_ITEM_EXIT_CODE = if ($status -eq 'success' -and $mergeSucceeded) { 0 } else { 1 }
988
- return
989
- }
990
-
991
- if ($itemId) {
992
- Invoke-PrizmPipelineItem $itemId
993
- $global:PRIZM_EXIT_CODE = $script:PRIZM_ITEM_EXIT_CODE
994
- return
995
- }
996
-
997
- $processedCount = 0
998
- $lastExitCode = 0
999
- while ($true) {
1000
- $getNextArgs = @((Join-Path $paths.ScriptsDir $updateScript), $listOption, $listPath, '--state-dir', $stateDir, '--action', 'get_next')
1001
- if ($featuresFilter -and $Kind -eq 'feature') { $getNextArgs += @('--features', $featuresFilter) }
1002
- $getNextOutput = (Invoke-PrizmPythonOutput $python $getNextArgs).Trim()
1003
- if (-not $getNextOutput -or $getNextOutput -eq 'PIPELINE_COMPLETE') {
1004
- if ($processedCount -eq 0) {
1005
- Write-PrizmSuccess "No pending $Kind items."
1006
- } else {
1007
- Write-PrizmSuccess "Processed $processedCount $Kind item(s)."
1008
- }
1009
- if (-not $dryRun) {
1010
- $deployExit = Invoke-PrizmDeploySession $Kind $listPath
1011
- if ($deployExit -ne 0 -and $lastExitCode -eq 0) { $lastExitCode = $deployExit }
1012
- }
1013
- $global:PRIZM_EXIT_CODE = $lastExitCode
1014
- return
1015
- }
1016
- if ($getNextOutput -eq 'PIPELINE_BLOCKED') {
1017
- Write-PrizmWarn "All remaining $Kind items are blocked."
1018
- Write-PrizmWarn "Run .\run-$Kind.ps1 status to see details."
1019
- $global:PRIZM_EXIT_CODE = $lastExitCode
1020
- return
1021
- }
1022
- if ($getNextOutput -notmatch '^\s*[\{\[]') {
1023
- throw "Unexpected get_next output: $getNextOutput"
1024
- }
1025
- $next = $getNextOutput | ConvertFrom-Json
1026
- $nextItemId = $next.PSObject.Properties["${idName}_id"].Value
1027
- if (-not $nextItemId) {
1028
- if ($processedCount -eq 0) {
1029
- Write-PrizmSuccess "No pending $Kind items."
1030
- } else {
1031
- Write-PrizmSuccess "Processed $processedCount $Kind item(s)."
1032
- }
1033
- $global:PRIZM_EXIT_CODE = $lastExitCode
1034
- return
1035
- }
1036
-
1037
- $processedCount++
1038
- Invoke-PrizmPipelineItem $nextItemId $next
1039
- $lastExitCode = $script:PRIZM_ITEM_EXIT_CODE
1040
- if ($dryRun) {
1041
- $global:PRIZM_EXIT_CODE = $lastExitCode
1042
- return
1043
- }
1044
- if ($lastExitCode -ne 0 -and $stopOnFailure -and $script:PRIZM_ITEM_LIST_STATUS -eq 'failed') {
1045
- $global:PRIZM_EXIT_CODE = $lastExitCode
1046
- return
1047
- } elseif ($lastExitCode -ne 0 -and $stopOnFailure) {
1048
- Write-PrizmInfo "STOP_ON_FAILURE: $nextItemId is $($script:PRIZM_ITEM_LIST_STATUS); code/infra retry budget not exhausted, continuing."
1049
- }
1050
- }
1051
- }