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