@opengsd/gsd-pi 1.9.0 → 1.10.0-dev.a5e42e99
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/README.md +10 -9
- package/dist/headless.js +2 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/GSD-WORKFLOW.md +2 -2
- package/dist/resources/extensions/gsd/artifact-verification.js +3 -4
- package/dist/resources/extensions/gsd/auto/loop.js +24 -4
- package/dist/resources/extensions/gsd/auto/run-unit.js +19 -1
- package/dist/resources/extensions/gsd/auto/unit-phase.js +37 -5
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +14 -8
- package/dist/resources/extensions/gsd/auto-dispatch.js +2 -0
- package/dist/resources/extensions/gsd/auto-model-selection.js +1 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +102 -21
- package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
- package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -5
- package/dist/resources/extensions/gsd/auto-start.js +30 -10
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +40 -0
- package/dist/resources/extensions/gsd/auto-verification.js +25 -12
- package/dist/resources/extensions/gsd/auto-worktree-cleanup.js +4 -0
- package/dist/resources/extensions/gsd/auto-worktree-sync.js +7 -3
- package/dist/resources/extensions/gsd/auto-worktree-teardown.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +15 -5
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -7
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +7 -26
- package/dist/resources/extensions/gsd/commands-verdict.js +10 -9
- package/dist/resources/extensions/gsd/compat/compat-marker.js +80 -5
- package/dist/resources/extensions/gsd/constants.js +12 -13
- package/dist/resources/extensions/gsd/context-masker.js +97 -21
- package/dist/resources/extensions/gsd/db/engine.js +5 -2
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +33 -2
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +40 -12
- package/dist/resources/extensions/gsd/error-classifier.js +12 -2
- package/dist/resources/extensions/gsd/exec-sandbox.js +1 -0
- package/dist/resources/extensions/gsd/flat-phase-migration.js +12 -0
- package/dist/resources/extensions/gsd/git-service.js +19 -7
- package/dist/resources/extensions/gsd/gsd-db.js +75 -31
- package/dist/resources/extensions/gsd/guided-flow.js +11 -5
- package/dist/resources/extensions/gsd/markdown-renderer.js +5 -21
- package/dist/resources/extensions/gsd/md-importer.js +5 -6
- package/dist/resources/extensions/gsd/model-cost-table.js +6 -1
- package/dist/resources/extensions/gsd/model-router.js +16 -0
- package/dist/resources/extensions/gsd/paths.js +66 -15
- package/dist/resources/extensions/gsd/planning-subagent-policy.js +37 -0
- package/dist/resources/extensions/gsd/planning-subagent-registry.js +33 -0
- package/dist/resources/extensions/gsd/preferences-models.js +50 -10
- package/dist/resources/extensions/gsd/preferences-types.js +6 -0
- package/dist/resources/extensions/gsd/preferences-validation.js +86 -4
- package/dist/resources/extensions/gsd/preferences.js +24 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
- package/dist/resources/extensions/gsd/provider-payload-policy.js +16 -5
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +1 -1
- package/dist/resources/extensions/gsd/skill-activation.js +17 -3
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +98 -2
- package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +4 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +5 -2
- package/dist/resources/extensions/gsd/stop-notice.js +9 -0
- package/dist/resources/extensions/gsd/templates/PREFERENCES.md +8 -0
- package/dist/resources/extensions/gsd/tools/complete-task.js +12 -5
- package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -1
- package/dist/resources/extensions/gsd/tools/reopen-milestone.js +14 -5
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +15 -5
- package/dist/resources/extensions/gsd/tools/reopen-task.js +16 -10
- package/dist/resources/extensions/gsd/unit-context-composer.js +28 -5
- package/dist/resources/extensions/gsd/verification-evidence.js +5 -3
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -3
- package/dist/resources/extensions/gsd/workspace.js +2 -1
- package/dist/resources/extensions/gsd/worktree-state-projection.js +20 -18
- package/dist/resources/extensions/ollama/ollama-chat-provider.js +2 -2
- package/dist/resources/extensions/shared/interview-ui.js +43 -6
- package/dist/resources/extensions/subagent/index.js +1 -1
- package/dist/startup-model-validation.d.ts +1 -1
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
- 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/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- 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/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- 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 +3 -3
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- 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 +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
- package/dist/web/standalone/.next/server/chunks/1991.js +2 -2
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
- package/dist/web/standalone/.next/server/chunks/8357.js +3 -3
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +3 -3
- 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/app/_not-found/page-a6fb1847f67f167c.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-b35cbfff38aaf4cf.js → layout-4ae2d68984392bbf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-72a856634ad14c10.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-590a74400e35f685.js → main-app-90d1d8d5e5d2dc6b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +1 -0
- package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/integrations/hermes/open_gsd_hermes/gsd_client.py +1 -1
- package/integrations/hermes/pyproject.toml +1 -1
- package/package.json +8 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/rpc.d.ts +1 -1
- package/packages/contracts/dist/rpc.d.ts.map +1 -1
- package/packages/contracts/dist/rpc.js +1 -1
- package/packages/contracts/dist/rpc.js.map +1 -1
- package/packages/contracts/dist/rpc.test.js +1 -1
- package/packages/contracts/dist/rpc.test.js.map +1 -1
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/compaction/compaction.js +36 -4
- package/packages/gsd-agent-core/dist/compaction/compaction.js.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +1 -0
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/cli/args.js +2 -2
- package/packages/gsd-agent-modes/dist/cli/args.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/thinking-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/gsd-cloud/README.md +21 -5
- package/packages/gsd-cloud/dist/background-cli.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/background-cli.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/background-cli.test.js +325 -0
- package/packages/gsd-cloud/dist/background-cli.test.js.map +1 -0
- package/packages/gsd-cloud/dist/cli.d.ts.map +1 -1
- package/packages/gsd-cloud/dist/cli.js +146 -16
- package/packages/gsd-cloud/dist/cli.js.map +1 -1
- package/packages/gsd-cloud/dist/cloud-config.d.ts +1 -1
- package/packages/gsd-cloud/dist/cloud-config.d.ts.map +1 -1
- package/packages/gsd-cloud/dist/cloud-config.js +7 -1
- package/packages/gsd-cloud/dist/cloud-config.js.map +1 -1
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts +7 -4
- package/packages/gsd-cloud/dist/cloud-runtime.d.ts.map +1 -1
- package/packages/gsd-cloud/dist/cloud-runtime.js +115 -31
- package/packages/gsd-cloud/dist/cloud-runtime.js.map +1 -1
- package/packages/gsd-cloud/dist/cloud-runtime.test.js +224 -59
- package/packages/gsd-cloud/dist/cloud-runtime.test.js.map +1 -1
- package/packages/gsd-cloud/dist/runtime-artifacts.d.ts +3 -0
- package/packages/gsd-cloud/dist/runtime-artifacts.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-artifacts.js +36 -0
- package/packages/gsd-cloud/dist/runtime-artifacts.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.d.ts +32 -0
- package/packages/gsd-cloud/dist/runtime-process.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.js +640 -0
- package/packages/gsd-cloud/dist/runtime-process.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/runtime-process.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-process.test.js +543 -0
- package/packages/gsd-cloud/dist/runtime-process.test.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.d.ts +117 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.js +291 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.js.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.d.ts +2 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.d.ts.map +1 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.js +434 -0
- package/packages/gsd-cloud/dist/runtime-telemetry.test.js.map +1 -0
- package/packages/gsd-cloud/package.json +2 -2
- package/packages/mcp-server/README.md +7 -2
- package/packages/mcp-server/dist/cli-runner.d.ts +3 -0
- package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
- package/packages/mcp-server/dist/cli-runner.js +119 -33
- package/packages/mcp-server/dist/cli-runner.js.map +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +5 -5
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +4 -3
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +4 -4
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +5 -1
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +2 -0
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/types.d.ts +2 -2
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +187 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +145 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.js +18 -6
- package/packages/pi-ai/dist/models.js.map +1 -1
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +3 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +6 -1
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/azure-openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/google-vertex.js.map +1 -1
- package/packages/pi-ai/dist/providers/google.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +103 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js +1 -1
- package/packages/pi-ai/dist/providers/openai-responses.js.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts +1 -1
- package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js +1 -1
- package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +9 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js +1 -1
- package/packages/pi-coding-agent/dist/core/capability-patches.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +2 -2
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +14 -4
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +8 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/skills.js +54 -0
- package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +1 -0
- package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme.d.ts +1 -1
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +1 -0
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +2 -2
- package/src/resources/extensions/gsd/artifact-verification.ts +3 -8
- package/src/resources/extensions/gsd/auto/loop.ts +48 -4
- package/src/resources/extensions/gsd/auto/run-unit.ts +20 -1
- package/src/resources/extensions/gsd/auto/unit-phase.ts +41 -5
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +14 -7
- package/src/resources/extensions/gsd/auto-dispatch.ts +1 -0
- package/src/resources/extensions/gsd/auto-model-selection.ts +1 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +118 -19
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -8
- package/src/resources/extensions/gsd/auto-runtime-state.ts +12 -7
- package/src/resources/extensions/gsd/auto-start.ts +32 -9
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +56 -0
- package/src/resources/extensions/gsd/auto-verification.ts +46 -12
- package/src/resources/extensions/gsd/auto-worktree-cleanup.ts +4 -0
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +10 -3
- package/src/resources/extensions/gsd/auto-worktree-teardown.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +20 -7
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +1 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +41 -12
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +11 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +10 -31
- package/src/resources/extensions/gsd/commands-verdict.ts +16 -9
- package/src/resources/extensions/gsd/compat/compat-marker.ts +99 -5
- package/src/resources/extensions/gsd/constants.ts +14 -13
- package/src/resources/extensions/gsd/context-masker.ts +98 -2
- package/src/resources/extensions/gsd/db/engine.ts +5 -2
- package/src/resources/extensions/gsd/docs/preferences-reference.md +33 -2
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +45 -11
- package/src/resources/extensions/gsd/error-classifier.ts +13 -2
- package/src/resources/extensions/gsd/exec-sandbox.ts +1 -0
- package/src/resources/extensions/gsd/flat-phase-migration.ts +14 -0
- package/src/resources/extensions/gsd/git-service.ts +19 -6
- package/src/resources/extensions/gsd/gsd-db.ts +85 -33
- package/src/resources/extensions/gsd/guided-flow.ts +11 -4
- package/src/resources/extensions/gsd/markdown-renderer.ts +5 -23
- package/src/resources/extensions/gsd/md-importer.ts +5 -5
- package/src/resources/extensions/gsd/model-cost-table.ts +14 -1
- package/src/resources/extensions/gsd/model-router.ts +17 -0
- package/src/resources/extensions/gsd/paths.ts +73 -15
- package/src/resources/extensions/gsd/planning-subagent-policy.ts +58 -0
- package/src/resources/extensions/gsd/planning-subagent-registry.ts +45 -0
- package/src/resources/extensions/gsd/preferences-models.ts +54 -10
- package/src/resources/extensions/gsd/preferences-types.ts +26 -2
- package/src/resources/extensions/gsd/preferences-validation.ts +108 -3
- package/src/resources/extensions/gsd/preferences.ts +38 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -5
- package/src/resources/extensions/gsd/provider-payload-policy.ts +18 -4
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +1 -1
- package/src/resources/extensions/gsd/skill-activation.ts +17 -3
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +132 -2
- package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +4 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +4 -2
- package/src/resources/extensions/gsd/stop-notice.ts +11 -0
- package/src/resources/extensions/gsd/templates/PREFERENCES.md +8 -0
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +7 -7
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +74 -1
- package/src/resources/extensions/gsd/tests/before-provider-context-management.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/compat-marker.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +76 -1
- package/src/resources/extensions/gsd/tests/context-masker.test.ts +204 -8
- package/src/resources/extensions/gsd/tests/db-engine-cjs-compat.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/db-tools-alias-suppression.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/destructive-confirmation.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +147 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +33 -1
- package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +8 -9
- package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +13 -0
- package/src/resources/extensions/gsd/tests/integration/paths.test.ts +22 -4
- package/src/resources/extensions/gsd/tests/integration-branch-meta-location.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +5 -5
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +38 -1
- package/src/resources/extensions/gsd/tests/preferences.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +121 -1
- package/src/resources/extensions/gsd/tests/reactive-executor.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +105 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +33 -7
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -16
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +52 -0
- package/src/resources/extensions/gsd/tests/stop-notice.test.ts +21 -1
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +13 -7
- package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/thinking-level-resolution.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-faults.test.ts +238 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-fixture.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-fixture.ts +141 -0
- package/src/resources/extensions/gsd/tests/workflow-authority-projection-conflict.test.ts +177 -0
- package/src/resources/extensions/gsd/tests/workflow-fault-harness.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/workflow-fault-harness.ts +72 -0
- package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +60 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +74 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +20 -5
- package/src/resources/extensions/gsd/tools/plan-slice.ts +5 -1
- package/src/resources/extensions/gsd/tools/reopen-milestone.ts +24 -5
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +25 -5
- package/src/resources/extensions/gsd/tools/reopen-task.ts +23 -9
- package/src/resources/extensions/gsd/unit-context-composer.ts +34 -8
- package/src/resources/extensions/gsd/verification-evidence.ts +5 -2
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -3
- package/src/resources/extensions/gsd/workspace.ts +2 -1
- package/src/resources/extensions/gsd/worktree-state-projection.ts +21 -24
- package/src/resources/extensions/ollama/ollama-chat-provider.ts +2 -2
- package/src/resources/extensions/ollama/tests/ollama-chat-provider-think.test.ts +4 -0
- package/src/resources/extensions/shared/interview-ui.ts +47 -8
- package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +29 -0
- package/src/resources/extensions/subagent/index.ts +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +0 -1
- /package/dist/web/standalone/.next/static/{BE5XoklToI6lZjRzpXih8 → xwUaOqui04jIIFVsIBLiL}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BE5XoklToI6lZjRzpXih8 → xwUaOqui04jIIFVsIBLiL}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// GSD auto-mode runtime state
|
|
2
2
|
import { AutoSession } from "./auto/session.js";
|
|
3
|
-
import {
|
|
3
|
+
import { markToolEnd as markTrackedToolEnd, markToolStart as markTrackedToolStart, shouldClearToolInvocationErrorAfterSuccess, updateToolInvocationError, } from "./auto-tool-tracking.js";
|
|
4
4
|
// Re-exported as a pure pass-through. Must stay UNGATED (no autoSession.active
|
|
5
5
|
// argument, unlike markToolStart at the bottom of this file) so it is true in
|
|
6
6
|
// foreground where the foreground approval-gate pause consults it.
|
|
@@ -61,13 +61,13 @@ export function markToolEnd(toolCallId) {
|
|
|
61
61
|
export function recordToolInvocationError(toolName, errorMsg) {
|
|
62
62
|
if (!autoSession.active)
|
|
63
63
|
return;
|
|
64
|
-
|
|
65
|
-
autoSession.lastToolInvocationError = `${toolName}: ${errorMsg}`;
|
|
66
|
-
}
|
|
64
|
+
autoSession.lastToolInvocationError = updateToolInvocationError(autoSession.lastToolInvocationError, toolName, errorMsg);
|
|
67
65
|
}
|
|
68
|
-
export function clearToolInvocationError() {
|
|
66
|
+
export function clearToolInvocationError(successfulToolName) {
|
|
69
67
|
if (!autoSession.active)
|
|
70
68
|
return;
|
|
69
|
+
if (!shouldClearToolInvocationErrorAfterSuccess(autoSession.lastToolInvocationError, successfulToolName))
|
|
70
|
+
return;
|
|
71
71
|
autoSession.lastToolInvocationError = null;
|
|
72
72
|
}
|
|
73
73
|
export function getSourceObservationStore() {
|
|
@@ -46,9 +46,10 @@ import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.
|
|
|
46
46
|
import { extractVerdict } from "./verdict-parser.js";
|
|
47
47
|
import { auditOrphanedPreflightStashes } from "./orphan-stash-audit.js";
|
|
48
48
|
import { parseProject } from "./schemas/parsers.js";
|
|
49
|
+
import { LAYOUT_SEGMENTS } from "./layout-policy.js";
|
|
49
50
|
import { debugLog, enableDebug, isDebugEnabled, getDebugLogPath, } from "./debug-logger.js";
|
|
50
51
|
import { logWarning, logError } from "./workflow-logger.js";
|
|
51
|
-
import { existsSync, mkdirSync, readFileSync, rmSync, } from "node:fs";
|
|
52
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, } from "node:fs";
|
|
52
53
|
import { join } from "node:path";
|
|
53
54
|
import { validateDirectory } from "./validate-directory.js";
|
|
54
55
|
import { isCustomProvider, resolveDefaultSessionModel, resolveDynamicRoutingConfig, } from "./preferences-models.js";
|
|
@@ -73,6 +74,30 @@ const MAX_CONSECUTIVE_COMPLETE_BOOTSTRAPS = 2;
|
|
|
73
74
|
export function hasGitIndexLockForTest(basePath) {
|
|
74
75
|
return existsSync(join(basePath, ".git", "index.lock"));
|
|
75
76
|
}
|
|
77
|
+
function isEmptyDirectory(dirPath) {
|
|
78
|
+
try {
|
|
79
|
+
return existsSync(dirPath) && readdirSync(dirPath).length === 0;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export function reconcileFlatPhaseBootstrapLayout(basePath) {
|
|
86
|
+
const gsdDir = join(basePath, ".gsd");
|
|
87
|
+
const phasesPath = join(gsdDir, LAYOUT_SEGMENTS.level1);
|
|
88
|
+
const milestonesPath = join(gsdDir, "milestones");
|
|
89
|
+
if (isEmptyDirectory(milestonesPath)) {
|
|
90
|
+
if (!existsSync(phasesPath))
|
|
91
|
+
mkdirSync(phasesPath, { recursive: true });
|
|
92
|
+
rmSync(milestonesPath, { recursive: true, force: true });
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if (!existsSync(phasesPath) && !existsSync(milestonesPath)) {
|
|
96
|
+
mkdirSync(phasesPath, { recursive: true });
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
76
101
|
export function _shouldAbortBootstrapForUnavailableDbForTest(gsdDbPath, dbAvailable, pathExists = existsSync) {
|
|
77
102
|
return pathExists(gsdDbPath) && !dbAvailable;
|
|
78
103
|
}
|
|
@@ -796,7 +821,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
796
821
|
// provider the user is not logged into and surface as "Not logged in · Please
|
|
797
822
|
// run /login" before pausing and resetting to claude-code/claude-sonnet-4-6.
|
|
798
823
|
const manualSessionOverride = getSessionModelOverride(ctx.sessionManager.getSessionId());
|
|
799
|
-
const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider);
|
|
824
|
+
const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider, ctx.modelRegistry);
|
|
800
825
|
const profileModelIds = modelIdsForProfileResolution(ctx.modelRegistry, resolveProfileAnchorProvider(ctx.model?.provider), resolveDisabledModelProvidersFromPreferences());
|
|
801
826
|
const preferredModel = sessionProviderIsCustom
|
|
802
827
|
? null
|
|
@@ -868,20 +893,15 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
868
893
|
ensureGitignore(base, { manageGitignore });
|
|
869
894
|
if (manageGitignore !== false)
|
|
870
895
|
untrackRuntimeFiles(base);
|
|
871
|
-
// Bootstrap
|
|
872
|
-
|
|
873
|
-
// so checking .gsd/ existence would be dead code (#2942).
|
|
874
|
-
const gsdDir = join(base, ".gsd");
|
|
875
|
-
const milestonesPath = join(gsdDir, "milestones");
|
|
876
|
-
if (!existsSync(milestonesPath)) {
|
|
877
|
-
mkdirSync(milestonesPath, { recursive: true });
|
|
896
|
+
// Bootstrap the flat-phase projection root and clean empty legacy scaffolds.
|
|
897
|
+
if (reconcileFlatPhaseBootstrapLayout(base)) {
|
|
878
898
|
try {
|
|
879
899
|
nativeAddAll(base);
|
|
880
900
|
nativeCommit(base, "chore: init gsd");
|
|
881
901
|
}
|
|
882
902
|
catch (err) {
|
|
883
903
|
/* nothing to commit */
|
|
884
|
-
logWarning("engine", `
|
|
904
|
+
logWarning("engine", `layout bootstrap commit failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
885
905
|
}
|
|
886
906
|
}
|
|
887
907
|
{
|
|
@@ -118,6 +118,8 @@ export function clearInFlightTools() {
|
|
|
118
118
|
*/
|
|
119
119
|
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Input validation error|Invalid arguments for tool|MCP error -32602|No such tool available|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON|does not provide an export named|Named export .* not found|Cannot find module|ERR_MODULE_NOT_FOUND|ERR_MODULE_NOT_EXPORTED|ERR_PACKAGE_PATH_NOT_EXPORTED/i;
|
|
120
120
|
const DETERMINISTIC_POLICY_ERROR_RE = /(?:^|\b)(?:HARD BLOCK:|Blocked: \/gsd queue is a planning tool|Direct writes to \.gsd\/STATE\.md and \.gsd\/gsd\.db are blocked|This is a mechanical gate)/i;
|
|
121
|
+
const SCHEDULE_WAKEUP_TOOL_NAME = "ScheduleWakeup";
|
|
122
|
+
const SCHEDULE_WAKEUP_CONTINUATION_ERROR = "`prompt` is required when `stop` is not true";
|
|
121
123
|
/**
|
|
122
124
|
* Matches the runtime's "tool not registered" error. Unlike the deterministic
|
|
123
125
|
* invocation failures above, this one is usually transient: the workflow MCP
|
|
@@ -135,6 +137,44 @@ export function isToolInvocationError(errorMsg) {
|
|
|
135
137
|
return false;
|
|
136
138
|
return TOOL_INVOCATION_ERROR_RE.test(errorMsg) || isDeterministicPolicyError(errorMsg);
|
|
137
139
|
}
|
|
140
|
+
/**
|
|
141
|
+
* Claude Code validates its native ScheduleWakeup tool outside GSD's schema.
|
|
142
|
+
* Keep this exact and tool-scoped so similarly worded business validation from
|
|
143
|
+
* unrelated tools does not pause auto-mode.
|
|
144
|
+
*/
|
|
145
|
+
export function isScheduleWakeupContinuationError(toolName, errorMsg) {
|
|
146
|
+
return stripMcpToolPrefix(toolName) === SCHEDULE_WAKEUP_TOOL_NAME
|
|
147
|
+
&& errorMsg.trim() === SCHEDULE_WAKEUP_CONTINUATION_ERROR;
|
|
148
|
+
}
|
|
149
|
+
function shouldRecordToolInvocationError(toolName, errorMsg) {
|
|
150
|
+
return isScheduleWakeupContinuationError(toolName, errorMsg)
|
|
151
|
+
|| isToolInvocationError(errorMsg)
|
|
152
|
+
|| isQueuedUserMessageSkip(errorMsg);
|
|
153
|
+
}
|
|
154
|
+
function isRecordedScheduleWakeupContinuationError(recordedError) {
|
|
155
|
+
if (!recordedError)
|
|
156
|
+
return false;
|
|
157
|
+
const separator = recordedError.indexOf(": ");
|
|
158
|
+
return separator >= 0 && isScheduleWakeupContinuationError(recordedError.slice(0, separator), recordedError.slice(separator + 2));
|
|
159
|
+
}
|
|
160
|
+
export function updateToolInvocationError(recordedError, toolName, errorMsg) {
|
|
161
|
+
if (!shouldRecordToolInvocationError(toolName, errorMsg))
|
|
162
|
+
return recordedError;
|
|
163
|
+
if (isRecordedScheduleWakeupContinuationError(recordedError)
|
|
164
|
+
&& !isScheduleWakeupContinuationError(toolName, errorMsg))
|
|
165
|
+
return recordedError;
|
|
166
|
+
return `${toolName}: ${errorMsg}`;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* A failed continuation must survive successful diagnostic/read calls in the
|
|
170
|
+
* same turn. Only a later successful ScheduleWakeup proves the continuation
|
|
171
|
+
* was armed; all other invocation errors retain their existing clear-on-success
|
|
172
|
+
* behavior.
|
|
173
|
+
*/
|
|
174
|
+
export function shouldClearToolInvocationErrorAfterSuccess(recordedError, successfulToolName) {
|
|
175
|
+
return !isRecordedScheduleWakeupContinuationError(recordedError)
|
|
176
|
+
|| stripMcpToolPrefix(successfulToolName ?? "") === SCHEDULE_WAKEUP_TOOL_NAME;
|
|
177
|
+
}
|
|
138
178
|
/**
|
|
139
179
|
* Returns true if the error message indicates the called tool was not on the
|
|
140
180
|
* session's tool surface (MCP startup race — see TOOL_UNAVAILABLE_ERROR_RE).
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Post-unit verification gate for GSD auto-mode units.
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
|
|
4
|
-
import { relMilestoneFile, resolveSlicePath } from "./paths.js";
|
|
4
|
+
import { legacyMilestonesDir, relMilestoneFile, resolveMilestonePath, resolveSlicePath } from "./paths.js";
|
|
5
5
|
import { resolveMilestoneValidationVerdict } from "./milestone-validation-verdict.js";
|
|
6
6
|
import { resolveCanonicalMilestoneRoot } from "./worktree-manager.js";
|
|
7
7
|
import { parseUnitId } from "./unit-id.js";
|
|
@@ -24,6 +24,20 @@ import { getLedger } from "./metrics.js";
|
|
|
24
24
|
import { getUnitCostSpikeAction, resolveUnitCostSpikeMultiplier } from "./auto-budget.js";
|
|
25
25
|
import { formatPostUnitStatusCard } from "./auto-status-message.js";
|
|
26
26
|
import { detectWebApp } from "./web-app-uat.js";
|
|
27
|
+
function resolveVerificationEvidenceLocation(basePath, milestoneId, sliceId) {
|
|
28
|
+
const mDir = resolveMilestonePath(basePath, milestoneId);
|
|
29
|
+
if (!mDir)
|
|
30
|
+
return null;
|
|
31
|
+
const legacyBase = legacyMilestonesDir(basePath);
|
|
32
|
+
const isLegacy = mDir.startsWith(legacyBase + "/") || mDir.startsWith(legacyBase + "\\");
|
|
33
|
+
if (!isLegacy) {
|
|
34
|
+
return { dir: mDir, fileSliceId: sliceId };
|
|
35
|
+
}
|
|
36
|
+
const sDir = resolveSlicePath(basePath, milestoneId, sliceId);
|
|
37
|
+
if (!sDir)
|
|
38
|
+
return null;
|
|
39
|
+
return { dir: join(sDir, "tasks") };
|
|
40
|
+
}
|
|
27
41
|
function getCurrentUnitCostStats(unitId) {
|
|
28
42
|
const ledger = getLedger();
|
|
29
43
|
if (!ledger || !Array.isArray(ledger.units) || ledger.units.length === 0) {
|
|
@@ -431,11 +445,10 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
431
445
|
const taskAlreadyComplete = taskRow?.status === "complete" || taskRow?.status === "done";
|
|
432
446
|
if (mid && sid && tid) {
|
|
433
447
|
try {
|
|
434
|
-
const
|
|
435
|
-
if (
|
|
436
|
-
const tasksDir = join(sDir, "tasks");
|
|
448
|
+
const evidenceLocation = resolveVerificationEvidenceLocation(s.basePath, mid, sid);
|
|
449
|
+
if (evidenceLocation) {
|
|
437
450
|
if (result.passed) {
|
|
438
|
-
writeVerificationJSON(result,
|
|
451
|
+
writeVerificationJSON(result, evidenceLocation.dir, tid, s.currentUnit.id, undefined, undefined, evidenceLocation.fileSliceId);
|
|
439
452
|
}
|
|
440
453
|
else {
|
|
441
454
|
const nextAttempt = attempt + 1;
|
|
@@ -444,7 +457,7 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
444
457
|
verdict.retryable &&
|
|
445
458
|
autoFixEnabled &&
|
|
446
459
|
nextAttempt <= maxRetries;
|
|
447
|
-
writeVerificationJSON(result,
|
|
460
|
+
writeVerificationJSON(result, evidenceLocation.dir, tid, s.currentUnit.id, includeRetryMetadata ? nextAttempt : undefined, includeRetryMetadata ? maxRetries : undefined, evidenceLocation.fileSliceId);
|
|
448
461
|
}
|
|
449
462
|
}
|
|
450
463
|
}
|
|
@@ -560,9 +573,8 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
560
573
|
// Re-write verification evidence JSON with post-execution checks
|
|
561
574
|
if (postExecChecks && postExecChecks.length > 0 && mid && sid && tid) {
|
|
562
575
|
try {
|
|
563
|
-
const
|
|
564
|
-
if (
|
|
565
|
-
const tasksDir = join(sDir, "tasks");
|
|
576
|
+
const evidenceLocation = resolveVerificationEvidenceLocation(s.basePath, mid, sid);
|
|
577
|
+
if (evidenceLocation) {
|
|
566
578
|
// Add postExecutionChecks to the result for the JSON write
|
|
567
579
|
const resultWithPostExec = {
|
|
568
580
|
...result,
|
|
@@ -570,7 +582,7 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
570
582
|
passed: result.passed && !postExecBlockingFailure,
|
|
571
583
|
};
|
|
572
584
|
// Manually write with postExecutionChecks field
|
|
573
|
-
writeVerificationJSONWithPostExec(resultWithPostExec,
|
|
585
|
+
writeVerificationJSONWithPostExec(resultWithPostExec, evidenceLocation.dir, tid, s.currentUnit.id, postExecChecks, postExecBlockingFailure ? attempt + 1 : undefined, postExecBlockingFailure ? maxRetries : undefined, evidenceLocation.fileSliceId);
|
|
574
586
|
}
|
|
575
587
|
}
|
|
576
588
|
catch (evidenceErr) {
|
|
@@ -738,7 +750,7 @@ export async function runPostUnitVerification(vctx, pauseAuto) {
|
|
|
738
750
|
* Write verification evidence JSON with post-execution checks included.
|
|
739
751
|
* This is a variant of writeVerificationJSON that adds the postExecutionChecks field.
|
|
740
752
|
*/
|
|
741
|
-
function writeVerificationJSONWithPostExec(result, tasksDir, taskId, unitId, postExecutionChecks, retryAttempt, maxRetries) {
|
|
753
|
+
function writeVerificationJSONWithPostExec(result, tasksDir, taskId, unitId, postExecutionChecks, retryAttempt, maxRetries, sliceId) {
|
|
742
754
|
mkdirSync(tasksDir, { recursive: true });
|
|
743
755
|
const evidence = {
|
|
744
756
|
schemaVersion: 1,
|
|
@@ -774,6 +786,7 @@ function writeVerificationJSONWithPostExec(result, tasksDir, taskId, unitId, pos
|
|
|
774
786
|
fixAvailable: w.fixAvailable,
|
|
775
787
|
}));
|
|
776
788
|
}
|
|
777
|
-
const
|
|
789
|
+
const fileName = sliceId ? `${sliceId}-${taskId}-VERIFY.json` : `${taskId}-VERIFY.json`;
|
|
790
|
+
const filePath = join(tasksDir, fileName);
|
|
778
791
|
writeFileSync(filePath, JSON.stringify(evidence, null, 2) + "\n", "utf-8");
|
|
779
792
|
}
|
|
@@ -8,6 +8,7 @@ import { execFileSync } from "node:child_process";
|
|
|
8
8
|
import { existsSync, realpathSync, unlinkSync } from "node:fs";
|
|
9
9
|
import { isAbsolute, join, relative } from "node:path";
|
|
10
10
|
import { gsdRoot } from "./paths.js";
|
|
11
|
+
import { milestoneMetaPath } from "./git-service.js";
|
|
11
12
|
import { logWarning } from "./workflow-logger.js";
|
|
12
13
|
function isSamePath(a, b) {
|
|
13
14
|
try {
|
|
@@ -73,6 +74,9 @@ export function clearProjectRootStateFiles(basePath, milestoneId) {
|
|
|
73
74
|
// worth removing on teardown.
|
|
74
75
|
const transientFiles = [
|
|
75
76
|
join(gsdDir, "STATE.md"),
|
|
77
|
+
// Integration-branch META now lives flat at .gsd/<MID>-META.json (ADR-045).
|
|
78
|
+
milestoneMetaPath(basePath, milestoneId),
|
|
79
|
+
// Legacy location — still cleaned for pre-migration trees.
|
|
76
80
|
join(gsdDir, "milestones", milestoneId, `${milestoneId}-META.json`),
|
|
77
81
|
];
|
|
78
82
|
for (const file of transientFiles) {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { cpSync, existsSync, lstatSync as lstatSyncFn, mkdirSync, readdirSync, } from "node:fs";
|
|
6
6
|
import { join } from "node:path";
|
|
7
7
|
import { _isSamePath as isSamePath, } from "./auto-worktree-cleanup.js";
|
|
8
|
-
import { resolveGsdPathContract } from "./paths.js";
|
|
8
|
+
import { dirIsContentBearingLegacyMilestone, resolveGsdPathContract } from "./paths.js";
|
|
9
9
|
import { WorktreeStateProjection } from "./worktree-state-projection.js";
|
|
10
10
|
import { logWarning } from "./workflow-logger.js";
|
|
11
11
|
const PROJECT_PREFERENCES_FILE = "PREFERENCES.md";
|
|
@@ -143,10 +143,14 @@ function syncMilestoneLayout(mainGsd, wtGsd, layoutSegment, synced) {
|
|
|
143
143
|
if (!existsSync(mainMilestonesDir))
|
|
144
144
|
return;
|
|
145
145
|
try {
|
|
146
|
-
mkdirSync(wtMilestonesDir, { recursive: true });
|
|
147
146
|
const mainMilestones = readdirSync(mainMilestonesDir, { withFileTypes: true })
|
|
148
147
|
.filter((entry) => entry.isDirectory())
|
|
149
|
-
.map((entry) => entry.name)
|
|
148
|
+
.map((entry) => entry.name)
|
|
149
|
+
.filter((name) => layoutSegment !== "milestones" ||
|
|
150
|
+
dirIsContentBearingLegacyMilestone(join(mainMilestonesDir, name)));
|
|
151
|
+
if (mainMilestones.length === 0)
|
|
152
|
+
return;
|
|
153
|
+
mkdirSync(wtMilestonesDir, { recursive: true });
|
|
150
154
|
for (const milestoneId of mainMilestones) {
|
|
151
155
|
syncMilestoneDirectory(mainMilestonesDir, wtMilestonesDir, milestoneId, synced);
|
|
152
156
|
}
|
|
@@ -45,7 +45,7 @@ export function teardownAutoWorktree(originalBasePath, milestoneId, opts = {}) {
|
|
|
45
45
|
throw new GSDError(GSD_IO_ERROR, `Failed to chdir back to ${originalBasePath} during teardown: ${err instanceof Error ? err.message : String(err)}`);
|
|
46
46
|
}
|
|
47
47
|
// Mirror cleanup steps from mergeMilestoneToMain abort path:
|
|
48
|
-
// 1. Remove transient state files (STATE.md, auto.lock, {MID}-META.json).
|
|
48
|
+
// 1. Remove transient state files (STATE.md, auto.lock, .gsd/{MID}-META.json).
|
|
49
49
|
// Non-fatal — must not block teardown.
|
|
50
50
|
try {
|
|
51
51
|
clearProjectRootStateFiles(originalBasePath, milestoneId);
|
|
@@ -28,7 +28,7 @@ import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSes
|
|
|
28
28
|
import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, loadEffectiveGSDPreferencesWithRegistry, resolveProfileAnchorProvider, getIsolationMode, resolveEffectiveUnitIsolationMode, } from "./preferences.js";
|
|
29
29
|
import { playNotificationBell, sendDesktopNotification } from "./notifications.js";
|
|
30
30
|
import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, HARD_CONTEXT_REROOT_THRESHOLD_PERCENT, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, shouldWarnStepSessionForContext, } from "./auto-budget.js";
|
|
31
|
-
import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools,
|
|
31
|
+
import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, updateToolInvocationError, } from "./auto-tool-tracking.js";
|
|
32
32
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
33
33
|
import { selectAndApplyModel, resolveModelId, clearToolBaseline, isModelUnavailable, applyThinkingLevelForModel } from "./auto-model-selection.js";
|
|
34
34
|
import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
|
|
@@ -617,15 +617,14 @@ export function markToolEnd(toolCallId) {
|
|
|
617
617
|
* Called from tool_execution_end when a GSD tool fails with isError.
|
|
618
618
|
* Stores the error if it matches:
|
|
619
619
|
* - tool-invocation-error pattern (malformed/truncated JSON)
|
|
620
|
+
* - failed ScheduleWakeup continuation validation (#1379)
|
|
620
621
|
* - queued-user-message skip pattern
|
|
621
622
|
* - deterministic policy rejection (#4973, e.g. context_write_blocked)
|
|
622
623
|
*/
|
|
623
624
|
export function recordToolInvocationError(toolName, errorMsg) {
|
|
624
625
|
if (!s.active)
|
|
625
626
|
return;
|
|
626
|
-
|
|
627
|
-
s.lastToolInvocationError = `${toolName}: ${errorMsg}`;
|
|
628
|
-
}
|
|
627
|
+
s.lastToolInvocationError = updateToolInvocationError(s.lastToolInvocationError, toolName, errorMsg);
|
|
629
628
|
}
|
|
630
629
|
export function getOldestInFlightToolAgeMs() {
|
|
631
630
|
return _getOldestInFlightToolAgeMs();
|
|
@@ -2441,7 +2440,18 @@ export async function dispatchHookUnit(ctx, pi, hookName, triggerUnitType, trigg
|
|
|
2441
2440
|
startedAt: hookStartedAt,
|
|
2442
2441
|
workspaceRoot: s.basePath,
|
|
2443
2442
|
});
|
|
2444
|
-
const
|
|
2443
|
+
const cmdCtx = s.cmdCtx;
|
|
2444
|
+
if (typeof cmdCtx?.newSession !== "function") {
|
|
2445
|
+
const message = "Auto-mode has no command context for dispatch.";
|
|
2446
|
+
ctx.ui.notify(message, "error");
|
|
2447
|
+
const unitToCommit = previousCurrentUnit ?? s.currentUnit;
|
|
2448
|
+
if (unitToCommit) {
|
|
2449
|
+
await autoCommitUnit(s.basePath, unitToCommit.type, unitToCommit.id, ctx);
|
|
2450
|
+
}
|
|
2451
|
+
await stopAuto(ctx, pi, message, { preserveWorktree: true });
|
|
2452
|
+
return false;
|
|
2453
|
+
}
|
|
2454
|
+
const result = await cmdCtx.newSession({ workspaceRoot: s.basePath });
|
|
2445
2455
|
if (result.cancelled) {
|
|
2446
2456
|
await stopAuto(ctx, pi);
|
|
2447
2457
|
return false;
|
|
@@ -46,6 +46,8 @@ function registerAlias(pi, toolDef, aliasName, canonicalName) {
|
|
|
46
46
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- toolDef shape matches ToolDefinition but varies by schema
|
|
47
47
|
function registerWorkflowTool(pi, toolDef) {
|
|
48
48
|
pi.registerTool(toolDef);
|
|
49
|
+
if (process.env.GSD_ADVERTISE_TOOL_ALIASES !== "1")
|
|
50
|
+
return; // canonical-only model surface (see plan 035)
|
|
49
51
|
for (const alias of aliasesForWorkflowTool(toolDef.name)) {
|
|
50
52
|
registerAlias(pi, toolDef, alias, toolDef.name);
|
|
51
53
|
}
|
|
@@ -22,13 +22,14 @@ import { saveActivityLog } from "../activity-log.js";
|
|
|
22
22
|
import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
|
|
23
23
|
import { parseUnitId } from "../unit-id.js";
|
|
24
24
|
import { classifyCommand } from "../safety/destructive-guard.js";
|
|
25
|
-
import { confirmDestructiveCommand, consumeDestructiveConfirmation, isDestructiveConfirmGateId, requestDestructiveConfirmation, } from "../safety/destructive-confirmation.js";
|
|
25
|
+
import { confirmDestructiveCommand, consumeDestructiveConfirmation, isDestructiveConfirmGateId, peekPendingDestructiveCommand, requestDestructiveConfirmation, resetDestructiveConfirmation, } from "../safety/destructive-confirmation.js";
|
|
26
26
|
import { logWarning as safetyLogWarning, setStderrLoggingEnabled } from "../workflow-logger.js";
|
|
27
27
|
import { isUnitCloseoutTool, runInteractiveUnitCloseout } from "../unit-closeout.js";
|
|
28
28
|
import { installNotifyInterceptor } from "./notify-interceptor.js";
|
|
29
29
|
import { initNotificationStore } from "../notification-store.js";
|
|
30
30
|
import { initNotificationWidget } from "../notification-widget.js";
|
|
31
31
|
import { notifyPreferenceDiagnostics } from "../preferences-diagnostics.js";
|
|
32
|
+
import { resolveEffectivePlanningToolsPolicy } from "../planning-subagent-policy.js";
|
|
32
33
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
33
34
|
import { extractSubagentAgentClasses } from "./subagent-input.js";
|
|
34
35
|
import { approvalGateIdForUnit, evaluateAskUserQuestionsRound, formatUnansweredConsentQuestionMessage, isExplicitApprovalResponse, messageHasPendingAskUserQuestionsTool, shouldPauseForQuestion, } from "../consent-question.js";
|
|
@@ -136,6 +137,7 @@ function suppressWelcomeHeader(ctx) {
|
|
|
136
137
|
* are bounded — cleared on activation, session boundaries, and verification.
|
|
137
138
|
*/
|
|
138
139
|
const deferredApprovalGates = new Map();
|
|
140
|
+
const deferredDestructiveConfirmationPauses = new Set();
|
|
139
141
|
export const MINIMAL_GSD_TOOL_NAMES = [
|
|
140
142
|
"gsd_exec",
|
|
141
143
|
"gsd_exec_search",
|
|
@@ -456,6 +458,21 @@ function clearDeferredApprovalGate(basePath) {
|
|
|
456
458
|
deferredApprovalGates.delete(basePath);
|
|
457
459
|
}
|
|
458
460
|
}
|
|
461
|
+
function deferDestructiveConfirmationPause(basePath) {
|
|
462
|
+
deferredDestructiveConfirmationPauses.add(basePath);
|
|
463
|
+
}
|
|
464
|
+
function clearDeferredDestructiveConfirmationPause(basePath) {
|
|
465
|
+
if (!basePath) {
|
|
466
|
+
deferredDestructiveConfirmationPauses.clear();
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
deferredDestructiveConfirmationPauses.delete(basePath);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
function isDestructiveConfirmationBlocking(basePath) {
|
|
473
|
+
return deferredDestructiveConfirmationPauses.has(basePath)
|
|
474
|
+
&& Boolean(peekPendingDestructiveCommand(basePath));
|
|
475
|
+
}
|
|
459
476
|
function deferApprovalGate(gateId, basePath) {
|
|
460
477
|
// Verified-on-disk wins (same adapter policy as activation/re-arm): if the
|
|
461
478
|
// workflow MCP child already verified this gate, deferring would block
|
|
@@ -798,6 +815,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
798
815
|
await applyToolCallLoopGuardConfig(basePath);
|
|
799
816
|
approvalQuestionAbortInFlight = false;
|
|
800
817
|
clearDeferredApprovalGate();
|
|
818
|
+
clearDeferredDestructiveConfirmationPause();
|
|
801
819
|
await resetAskUserQuestionsTurnCache();
|
|
802
820
|
await syncServiceTierStatus(ctx);
|
|
803
821
|
await applyDisabledModelProviderPolicy(ctx);
|
|
@@ -883,6 +901,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
883
901
|
resetToolCallLoopGuard();
|
|
884
902
|
await applyToolCallLoopGuardConfig(basePath);
|
|
885
903
|
clearDeferredApprovalGate();
|
|
904
|
+
clearDeferredDestructiveConfirmationPause();
|
|
886
905
|
await resetAskUserQuestionsTurnCache();
|
|
887
906
|
clearDiscussionFlowState(basePath);
|
|
888
907
|
// /clear or /new destroys the conversation holding a discuss interview, so
|
|
@@ -933,6 +952,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
933
952
|
}
|
|
934
953
|
}
|
|
935
954
|
clearDeferredApprovalGate(beforeAgentBasePath);
|
|
955
|
+
clearDeferredDestructiveConfirmationPause(beforeAgentBasePath);
|
|
936
956
|
// session_start can fire before the active provider has settled. By
|
|
937
957
|
// before_agent_start, Claude Code CLI sessions should get the same
|
|
938
958
|
// project MCP config that /gsd mcp init would write.
|
|
@@ -1010,7 +1030,10 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1010
1030
|
}
|
|
1011
1031
|
finally {
|
|
1012
1032
|
activateDeferredApprovalGate(agentEndBasePath);
|
|
1033
|
+
const destructiveConfirmationBlocking = isDestructiveConfirmationBlocking(agentEndBasePath);
|
|
1034
|
+
clearDeferredDestructiveConfirmationPause(agentEndBasePath);
|
|
1013
1035
|
await maybePauseAutoForApprovalGate(ctx, pi, isApprovalGateBlocking(agentEndBasePath), "Depth confirmation is waiting for your answer — pausing auto-mode.");
|
|
1036
|
+
await maybePauseAutoForApprovalGate(ctx, pi, destructiveConfirmationBlocking, "Destructive-command confirmation is waiting for your answer — pausing auto-mode.");
|
|
1014
1037
|
}
|
|
1015
1038
|
});
|
|
1016
1039
|
pi.on("message_end", async (event) => {
|
|
@@ -1276,6 +1299,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1276
1299
|
const activeUnitType = dash.currentUnit?.type ?? guidedUnit?.unitType;
|
|
1277
1300
|
if (activeUnitType) {
|
|
1278
1301
|
const manifest = resolveManifest(activeUnitType);
|
|
1302
|
+
const planningBasePath = dash.basePath || guidedUnit?.basePath || discussionBasePath;
|
|
1279
1303
|
let planningInput = "";
|
|
1280
1304
|
let agentClasses;
|
|
1281
1305
|
if (isToolCallEventType("write", event)) {
|
|
@@ -1291,7 +1315,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1291
1315
|
// Subagent inputs use { agent }, { tasks: [{ agent }] }, or { chain: [{ agent }] }.
|
|
1292
1316
|
agentClasses = extractSubagentAgentClasses(event.input);
|
|
1293
1317
|
}
|
|
1294
|
-
const planningGuard = shouldBlockPlanningUnit(event.toolName, planningInput,
|
|
1318
|
+
const planningGuard = shouldBlockPlanningUnit(event.toolName, planningInput, planningBasePath, activeUnitType, resolveEffectivePlanningToolsPolicy(activeUnitType, manifest?.tools, planningBasePath), agentClasses, event.input, dash.currentUnit?.id);
|
|
1295
1319
|
if (planningGuard.block)
|
|
1296
1320
|
return planningGuard;
|
|
1297
1321
|
}
|
|
@@ -1373,6 +1397,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1373
1397
|
// Record the command as pending so an affirmative answer to a
|
|
1374
1398
|
// destructive_confirm gate (handled in tool_result) can confirm it.
|
|
1375
1399
|
requestDestructiveConfirmation(command, guardBasePath);
|
|
1400
|
+
deferDestructiveConfirmationPause(guardBasePath);
|
|
1376
1401
|
const reason = [
|
|
1377
1402
|
"HARD BLOCK: destructive Bash command requires explicit human confirmation.",
|
|
1378
1403
|
`Detected: ${classification.labels.join(", ")}`,
|
|
@@ -1383,9 +1408,6 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1383
1408
|
safetyLogWarning("safety", `destructive command: ${classification.labels.join(", ")}`, {
|
|
1384
1409
|
command: String(command).slice(0, 200),
|
|
1385
1410
|
});
|
|
1386
|
-
if (ctx) {
|
|
1387
|
-
await maybePauseAutoForApprovalGate(ctx, pi, isAutoActive(), "Destructive-command confirmation is waiting for your answer — pausing auto-mode.");
|
|
1388
|
-
}
|
|
1389
1411
|
return { block: true, reason };
|
|
1390
1412
|
}
|
|
1391
1413
|
}
|
|
@@ -1426,7 +1448,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1426
1448
|
recordRetryableHarnessToolError(toolName, resultPayload, errorText);
|
|
1427
1449
|
}
|
|
1428
1450
|
else if (isAutoActive()) {
|
|
1429
|
-
clearToolInvocationError();
|
|
1451
|
+
clearToolInvocationError(event.toolName);
|
|
1430
1452
|
}
|
|
1431
1453
|
// Interactive Closeout adapter (ADR-032): auto-mode owns closeout for its
|
|
1432
1454
|
// own units; interactive completions get the durable git subset (commit +
|
|
@@ -1541,6 +1563,10 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1541
1563
|
if (isDepthConfirmationAnswer(answer?.selected, question.options)) {
|
|
1542
1564
|
confirmDestructiveCommand(basePath);
|
|
1543
1565
|
}
|
|
1566
|
+
else {
|
|
1567
|
+
resetDestructiveConfirmation(basePath);
|
|
1568
|
+
}
|
|
1569
|
+
clearDeferredDestructiveConfirmationPause(basePath);
|
|
1544
1570
|
break;
|
|
1545
1571
|
}
|
|
1546
1572
|
}
|
|
@@ -1605,7 +1631,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1605
1631
|
recordRetryableHarnessToolError(toolName, event.result, errorText);
|
|
1606
1632
|
}
|
|
1607
1633
|
else if (isAutoActive()) {
|
|
1608
|
-
clearToolInvocationError();
|
|
1634
|
+
clearToolInvocationError(event.toolName);
|
|
1609
1635
|
}
|
|
1610
1636
|
// Safety harness: record tool execution results for evidence cross-referencing
|
|
1611
1637
|
if (isAutoActive()) {
|
|
@@ -18,6 +18,13 @@ import { formatOverridesSection, formatShortcut, loadActiveOverrides, loadFile,
|
|
|
18
18
|
import { toPosixPath } from "../../shared/mod.js";
|
|
19
19
|
import { autoEnableCmuxPreferences } from "../commands-cmux.js";
|
|
20
20
|
import { gsdHome } from "../gsd-home.js";
|
|
21
|
+
import { GSD_CONTEXT_MESSAGE_SENTINEL } from "../constants.js";
|
|
22
|
+
// Single source of truth lives in ../constants.js; re-exported here because
|
|
23
|
+
// buildContextMessage() stamps this marker on every context injection and the
|
|
24
|
+
// provider payload policy (filterSupersededContextInjections in
|
|
25
|
+
// context-masker.ts) matches it to dedupe. Adding a new context customType?
|
|
26
|
+
// Ensure buildContextMessage still prepends this sentinel.
|
|
27
|
+
export { GSD_CONTEXT_MESSAGE_SENTINEL };
|
|
21
28
|
const DEFAULT_CONTEXT_MESSAGE_MAX_CHARS = 4_000;
|
|
22
29
|
const DEFAULT_KNOWLEDGE_MAX_CHARS = 12_000;
|
|
23
30
|
const DEFAULT_CODEBASE_MAX_CHARS = 8_000;
|
|
@@ -385,17 +392,17 @@ export function buildContextMessage(opts) {
|
|
|
385
392
|
const contextCharLimit = getContextMessageCharLimit();
|
|
386
393
|
const memoryContent = markMemoryContextSupplied(opts.memoryBlock.trim());
|
|
387
394
|
if (opts.injection) {
|
|
388
|
-
const content = limitContextMessageContent(memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection
|
|
395
|
+
const content = limitContextMessageContent(`${GSD_CONTEXT_MESSAGE_SENTINEL}\n${memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection}`, contextCharLimit);
|
|
389
396
|
return { customType: "gsd-guided-context", content, display: false };
|
|
390
397
|
}
|
|
391
398
|
if (opts.forensicsInjection) {
|
|
392
|
-
const content = limitContextMessageContent(memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection
|
|
399
|
+
const content = limitContextMessageContent(`${GSD_CONTEXT_MESSAGE_SENTINEL}\n${memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection}`, contextCharLimit);
|
|
393
400
|
return { customType: "gsd-forensics", content, display: false };
|
|
394
401
|
}
|
|
395
402
|
if (memoryContent) {
|
|
396
403
|
return {
|
|
397
404
|
customType: "gsd-memory",
|
|
398
|
-
content: limitContextMessageContent(memoryContent
|
|
405
|
+
content: limitContextMessageContent(`${GSD_CONTEXT_MESSAGE_SENTINEL}\n${memoryContent}`, contextCharLimit),
|
|
399
406
|
display: false,
|
|
400
407
|
};
|
|
401
408
|
}
|
|
@@ -5,8 +5,9 @@ import { minimatch } from "minimatch";
|
|
|
5
5
|
import { GSD_PHASE_SCOPE_DISPLAY_REASON, shouldBlockAutoUnitToolCall } from "../auto-unit-tool-scope.js";
|
|
6
6
|
import { canonicalToolName } from "../engine-hook-contract.js";
|
|
7
7
|
import { loadJsonFileOrNull } from "../json-persistence.js";
|
|
8
|
-
import { getIsolationMode } from "../preferences.js";
|
|
8
|
+
import { getIsolationMode, loadEffectiveGSDPreferences } from "../preferences.js";
|
|
9
9
|
import { compileSubagentPermissionContract } from "../unit-context-manifest.js";
|
|
10
|
+
import { allowedPlanningDispatchAgentsList, isReadOnlyPlanningDispatchAgent, } from "../planning-subagent-registry.js";
|
|
10
11
|
import { logWarning } from "../workflow-logger.js";
|
|
11
12
|
import { acquireSyncLock, releaseSyncLock } from "../sync-lock.js";
|
|
12
13
|
import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
@@ -981,29 +982,8 @@ export function shouldBlockQueueExecutionInSnapshot(snapshot, toolName, input, q
|
|
|
981
982
|
// guards.
|
|
982
983
|
const PLANNING_WRITE_TOOLS = new Set(["write", "edit", "multi_edit", "notebook_edit"]);
|
|
983
984
|
const PLANNING_SUBAGENT_TOOLS = new Set(["subagent", "task"]);
|
|
984
|
-
|
|
985
|
-
* Canonical registry for agents that planning-dispatch may consider. Unit
|
|
986
|
-
* manifests still declare per-unit subsets via ToolsPolicy.allowedSubagents.
|
|
987
|
-
*/
|
|
988
|
-
const PLANNING_DISPATCH_AGENT_REGISTRY = {
|
|
989
|
-
mnemo: { readOnlySpecialist: true },
|
|
990
|
-
scout: { readOnlySpecialist: true },
|
|
991
|
-
planner: { readOnlySpecialist: true },
|
|
992
|
-
reviewer: { readOnlySpecialist: true },
|
|
993
|
-
security: { readOnlySpecialist: true },
|
|
994
|
-
tester: { readOnlySpecialist: true },
|
|
995
|
-
};
|
|
996
|
-
export const ALLOWED_PLANNING_DISPATCH_AGENTS = new Set(Object.entries(PLANNING_DISPATCH_AGENT_REGISTRY)
|
|
997
|
-
.filter(([, metadata]) => metadata.readOnlySpecialist)
|
|
998
|
-
.map(([agentId]) => agentId));
|
|
985
|
+
export { ALLOWED_PLANNING_DISPATCH_AGENTS } from "../planning-subagent-registry.js";
|
|
999
986
|
let warnedMissingControlledDispatchAgentClasses = false;
|
|
1000
|
-
function isReadOnlySpecialist(agentId) {
|
|
1001
|
-
const metadata = PLANNING_DISPATCH_AGENT_REGISTRY[agentId];
|
|
1002
|
-
return metadata?.readOnlySpecialist === true;
|
|
1003
|
-
}
|
|
1004
|
-
function allowedPlanningDispatchAgentsList() {
|
|
1005
|
-
return [...ALLOWED_PLANNING_DISPATCH_AGENTS].join(", ");
|
|
1006
|
-
}
|
|
1007
987
|
function allowsControlledSubagentDispatch(policy) {
|
|
1008
988
|
return ((policy.mode === "planning-dispatch" || policy.mode === "verification" || policy.mode === "workflow-only") &&
|
|
1009
989
|
Array.isArray(policy.allowedSubagents));
|
|
@@ -1138,6 +1118,7 @@ export function shouldBlockPlanningUnit(toolName, pathOrCommand, basePath, unitT
|
|
|
1138
1118
|
const dispatchContract = compileSubagentPermissionContract(policy);
|
|
1139
1119
|
const allowedSubagents = dispatchContract.allowedSubagents;
|
|
1140
1120
|
const allowed = new Set(allowedSubagents);
|
|
1121
|
+
const planningSubagentRegistry = loadEffectiveGSDPreferences(basePath)?.preferences.planning_subagent_registry;
|
|
1141
1122
|
// When agentClasses is undefined, the caller has not been updated to extract
|
|
1142
1123
|
// agent identities yet. Block and warn so stale callers surface in telemetry
|
|
1143
1124
|
// instead of silently bypassing the gate.
|
|
@@ -1151,13 +1132,13 @@ export function shouldBlockPlanningUnit(toolName, pathOrCommand, basePath, unitT
|
|
|
1151
1132
|
if (requested.length === 0) {
|
|
1152
1133
|
return { block: false };
|
|
1153
1134
|
}
|
|
1154
|
-
const globallyDisallowed = requested.find(a => !
|
|
1135
|
+
const globallyDisallowed = requested.find(a => !isReadOnlyPlanningDispatchAgent(a, planningSubagentRegistry));
|
|
1155
1136
|
if (globallyDisallowed) {
|
|
1156
|
-
return planningBlock(unitType, policy.mode, `subagent dispatch of "${globallyDisallowed}" not permitted; only read-only specialists (${allowedPlanningDispatchAgentsList()}) may be dispatched from ${policy.mode} units`);
|
|
1137
|
+
return planningBlock(unitType, policy.mode, `subagent dispatch of "${globallyDisallowed}" not permitted; only read-only specialists (${allowedPlanningDispatchAgentsList(planningSubagentRegistry)}) may be dispatched from ${policy.mode} units`);
|
|
1157
1138
|
}
|
|
1158
1139
|
const disallowedByPolicy = requested.find(a => !allowed.has(a));
|
|
1159
1140
|
if (disallowedByPolicy) {
|
|
1160
|
-
return planningBlock(unitType, policy.mode, `subagent dispatch of "${disallowedByPolicy}" not permitted by ToolsPolicy.allowedSubagents; permitted agents for this unit: ${allowedSubagents.join(", ")}`);
|
|
1141
|
+
return planningBlock(unitType, policy.mode, `subagent dispatch of "${disallowedByPolicy}" not permitted by unit allowlist (ToolsPolicy.allowedSubagents/planning_subagents); permitted agents for this unit: ${allowedSubagents.join(", ")}`);
|
|
1161
1142
|
}
|
|
1162
1143
|
return { block: false };
|
|
1163
1144
|
}
|