@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.b1abb545
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/dist/cli-web-branch.d.ts +2 -0
- package/dist/cli-web-branch.js +9 -2
- package/dist/help-text.js +5 -0
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +78 -23
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +84 -228
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +224 -0
- package/dist/resources/extensions/github-sync/templates.js +3 -3
- package/dist/resources/extensions/gsd/artifact-projection.js +14 -0
- package/dist/resources/extensions/gsd/auto/loop.js +74 -56
- package/dist/resources/extensions/gsd/auto/orchestrator.js +109 -11
- package/dist/resources/extensions/gsd/auto/phases.js +28 -3
- package/dist/resources/extensions/gsd/auto/run-unit.js +2 -1
- package/dist/resources/extensions/gsd/auto/session.js +3 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +16 -4
- package/dist/resources/extensions/gsd/auto-dispatch.js +6 -5
- package/dist/resources/extensions/gsd/auto-model-selection.js +8 -0
- package/dist/resources/extensions/gsd/auto-post-unit.js +4 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +81 -8
- package/dist/resources/extensions/gsd/auto-recovery.js +48 -49
- package/dist/resources/extensions/gsd/auto-runtime-state.js +14 -0
- package/dist/resources/extensions/gsd/auto-start.js +12 -23
- package/dist/resources/extensions/gsd/auto-timers.js +16 -2
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +32 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +4 -29
- package/dist/resources/extensions/gsd/auto-verification.js +7 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +21 -19
- package/dist/resources/extensions/gsd/auto.js +11 -7
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +11 -37
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +100 -138
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +63 -4
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +3 -0
- package/dist/resources/extensions/gsd/commands-handlers.js +20 -0
- package/dist/resources/extensions/gsd/commands-inspect.js +4 -8
- package/dist/resources/extensions/gsd/commands-maintenance.js +61 -41
- package/dist/resources/extensions/gsd/commands-ship.js +2 -2
- package/dist/resources/extensions/gsd/commands-verdict.js +12 -2
- package/dist/resources/extensions/gsd/db-workspace.js +103 -0
- package/dist/resources/extensions/gsd/delegation-policy.js +2 -10
- package/dist/resources/extensions/gsd/discussion-handoff.js +218 -0
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/dist/resources/extensions/gsd/doctor.js +16 -9
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/git-conflict-state.js +16 -1
- package/dist/resources/extensions/gsd/gsd-db.js +12 -0
- package/dist/resources/extensions/gsd/guided-flow.js +34 -468
- package/dist/resources/extensions/gsd/guided-unit-completion.js +225 -0
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -1
- package/dist/resources/extensions/gsd/mcp-filter.js +2 -1
- package/dist/resources/extensions/gsd/mcp-tool-name.js +26 -0
- package/dist/resources/extensions/gsd/md-importer.js +4 -3
- package/dist/resources/extensions/gsd/migrate/safety.js +2 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +3 -2
- package/dist/resources/extensions/gsd/milestone-closeout-proof.js +72 -0
- package/dist/resources/extensions/gsd/milestone-closeout.js +12 -4
- package/dist/resources/extensions/gsd/milestone-merge-transaction.js +10 -0
- package/dist/resources/extensions/gsd/milestone-planning-persistence.js +156 -0
- package/dist/resources/extensions/gsd/milestone-readiness.js +77 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +50 -0
- package/dist/resources/extensions/gsd/milestone-validation-evidence.js +73 -0
- package/dist/resources/extensions/gsd/milestone-validation-verdict.js +57 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +147 -29
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/provider-payload-policy.js +83 -0
- package/dist/resources/extensions/gsd/pull-request-process.js +13 -0
- package/dist/resources/extensions/gsd/quality-gate-closure.js +109 -0
- package/dist/resources/extensions/gsd/question-transport.js +86 -0
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/templates/plan.md +7 -0
- package/dist/resources/extensions/gsd/templates/project.md +1 -0
- package/dist/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/dist/resources/extensions/gsd/templates/uat.md +5 -1
- package/dist/resources/extensions/gsd/tool-contract.js +52 -8
- package/dist/resources/extensions/gsd/tool-presentation-plan.js +15 -34
- package/dist/resources/extensions/gsd/tool-surface-snapshot.js +17 -0
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +15 -143
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +39 -0
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +15 -78
- package/dist/resources/extensions/gsd/uat-policy.js +16 -10
- package/dist/resources/extensions/gsd/uat-run.js +9 -14
- package/dist/resources/extensions/gsd/unit-context-composer.js +40 -20
- package/dist/resources/extensions/gsd/unit-runtime.js +3 -2
- package/dist/resources/extensions/gsd/unit-tool-contracts.js +2 -1
- package/dist/resources/extensions/gsd/user-input-boundary.js +23 -0
- package/dist/resources/extensions/gsd/validation-block-guard.js +2 -0
- package/dist/resources/extensions/gsd/web-app-uat.js +80 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +15 -102
- package/dist/resources/extensions/gsd/workflow-reconcile.js +4 -3
- package/dist/resources/extensions/gsd/workflow-tool-surface.js +46 -0
- package/dist/resources/extensions/gsd/workspace-git-guard.js +2 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +33 -4
- package/dist/resources/extensions/gsd/worktree-telemetry.js +12 -0
- package/dist/resources/extensions/shared/interview-ui.js +2 -2
- package/dist/resources/shared/claude-runtime-floor.js +182 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/update-cmd.js +20 -0
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +7 -7
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +8 -8
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +7 -7
- package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2659.b7b129ee6a769448.js +1 -0
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.4113d484a994e411.js → 3616.3c60753b8ffcbd2e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/4283.e4873b058df143a1.js +2 -0
- package/dist/web/standalone/.next/static/chunks/5826.a46ecdd1cfe8dabc.js +1 -0
- package/dist/web/standalone/.next/static/chunks/796.cf859a427a2cb2ac.js +10 -0
- package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-dda80a1ef5587410.js → webpack-fbea77b5f9953368.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web-mode.d.ts +2 -0
- package/dist/web-mode.js +20 -8
- package/package.json +2 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +2 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +14 -0
- package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +106 -40
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js +6 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-extension-widgets.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/server.d.ts +10 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +8 -0
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +41 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +2 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +8 -93
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +35 -120
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/components/input.js +1 -1
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +39 -30
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
- package/packages/pi-tui/dist/stdin-buffer.js +22 -0
- package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +87 -24
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +108 -281
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +240 -0
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +287 -0
- package/src/resources/extensions/github-sync/templates.ts +3 -3
- package/src/resources/extensions/github-sync/tests/templates.test.ts +2 -2
- package/src/resources/extensions/gsd/artifact-projection.ts +31 -0
- package/src/resources/extensions/gsd/auto/contracts.ts +32 -2
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +125 -12
- package/src/resources/extensions/gsd/auto/phases.ts +35 -3
- package/src/resources/extensions/gsd/auto/run-unit.ts +2 -1
- package/src/resources/extensions/gsd/auto/session.ts +4 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +18 -4
- package/src/resources/extensions/gsd/auto-dispatch.ts +20 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +8 -0
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -3
- package/src/resources/extensions/gsd/auto-prompts.ts +107 -9
- package/src/resources/extensions/gsd/auto-recovery.ts +50 -50
- package/src/resources/extensions/gsd/auto-runtime-state.ts +26 -0
- package/src/resources/extensions/gsd/auto-start.ts +17 -20
- package/src/resources/extensions/gsd/auto-timers.ts +16 -2
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +35 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +9 -30
- package/src/resources/extensions/gsd/auto-verification.ts +7 -8
- package/src/resources/extensions/gsd/auto-worktree.ts +33 -26
- package/src/resources/extensions/gsd/auto.ts +15 -8
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +10 -37
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +116 -151
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +107 -3
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +3 -0
- package/src/resources/extensions/gsd/commands-handlers.ts +18 -0
- package/src/resources/extensions/gsd/commands-inspect.ts +7 -8
- package/src/resources/extensions/gsd/commands-maintenance.ts +74 -40
- package/src/resources/extensions/gsd/commands-ship.ts +2 -2
- package/src/resources/extensions/gsd/commands-verdict.ts +19 -2
- package/src/resources/extensions/gsd/db-workspace.ts +170 -0
- package/src/resources/extensions/gsd/delegation-policy.ts +3 -11
- package/src/resources/extensions/gsd/discussion-handoff.ts +276 -0
- package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -0
- package/src/resources/extensions/gsd/doctor.ts +15 -5
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/git-conflict-state.ts +17 -1
- package/src/resources/extensions/gsd/gsd-db.ts +12 -0
- package/src/resources/extensions/gsd/guided-flow.ts +47 -558
- package/src/resources/extensions/gsd/guided-unit-completion.ts +275 -0
- package/src/resources/extensions/gsd/markdown-renderer.ts +2 -1
- package/src/resources/extensions/gsd/mcp-filter.ts +2 -1
- package/src/resources/extensions/gsd/mcp-tool-name.ts +35 -0
- package/src/resources/extensions/gsd/md-importer.ts +3 -3
- package/src/resources/extensions/gsd/migrate/safety.ts +2 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +2 -2
- package/src/resources/extensions/gsd/milestone-closeout-proof.ts +131 -0
- package/src/resources/extensions/gsd/milestone-closeout.ts +12 -4
- package/src/resources/extensions/gsd/milestone-merge-transaction.ts +47 -0
- package/src/resources/extensions/gsd/milestone-planning-persistence.ts +224 -0
- package/src/resources/extensions/gsd/milestone-readiness.ts +125 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +81 -0
- package/src/resources/extensions/gsd/milestone-validation-evidence.ts +95 -0
- package/src/resources/extensions/gsd/milestone-validation-verdict.ts +80 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/preferences-diagnostics.ts +98 -0
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +173 -28
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -0
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/provider-payload-policy.ts +140 -0
- package/src/resources/extensions/gsd/pull-request-process.ts +41 -0
- package/src/resources/extensions/gsd/quality-gate-closure.ts +140 -0
- package/src/resources/extensions/gsd/question-transport.ts +138 -0
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/templates/plan.md +7 -0
- package/src/resources/extensions/gsd/templates/project.md +1 -0
- package/src/resources/extensions/gsd/templates/roadmap.md +1 -1
- package/src/resources/extensions/gsd/templates/uat.md +5 -1
- package/src/resources/extensions/gsd/tests/ask-user-questions-render.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +29 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +321 -5
- package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +133 -4
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +34 -3
- package/src/resources/extensions/gsd/tests/dispatch-run-uat-browser-tools.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +1 -5
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +48 -1
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout-proof.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-transaction.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/milestone-readiness.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-evidence.test.ts +41 -0
- package/src/resources/extensions/gsd/tests/milestone-validation-verdict.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +2 -0
- package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/preferences-diagnostics.test.ts +67 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +183 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/provider-payload-policy.test.ts +165 -0
- package/src/resources/extensions/gsd/tests/pull-request-process.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +94 -0
- package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +25 -1
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +101 -1
- package/src/resources/extensions/gsd/tests/stale-queued-milestone.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/tool-availability-audit.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +35 -42
- package/src/resources/extensions/gsd/tests/uat-policy.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +86 -1
- package/src/resources/extensions/gsd/tests/validate-milestone-stuck-guard.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/web-app-uat.test.ts +150 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +126 -9
- package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +79 -0
- package/src/resources/extensions/gsd/tool-contract.ts +86 -8
- package/src/resources/extensions/gsd/tool-presentation-plan.ts +16 -33
- package/src/resources/extensions/gsd/tool-surface-snapshot.ts +47 -0
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +19 -160
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +43 -0
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +25 -84
- package/src/resources/extensions/gsd/uat-policy.ts +19 -10
- package/src/resources/extensions/gsd/uat-run.ts +10 -14
- package/src/resources/extensions/gsd/unit-context-composer.ts +85 -20
- package/src/resources/extensions/gsd/unit-runtime.ts +3 -2
- package/src/resources/extensions/gsd/unit-tool-contracts.ts +2 -1
- package/src/resources/extensions/gsd/user-input-boundary.ts +18 -0
- package/src/resources/extensions/gsd/validation-block-guard.ts +2 -0
- package/src/resources/extensions/gsd/web-app-uat.ts +101 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +22 -110
- package/src/resources/extensions/gsd/workflow-reconcile.ts +3 -3
- package/src/resources/extensions/gsd/workflow-tool-surface.ts +73 -0
- package/src/resources/extensions/gsd/workspace-git-guard.ts +1 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +7 -16
- package/src/resources/extensions/gsd/worktree-state-projection.ts +55 -7
- package/src/resources/extensions/gsd/worktree-telemetry.ts +16 -0
- package/src/resources/extensions/shared/interview-ui.ts +15 -2
- package/src/resources/shared/claude-runtime-floor.ts +248 -0
- package/dist/web/standalone/.next/static/chunks/2659.feb6499ca863ebfc.js +0 -1
- package/dist/web/standalone/.next/static/chunks/2772.151789db0edea835.js +0 -1
- package/dist/web/standalone/.next/static/chunks/4283.10a065467b5340d8.js +0 -2
- package/dist/web/standalone/.next/static/chunks/5826.960dc4634cc9b0d3.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.46f811c0fac23aab.js +0 -10
- package/dist/web/standalone/.next/static/chunks/8785.d32f7a61f55c1600.js +0 -1
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → 3PtrU9qGPEXwNLWkIyiqk}/_ssgManifest.js +0 -0
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
8
8
|
|
|
9
9
|
import type { AutoSession } from "./session.js";
|
|
10
|
+
import type { AutoTerminalOutcome } from "./contracts.js";
|
|
10
11
|
import type { ErrorContext } from "./types.js";
|
|
11
12
|
import type { GSDPreferences } from "../preferences.js";
|
|
12
13
|
import type { GSDState } from "../types.js";
|
|
@@ -33,6 +34,7 @@ export interface StopAutoOptions {
|
|
|
33
34
|
milestoneTitle?: string | null;
|
|
34
35
|
allMilestonesComplete?: boolean;
|
|
35
36
|
};
|
|
37
|
+
terminalOutcome?: AutoTerminalOutcome;
|
|
36
38
|
/**
|
|
37
39
|
* Foreground closeout-boundary stops already have the useful final surface in
|
|
38
40
|
* the transcript. Preserve it instead of installing a replacement widget.
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* auto/loop.ts — Main auto-mode execution loop.
|
|
5
5
|
*
|
|
6
|
-
* Iterates:
|
|
6
|
+
* Iterates: orchestration.advance → guards → runUnit → finalize → repeat.
|
|
7
7
|
* Exits when s.active becomes false or a terminal condition is reached.
|
|
8
8
|
*
|
|
9
9
|
* Imports from: auto/types, auto/resolve, auto/phases
|
|
@@ -15,6 +15,7 @@ import { randomUUID } from "node:crypto";
|
|
|
15
15
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
16
16
|
import { join } from "node:path";
|
|
17
17
|
import type { AutoSession } from "./session.js";
|
|
18
|
+
import type { AutoTerminalOutcome } from "./contracts.js";
|
|
18
19
|
import type { LoopDeps, StopAutoOptions } from "./loop-deps.js";
|
|
19
20
|
import type { GSDState } from "../types.js";
|
|
20
21
|
import {
|
|
@@ -24,13 +25,7 @@ import {
|
|
|
24
25
|
type IterationData,
|
|
25
26
|
} from "./types.js";
|
|
26
27
|
import { _clearCurrentResolve } from "./resolve.js";
|
|
27
|
-
import {
|
|
28
|
-
runPreDispatch,
|
|
29
|
-
runDispatch,
|
|
30
|
-
runGuards,
|
|
31
|
-
runFinalize,
|
|
32
|
-
STUCK_WINDOW_SIZE,
|
|
33
|
-
} from "./phases.js";
|
|
28
|
+
import { runGuards, runFinalize, STUCK_WINDOW_SIZE } from "./phases.js";
|
|
34
29
|
import { debugLog } from "../debug-logger.js";
|
|
35
30
|
import { isInfrastructureError, isTransientCooldownError, getCooldownRetryAfterMs, COOLDOWN_FALLBACK_WAIT_MS, MAX_COOLDOWN_RETRIES } from "./infra-errors.js";
|
|
36
31
|
import { ModelPolicyDispatchBlockedError } from "../auto-model-selection.js";
|
|
@@ -146,6 +141,25 @@ function resolveCompletionStopFromState(
|
|
|
146
141
|
};
|
|
147
142
|
}
|
|
148
143
|
|
|
144
|
+
function resolveCompletionStopFromOutcome(
|
|
145
|
+
outcome: AutoTerminalOutcome | undefined,
|
|
146
|
+
stateSnapshot: GSDState | undefined,
|
|
147
|
+
): { reason: string; options: StopAutoOptions } | null {
|
|
148
|
+
if (outcome?.code !== "all-complete") return null;
|
|
149
|
+
const completedMilestone = stateSnapshot?.lastCompletedMilestone ?? stateSnapshot?.activeMilestone;
|
|
150
|
+
return {
|
|
151
|
+
reason: outcome.displayReason,
|
|
152
|
+
options: {
|
|
153
|
+
completionWidget: {
|
|
154
|
+
milestoneId: completedMilestone?.id ?? null,
|
|
155
|
+
milestoneTitle: completedMilestone?.title ?? null,
|
|
156
|
+
allMilestonesComplete: true,
|
|
157
|
+
},
|
|
158
|
+
terminalOutcome: outcome,
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
149
163
|
// ── Stuck detection persistence (#3704) ──────────────────────────────────
|
|
150
164
|
// Phase C migration: stuck-state.json deleted in favor of DB-backed
|
|
151
165
|
// equivalents. recentUnits is rebuilt from unit_dispatches (Phase B
|
|
@@ -158,6 +172,8 @@ function resolveCompletionStopFromState(
|
|
|
158
172
|
// tolerates — same behavior as a fresh session.
|
|
159
173
|
const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
|
|
160
174
|
const MAX_CONSECUTIVE_ALREADY_ACTIVE_SKIPS = 3;
|
|
175
|
+
const ORCHESTRATION_MISSING_REASON =
|
|
176
|
+
"Auto Orchestration Module is not wired; cannot dispatch built-in GSD Unit.";
|
|
161
177
|
|
|
162
178
|
function stableStuckStateScopeId(s: AutoSession): string {
|
|
163
179
|
return normalizeRealPath(s.scope?.workspace.projectRoot ?? (s.originalBasePath || s.basePath));
|
|
@@ -353,9 +369,9 @@ function closeOutCrashedUnit(s: AutoSession, iterData: IterationData, err: unkno
|
|
|
353
369
|
}
|
|
354
370
|
|
|
355
371
|
/**
|
|
356
|
-
* Main auto-mode execution loop. Iterates:
|
|
357
|
-
* runUnit → finalize → repeat. Exits when s.active becomes false or a
|
|
358
|
-
*
|
|
372
|
+
* Main auto-mode execution loop. Iterates: orchestration.advance → guards →
|
|
373
|
+
* runUnit → finalize → repeat. Exits when s.active becomes false or a terminal
|
|
374
|
+
* condition is reached.
|
|
359
375
|
*
|
|
360
376
|
* This is the linear replacement for the recursive
|
|
361
377
|
* dispatchNextUnit → resolveAgentEnd → dispatchNextUnit chain.
|
|
@@ -572,10 +588,9 @@ export async function autoLoop(
|
|
|
572
588
|
let iterData: IterationData;
|
|
573
589
|
|
|
574
590
|
// ── Custom engine path ──────────────────────────────────────────────
|
|
575
|
-
// When activeEngineId is a non-dev value,
|
|
576
|
-
//
|
|
577
|
-
//
|
|
578
|
-
// After unit execution, verifies then reconciles via the engine layer.
|
|
591
|
+
// When activeEngineId is a non-dev value, the custom engine drives its own
|
|
592
|
+
// state via GRAPH.yaml. It shares guards and Unit execution with the dev
|
|
593
|
+
// path, then verifies and reconciles via the engine layer.
|
|
579
594
|
//
|
|
580
595
|
// GSD_ENGINE_BYPASS=1 skips the engine layer entirely — falls through
|
|
581
596
|
// to the dev path below.
|
|
@@ -656,7 +671,7 @@ export async function autoLoop(
|
|
|
656
671
|
observedUnitType = iterData.unitType;
|
|
657
672
|
observedUnitId = iterData.unitId;
|
|
658
673
|
|
|
659
|
-
// ── Progress widget (mirrors dev path
|
|
674
|
+
// ── Progress widget (mirrors the dev path) ──
|
|
660
675
|
deps.updateProgressWidget(ctx, iterData.unitType, iterData.unitId, iterData.state);
|
|
661
676
|
|
|
662
677
|
// ── Guards (shared with dev path) ──
|
|
@@ -876,14 +891,22 @@ export async function autoLoop(
|
|
|
876
891
|
|
|
877
892
|
if (orchestrationResult.kind === "blocked") {
|
|
878
893
|
s.pendingOrchestrationDispatch = null;
|
|
894
|
+
const blockMessage = orchestrationResult.terminalOutcome?.code === "settlement-blocked"
|
|
895
|
+
? [
|
|
896
|
+
orchestrationResult.terminalOutcome.displayReason,
|
|
897
|
+
`Next: ${orchestrationResult.terminalOutcome.nextAction}`,
|
|
898
|
+
].join("\n")
|
|
899
|
+
: orchestrationResult.reason;
|
|
879
900
|
if (orchestrationResult.action === "pause") {
|
|
880
901
|
await deps.pauseAuto(ctx, pi, {
|
|
881
|
-
message:
|
|
902
|
+
message: blockMessage,
|
|
882
903
|
category: "unknown",
|
|
904
|
+
}, {
|
|
905
|
+
expectedCurrentUnit: null,
|
|
883
906
|
});
|
|
884
907
|
finishTurn("paused", "manual-attention", "orchestration-blocked");
|
|
885
908
|
} else {
|
|
886
|
-
await deps.stopAuto(ctx, pi,
|
|
909
|
+
await deps.stopAuto(ctx, pi, blockMessage);
|
|
887
910
|
finishTurn("stopped", "manual-attention", "orchestration-blocked");
|
|
888
911
|
}
|
|
889
912
|
finishIncompleteIteration({
|
|
@@ -894,8 +917,20 @@ export async function autoLoop(
|
|
|
894
917
|
break;
|
|
895
918
|
}
|
|
896
919
|
|
|
920
|
+
if (orchestrationResult.kind === "skipped") {
|
|
921
|
+
s.pendingOrchestrationDispatch = null;
|
|
922
|
+
emitIterationEnd({ skipped: true });
|
|
923
|
+
completeIteration();
|
|
924
|
+
finishTurn("skipped");
|
|
925
|
+
continue;
|
|
926
|
+
}
|
|
927
|
+
|
|
897
928
|
if (orchestrationResult.kind === "paused") {
|
|
898
929
|
s.pendingOrchestrationDispatch = null;
|
|
930
|
+
finishIncompleteIteration({
|
|
931
|
+
status: "paused",
|
|
932
|
+
reason: orchestrationResult.reason,
|
|
933
|
+
});
|
|
899
934
|
finishTurn("skipped");
|
|
900
935
|
continue;
|
|
901
936
|
}
|
|
@@ -917,7 +952,11 @@ export async function autoLoop(
|
|
|
917
952
|
|
|
918
953
|
if (orchestrationResult.kind === "stopped") {
|
|
919
954
|
s.pendingOrchestrationDispatch = null;
|
|
920
|
-
|
|
955
|
+
let completionStop = resolveCompletionStopFromOutcome(
|
|
956
|
+
orchestrationResult.terminalOutcome,
|
|
957
|
+
orchestrationResult.stateSnapshot,
|
|
958
|
+
);
|
|
959
|
+
completionStop ??= resolveCompletionStopFromState(orchestrationResult.stateSnapshot);
|
|
921
960
|
if (completionStop) {
|
|
922
961
|
await deps.stopAuto(ctx, pi, completionStop.reason, completionStop.options);
|
|
923
962
|
} else {
|
|
@@ -998,54 +1037,37 @@ export async function autoLoop(
|
|
|
998
1037
|
});
|
|
999
1038
|
observedUnitType = iterData.unitType;
|
|
1000
1039
|
observedUnitId = iterData.unitId;
|
|
1001
|
-
|
|
1002
|
-
const
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1040
|
+
|
|
1041
|
+
const guardMilestoneId = iterData.mid ?? s.currentMilestoneId ?? "workflow";
|
|
1042
|
+
const guardsResult = await runGuards(ic, guardMilestoneId);
|
|
1043
|
+
phaseReporter.report("guard", guardsResult.action, {
|
|
1044
|
+
unitType: iterData.unitType,
|
|
1045
|
+
unitId: iterData.unitId,
|
|
1046
|
+
});
|
|
1047
|
+
if (guardsResult.action === "break") {
|
|
1048
|
+
finishTurn("stopped", "manual-attention", "guard-break");
|
|
1006
1049
|
finishIncompleteIteration({
|
|
1007
1050
|
status: "stopped",
|
|
1008
|
-
reason: "
|
|
1051
|
+
reason: "guard-break",
|
|
1052
|
+
unitType: iterData.unitType,
|
|
1053
|
+
unitId: iterData.unitId,
|
|
1009
1054
|
failureClass: "manual-attention",
|
|
1010
1055
|
});
|
|
1011
1056
|
break;
|
|
1012
1057
|
}
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
}
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
if (guardsResult.action === "break") {
|
|
1027
|
-
finishTurn("stopped", "manual-attention", "guard-break");
|
|
1028
|
-
break;
|
|
1029
|
-
}
|
|
1030
|
-
const dispatchResult = await runDispatch(ic, preData, loopState);
|
|
1031
|
-
phaseReporter.report("dispatch", dispatchResult.action);
|
|
1032
|
-
if (dispatchResult.action === "break") {
|
|
1033
|
-
finishTurn("stopped", "manual-attention", "dispatch-break");
|
|
1034
|
-
break;
|
|
1035
|
-
}
|
|
1036
|
-
if (dispatchResult.action === "continue") {
|
|
1037
|
-
emitIterationEnd({ skipped: true });
|
|
1038
|
-
completeIteration();
|
|
1039
|
-
finishTurn("skipped");
|
|
1040
|
-
continue;
|
|
1041
|
-
}
|
|
1042
|
-
if (dispatchResult.action === "retry") {
|
|
1043
|
-
finishTurn("retry", "execution", dispatchResult.reason);
|
|
1044
|
-
continue;
|
|
1045
|
-
}
|
|
1046
|
-
iterData = dispatchResult.data;
|
|
1047
|
-
observedUnitType = iterData.unitType;
|
|
1048
|
-
observedUnitId = iterData.unitId;
|
|
1058
|
+
} else {
|
|
1059
|
+
s.pendingOrchestrationDispatch = null;
|
|
1060
|
+
await deps.pauseAuto(ctx, pi, {
|
|
1061
|
+
message: ORCHESTRATION_MISSING_REASON,
|
|
1062
|
+
category: "unknown",
|
|
1063
|
+
});
|
|
1064
|
+
finishTurn("paused", "manual-attention", "orchestration-missing");
|
|
1065
|
+
finishIncompleteIteration({
|
|
1066
|
+
status: "paused",
|
|
1067
|
+
reason: ORCHESTRATION_MISSING_REASON,
|
|
1068
|
+
failureClass: "manual-attention",
|
|
1069
|
+
});
|
|
1070
|
+
break;
|
|
1049
1071
|
}
|
|
1050
1072
|
} else {
|
|
1051
1073
|
iterData = await buildSidecarIterationData({
|
|
@@ -12,11 +12,13 @@
|
|
|
12
12
|
|
|
13
13
|
import type { ExtensionAPI, ExtensionContext } from "@gsd/pi-coding-agent";
|
|
14
14
|
|
|
15
|
-
import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus } from "./contracts.js";
|
|
15
|
+
import type { AutoAdvanceResult, AutoOrchestrationModule, AutoSessionContext, AutoStatus, AutoTerminalOutcome } from "./contracts.js";
|
|
16
16
|
import type { AutoSession, PendingOrchestrationDispatch } from "./session.js";
|
|
17
17
|
import type { GSDState } from "../types.js";
|
|
18
18
|
import type { MinimalModelRegistry } from "../context-budget.js";
|
|
19
19
|
|
|
20
|
+
type BlockedAdvanceResult = Extract<AutoAdvanceResult, { kind: "blocked" }>;
|
|
21
|
+
|
|
20
22
|
import { debugCount, debugTime } from "../debug-logger.js";
|
|
21
23
|
import { reconcileBeforeDispatch } from "../state-reconciliation.js";
|
|
22
24
|
import { resolveDispatch } from "../auto-dispatch.js";
|
|
@@ -36,13 +38,20 @@ import { getSessionLockStatus } from "../session-lock.js";
|
|
|
36
38
|
import { resolveUokFlags } from "../uok/flags.js";
|
|
37
39
|
import { emitJournalEvent as _emitJournalEvent } from "../journal.js";
|
|
38
40
|
import { loadEffectiveGSDPreferences, getIsolationMode } from "../preferences.js";
|
|
39
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
detectWorktreeName,
|
|
43
|
+
getMainBranch,
|
|
44
|
+
resolveProjectRoot,
|
|
45
|
+
resolveWorktreeProjectRoot,
|
|
46
|
+
} from "../worktree.js";
|
|
47
|
+
import { getPriorSliceCompletionBlocker } from "../dispatch-guard.js";
|
|
40
48
|
import { GitServiceImpl } from "../git-service.js";
|
|
41
49
|
import { WorktreeStateProjection } from "../worktree-state-projection.js";
|
|
42
50
|
import { WorktreeLifecycle } from "../worktree-lifecycle.js";
|
|
51
|
+
import { createMilestoneMergeTransaction } from "../milestone-merge-transaction.js";
|
|
43
52
|
import { createWorkspace, scopeMilestone } from "../workspace.js";
|
|
44
53
|
import { supportsStructuredQuestions } from "../workflow-mcp.js";
|
|
45
|
-
import { getToolBaselineSnapshot } from "../auto-model-selection.js";
|
|
54
|
+
import { getRegisteredToolSnapshot, getToolBaselineSnapshot } from "../auto-model-selection.js";
|
|
46
55
|
import { deriveState } from "../state.js";
|
|
47
56
|
import { parseUnitId } from "../unit-id.js";
|
|
48
57
|
import { isClosedStatus } from "../status-guards.js";
|
|
@@ -50,12 +59,13 @@ import {
|
|
|
50
59
|
isDbAvailable,
|
|
51
60
|
getSlice,
|
|
52
61
|
getTask,
|
|
53
|
-
refreshOpenDatabaseFromDisk,
|
|
54
62
|
} from "../gsd-db.js";
|
|
63
|
+
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
55
64
|
import { getErrorMessage } from "../error-utils.js";
|
|
56
65
|
import { logWarning } from "../workflow-logger.js";
|
|
57
66
|
import { existsSync, readFileSync } from "node:fs";
|
|
58
67
|
import { join } from "node:path";
|
|
68
|
+
import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
|
|
59
69
|
|
|
60
70
|
function now(): number {
|
|
61
71
|
return Date.now();
|
|
@@ -71,11 +81,19 @@ function now(): number {
|
|
|
71
81
|
*/
|
|
72
82
|
export const STUCK_WINDOW_SIZE = 6;
|
|
73
83
|
|
|
74
|
-
function
|
|
84
|
+
function noRemainingUnitsOutcome(stateSnapshot: GSDState): AutoTerminalOutcome {
|
|
75
85
|
if (stateSnapshot.phase === "complete") {
|
|
76
|
-
return
|
|
86
|
+
return {
|
|
87
|
+
code: "all-complete",
|
|
88
|
+
displayReason: "All milestones complete",
|
|
89
|
+
allMilestonesComplete: true,
|
|
90
|
+
};
|
|
77
91
|
}
|
|
78
|
-
return
|
|
92
|
+
return {
|
|
93
|
+
code: "no-remaining-units",
|
|
94
|
+
displayReason: "No remaining units",
|
|
95
|
+
allMilestonesComplete: false,
|
|
96
|
+
};
|
|
79
97
|
}
|
|
80
98
|
|
|
81
99
|
/**
|
|
@@ -118,7 +136,7 @@ export interface DispatchDecisionInput {
|
|
|
118
136
|
|
|
119
137
|
function getAlreadyClosedDispatchReason(unitType: string, unitId: string): string | null {
|
|
120
138
|
if (!isDbAvailable()) return null;
|
|
121
|
-
|
|
139
|
+
refreshWorkflowDatabaseFromDisk();
|
|
122
140
|
const { milestone, slice, task } = parseUnitId(unitId);
|
|
123
141
|
if (unitType === "execute-task" && milestone && slice && task) {
|
|
124
142
|
const row = getTask(milestone, slice, task);
|
|
@@ -201,6 +219,7 @@ export async function decideOrchestratorDispatch(
|
|
|
201
219
|
// active set may be narrowed by the prior unit before selectAndApplyModel
|
|
202
220
|
// restores it, causing false transport-preflight failures (#477 follow-up).
|
|
203
221
|
const activeTools = getToolBaselineSnapshot(pi);
|
|
222
|
+
const registeredTools = getRegisteredToolSnapshot(pi);
|
|
204
223
|
// Mirrors runDispatch: deep-planning keeps approval gates in plain chat
|
|
205
224
|
// because structured questions can be cancelled outside the chat turn on
|
|
206
225
|
// some transports.
|
|
@@ -248,6 +267,7 @@ export async function decideOrchestratorDispatch(
|
|
|
248
267
|
sessionProvider,
|
|
249
268
|
modelRegistry,
|
|
250
269
|
activeTools,
|
|
270
|
+
registeredTools,
|
|
251
271
|
sessionAuthMode: authMode,
|
|
252
272
|
sessionBaseUrl: ctx.model?.baseUrl,
|
|
253
273
|
});
|
|
@@ -532,6 +552,55 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
532
552
|
return decideOrchestratorDispatch(this.ctx, this.pi, this.dispatchBasePath, this.s, input);
|
|
533
553
|
}
|
|
534
554
|
|
|
555
|
+
private evaluateNoRemainingUnitsSettlement(stateSnapshot: GSDState): BlockedAdvanceResult | null {
|
|
556
|
+
const settlement = evaluateAllCompleteSettlement({
|
|
557
|
+
milestoneId: this.s.currentMilestoneId ?? stateSnapshot.activeMilestone?.id,
|
|
558
|
+
statePhase: stateSnapshot.phase,
|
|
559
|
+
basePath: this.s.basePath || this.getLiveDispatchBasePath(),
|
|
560
|
+
originalBasePath: this.s.originalBasePath || this.runtimeBasePath,
|
|
561
|
+
milestoneMerged: this.s.milestoneMergedInPhases,
|
|
562
|
+
});
|
|
563
|
+
this.s.milestoneSettlement = settlement;
|
|
564
|
+
if (settlement.ok) return null;
|
|
565
|
+
return {
|
|
566
|
+
kind: "blocked",
|
|
567
|
+
reason: settlement.message,
|
|
568
|
+
action: settlement.action,
|
|
569
|
+
stateSnapshot,
|
|
570
|
+
terminalOutcome: {
|
|
571
|
+
code: "settlement-blocked",
|
|
572
|
+
displayReason: settlement.message,
|
|
573
|
+
nextAction: settlement.nextAction,
|
|
574
|
+
milestoneId: settlement.milestoneId,
|
|
575
|
+
allMilestonesComplete: false,
|
|
576
|
+
},
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
private clearPendingDispatch(): void {
|
|
581
|
+
this.s.pendingOrchestrationDispatch = null;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
private findPriorSliceCompletionBlocker(unitType: string, unitId: string): string | null {
|
|
585
|
+
const guardBasePath = resolveWorktreeProjectRoot(
|
|
586
|
+
this.getLiveDispatchBasePath(),
|
|
587
|
+
this.s.originalBasePath,
|
|
588
|
+
);
|
|
589
|
+
let mainBranch = "main";
|
|
590
|
+
try {
|
|
591
|
+
mainBranch = getMainBranch(guardBasePath);
|
|
592
|
+
} catch (err) {
|
|
593
|
+
// Preserve legacy dispatch behavior: fall back to main when branch
|
|
594
|
+
// discovery fails, then let the guard make the progression decision.
|
|
595
|
+
logWarning(
|
|
596
|
+
"engine",
|
|
597
|
+
`branch discovery failed, falling back to main: ${getErrorMessage(err)}`,
|
|
598
|
+
{ file: "orchestrator.ts" },
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
return getPriorSliceCompletionBlocker(guardBasePath, mainBranch, unitType, unitId);
|
|
602
|
+
}
|
|
603
|
+
|
|
535
604
|
// ── ToolContractAdapter (folded) ─────────────────────────────────────────
|
|
536
605
|
|
|
537
606
|
private compileUnitToolContract(unitType: string): { ok: true; reason: string } | { ok: false; reason: string } {
|
|
@@ -554,7 +623,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
554
623
|
return new GitServiceImpl(basePath, gitConfig);
|
|
555
624
|
},
|
|
556
625
|
worktreeProjection: new WorktreeStateProjection(),
|
|
557
|
-
mergeMilestoneToMain,
|
|
626
|
+
mergeMilestoneToMain: createMilestoneMergeTransaction(mergeMilestoneToMain),
|
|
558
627
|
});
|
|
559
628
|
}
|
|
560
629
|
|
|
@@ -809,10 +878,23 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
809
878
|
|
|
810
879
|
const decision = await this.decideNextUnit({ stateSnapshot: reconciliation.stateSnapshot });
|
|
811
880
|
if (!decision) {
|
|
881
|
+
const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
|
|
882
|
+
if (settlementBlock) {
|
|
883
|
+
this.status.phase = "paused";
|
|
884
|
+
this.status.activeUnit = undefined;
|
|
885
|
+
this.lastAdvanceKey = null;
|
|
886
|
+
this.dispatchKeyWindow = [];
|
|
887
|
+
this.bumpTransition();
|
|
888
|
+
this.journalTransition({ name: "advance-blocked", reason: settlementBlock.reason });
|
|
889
|
+
this.postAdvanceRecord(settlementBlock);
|
|
890
|
+
return settlementBlock;
|
|
891
|
+
}
|
|
892
|
+
const terminalOutcome = noRemainingUnitsOutcome(reconciliation.stateSnapshot);
|
|
812
893
|
const stopped: AutoAdvanceResult = {
|
|
813
894
|
kind: "stopped",
|
|
814
|
-
reason:
|
|
895
|
+
reason: terminalOutcome.displayReason,
|
|
815
896
|
stateSnapshot: reconciliation.stateSnapshot,
|
|
897
|
+
terminalOutcome,
|
|
816
898
|
};
|
|
817
899
|
this.status.phase = "stopped";
|
|
818
900
|
this.status.activeUnit = undefined;
|
|
@@ -848,6 +930,25 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
848
930
|
return blocked;
|
|
849
931
|
}
|
|
850
932
|
|
|
933
|
+
const priorSliceBlocker = this.findPriorSliceCompletionBlocker(decision.unitType, decision.unitId);
|
|
934
|
+
if (priorSliceBlocker) {
|
|
935
|
+
this.clearPendingDispatch();
|
|
936
|
+
const blocked: AutoAdvanceResult = {
|
|
937
|
+
kind: "blocked",
|
|
938
|
+
reason: priorSliceBlocker,
|
|
939
|
+
action: "stop",
|
|
940
|
+
stateSnapshot: reconciliation.stateSnapshot,
|
|
941
|
+
};
|
|
942
|
+
this.journalTransition({
|
|
943
|
+
name: "advance-blocked",
|
|
944
|
+
reason: blocked.reason,
|
|
945
|
+
unitType: decision.unitType,
|
|
946
|
+
unitId: decision.unitId,
|
|
947
|
+
});
|
|
948
|
+
this.postAdvanceRecord(blocked);
|
|
949
|
+
return blocked;
|
|
950
|
+
}
|
|
951
|
+
|
|
851
952
|
const nextKey = `${decision.unitType}:${decision.unitId}`;
|
|
852
953
|
|
|
853
954
|
// Record every dispatch decision in the ring buffer before pre-flight
|
|
@@ -865,8 +966,10 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
865
966
|
// actually completed on disk with a stale DB. Verify + recover before
|
|
866
967
|
// hard-stopping (legacy graduated stuck-recovery parity).
|
|
867
968
|
if (this.tryStuckArtifactRecovery(decision.unitType, decision.unitId)) {
|
|
969
|
+
this.clearPendingDispatch();
|
|
868
970
|
return this.stuckRecovered(decision, reconciliation.stateSnapshot);
|
|
869
971
|
}
|
|
972
|
+
this.clearPendingDispatch();
|
|
870
973
|
const blocked: AutoAdvanceResult = {
|
|
871
974
|
kind: "blocked",
|
|
872
975
|
reason: `state did not advance after finalized ${decision.unitType} ${decision.unitId}`,
|
|
@@ -890,6 +993,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
890
993
|
// checks coexist: idempotency for the common immediate-repeat case,
|
|
891
994
|
// stuck-loop for the saturated-window case.
|
|
892
995
|
if (this.lastAdvanceKey === nextKey && matchingCount < STUCK_WINDOW_SIZE) {
|
|
996
|
+
this.clearPendingDispatch();
|
|
893
997
|
const blocked: AutoAdvanceResult = { kind: "blocked", reason: "idempotent advance: unit already active", action: "pause" };
|
|
894
998
|
this.journalTransition({
|
|
895
999
|
name: "advance-blocked",
|
|
@@ -910,8 +1014,10 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
910
1014
|
// complete on disk (stale DB) and recover if so — legacy graduated
|
|
911
1015
|
// stuck-recovery parity. Otherwise hard-stop with a diagnosable reason.
|
|
912
1016
|
if (this.tryStuckArtifactRecovery(decision.unitType, decision.unitId)) {
|
|
1017
|
+
this.clearPendingDispatch();
|
|
913
1018
|
return this.stuckRecovered(decision, reconciliation.stateSnapshot);
|
|
914
1019
|
}
|
|
1020
|
+
this.clearPendingDispatch();
|
|
915
1021
|
const blocked: AutoAdvanceResult = {
|
|
916
1022
|
kind: "blocked",
|
|
917
1023
|
reason: `stuck-loop: ${nextKey} picked ${matchingCount} times`,
|
|
@@ -929,6 +1035,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
929
1035
|
|
|
930
1036
|
const contract = this.compileUnitToolContract(decision.unitType);
|
|
931
1037
|
if (!contract.ok) {
|
|
1038
|
+
this.clearPendingDispatch();
|
|
932
1039
|
const blocked: AutoAdvanceResult = {
|
|
933
1040
|
kind: "blocked",
|
|
934
1041
|
reason: contract.reason,
|
|
@@ -947,6 +1054,7 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
947
1054
|
|
|
948
1055
|
const worktree = await this.prepareWorktreeForUnit(decision.unitType, decision.unitId);
|
|
949
1056
|
if (!worktree.ok) {
|
|
1057
|
+
this.clearPendingDispatch();
|
|
950
1058
|
const blocked: AutoAdvanceResult = {
|
|
951
1059
|
kind: "blocked",
|
|
952
1060
|
reason: worktree.reason,
|
|
@@ -1035,7 +1143,8 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1035
1143
|
public async resume(): Promise<AutoAdvanceResult> {
|
|
1036
1144
|
this.lastAdvanceKey = null;
|
|
1037
1145
|
this.lastFinalizedUnitKey = null;
|
|
1038
|
-
|
|
1146
|
+
// Preserve dispatchKeyWindow across resume so stuck-loop detection
|
|
1147
|
+
// accumulates across pause/resume cycles rather than resetting each time.
|
|
1039
1148
|
this.lastStuckRecoveryKey = null;
|
|
1040
1149
|
this.status.phase = "running";
|
|
1041
1150
|
this.bumpTransition();
|
|
@@ -1053,7 +1162,11 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
1053
1162
|
this.status.activeUnit = undefined;
|
|
1054
1163
|
this.lastAdvanceKey = null;
|
|
1055
1164
|
this.lastFinalizedUnitKey = null;
|
|
1056
|
-
|
|
1165
|
+
// Preserve dispatchKeyWindow on pause so stuck-loop detection accumulates
|
|
1166
|
+
// across pause/resume cycles. Only clear on a hard stop.
|
|
1167
|
+
if (reason !== "pause") {
|
|
1168
|
+
this.dispatchKeyWindow = [];
|
|
1169
|
+
}
|
|
1057
1170
|
this.lastStuckRecoveryKey = null;
|
|
1058
1171
|
this.bumpTransition();
|
|
1059
1172
|
this.journalTransition({ name: "stop", reason });
|
|
@@ -60,7 +60,8 @@ import { writeUnitRuntimeRecord } from "../unit-runtime.js";
|
|
|
60
60
|
import { withTimeout, FINALIZE_PRE_TIMEOUT_MS, FINALIZE_POST_TIMEOUT_MS } from "./finalize-timeout.js";
|
|
61
61
|
import { getEligibleSlices } from "../slice-parallel-eligibility.js";
|
|
62
62
|
import { isSliceParallelActive, startSliceParallel } from "../slice-parallel-orchestrator.js";
|
|
63
|
-
import { isDbAvailable, getMilestoneSlices, getSlice, getTask
|
|
63
|
+
import { isDbAvailable, getMilestoneSlices, getSlice, getTask } from "../gsd-db.js";
|
|
64
|
+
import { refreshWorkflowDatabaseFromDisk } from "../db-workspace.js";
|
|
64
65
|
import { isClosedStatus } from "../status-guards.js";
|
|
65
66
|
import { setRuntimeKv } from "../db/runtime-kv.js";
|
|
66
67
|
import { getLatestForUnit } from "../db/unit-dispatches.js";
|
|
@@ -85,7 +86,12 @@ import {
|
|
|
85
86
|
supportsStructuredQuestions,
|
|
86
87
|
} from "../workflow-mcp.js";
|
|
87
88
|
import { prepareWorkflowMcpForProject } from "../workflow-mcp-auto-prep.js";
|
|
88
|
-
import {
|
|
89
|
+
import {
|
|
90
|
+
applyThinkingLevelForModel,
|
|
91
|
+
floorThinkingLevelForUnit,
|
|
92
|
+
getRegisteredToolSnapshot,
|
|
93
|
+
getToolBaselineSnapshot,
|
|
94
|
+
} from "../auto-model-selection.js";
|
|
89
95
|
import type { DispatchAction } from "../auto-dispatch.js";
|
|
90
96
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
91
97
|
import { createWorktreeSafetyModule, type WorktreeSafetyResult } from "../worktree-safety.js";
|
|
@@ -225,7 +231,7 @@ function rememberRetryDispatch(
|
|
|
225
231
|
|
|
226
232
|
function getAlreadyClosedDispatchReason(unitType: string, unitId: string): string | null {
|
|
227
233
|
if (!isDbAvailable()) return null;
|
|
228
|
-
|
|
234
|
+
refreshWorkflowDatabaseFromDisk();
|
|
229
235
|
const { milestone, slice, task } = parseUnitId(unitId);
|
|
230
236
|
if (unitType === "execute-task" && milestone && slice && task) {
|
|
231
237
|
const row = getTask(milestone, slice, task);
|
|
@@ -624,6 +630,16 @@ export async function _runMilestoneMergeWithStashRestore(
|
|
|
624
630
|
);
|
|
625
631
|
if (exitResult.ok) {
|
|
626
632
|
s.milestoneMergedInPhases = true;
|
|
633
|
+
try {
|
|
634
|
+
const projectRoot = s.originalBasePath || s.canonicalProjectRoot || s.basePath;
|
|
635
|
+
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
|
|
636
|
+
await rebuildMarkdownProjectionsFromDb(projectRoot);
|
|
637
|
+
} catch (err) {
|
|
638
|
+
logWarning(
|
|
639
|
+
"engine",
|
|
640
|
+
`markdown projection rebuild after milestone merge failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
641
|
+
);
|
|
642
|
+
}
|
|
627
643
|
} else {
|
|
628
644
|
mergeError = exitResult.cause ?? new Error(`exit ${exitResult.reason}`);
|
|
629
645
|
}
|
|
@@ -1232,6 +1248,19 @@ export async function runPreDispatch(
|
|
|
1232
1248
|
} catch (e) {
|
|
1233
1249
|
logWarning("engine", "STATE.md rebuild failed after milestone transition", { error: String(e) });
|
|
1234
1250
|
}
|
|
1251
|
+
|
|
1252
|
+
// Re-project ROADMAP/PLAN markdown from the authoritative DB. Worktree DB
|
|
1253
|
+
// reconciliation during merge can leave main-branch markdown stale relative
|
|
1254
|
+
// to gsd.db (the 3M/3S/10T vs 3M/5S/16T drift class at /gsd startup).
|
|
1255
|
+
try {
|
|
1256
|
+
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
|
|
1257
|
+
await rebuildMarkdownProjectionsFromDb(s.canonicalProjectRoot);
|
|
1258
|
+
if (s.basePath !== s.canonicalProjectRoot) {
|
|
1259
|
+
await rebuildMarkdownProjectionsFromDb(s.basePath);
|
|
1260
|
+
}
|
|
1261
|
+
} catch (e) {
|
|
1262
|
+
logWarning("engine", "markdown projection rebuild failed after milestone transition", { error: String(e) });
|
|
1263
|
+
}
|
|
1235
1264
|
}
|
|
1236
1265
|
|
|
1237
1266
|
if (mid) {
|
|
@@ -1458,6 +1487,7 @@ export async function runDispatch(
|
|
|
1458
1487
|
// Checking a stale-narrowed set causes false transport-preflight warnings
|
|
1459
1488
|
// that repeat on every /gsd auto resume (#477 follow-up).
|
|
1460
1489
|
const activeTools = getToolBaselineSnapshot(pi);
|
|
1490
|
+
const registeredTools = getRegisteredToolSnapshot(pi);
|
|
1461
1491
|
// Deep planning intentionally keeps human checkpoints in plain chat. In
|
|
1462
1492
|
// Claude Code/local MCP transports, structured question requests can be
|
|
1463
1493
|
// cancelled outside the normal chat flow, which made approval gates easy to
|
|
@@ -1482,6 +1512,7 @@ export async function runDispatch(
|
|
|
1482
1512
|
sessionProvider: ctx.model?.provider,
|
|
1483
1513
|
modelRegistry: ctx.modelRegistry as MinimalModelRegistry | undefined,
|
|
1484
1514
|
activeTools,
|
|
1515
|
+
registeredTools,
|
|
1485
1516
|
sessionBaseUrl: ctx.model?.baseUrl,
|
|
1486
1517
|
sessionAuthMode: authMode,
|
|
1487
1518
|
});
|
|
@@ -1508,6 +1539,7 @@ export async function runDispatch(
|
|
|
1508
1539
|
sessionProvider: ctx.model?.provider,
|
|
1509
1540
|
modelRegistry: ctx.modelRegistry as MinimalModelRegistry | undefined,
|
|
1510
1541
|
activeTools,
|
|
1542
|
+
registeredTools,
|
|
1511
1543
|
sessionBaseUrl: ctx.model?.baseUrl,
|
|
1512
1544
|
sessionAuthMode: authMode,
|
|
1513
1545
|
});
|
|
@@ -130,7 +130,8 @@ export async function runUnit(
|
|
|
130
130
|
unitId,
|
|
131
131
|
error: msg,
|
|
132
132
|
});
|
|
133
|
-
|
|
133
|
+
const isStructural = sessionErr instanceof TypeError || /is not a function/i.test(msg);
|
|
134
|
+
return { status: "cancelled", errorContext: { message: `Session creation failed: ${msg}`, category: "session-failed", isTransient: !isStructural } };
|
|
134
135
|
}
|
|
135
136
|
if (sessionTimeoutHandle) clearTimeout(sessionTimeoutHandle);
|
|
136
137
|
|
|
@@ -29,6 +29,7 @@ import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
|
29
29
|
import { normalizeRealPath } from "../paths.js";
|
|
30
30
|
import type { MilestoneScope } from "../workspace.js";
|
|
31
31
|
import type { RootDirtySnapshot } from "../root-write-leak-guard.js";
|
|
32
|
+
import type { MilestoneSettlementOutcome } from "../milestone-settlement.js";
|
|
32
33
|
|
|
33
34
|
// ─── Exported Types ──────────────────────────────────────────────────────────
|
|
34
35
|
|
|
@@ -230,6 +231,8 @@ export class AutoSession {
|
|
|
230
231
|
/** Set to true after phases.ts successfully calls mergeAndExit, so that
|
|
231
232
|
* stopAuto does not attempt the same merge a second time (#2645). */
|
|
232
233
|
milestoneMergedInPhases = false;
|
|
234
|
+
/** Last milestone settlement result observed by Auto Orchestration. */
|
|
235
|
+
milestoneSettlement: MilestoneSettlementOutcome | null = null;
|
|
233
236
|
|
|
234
237
|
// #4765 — slice-cadence collapse: main-branch SHAs at the moment each
|
|
235
238
|
// milestone's first slice merge began. Used by resquashMilestoneOnMain at
|
|
@@ -410,6 +413,7 @@ export class AutoSession {
|
|
|
410
413
|
this.strandedRecoveryIsolationMode = null;
|
|
411
414
|
this.rootWriteBaseline = null;
|
|
412
415
|
this.milestoneMergedInPhases = false;
|
|
416
|
+
this.milestoneSettlement = null;
|
|
413
417
|
this.milestoneStartShas = new Map();
|
|
414
418
|
this.checkpointSha = null;
|
|
415
419
|
|