@opengsd/gsd-pi 1.2.0-dev.844675c9 → 1.2.0-dev.955e4da0
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/bg-shell/utilities.js +2 -2
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +92 -230
- 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 +142 -15
- package/dist/resources/extensions/gsd/auto/phases.js +34 -4
- 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 +12 -9
- 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 +20 -36
- 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-repair.js +10 -2
- package/dist/resources/extensions/gsd/auto-worktree.js +34 -289
- package/dist/resources/extensions/gsd/auto.js +15 -14
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +28 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +20 -43
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +131 -140
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +89 -8
- package/dist/resources/extensions/gsd/captures.js +5 -13
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +21 -4
- package/dist/resources/extensions/gsd/closeout-recovery.js +3 -2
- package/dist/resources/extensions/gsd/codebase-generator.js +8 -4
- package/dist/resources/extensions/gsd/commands/catalog.js +6 -62
- 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/engine.js +755 -0
- package/dist/resources/extensions/gsd/db/queries.js +372 -0
- package/dist/resources/extensions/gsd/db/sql-constants.js +11 -0
- package/dist/resources/extensions/gsd/db/writers/cascades.js +194 -0
- package/dist/resources/extensions/gsd/db/writers/import-restore.js +182 -0
- package/dist/resources/extensions/gsd/db/writers/memory.js +149 -0
- package/dist/resources/extensions/gsd/db/writers/reconcile.js +458 -0
- package/dist/resources/extensions/gsd/db/writers/status.js +70 -0
- 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-environment.js +8 -10
- package/dist/resources/extensions/gsd/doctor-git-checks.js +4 -3
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +9 -2
- 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/git-service.js +1 -0
- package/dist/resources/extensions/gsd/gitignore.js +3 -0
- package/dist/resources/extensions/gsd/gsd-db.js +183 -2048
- package/dist/resources/extensions/gsd/guided-flow.js +68 -471
- 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 +19 -11
- package/dist/resources/extensions/gsd/migration-auto-check.js +27 -5
- 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/model-cost-table.js +1 -0
- package/dist/resources/extensions/gsd/model-router.js +3 -0
- package/dist/resources/extensions/gsd/parallel-eligibility.js +3 -6
- package/dist/resources/extensions/gsd/parallel-merge.js +14 -11
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +7 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/paths.js +10 -24
- package/dist/resources/extensions/gsd/preferences-diagnostics.js +67 -0
- package/dist/resources/extensions/gsd/preferences.js +161 -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/recovery-classification.js +12 -1
- package/dist/resources/extensions/gsd/roadmap-slices.js +8 -2
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +37 -4
- package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +7 -2
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +10 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +3 -2
- package/dist/resources/extensions/gsd/state-transition-matrix.js +38 -0
- package/dist/resources/extensions/gsd/state.js +13 -5
- package/dist/resources/extensions/gsd/status-guards.js +56 -8
- 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/complete-slice.js +24 -43
- package/dist/resources/extensions/gsd/tools/exec-tool.js +5 -5
- 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/reopen-milestone.js +11 -29
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +14 -33
- package/dist/resources/extensions/gsd/tools/skip-slice.js +18 -36
- 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/undo.js +8 -7
- 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-git-recovery.js +287 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +9 -1
- package/dist/resources/extensions/gsd/worktree-manager.js +45 -28
- package/dist/resources/extensions/gsd/worktree-placement.js +59 -0
- package/dist/resources/extensions/gsd/worktree-reentry.js +12 -8
- package/dist/resources/extensions/gsd/worktree-root.js +17 -6
- package/dist/resources/extensions/gsd/worktree-safety.js +8 -5
- package/dist/resources/extensions/gsd/worktree-session-state.js +12 -10
- 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/resources/skills/gsd-browser/SKILL.md +1 -1
- 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 +12 -12
- 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/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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 +12 -12
- package/dist/web/standalone/.next/server/chunks/{5047.js → 5942.js} +2 -2
- 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/dist/worktree-status-banner.js +7 -3
- 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/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- 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 +32 -22
- 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/image-models.generated.d.ts +2 -2
- package/packages/pi-ai/dist/image-models.generated.js +6 -6
- package/packages/pi-ai/dist/image-models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +295 -98
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +309 -154
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +3 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +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/bg-shell/utilities.ts +2 -2
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +114 -281
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +268 -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 +3 -1
- package/src/resources/extensions/gsd/auto/loop.ts +83 -61
- package/src/resources/extensions/gsd/auto/orchestrator.ts +164 -17
- package/src/resources/extensions/gsd/auto/phases.ts +45 -4
- 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 +16 -8
- 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 +25 -34
- 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-repair.ts +13 -2
- package/src/resources/extensions/gsd/auto-worktree.ts +53 -306
- package/src/resources/extensions/gsd/auto.ts +27 -17
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +29 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +20 -43
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +147 -153
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +132 -6
- package/src/resources/extensions/gsd/captures.ts +5 -14
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +27 -5
- package/src/resources/extensions/gsd/closeout-recovery.ts +2 -1
- package/src/resources/extensions/gsd/codebase-generator.ts +9 -5
- package/src/resources/extensions/gsd/commands/catalog.ts +6 -68
- 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/engine.ts +809 -0
- package/src/resources/extensions/gsd/db/queries.ts +453 -0
- package/src/resources/extensions/gsd/db/sql-constants.ts +12 -0
- package/src/resources/extensions/gsd/db/writers/cascades.ts +237 -0
- package/src/resources/extensions/gsd/db/writers/import-restore.ts +310 -0
- package/src/resources/extensions/gsd/db/writers/memory.ts +220 -0
- package/src/resources/extensions/gsd/db/writers/reconcile.ts +500 -0
- package/src/resources/extensions/gsd/db/writers/status.ts +88 -0
- 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-environment.ts +8 -11
- package/src/resources/extensions/gsd/doctor-git-checks.ts +3 -3
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +10 -3
- 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/git-service.ts +1 -0
- package/src/resources/extensions/gsd/gitignore.ts +3 -0
- package/src/resources/extensions/gsd/gsd-db.ts +185 -2373
- package/src/resources/extensions/gsd/guided-flow.ts +81 -561
- 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 +17 -9
- package/src/resources/extensions/gsd/migration-auto-check.ts +30 -5
- 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/model-cost-table.ts +1 -0
- package/src/resources/extensions/gsd/model-router.ts +3 -0
- package/src/resources/extensions/gsd/parallel-eligibility.ts +4 -5
- package/src/resources/extensions/gsd/parallel-merge.ts +12 -9
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +6 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/paths.ts +9 -22
- 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 +191 -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/recovery-classification.ts +14 -1
- package/src/resources/extensions/gsd/roadmap-slices.ts +8 -2
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +36 -4
- package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +7 -2
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +14 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +6 -2
- package/src/resources/extensions/gsd/state-transition-matrix.ts +42 -0
- package/src/resources/extensions/gsd/state.ts +15 -5
- package/src/resources/extensions/gsd/status-guards.ts +59 -8
- 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 +444 -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-paused-ui-cleanup.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +46 -0
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-worktree-repair.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +22 -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/evidence-xref-gsd-exec.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +33 -1
- 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/integration/auto-worktree-milestone-merge.test.ts +5 -4
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/mcp-tool-name.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +143 -1
- 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/recovery-classification-illegal-transition.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +185 -1
- 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/safety-harness-false-positives.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +80 -0
- package/src/resources/extensions/gsd/tests/session-switch-clears-pending-autostart.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +144 -7
- 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/state-transition-matrix.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/status-guards.test.ts +38 -0
- 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-lifecycle.test.ts +41 -4
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/worktree-placement.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/worktree-projection-writers.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-reentry.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +3 -1
- package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +12 -6
- package/src/resources/extensions/gsd/tests/worktree-teardown-safety.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +121 -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/complete-slice.ts +23 -58
- package/src/resources/extensions/gsd/tools/exec-tool.ts +5 -5
- 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/reopen-milestone.ts +11 -38
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +14 -42
- package/src/resources/extensions/gsd/tools/skip-slice.ts +18 -44
- 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/undo.ts +9 -8
- 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-git-recovery.ts +308 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +17 -17
- package/src/resources/extensions/gsd/worktree-manager.ts +47 -28
- package/src/resources/extensions/gsd/worktree-placement.ts +63 -0
- package/src/resources/extensions/gsd/worktree-reentry.ts +10 -7
- package/src/resources/extensions/gsd/worktree-root.ts +17 -6
- package/src/resources/extensions/gsd/worktree-safety.ts +8 -5
- package/src/resources/extensions/gsd/worktree-session-state.ts +12 -10
- 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/src/resources/skills/gsd-browser/SKILL.md +1 -1
- 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 → C24pqUd-aru-l0Dp0gLZP}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Qbr81pQ-pbQXP4bq2VXLv → C24pqUd-aru-l0Dp0gLZP}/_ssgManifest.js +0 -0
|
@@ -13,7 +13,7 @@ import type { GSDEcosystemBeforeAgentStartHandler } from "../ecosystem/gsd-exten
|
|
|
13
13
|
import { updateSnapshot } from "../ecosystem/gsd-extension-api.js";
|
|
14
14
|
|
|
15
15
|
import { buildMilestoneFileName, clearPathCache, milestonesDir, resolveMilestonePath, resolveSliceFile, resolveSlicePath } from "../paths.js";
|
|
16
|
-
import { canonicalToolName, clearDiscussionFlowState,
|
|
16
|
+
import { applyAskUserQuestionsGateResult, canonicalToolName, clearDiscussionFlowState, formatPendingAskUserQuestionsGateMessage, isApprovalGateVerifiedInSnapshot, isMilestoneDepthVerified, isMilestoneDepthVerifiedInSnapshot, isQueuePhaseActive, loadWriteGateSnapshot, markApprovalGateVerified, markDepthVerified, refreshWriteGateStateFromDisk, resetWriteGateState, shouldBlockContextWrite, shouldBlockPlanningUnit, shouldBlockQueueExecution, shouldBlockWorktreeWrite, isGateQuestionId, setPendingGate, clearPendingGate, getPendingGate, shouldBlockPendingGate, shouldBlockPendingGateBash, extractDepthVerificationMilestoneId } from "./write-gate.js";
|
|
17
17
|
import { resolveManifest } from "../unit-context-manifest.js";
|
|
18
18
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
19
19
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
@@ -25,10 +25,13 @@ import {
|
|
|
25
25
|
isAutoActive,
|
|
26
26
|
isAutoCompletionStopInProgress,
|
|
27
27
|
isAutoPaused,
|
|
28
|
+
isInteractiveElicitationInFlight,
|
|
28
29
|
markToolEnd,
|
|
29
30
|
markToolStart,
|
|
31
|
+
recordAutoToolSurfaceSnapshot,
|
|
30
32
|
recordToolInvocationError,
|
|
31
33
|
} from "../auto-runtime-state.js";
|
|
34
|
+
import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
|
|
32
35
|
|
|
33
36
|
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
34
37
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
@@ -40,17 +43,25 @@ import { logWarning as safetyLogWarning } from "../workflow-logger.js";
|
|
|
40
43
|
import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
41
44
|
import { initNotificationStore } from "../notification-store.js";
|
|
42
45
|
import { initNotificationWidget } from "../notification-widget.js";
|
|
46
|
+
import { notifyPreferenceDiagnostics } from "../preferences-diagnostics.js";
|
|
43
47
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
44
48
|
import { extractSubagentAgentClasses } from "./subagent-input.js";
|
|
45
|
-
import {
|
|
49
|
+
import {
|
|
50
|
+
approvalGateIdForUnit,
|
|
51
|
+
isExplicitApprovalResponse,
|
|
52
|
+
messageHasPendingAskUserQuestionsTool,
|
|
53
|
+
shouldPauseForUserApprovalQuestion,
|
|
54
|
+
} from "../user-input-boundary.js";
|
|
46
55
|
import { resolveSkillManifest } from "../skill-manifest.js";
|
|
47
56
|
import { applyUnitSkillVisibility, unitHasSkillManifest } from "../skill-scope.js";
|
|
48
57
|
import { getGuidedUnitContext } from "../guided-unit-context.js";
|
|
49
58
|
import { registerPlanMilestoneSchemaRecovery } from "./plan-milestone-schema-recovery.js";
|
|
50
|
-
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
59
|
+
import { AUTO_UNIT_SCOPED_TOOLS, RUN_UAT_BROWSER_TOOL_NAMES, canonicalWorkflowToolName, isWorkflowAliasTool } from "../auto-unit-tool-scope.js";
|
|
51
60
|
import { filterToolsForProvider } from "../model-router.js";
|
|
61
|
+
import { mcpToolMatchesBaseName } from "../mcp-tool-name.js";
|
|
52
62
|
import { RUN_UAT_READ_ONLY_TOOL_NAMES, RUN_UAT_WORKFLOW_TOOL_NAMES } from "../tool-presentation-plan.js";
|
|
53
|
-
import {
|
|
63
|
+
import { supportsSourceObservationsForUnit } from "../source-observations.js";
|
|
64
|
+
import { clearPendingAutoStart } from "../pending-auto-start.js";
|
|
54
65
|
|
|
55
66
|
let approvalQuestionAbortInFlight = false;
|
|
56
67
|
|
|
@@ -210,16 +221,22 @@ function resolveScopedToolNames(
|
|
|
210
221
|
|
|
211
222
|
for (const requested of requestedToolNames) {
|
|
212
223
|
const scopedMatches: string[] = [];
|
|
224
|
+
const aliasFallbacks: string[] = [];
|
|
213
225
|
|
|
214
226
|
for (const activeName of activeToolNames) {
|
|
215
|
-
if (
|
|
216
|
-
const toolSeparator = activeName.indexOf("__", "mcp__".length);
|
|
217
|
-
if (toolSeparator < 0) continue;
|
|
218
|
-
if (activeName.slice(toolSeparator + 2) === requested) {
|
|
227
|
+
if (mcpToolMatchesBaseName(activeName, requested)) {
|
|
219
228
|
scopedMatches.push(activeName);
|
|
229
|
+
} else if (isWorkflowAliasTool(activeName) && canonicalWorkflowToolName(activeName) === requested) {
|
|
230
|
+
aliasFallbacks.push(activeName);
|
|
220
231
|
}
|
|
221
232
|
}
|
|
222
233
|
|
|
234
|
+
// Only use alias as fallback when canonical is absent — not directly and not via MCP scoping.
|
|
235
|
+
// Prevents the alias from resurfacing alongside the canonical when both are in the active set.
|
|
236
|
+
if (!exact.has(requested) && scopedMatches.length === 0) {
|
|
237
|
+
scopedMatches.push(...aliasFallbacks);
|
|
238
|
+
}
|
|
239
|
+
|
|
223
240
|
if (requested.startsWith("browser_") && scopedMatches.length > 0) {
|
|
224
241
|
for (const match of scopedMatches) resolved.add(match);
|
|
225
242
|
continue;
|
|
@@ -276,7 +293,7 @@ export function buildRunUatGsdToolSet(
|
|
|
276
293
|
const resolved = [...new Set(scoped)];
|
|
277
294
|
|
|
278
295
|
const unresolved = RUN_UAT_WORKFLOW_TOOL_NAMES.filter(
|
|
279
|
-
(tool) => !resolved.some((name) => name === tool || (name
|
|
296
|
+
(tool) => !resolved.some((name) => name === tool || mcpToolMatchesBaseName(name, tool)),
|
|
280
297
|
);
|
|
281
298
|
if (unresolved.length > 0) {
|
|
282
299
|
safetyLogWarning(
|
|
@@ -368,11 +385,21 @@ function applyMinimalGsdToolSurface(pi: ExtensionAPI): void {
|
|
|
368
385
|
if (isFullGsdToolSurfaceRequested()) return;
|
|
369
386
|
const dash = getAutoRuntimeSnapshot();
|
|
370
387
|
if (dash.active && dash.currentUnit) {
|
|
371
|
-
pi.
|
|
372
|
-
|
|
388
|
+
const currentToolNames = pi.getActiveTools();
|
|
389
|
+
const registeredToolNames = resolveRegisteredToolNames(pi, currentToolNames);
|
|
390
|
+
const scopedToolNames = buildMinimalAutoGsdToolSet(
|
|
391
|
+
currentToolNames,
|
|
373
392
|
dash.currentUnit.type,
|
|
374
|
-
|
|
375
|
-
)
|
|
393
|
+
registeredToolNames,
|
|
394
|
+
);
|
|
395
|
+
recordAutoToolSurfaceSnapshot({
|
|
396
|
+
source: "runtime-scope",
|
|
397
|
+
unitType: dash.currentUnit.type,
|
|
398
|
+
modelFacingToolNames: scopedToolNames,
|
|
399
|
+
registeredToolNames,
|
|
400
|
+
scopedToolNames,
|
|
401
|
+
});
|
|
402
|
+
pi.setActiveTools(scopedToolNames);
|
|
376
403
|
return;
|
|
377
404
|
}
|
|
378
405
|
if (!isGeneralGsdToolScopingRequested()) return;
|
|
@@ -389,6 +416,13 @@ export function scopeGsdWorkflowToolsForDispatch(
|
|
|
389
416
|
const scoped = unitType
|
|
390
417
|
? buildMinimalAutoGsdToolSet(current, unitType, registeredToolNames)
|
|
391
418
|
: buildMinimalGsdWorkflowToolSet(current, registeredToolNames);
|
|
419
|
+
recordAutoToolSurfaceSnapshot({
|
|
420
|
+
source: "dispatch-scope",
|
|
421
|
+
unitType,
|
|
422
|
+
modelFacingToolNames: scoped,
|
|
423
|
+
registeredToolNames,
|
|
424
|
+
scopedToolNames: scoped,
|
|
425
|
+
});
|
|
392
426
|
const toolsChanged = !(scoped.length === current.length && scoped.every((name, index) => name === current[index]));
|
|
393
427
|
const canScopeSkills = unitHasSkillManifest(unitType) && pi.getVisibleSkills && pi.setVisibleSkills;
|
|
394
428
|
if (!toolsChanged && !canScopeSkills) {
|
|
@@ -539,8 +573,14 @@ function isShellExecutionTool(canonicalName: string): boolean {
|
|
|
539
573
|
|
|
540
574
|
function activateDeferredApprovalGate(basePath: string): void {
|
|
541
575
|
if (deferredApprovalGate?.basePath !== basePath) return;
|
|
542
|
-
|
|
576
|
+
const gateId = deferredApprovalGate.gateId;
|
|
543
577
|
deferredApprovalGate = null;
|
|
578
|
+
refreshWriteGateStateFromDisk(basePath);
|
|
579
|
+
const snapshot = loadWriteGateSnapshot(basePath);
|
|
580
|
+
const milestoneId = extractDepthVerificationMilestoneId(gateId);
|
|
581
|
+
if (isApprovalGateVerifiedInSnapshot(snapshot, gateId)) return;
|
|
582
|
+
if (milestoneId && isMilestoneDepthVerifiedInSnapshot(snapshot, milestoneId)) return;
|
|
583
|
+
setPendingGate(gateId, basePath);
|
|
544
584
|
}
|
|
545
585
|
|
|
546
586
|
function extractGateQuestionId(input: unknown): string | undefined {
|
|
@@ -697,6 +737,7 @@ function initSessionNotifications(ctx: ExtensionContext): void {
|
|
|
697
737
|
initNotificationStore(resolveNotificationStoreBasePath(contextBasePath(ctx)));
|
|
698
738
|
installNotifyInterceptor(ctx);
|
|
699
739
|
initNotificationWidget(ctx);
|
|
740
|
+
notifyPreferenceDiagnostics(ctx, contextBasePath(ctx), { surface: "session-start" });
|
|
700
741
|
}
|
|
701
742
|
|
|
702
743
|
async function prepareWorkflowMcpForHookContext(
|
|
@@ -768,7 +809,7 @@ export function registerHooks(
|
|
|
768
809
|
}
|
|
769
810
|
});
|
|
770
811
|
|
|
771
|
-
pi.on("session_switch", async (
|
|
812
|
+
pi.on("session_switch", async (event, ctx) => {
|
|
772
813
|
const basePath = contextBasePath(ctx);
|
|
773
814
|
const preserveCloseoutSurface = isAutoCompletionStopInProgress();
|
|
774
815
|
initSessionNotifications(ctx);
|
|
@@ -777,6 +818,13 @@ export function registerHooks(
|
|
|
777
818
|
clearDeferredApprovalGate();
|
|
778
819
|
await resetAskUserQuestionsTurnCache();
|
|
779
820
|
clearDiscussionFlowState(basePath);
|
|
821
|
+
// /clear or /new destroys the conversation holding a discuss interview, so
|
|
822
|
+
// its pending discuss→auto handoff can never be answered — clear it. Resume
|
|
823
|
+
// restores the interview transcript, so the entry survives. Auto-mode's own
|
|
824
|
+
// newSession() calls are safe: the handoff consumes the entry on agent_end.
|
|
825
|
+
if (event.reason === "new") {
|
|
826
|
+
clearPendingAutoStart(basePath);
|
|
827
|
+
}
|
|
780
828
|
await syncServiceTierStatus(ctx);
|
|
781
829
|
await applyDisabledModelProviderPolicy(ctx);
|
|
782
830
|
await applyCompactionThresholdOverride(ctx);
|
|
@@ -994,6 +1042,18 @@ export function registerHooks(
|
|
|
994
1042
|
|
|
995
1043
|
pi.on("message_update", async (event, ctx: ExtensionContext) => {
|
|
996
1044
|
if (approvalQuestionAbortInFlight) return;
|
|
1045
|
+
// If the model asked via ask_user_questions, that in-flight elicitation IS
|
|
1046
|
+
// the human boundary. Arming the pause/gate here (and emitting the "waiting
|
|
1047
|
+
// for your approval - pausing" notice) would tear it down and trigger the
|
|
1048
|
+
// foreground self-cancel/re-ask loop. The marker is set only by the
|
|
1049
|
+
// claude-code-cli SDK elicitation handler and is ungated, so it is true in
|
|
1050
|
+
// foreground; under the native-TUI provider it is always false and this path
|
|
1051
|
+
// runs unchanged (#cc-elicitation-self-cancel).
|
|
1052
|
+
if (isInteractiveElicitationInFlight()) return;
|
|
1053
|
+
// Prose with "?" can stream before the MCP tool/elicitation starts. When the
|
|
1054
|
+
// structured ask_user_questions call is already in the partial message, the
|
|
1055
|
+
// tool IS the human boundary — do not arm the text-based approval pause.
|
|
1056
|
+
if (messageHasPendingAskUserQuestionsTool(event.message)) return;
|
|
997
1057
|
|
|
998
1058
|
const dash = getAutoRuntimeSnapshot();
|
|
999
1059
|
if (dash.active) return;
|
|
@@ -1328,81 +1388,37 @@ export function registerHooks(
|
|
|
1328
1388
|
|
|
1329
1389
|
const details = event.details as any;
|
|
1330
1390
|
|
|
1331
|
-
// ── Discussion gate enforcement: handle gate question responses ──
|
|
1332
|
-
// If the result is cancelled or has no response, the pending gate stays active
|
|
1333
|
-
// so the model is blocked from non-read-only tools until it re-asks.
|
|
1334
|
-
// If the user responded at all (even "needs adjustment"), clear the pending gate
|
|
1335
|
-
// because the user engaged — the prompt handles the re-ask-after-adjustment flow.
|
|
1336
1391
|
const questions: any[] = (event.input as any)?.questions ?? [];
|
|
1337
|
-
const
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
? "Depth confirmation was interrupted — pausing auto-mode until you respond."
|
|
1355
|
-
: "Depth confirmation is waiting for your answer — pausing auto-mode.",
|
|
1356
|
-
);
|
|
1357
|
-
}
|
|
1358
|
-
return {
|
|
1359
|
-
content: [{
|
|
1360
|
-
type: "text" as const,
|
|
1361
|
-
text: [
|
|
1362
|
-
`Waiting for depth confirmation on gate "${currentPendingGate}".`,
|
|
1363
|
-
interrupted
|
|
1364
|
-
? "The confirmation question was interrupted before a response was recorded."
|
|
1365
|
-
: "No user response was received for the confirmation question.",
|
|
1366
|
-
"Do not infer approval from earlier or prior messages.",
|
|
1367
|
-
"Do not proceed, write files, save artifacts, or call other tools.",
|
|
1368
|
-
`Re-call ask_user_questions with the same gate question id ("${currentPendingGate}") and wait for the user's response.`,
|
|
1369
|
-
].join(" "),
|
|
1370
|
-
}],
|
|
1371
|
-
};
|
|
1372
|
-
} else {
|
|
1373
|
-
const pendingQuestion = questions.find((question) => question?.id === currentPendingGate);
|
|
1374
|
-
if (pendingQuestion) {
|
|
1375
|
-
const answer = details.response?.answers?.[currentPendingGate];
|
|
1376
|
-
if (isDepthConfirmationAnswer(answer?.selected, pendingQuestion.options)) {
|
|
1377
|
-
markApprovalGateVerified(currentPendingGate, basePath);
|
|
1378
|
-
const milestoneIdFromGate = extractDepthVerificationMilestoneId(currentPendingGate);
|
|
1379
|
-
if (milestoneIdFromGate) markDepthVerified(milestoneIdFromGate, basePath);
|
|
1380
|
-
clearPendingGate(basePath);
|
|
1381
|
-
clearDeferredApprovalGate(basePath);
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1392
|
+
const gateResult = applyAskUserQuestionsGateResult({
|
|
1393
|
+
basePath,
|
|
1394
|
+
questions,
|
|
1395
|
+
details,
|
|
1396
|
+
fallbackMilestoneId: milestoneId,
|
|
1397
|
+
});
|
|
1398
|
+
if (gateResult.status === "waiting") {
|
|
1399
|
+
resetToolCallLoopGuard();
|
|
1400
|
+
if (ctx) {
|
|
1401
|
+
await maybePauseAutoForApprovalGate(
|
|
1402
|
+
ctx,
|
|
1403
|
+
pi,
|
|
1404
|
+
true,
|
|
1405
|
+
gateResult.interrupted
|
|
1406
|
+
? "Depth confirmation was interrupted — pausing auto-mode until you respond."
|
|
1407
|
+
: "Depth confirmation is waiting for your answer — pausing auto-mode.",
|
|
1408
|
+
);
|
|
1384
1409
|
}
|
|
1410
|
+
return {
|
|
1411
|
+
content: [{
|
|
1412
|
+
type: "text" as const,
|
|
1413
|
+
text: formatPendingAskUserQuestionsGateMessage(gateResult.pendingGateId, gateResult.interrupted),
|
|
1414
|
+
}],
|
|
1415
|
+
};
|
|
1385
1416
|
}
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
for (const question of questions) {
|
|
1390
|
-
if (typeof question.id === "string" && question.id.includes("depth_verification")) {
|
|
1391
|
-
// Only unlock the gate if the user selected the first option (confirmation).
|
|
1392
|
-
// Cross-references against the question's defined options to reject free-form "Other" text.
|
|
1393
|
-
const answer = details.response?.answers?.[question.id];
|
|
1394
|
-
const inferredMilestoneId = extractDepthVerificationMilestoneId(question.id) ?? milestoneId;
|
|
1395
|
-
if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
|
|
1396
|
-
if (currentPendingGate && question.id !== currentPendingGate) break;
|
|
1397
|
-
markApprovalGateVerified(question.id, basePath);
|
|
1398
|
-
markDepthVerified(inferredMilestoneId, basePath);
|
|
1399
|
-
clearPendingGate(basePath);
|
|
1400
|
-
clearDeferredApprovalGate(basePath);
|
|
1401
|
-
}
|
|
1402
|
-
break;
|
|
1403
|
-
}
|
|
1417
|
+
if (gateResult.status === "verified") {
|
|
1418
|
+
clearDeferredApprovalGate(basePath);
|
|
1404
1419
|
}
|
|
1405
1420
|
|
|
1421
|
+
if (details?.cancelled || !details?.response) return;
|
|
1406
1422
|
if (!milestoneId) return;
|
|
1407
1423
|
await saveDiscussionQuestionRound(basePath, milestoneId, questions, details);
|
|
1408
1424
|
});
|
|
@@ -1417,6 +1433,21 @@ export function registerHooks(
|
|
|
1417
1433
|
clearDeferredApprovalGate(basePath);
|
|
1418
1434
|
}
|
|
1419
1435
|
}
|
|
1436
|
+
|
|
1437
|
+
// Safety harness: record evidence here, not only in tool_call. External
|
|
1438
|
+
// engines (claude-code-cli) pre-execute tools, so the agent loop skips
|
|
1439
|
+
// beforeToolCall/tool_call for them — tool_execution_start is the only
|
|
1440
|
+
// event that fires for every tool call. recordToolCall dedupes by
|
|
1441
|
+
// toolCallId, so native tools (which hit both events) record once.
|
|
1442
|
+
safetyRecordToolCall(event.toolCallId, event.toolName, (event.args ?? {}) as Record<string, unknown>);
|
|
1443
|
+
const execDash = getAutoRuntimeSnapshot();
|
|
1444
|
+
if (execDash.basePath && execDash.currentUnit?.type === "execute-task") {
|
|
1445
|
+
const { milestone: xMid, slice: xSid, task: xTid } = parseUnitId(execDash.currentUnit.id);
|
|
1446
|
+
if (xMid && xSid && xTid) {
|
|
1447
|
+
saveEvidenceToDisk(execDash.basePath, xMid, xSid, xTid);
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
|
|
1420
1451
|
if (!isAutoActive()) return;
|
|
1421
1452
|
markToolStart(event.toolCallId, event.toolName);
|
|
1422
1453
|
});
|
|
@@ -1458,66 +1489,10 @@ export function registerHooks(
|
|
|
1458
1489
|
const payload = event.payload as Record<string, unknown> | null;
|
|
1459
1490
|
if (!payload || typeof payload !== "object") return;
|
|
1460
1491
|
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
const {
|
|
1466
|
-
createObservationMask,
|
|
1467
|
-
createResponsesInputObservationMask,
|
|
1468
|
-
truncateContextResultMessages,
|
|
1469
|
-
truncateResponsesInputResultItems,
|
|
1470
|
-
} = await import("../context-masker.js");
|
|
1471
|
-
const prefs = loadEffectiveGSDPreferences();
|
|
1472
|
-
const cmConfig = prefs?.preferences.context_management;
|
|
1473
|
-
|
|
1474
|
-
// Observation masking: replace old tool results with placeholders.
|
|
1475
|
-
// Only active during auto-mode when context_management.observation_masking is enabled.
|
|
1476
|
-
if (isAutoActive() && cmConfig?.observation_masking !== false) {
|
|
1477
|
-
const keepTurns = cmConfig?.observation_mask_turns ?? 8;
|
|
1478
|
-
const messages = payload.messages;
|
|
1479
|
-
if (Array.isArray(messages)) {
|
|
1480
|
-
payload.messages = createObservationMask(keepTurns)(messages);
|
|
1481
|
-
}
|
|
1482
|
-
const input = payload.input;
|
|
1483
|
-
if (Array.isArray(input)) {
|
|
1484
|
-
payload.input = createResponsesInputObservationMask(keepTurns)(input);
|
|
1485
|
-
}
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
|
-
// Tool result truncation: cap individual tool result content length.
|
|
1489
|
-
// Applies in ALL modes (auto + interactive) to prevent context bloat.
|
|
1490
|
-
// In pi-ai format, toolResult messages have role: "toolResult" and content: TextContent[].
|
|
1491
|
-
// Creates new objects to avoid mutating shared conversation state.
|
|
1492
|
-
const maxChars = cmConfig?.tool_result_max_chars ?? 800;
|
|
1493
|
-
const msgs = payload.messages;
|
|
1494
|
-
if (Array.isArray(msgs)) {
|
|
1495
|
-
payload.messages = truncateContextResultMessages(msgs as any, maxChars);
|
|
1496
|
-
}
|
|
1497
|
-
const input = payload.input;
|
|
1498
|
-
if (Array.isArray(input)) {
|
|
1499
|
-
payload.input = truncateResponsesInputResultItems(input as any, maxChars);
|
|
1500
|
-
}
|
|
1501
|
-
} catch { /* non-fatal */ }
|
|
1502
|
-
|
|
1503
|
-
try {
|
|
1504
|
-
if (isAutoActive()) {
|
|
1505
|
-
const sourceContextBlock = getSourceObservationStore().renderActiveBlock();
|
|
1506
|
-
if (sourceContextBlock) {
|
|
1507
|
-
const nextPayload = injectSourceContextBlockIntoPayload(payload, sourceContextBlock);
|
|
1508
|
-
Object.assign(payload, nextPayload);
|
|
1509
|
-
}
|
|
1510
|
-
}
|
|
1511
|
-
} catch { /* non-fatal */ }
|
|
1512
|
-
|
|
1513
|
-
// ── Service Tier ────────────────────────────────────────────────────
|
|
1514
|
-
const modelId = event.model?.id;
|
|
1515
|
-
if (!modelId) return payload;
|
|
1516
|
-
const { getEffectiveServiceTier, supportsServiceTier } = await import("../service-tier.js");
|
|
1517
|
-
const tier = getEffectiveServiceTier();
|
|
1518
|
-
if (!tier || !supportsServiceTier(modelId)) return payload;
|
|
1519
|
-
payload.service_tier = tier;
|
|
1520
|
-
return payload;
|
|
1492
|
+
return applyProviderPayloadPolicy({
|
|
1493
|
+
payload,
|
|
1494
|
+
modelId: event.model?.id,
|
|
1495
|
+
});
|
|
1521
1496
|
});
|
|
1522
1497
|
|
|
1523
1498
|
// Capability-aware model routing hook (ADR-004)
|
|
@@ -1559,25 +1534,44 @@ export function registerHooks(
|
|
|
1559
1534
|
event.selectedModelProvider,
|
|
1560
1535
|
).compatible.filter((name) => !(dropAliases && isWorkflowAliasTool(name)));
|
|
1561
1536
|
const guidedUnit = getGuidedUnitContext();
|
|
1537
|
+
const requestRegisteredToolNames = guidedUnit?.unitType === "run-uat"
|
|
1538
|
+
? compatibleRegisteredToolNames
|
|
1539
|
+
: registeredToolNames;
|
|
1562
1540
|
const requestScoped = buildRequestScopedGsdToolSet(
|
|
1563
1541
|
guidedUnit?.unitType === "run-uat" ? aliasFilteredCompatible : providerCompatible,
|
|
1564
1542
|
event.requestCustomMessages,
|
|
1565
|
-
|
|
1543
|
+
requestRegisteredToolNames,
|
|
1566
1544
|
guidedUnit?.unitType,
|
|
1567
1545
|
);
|
|
1568
1546
|
if (requestScoped) {
|
|
1547
|
+
recordAutoToolSurfaceSnapshot({
|
|
1548
|
+
source: "provider-adjustment",
|
|
1549
|
+
unitType: guidedUnit?.unitType,
|
|
1550
|
+
modelFacingToolNames: requestScoped,
|
|
1551
|
+
registeredToolNames: requestRegisteredToolNames,
|
|
1552
|
+
scopedToolNames: requestScoped,
|
|
1553
|
+
});
|
|
1569
1554
|
return { toolNames: requestScoped };
|
|
1570
1555
|
}
|
|
1571
1556
|
const dash = getAutoRuntimeSnapshot();
|
|
1572
1557
|
if (dash.active && dash.currentUnit) {
|
|
1558
|
+
const registeredForUnit = dash.currentUnit.type === "run-uat"
|
|
1559
|
+
? compatibleRegisteredToolNames
|
|
1560
|
+
: resolveRegisteredToolNames(pi, event.activeToolNames);
|
|
1561
|
+
const scopedToolNames = buildMinimalAutoGsdToolSet(
|
|
1562
|
+
dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible,
|
|
1563
|
+
dash.currentUnit.type,
|
|
1564
|
+
registeredForUnit,
|
|
1565
|
+
);
|
|
1566
|
+
recordAutoToolSurfaceSnapshot({
|
|
1567
|
+
source: "provider-adjustment",
|
|
1568
|
+
unitType: dash.currentUnit.type,
|
|
1569
|
+
modelFacingToolNames: scopedToolNames,
|
|
1570
|
+
registeredToolNames: registeredForUnit,
|
|
1571
|
+
scopedToolNames,
|
|
1572
|
+
});
|
|
1573
1573
|
return {
|
|
1574
|
-
toolNames:
|
|
1575
|
-
dash.currentUnit.type === "run-uat" ? aliasFilteredCompatible : providerCompatible,
|
|
1576
|
-
dash.currentUnit.type,
|
|
1577
|
-
dash.currentUnit.type === "run-uat"
|
|
1578
|
-
? compatibleRegisteredToolNames
|
|
1579
|
-
: resolveRegisteredToolNames(pi, event.activeToolNames),
|
|
1580
|
-
),
|
|
1574
|
+
toolNames: scopedToolNames,
|
|
1581
1575
|
};
|
|
1582
1576
|
}
|
|
1583
1577
|
if (isGeneralGsdToolScopingRequested()) {
|
|
@@ -5,10 +5,12 @@ import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
|
5
5
|
import { minimatch } from "minimatch";
|
|
6
6
|
|
|
7
7
|
import { GSD_PHASE_SCOPE_DISPLAY_REASON, shouldBlockAutoUnitToolCall } from "../auto-unit-tool-scope.js";
|
|
8
|
+
import { stripMcpToolPrefix } from "../mcp-tool-name.js";
|
|
8
9
|
import { getIsolationMode } from "../preferences.js";
|
|
9
10
|
import { compileSubagentPermissionContract, type ToolsPolicy } from "../unit-context-manifest.js";
|
|
10
11
|
import { logWarning } from "../workflow-logger.js";
|
|
11
12
|
import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
13
|
+
import { worktreesDirs } from "../worktree-placement.js";
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Regex matching milestone CONTEXT.md file names in both legacy M001
|
|
@@ -123,9 +125,7 @@ const GATE_SAFE_TOOLS = new Set([
|
|
|
123
125
|
]);
|
|
124
126
|
|
|
125
127
|
export function canonicalToolName(toolName: string): string {
|
|
126
|
-
|
|
127
|
-
const toolSeparator = toolName.indexOf("__", "mcp__".length);
|
|
128
|
-
return toolSeparator >= 0 ? toolName.slice(toolSeparator + 2) : toolName;
|
|
128
|
+
return stripMcpToolPrefix(toolName);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
export interface WriteGateSnapshot {
|
|
@@ -245,6 +245,23 @@ export function loadWriteGateSnapshot(basePath: string): WriteGateSnapshot {
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
+
/**
|
|
249
|
+
* Merge the persisted write-gate snapshot into the in-process Map entry.
|
|
250
|
+
* The workflow MCP server runs in a child process and records depth
|
|
251
|
+
* verification there; without this refresh the extension host keeps stale
|
|
252
|
+
* pending-gate memory and `activateDeferredApprovalGate` can re-arm a gate
|
|
253
|
+
* that the subprocess already cleared on disk.
|
|
254
|
+
*/
|
|
255
|
+
export function refreshWriteGateStateFromDisk(basePath: string): void {
|
|
256
|
+
if (!shouldPersistWriteGateSnapshot()) return;
|
|
257
|
+
const snapshot = loadWriteGateSnapshot(basePath);
|
|
258
|
+
const state = getWriteGateState(basePath);
|
|
259
|
+
state.pendingGateId = snapshot.pendingGateId;
|
|
260
|
+
state.activeQueuePhase = snapshot.activeQueuePhase;
|
|
261
|
+
state.verifiedDepthMilestones = new Set(snapshot.verifiedDepthMilestones);
|
|
262
|
+
state.verifiedApprovalGates = new Set(snapshot.verifiedApprovalGates ?? []);
|
|
263
|
+
}
|
|
264
|
+
|
|
248
265
|
export function isDepthVerified(basePath: string = process.cwd()): boolean {
|
|
249
266
|
return getWriteGateState(basePath).verifiedDepthMilestones.size > 0;
|
|
250
267
|
}
|
|
@@ -257,6 +274,7 @@ export function isMilestoneDepthVerified(
|
|
|
257
274
|
basePath: string = process.cwd(),
|
|
258
275
|
): boolean {
|
|
259
276
|
if (!milestoneId) return false;
|
|
277
|
+
refreshWriteGateStateFromDisk(basePath);
|
|
260
278
|
return getWriteGateState(basePath).verifiedDepthMilestones.has(milestoneId);
|
|
261
279
|
}
|
|
262
280
|
|
|
@@ -358,6 +376,7 @@ export function clearPendingGate(basePath: string): void {
|
|
|
358
376
|
* Get the currently pending gate, if any.
|
|
359
377
|
*/
|
|
360
378
|
export function getPendingGate(basePath: string = process.cwd()): string | null {
|
|
379
|
+
refreshWriteGateStateFromDisk(basePath);
|
|
361
380
|
return getWriteGateState(basePath).pendingGateId;
|
|
362
381
|
}
|
|
363
382
|
|
|
@@ -462,6 +481,111 @@ export function isDepthConfirmationAnswer(
|
|
|
462
481
|
return false;
|
|
463
482
|
}
|
|
464
483
|
|
|
484
|
+
export interface AskUserQuestionsGateQuestion {
|
|
485
|
+
id?: unknown;
|
|
486
|
+
options?: Array<{ label?: string }>;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
export interface AskUserQuestionsGateDetails {
|
|
490
|
+
cancelled?: boolean;
|
|
491
|
+
interrupted?: boolean;
|
|
492
|
+
response?: {
|
|
493
|
+
answers?: Record<string, { selected?: unknown } | undefined>;
|
|
494
|
+
} | null;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export type AskUserQuestionsGateResult =
|
|
498
|
+
| { status: "not-gate" }
|
|
499
|
+
| { status: "waiting"; pendingGateId: string; interrupted: boolean }
|
|
500
|
+
| { status: "verified"; gateId: string; milestoneId: string | null }
|
|
501
|
+
| { status: "answered"; gateId: string };
|
|
502
|
+
|
|
503
|
+
function findGateQuestion(
|
|
504
|
+
questions: AskUserQuestionsGateQuestion[],
|
|
505
|
+
gateId: string,
|
|
506
|
+
): AskUserQuestionsGateQuestion | undefined {
|
|
507
|
+
return questions.find((question) => question?.id === gateId);
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function readSelectedGateAnswer(
|
|
511
|
+
details: AskUserQuestionsGateDetails,
|
|
512
|
+
questionId: string,
|
|
513
|
+
): unknown {
|
|
514
|
+
return details.response?.answers?.[questionId]?.selected;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
function verifyAnsweredGate(
|
|
518
|
+
basePath: string,
|
|
519
|
+
question: AskUserQuestionsGateQuestion,
|
|
520
|
+
fallbackMilestoneId?: string | null,
|
|
521
|
+
): AskUserQuestionsGateResult {
|
|
522
|
+
const gateId = typeof question.id === "string" ? question.id : "";
|
|
523
|
+
const milestoneId = extractDepthVerificationMilestoneId(gateId) ?? fallbackMilestoneId ?? null;
|
|
524
|
+
markApprovalGateVerified(gateId, basePath);
|
|
525
|
+
markDepthVerified(milestoneId, basePath);
|
|
526
|
+
clearPendingGate(basePath);
|
|
527
|
+
return { status: "verified", gateId, milestoneId };
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
export function applyAskUserQuestionsGateResult(options: {
|
|
531
|
+
basePath: string;
|
|
532
|
+
questions: AskUserQuestionsGateQuestion[];
|
|
533
|
+
details: AskUserQuestionsGateDetails;
|
|
534
|
+
fallbackMilestoneId?: string | null;
|
|
535
|
+
}): AskUserQuestionsGateResult {
|
|
536
|
+
const { basePath, questions, details, fallbackMilestoneId } = options;
|
|
537
|
+
const currentPendingGate = getPendingGate(basePath);
|
|
538
|
+
if (currentPendingGate) {
|
|
539
|
+
if (details.cancelled || !details.response) {
|
|
540
|
+
return {
|
|
541
|
+
status: "waiting",
|
|
542
|
+
pendingGateId: currentPendingGate,
|
|
543
|
+
interrupted: details.interrupted === true,
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
const pendingQuestion = findGateQuestion(questions, currentPendingGate);
|
|
548
|
+
if (pendingQuestion) {
|
|
549
|
+
const selected = readSelectedGateAnswer(details, currentPendingGate);
|
|
550
|
+
if (isDepthConfirmationAnswer(selected, pendingQuestion.options)) {
|
|
551
|
+
return verifyAnsweredGate(basePath, pendingQuestion, fallbackMilestoneId);
|
|
552
|
+
}
|
|
553
|
+
return { status: "answered", gateId: currentPendingGate };
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (details.cancelled || !details.response) return { status: "not-gate" };
|
|
558
|
+
|
|
559
|
+
for (const question of questions) {
|
|
560
|
+
if (typeof question.id !== "string" || !isGateQuestionId(question.id)) continue;
|
|
561
|
+
const selected = readSelectedGateAnswer(details, question.id);
|
|
562
|
+
if (!isDepthConfirmationAnswer(selected, question.options)) {
|
|
563
|
+
return { status: "answered", gateId: question.id };
|
|
564
|
+
}
|
|
565
|
+
if (currentPendingGate && question.id !== currentPendingGate) {
|
|
566
|
+
return { status: "answered", gateId: currentPendingGate };
|
|
567
|
+
}
|
|
568
|
+
return verifyAnsweredGate(basePath, question, fallbackMilestoneId);
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return { status: "not-gate" };
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
export function formatPendingAskUserQuestionsGateMessage(
|
|
575
|
+
pendingGateId: string,
|
|
576
|
+
interrupted: boolean,
|
|
577
|
+
): string {
|
|
578
|
+
return [
|
|
579
|
+
`Waiting for depth confirmation on gate "${pendingGateId}".`,
|
|
580
|
+
interrupted
|
|
581
|
+
? "The confirmation question was interrupted before a response was recorded."
|
|
582
|
+
: "No user response was received for the confirmation question.",
|
|
583
|
+
"Do not infer approval from earlier or prior messages.",
|
|
584
|
+
"Do not proceed, write files, save artifacts, or call other tools.",
|
|
585
|
+
`Re-call ask_user_questions with the same gate question id ("${pendingGateId}") and wait for the user's response.`,
|
|
586
|
+
].join(" ");
|
|
587
|
+
}
|
|
588
|
+
|
|
465
589
|
export function shouldBlockContextWrite(
|
|
466
590
|
toolName: string,
|
|
467
591
|
inputPath: string,
|
|
@@ -1034,10 +1158,12 @@ export function shouldBlockWorktreeWrite(
|
|
|
1034
1158
|
const realTarget = realpathOrResolve(absTarget);
|
|
1035
1159
|
const realRoot = realpathOrResolve(projectRoot);
|
|
1036
1160
|
const realGsd = realpathOrResolve(join(projectRoot, ".gsd"));
|
|
1037
|
-
const realWorktreesDir = realpathOrResolve(join(projectRoot, ".gsd", "worktrees"));
|
|
1038
1161
|
|
|
1039
|
-
// Allow writes inside
|
|
1040
|
-
|
|
1162
|
+
// Allow writes inside a legitimate worktrees subtree (canonical
|
|
1163
|
+
// .gsd-worktrees/ or legacy .gsd/worktrees/).
|
|
1164
|
+
for (const container of worktreesDirs(projectRoot)) {
|
|
1165
|
+
if (isPathContained(realTarget, realpathOrResolve(container))) return { block: false };
|
|
1166
|
+
}
|
|
1041
1167
|
|
|
1042
1168
|
// Allow writes to .gsd/ planning artifacts, but reject siblings whose name
|
|
1043
1169
|
// starts with "worktrees" (the worktrees-extra prefix trick — case 4).
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
12
|
-
import { join, resolve
|
|
12
|
+
import { join, resolve } from "node:path";
|
|
13
13
|
import { randomUUID } from "node:crypto";
|
|
14
14
|
import { gsdRoot } from "./paths.js";
|
|
15
|
+
import { findWorktreeSegment } from "./worktree-root.js";
|
|
15
16
|
|
|
16
17
|
// ─── Types ────────────────────────────────────────────────────────────────────
|
|
17
18
|
|
|
@@ -60,20 +61,10 @@ const VALID_CLASSIFICATIONS: readonly string[] = [
|
|
|
60
61
|
*/
|
|
61
62
|
export function resolveCapturesPath(basePath: string): string {
|
|
62
63
|
const resolved = resolve(basePath);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
let idx = resolved.indexOf(worktreeMarker);
|
|
66
|
-
if (idx === -1) {
|
|
67
|
-
// Symlink-resolved layout: /.gsd/projects/<hash>/worktrees/
|
|
68
|
-
const symlinkRe = new RegExp(
|
|
69
|
-
`\\${sep}\\.gsd\\${sep}projects\\${sep}[a-f0-9]+\\${sep}worktrees\\${sep}`,
|
|
70
|
-
);
|
|
71
|
-
const match = resolved.match(symlinkRe);
|
|
72
|
-
if (match && match.index !== undefined) idx = match.index;
|
|
73
|
-
}
|
|
74
|
-
if (idx !== -1) {
|
|
64
|
+
const segment = findWorktreeSegment(resolved.replaceAll("\\", "/"));
|
|
65
|
+
if (segment) {
|
|
75
66
|
// basePath is inside a worktree — resolve to project root
|
|
76
|
-
const projectRoot = resolved.slice(0,
|
|
67
|
+
const projectRoot = resolved.slice(0, segment.gsdIdx);
|
|
77
68
|
return join(projectRoot, ".gsd", CAPTURES_FILENAME);
|
|
78
69
|
}
|
|
79
70
|
return join(gsdRoot(basePath), CAPTURES_FILENAME);
|