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