@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
|
@@ -56,6 +56,26 @@ const ZERO_TOOL_PROVIDER_ERROR_PREFIX_RE =
|
|
|
56
56
|
/^(?:api error(?::|$|\s*\()|provider error(?::|$|\s*\()|request failed\b|(?:http\s*)?(?:429|500|502|503)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|socket hang up\b|fetch failed\b|(?:network|connection|server) error(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|dns\b.*(?:fail|error|timeout)|unexpected eof\b|stream idle timeout\b|partial response received\b|stream_exhausted\b|terminated(?::|$)|(?:connection|stream|request)\b.{0,40}\bterminated\b|other side closed\b|rate.?limit(?:ed| exceeded| reached| error)|too many requests\b|you(?:'ve| have) (?:hit|reached) your (?:\w+ )?limit\b|.*\b(?:usage|session|weekly|daily|monthly|quota) limit\b|limit\b.{0,40}\bresets?\b|out of extra usage\b|service.?unavailable\b|internal(?: server)? error(?::|$)|internal(?:[_-]server)?[_-]error\b|server[_-]error\b|(?:provider|server|api|model|codex|claude|openai|anthropic|gemini)\b.{0,80}\boverloaded\b|overloaded\b.{0,80}\b(?:provider|server|api|model)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
57
57
|
const ZERO_TOOL_PROVIDER_ERROR_SIGNAL_RE =
|
|
58
58
|
/(?:\b(?:http|status(?: code)?|code|error:)\s*(?:429|500|502|503)\b|\b(?:api|provider) error\s*[:(]?\s*(?:429|500|502|503)\b|\b(?:typeerror|error):\s*(?:fetch failed\b|socket hang up\b|terminated(?::|$)|connection (?:reset|refused)(?::|$|\s+by\b)|(?:network|connection|server) error(?::|$)|stream idle timeout\b|partial response received\b|unexpected eof\b)|\b(?:server_error|api_error|stream_exhausted(?:_without_result)?)\b|\b(?:econnreset|etimedout|econnrefused|epipe)\b|context (?:window|length) exceed|context window exceed)/i;
|
|
59
|
+
const ZERO_TOOL_PSEUDO_TOOL_CALL_RE =
|
|
60
|
+
/<arg_key>[\s\S]*?<\/arg_key>\s*<arg_value>[\s\S]*?<\/arg_value>[\s\S]*?<\/tool_call>/i;
|
|
61
|
+
const ZERO_TOOL_PSEUDO_TOOL_CALL_SNIPPET_CHARS = 200;
|
|
62
|
+
|
|
63
|
+
function zeroToolMessageSnippet(message: string): string {
|
|
64
|
+
const compact = message.trim().replace(/\s+/g, " ");
|
|
65
|
+
if (compact.length <= ZERO_TOOL_PSEUDO_TOOL_CALL_SNIPPET_CHARS) return compact;
|
|
66
|
+
return `${compact.slice(0, ZERO_TOOL_PSEUDO_TOOL_CALL_SNIPPET_CHARS - 3)}...`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Provider serialization drift: the model emitted a tool call as plain assistant
|
|
70
|
+
// text (`toolName<arg_key>…</arg_key><arg_value>…</arg_value></tool_call>`)
|
|
71
|
+
// instead of a structured tool call. Returns an operator-visible snippet when
|
|
72
|
+
// detected. Kept separate from error classification so a drift snippet is never
|
|
73
|
+
// conflated with an ErrorClass (which would force a fragile union whose
|
|
74
|
+
// narrowing the root and extensions tsconfigs disagree on).
|
|
75
|
+
function zeroToolPseudoToolCallSnippet(message: string): string | null {
|
|
76
|
+
if (!ZERO_TOOL_PSEUDO_TOOL_CALL_RE.test(message)) return null;
|
|
77
|
+
return zeroToolMessageSnippet(message);
|
|
78
|
+
}
|
|
59
79
|
|
|
60
80
|
function classifyZeroToolProviderMessage(message: string): ReturnType<typeof classifyError> | null {
|
|
61
81
|
const firstLine = message.trim().split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
@@ -68,6 +88,7 @@ function classifyZeroToolProviderMessage(message: string): ReturnType<typeof cla
|
|
|
68
88
|
}
|
|
69
89
|
|
|
70
90
|
export const _classifyZeroToolProviderMessageForTest = classifyZeroToolProviderMessage;
|
|
91
|
+
export const _zeroToolPseudoToolCallSnippetForTest = zeroToolPseudoToolCallSnippet;
|
|
71
92
|
|
|
72
93
|
export function resolveDispatchRecoveryAttempts(
|
|
73
94
|
unitRecoveryCount: Map<string, number>,
|
|
@@ -767,15 +788,30 @@ export async function runUnitPhase(
|
|
|
767
788
|
);
|
|
768
789
|
if (lastUnit && lastUnit.toolCalls === 0) {
|
|
769
790
|
const lastAssistantMessage = lastAssistantText(s.lastUnitAgentEndMessages);
|
|
770
|
-
const
|
|
771
|
-
if (
|
|
772
|
-
|
|
791
|
+
const pseudoToolCallSnippet = zeroToolPseudoToolCallSnippet(lastAssistantMessage);
|
|
792
|
+
if (pseudoToolCallSnippet) {
|
|
793
|
+
debugLog("runUnitPhase", {
|
|
794
|
+
phase: "zero-tool-serialization-drift",
|
|
795
|
+
unitType,
|
|
796
|
+
unitId,
|
|
797
|
+
snippet: pseudoToolCallSnippet,
|
|
798
|
+
});
|
|
799
|
+
ctx.ui.notify(
|
|
800
|
+
`${unitType} ${unitId} completed with 0 tool calls - provider serialization drift: model emitted pseudo-tool-call text. Snippet: ${pseudoToolCallSnippet}`,
|
|
801
|
+
"error",
|
|
802
|
+
);
|
|
803
|
+
await deps.pauseAuto(ctx, pi);
|
|
804
|
+
return { action: "break", reason: "zero-tool-serialization-drift" };
|
|
805
|
+
}
|
|
806
|
+
const providerErrorClass = classifyZeroToolProviderMessage(lastAssistantMessage);
|
|
807
|
+
if (providerErrorClass && isTransient(providerErrorClass)) {
|
|
808
|
+
const retryAfterMs = "retryAfterMs" in providerErrorClass ? providerErrorClass.retryAfterMs : 15_000;
|
|
773
809
|
await pauseAutoForProviderError(
|
|
774
810
|
ctx.ui,
|
|
775
811
|
` for ${unitType} ${unitId}`,
|
|
776
812
|
() => deps.pauseAuto(ctx, pi),
|
|
777
813
|
{
|
|
778
|
-
isRateLimit:
|
|
814
|
+
isRateLimit: providerErrorClass.kind === "rate-limit",
|
|
779
815
|
isTransient: true,
|
|
780
816
|
retryAfterMs,
|
|
781
817
|
resume: () => {
|
|
@@ -793,7 +829,7 @@ export async function runUnitPhase(
|
|
|
793
829
|
});
|
|
794
830
|
return {
|
|
795
831
|
action: "break",
|
|
796
|
-
reason:
|
|
832
|
+
reason: providerErrorClass.kind === "rate-limit" ? "rate-limit" : "api-timeout",
|
|
797
833
|
};
|
|
798
834
|
}
|
|
799
835
|
if (USER_DRIVEN_DEEP_UNITS.has(unitType) && isAwaitingUserInput(s.lastUnitAgentEndMessages ?? undefined)) {
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
resolveSliceFile,
|
|
16
16
|
relMilestoneFile,
|
|
17
17
|
relSliceFile,
|
|
18
|
+
buildFlatTaskFileName,
|
|
18
19
|
buildTaskFileName,
|
|
19
20
|
resolveSlicePath,
|
|
20
21
|
resolveTasksDir,
|
|
@@ -103,12 +104,15 @@ function resolveProjectMilestonePath(base: string, mid: string): string | null {
|
|
|
103
104
|
const milestonesDir = join(gsdRoot(base), "milestones");
|
|
104
105
|
const dir = resolveDir(milestonesDir, mid);
|
|
105
106
|
if (!dir) return null;
|
|
106
|
-
// git-service.ts
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
//
|
|
107
|
+
// Historically git-service.ts wrote integration-branch metadata into
|
|
108
|
+
// milestones/<MID>/<MID>-META.json, which could create that dir in flat-phase
|
|
109
|
+
// projects and poison layout detection. As of ADR-045 that META lives flat at
|
|
110
|
+
// .gsd/<MID>-META.json and no longer poisons detection. A dir that holds ONLY
|
|
111
|
+
// *-META.json files (a pre-migration on-disk tree) must still not be treated
|
|
112
|
+
// as a real legacy milestone dir — otherwise this early-return resolves
|
|
113
|
+
// CONTEXT/ROADMAP/SUMMARY to the legacy path (milestones/<MID>/<MID>-<SUFFIX>.md)
|
|
114
|
+
// before the flat-phase fallback can run, trapping the unit in a
|
|
115
|
+
// finalize-retry loop (#852 follow-up).
|
|
112
116
|
//
|
|
113
117
|
// We use dirIsMetaOnlyLegacyMilestone rather than !dirIsContentBearingLegacyMilestone
|
|
114
118
|
// so that an EMPTY dir (a new milestone before any content is written) is NOT
|
|
@@ -232,7 +236,10 @@ export function resolveExpectedArtifactPath(
|
|
|
232
236
|
const summaryDir = isLegacySlice
|
|
233
237
|
? (resolveTasksDir(base, mid, sid!) ?? slicePath)
|
|
234
238
|
: slicePath;
|
|
235
|
-
|
|
239
|
+
const fileName = isLegacySlice
|
|
240
|
+
? buildTaskFileName(tid, "SUMMARY")
|
|
241
|
+
: buildFlatTaskFileName(sid!, tid, "SUMMARY");
|
|
242
|
+
return join(summaryDir, fileName);
|
|
236
243
|
}
|
|
237
244
|
case "complete-slice": {
|
|
238
245
|
return resolveSliceArtifactPath(base, mid, sid!, "SUMMARY");
|
|
@@ -1956,6 +1956,7 @@ function applyLanguageDirectiveToDispatch(
|
|
|
1956
1956
|
if (action.action !== "dispatch" || !action.prompt) return action;
|
|
1957
1957
|
const directive = renderLanguageDirectiveForPrompt(prefs);
|
|
1958
1958
|
if (!directive) return action;
|
|
1959
|
+
if (action.prompt.startsWith(directive)) return action;
|
|
1959
1960
|
return { ...action, prompt: `${directive}\n\n${action.prompt}` };
|
|
1960
1961
|
}
|
|
1961
1962
|
|
|
@@ -16,10 +16,11 @@ import { loadPrompt, inlineTemplate } from "./prompt-loader.js";
|
|
|
16
16
|
import {
|
|
17
17
|
resolveMilestoneFile, resolveSliceFile, resolveSlicePath,
|
|
18
18
|
resolveTasksDir, resolveTaskFiles, resolveTaskFile,
|
|
19
|
+
taskIdFromTaskFileName,
|
|
19
20
|
relMilestoneFile, relSliceFile, relSlicePath, relMilestonePath,
|
|
20
21
|
relTaskFile, resolveGsdRootFile, relGsdRootFile, resolveRuntimeFile,
|
|
21
22
|
} from "./paths.js";
|
|
22
|
-
import { resolveInlineLevel, loadEffectiveGSDPreferences } from "./preferences.js";
|
|
23
|
+
import { resolveInlineLevel, loadEffectiveGSDPreferences, renderLanguageDirectiveForPrompt } from "./preferences.js";
|
|
23
24
|
import { createRepositoryRegistryFromPreferences } from "./repository-registry.js";
|
|
24
25
|
import { isContextModeEnabled } from "./preferences-types.js";
|
|
25
26
|
import { parseRoadmap } from "./parsers-legacy.js";
|
|
@@ -28,6 +29,7 @@ import type { GSDPreferences } from "./preferences.js";
|
|
|
28
29
|
import { join, basename, relative, sep } from "node:path";
|
|
29
30
|
import { existsSync } from "node:fs";
|
|
30
31
|
import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary, type MinimalModelRegistry } from "./context-budget.js";
|
|
32
|
+
import type { TokenProvider } from "./token-counter.js";
|
|
31
33
|
import { getBlockingReworkFindingsForTask, getGateResults, getPendingGates, getPendingGatesForTurn } from "./gsd-db.js";
|
|
32
34
|
import {
|
|
33
35
|
GATE_REGISTRY,
|
|
@@ -76,6 +78,14 @@ export { buildSkillActivationBlock, buildSkillDiscoveryVars };
|
|
|
76
78
|
*/
|
|
77
79
|
const MAX_PREAMBLE_CHARS = 20_000;
|
|
78
80
|
|
|
81
|
+
function prependLanguageDirectiveForBase(base: string, prompt: string): string {
|
|
82
|
+
const directive = renderLanguageDirectiveForPrompt(
|
|
83
|
+
loadEffectiveGSDPreferences(base)?.preferences,
|
|
84
|
+
);
|
|
85
|
+
if (!directive || prompt.startsWith(directive)) return prompt;
|
|
86
|
+
return `${directive}\n\n${prompt}`;
|
|
87
|
+
}
|
|
88
|
+
|
|
79
89
|
/**
|
|
80
90
|
* Resolve prompt budgets from the configured executor context window.
|
|
81
91
|
*
|
|
@@ -91,13 +101,29 @@ function resolvePromptBudgets(): ReturnType<typeof computeBudgets> {
|
|
|
91
101
|
const prefs = loadEffectiveGSDPreferences();
|
|
92
102
|
const sessionWindow = prefs?.preferences.context_window_override;
|
|
93
103
|
const windowTokens = resolveExecutorContextWindow(undefined, prefs?.preferences, sessionWindow);
|
|
94
|
-
return computeBudgets(windowTokens);
|
|
104
|
+
return computeBudgets(windowTokens, resolveExecutionProvider(prefs?.preferences));
|
|
95
105
|
} catch (e) {
|
|
96
106
|
logWarning("prompt", `resolvePromptBudgets failed: ${(e as Error).message}`);
|
|
97
107
|
return computeBudgets(200_000);
|
|
98
108
|
}
|
|
99
109
|
}
|
|
100
110
|
|
|
111
|
+
/**
|
|
112
|
+
* Best-effort provider for the chars/token ratio: the executor's configured
|
|
113
|
+
* model profile is the only provider source reachable here (the runtime
|
|
114
|
+
* `sessionProvider` that reaches `formatExecutorConstraints` isn't threaded to
|
|
115
|
+
* `capPreamble`/summary callers). Undefined when no explicit provider is set —
|
|
116
|
+
* `computeBudgets` then uses the 4.0 default, i.e. today's behavior.
|
|
117
|
+
*/
|
|
118
|
+
function resolveExecutionProvider(prefs?: { models?: { execution?: unknown } }): TokenProvider | undefined {
|
|
119
|
+
const exec = prefs?.models?.execution;
|
|
120
|
+
if (exec && typeof exec === "object" && "provider" in exec) {
|
|
121
|
+
const provider = (exec as { provider?: unknown }).provider;
|
|
122
|
+
if (typeof provider === "string" && provider) return provider as TokenProvider;
|
|
123
|
+
}
|
|
124
|
+
return undefined;
|
|
125
|
+
}
|
|
126
|
+
|
|
101
127
|
/**
|
|
102
128
|
* Character budget for dependency/prior slice summaries injected into dispatch
|
|
103
129
|
* prompts. Scales with the executor's configured context window (issue #4435).
|
|
@@ -236,7 +262,7 @@ function formatCloseoutReviewInstructions(validationContent: string | null, vali
|
|
|
236
262
|
].join("\n");
|
|
237
263
|
}
|
|
238
264
|
|
|
239
|
-
function capPreamble(preamble: string): string {
|
|
265
|
+
export function capPreamble(preamble: string): string {
|
|
240
266
|
// Cap inlined context at min(static ceiling, scaled inline budget).
|
|
241
267
|
// The ceiling bounds repeated auto prompt payloads; the scaled
|
|
242
268
|
// budget tightens the cap for small-window users whose true safe limit is
|
|
@@ -246,6 +272,41 @@ function capPreamble(preamble: string): string {
|
|
|
246
272
|
return truncateAtSectionBoundary(preamble, budget).content;
|
|
247
273
|
}
|
|
248
274
|
|
|
275
|
+
/**
|
|
276
|
+
* Cap the execute-task inline blocks against one shared budget in priority
|
|
277
|
+
* order. Unlike `capPreamble` (single concatenated preamble), execute-task
|
|
278
|
+
* feeds these blocks into separate, non-contiguous template placeholders, so
|
|
279
|
+
* they can't be joined and re-split — the budget is spent block-by-block.
|
|
280
|
+
*
|
|
281
|
+
* The task plan is the authoritative execution contract: it is never truncated
|
|
282
|
+
* here (it consumes budget first, whole). Remaining budget flows to the slice
|
|
283
|
+
* excerpt, then templates, each truncated at section boundaries so the lowest-
|
|
284
|
+
* priority context drops whole trailing sections first. When the task plan
|
|
285
|
+
* alone meets or exceeds the budget, the trailing blocks are dropped rather
|
|
286
|
+
* than the task plan being cut.
|
|
287
|
+
*/
|
|
288
|
+
function capExecuteTaskInlineBlocks(
|
|
289
|
+
taskPlan: string,
|
|
290
|
+
slicePlan: string,
|
|
291
|
+
templates: string,
|
|
292
|
+
budgetChars: number,
|
|
293
|
+
): { taskPlan: string; slicePlan: string; templates: string } {
|
|
294
|
+
let remaining = budgetChars - taskPlan.length;
|
|
295
|
+
if (remaining <= 0) {
|
|
296
|
+
return { taskPlan, slicePlan: "", templates: "" };
|
|
297
|
+
}
|
|
298
|
+
const cappedSlice = slicePlan.length <= remaining
|
|
299
|
+
? slicePlan
|
|
300
|
+
: truncateAtSectionBoundary(slicePlan, remaining).content;
|
|
301
|
+
remaining -= cappedSlice.length;
|
|
302
|
+
const cappedTemplates = remaining <= 0
|
|
303
|
+
? ""
|
|
304
|
+
: templates.length <= remaining
|
|
305
|
+
? templates
|
|
306
|
+
: truncateAtSectionBoundary(templates, remaining).content;
|
|
307
|
+
return { taskPlan, slicePlan: cappedSlice, templates: cappedTemplates };
|
|
308
|
+
}
|
|
309
|
+
|
|
249
310
|
type PromptContextMode = "inline" | "excerpt" | "on-demand" | "skipped";
|
|
250
311
|
|
|
251
312
|
interface PromptContextTelemetryEntry {
|
|
@@ -324,7 +385,7 @@ function prependContextModeToBlock(
|
|
|
324
385
|
block: string,
|
|
325
386
|
renderMode: ContextModeRenderMode = "standalone",
|
|
326
387
|
): string {
|
|
327
|
-
const toolSurface = composeToolSurfaceInstructions(unitType, { renderMode });
|
|
388
|
+
const toolSurface = composeToolSurfaceInstructions(unitType, { renderMode, basePath: base });
|
|
328
389
|
const contextMode = renderContextModeBlockForPrompt(unitType, base, renderMode);
|
|
329
390
|
const guidance = [toolSurface, contextMode].filter(Boolean).join("\n\n");
|
|
330
391
|
if (!guidance) return block;
|
|
@@ -405,7 +466,7 @@ function formatExecutorConstraints(
|
|
|
405
466
|
// so DEFAULT_CONTEXT_WINDOW stays the single source of truth.
|
|
406
467
|
windowTokens = resolveExecutorContextWindow(undefined, undefined, sessionContextWindow, sessionProvider);
|
|
407
468
|
}
|
|
408
|
-
const budgets = computeBudgets(windowTokens);
|
|
469
|
+
const budgets = computeBudgets(windowTokens, sessionProvider as TokenProvider | undefined);
|
|
409
470
|
const { min, max } = budgets.taskCountRange;
|
|
410
471
|
const execWindowK = Math.round(windowTokens / 1000);
|
|
411
472
|
const perTaskBudgetK = Math.round(budgets.inlineContextBudgetChars / 1000);
|
|
@@ -1431,6 +1492,18 @@ function resolveTaskSummariesLocation(
|
|
|
1431
1492
|
return { dir: slicePath, relPrefix: sRel };
|
|
1432
1493
|
}
|
|
1433
1494
|
|
|
1495
|
+
function summaryFileBelongsToSlice(
|
|
1496
|
+
fileName: string,
|
|
1497
|
+
base: string,
|
|
1498
|
+
mid: string,
|
|
1499
|
+
sid: string,
|
|
1500
|
+
): boolean {
|
|
1501
|
+
const tid = taskIdFromTaskFileName(fileName, "SUMMARY");
|
|
1502
|
+
if (!tid) return false;
|
|
1503
|
+
const resolved = resolveTaskFile(base, mid, sid, tid, "SUMMARY");
|
|
1504
|
+
return resolved !== null && basename(resolved) === fileName;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1434
1507
|
export async function getPriorTaskSummaryPaths(
|
|
1435
1508
|
mid: string, sid: string, currentTid: string, base: string,
|
|
1436
1509
|
): Promise<string[]> {
|
|
@@ -1442,7 +1515,10 @@ export async function getPriorTaskSummaryPaths(
|
|
|
1442
1515
|
|
|
1443
1516
|
return summaryFiles
|
|
1444
1517
|
.filter(f => {
|
|
1445
|
-
|
|
1518
|
+
if (!summaryFileBelongsToSlice(f, base, mid, sid)) return false;
|
|
1519
|
+
const tid = taskIdFromTaskFileName(f, "SUMMARY");
|
|
1520
|
+
if (!tid) return false;
|
|
1521
|
+
const num = parseInt(tid.replace(/^T/, ""), 10);
|
|
1446
1522
|
return num < currentNum;
|
|
1447
1523
|
})
|
|
1448
1524
|
.map(f => `${loc.relPrefix}/${f}`);
|
|
@@ -1475,8 +1551,9 @@ export async function getDependencyTaskSummaryPaths(
|
|
|
1475
1551
|
|
|
1476
1552
|
return summaryFiles
|
|
1477
1553
|
.filter((f) => {
|
|
1478
|
-
|
|
1479
|
-
const tid = f
|
|
1554
|
+
if (!summaryFileBelongsToSlice(f, base, mid, sid)) return false;
|
|
1555
|
+
const tid = taskIdFromTaskFileName(f, "SUMMARY");
|
|
1556
|
+
if (!tid) return false;
|
|
1480
1557
|
return depSet.has(tid);
|
|
1481
1558
|
})
|
|
1482
1559
|
.map((f) => `${loc.relPrefix}/${f}`);
|
|
@@ -1661,7 +1738,7 @@ export async function buildDiscussMilestonePrompt(
|
|
|
1661
1738
|
if (headless) {
|
|
1662
1739
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
1663
1740
|
const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
|
|
1664
|
-
|
|
1741
|
+
const prompt = loadPrompt("discuss-headless", {
|
|
1665
1742
|
seedContext: roadmapContent ?? "",
|
|
1666
1743
|
inlinedTemplates: contextTemplate,
|
|
1667
1744
|
workingDirectory: base,
|
|
@@ -1670,6 +1747,7 @@ export async function buildDiscussMilestonePrompt(
|
|
|
1670
1747
|
commitInstruction: "Do not commit planning artifacts — .gsd/ is managed externally.",
|
|
1671
1748
|
multiMilestoneCommitInstruction: "Do not commit planning artifacts — .gsd/ is managed externally.",
|
|
1672
1749
|
});
|
|
1750
|
+
return prependLanguageDirectiveForBase(base, prompt);
|
|
1673
1751
|
}
|
|
1674
1752
|
|
|
1675
1753
|
const rawInlinedContext = await buildDiscussMilestoneInlinedContext(mid, base);
|
|
@@ -1700,10 +1778,11 @@ export async function buildDiscussMilestonePrompt(
|
|
|
1700
1778
|
const truncationNote = cappedDraftSeed !== draftSeed
|
|
1701
1779
|
? `\n\n_(Draft seed truncated; read the full draft at \`${draftRelPath}\` if needed.)_`
|
|
1702
1780
|
: "";
|
|
1703
|
-
|
|
1781
|
+
const promptWithDraftSeed = `${promptWithContextMode}\n\n## Prior Discussion (Draft Seed)\n\nThe following draft was captured from a prior multi-milestone discussion. Use it as seed material — the user has already provided this context. Start with a brief reflection on what the draft covers, then probe for any gaps or open questions before writing the full CONTEXT.md.\n\n${cappedDraftSeed}${truncationNote}`;
|
|
1782
|
+
return prependLanguageDirectiveForBase(base, promptWithDraftSeed);
|
|
1704
1783
|
}
|
|
1705
1784
|
|
|
1706
|
-
return promptWithContextMode;
|
|
1785
|
+
return prependLanguageDirectiveForBase(base, promptWithContextMode);
|
|
1707
1786
|
}
|
|
1708
1787
|
|
|
1709
1788
|
/**
|
|
@@ -2725,7 +2804,7 @@ export async function buildExecuteTaskPrompt(
|
|
|
2725
2804
|
// Compute verification budget for the executor's context window (issue #707)
|
|
2726
2805
|
const prefs = loadEffectiveGSDPreferences();
|
|
2727
2806
|
const contextWindow = resolveExecutorContextWindow(opts.modelRegistry, prefs?.preferences, opts.sessionContextWindow, opts.sessionProvider);
|
|
2728
|
-
const budgets = computeBudgets(contextWindow);
|
|
2807
|
+
const budgets = computeBudgets(contextWindow, opts.sessionProvider as TokenProvider | undefined);
|
|
2729
2808
|
const verificationBudget = `~${Math.round(budgets.verificationBudgetChars / 1000)}K chars`;
|
|
2730
2809
|
|
|
2731
2810
|
// Truncate carry-forward section when it exceeds 40% of inline context budget.
|
|
@@ -2842,10 +2921,26 @@ export async function buildExecuteTaskPrompt(
|
|
|
2842
2921
|
}
|
|
2843
2922
|
},
|
|
2844
2923
|
});
|
|
2845
|
-
const
|
|
2846
|
-
const
|
|
2924
|
+
const rawTaskPlanInline = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "task-plan");
|
|
2925
|
+
const rawSlicePlanExcerpt = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "slice-plan");
|
|
2847
2926
|
const contractedCarryForward = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "prior-task-summaries");
|
|
2848
|
-
const
|
|
2927
|
+
const rawContractedTemplates = requireComposedArtifactBlock(contractedContext.blocks, "execute-task", "templates");
|
|
2928
|
+
// Cap the static inline blocks against one shared budget so a small-window
|
|
2929
|
+
// executor can't overflow (the sibling builders cap via `capPreamble`;
|
|
2930
|
+
// execute-task's blocks feed separate template slots, so they share a budget
|
|
2931
|
+
// block-by-block). Carry-forward already has its own truncation above.
|
|
2932
|
+
const inlineBudget = Math.min(MAX_PREAMBLE_CHARS, budgets.inlineContextBudgetChars);
|
|
2933
|
+
const { taskPlan: taskPlanInline, slicePlan: slicePlanExcerpt, templates: contractedTemplates } =
|
|
2934
|
+
capExecuteTaskInlineBlocks(rawTaskPlanInline, rawSlicePlanExcerpt, rawContractedTemplates, inlineBudget);
|
|
2935
|
+
const inlineDropped = (rawTaskPlanInline.length + rawSlicePlanExcerpt.length + rawContractedTemplates.length)
|
|
2936
|
+
- (taskPlanInline.length + slicePlanExcerpt.length + contractedTemplates.length);
|
|
2937
|
+
trackPromptContext(
|
|
2938
|
+
contextTelemetry,
|
|
2939
|
+
"inline-cap",
|
|
2940
|
+
inlineDropped > 0 ? "excerpt" : "skipped",
|
|
2941
|
+
null,
|
|
2942
|
+
inlineDropped > 0 ? `dropped ${inlineDropped} chars (budget ${inlineBudget})` : "within budget",
|
|
2943
|
+
);
|
|
2849
2944
|
const onDemandResult = renderExecuteTaskOnDemandContext(base, mid, sid, contractedContext.onDemand);
|
|
2850
2945
|
const onDemandContext = onDemandResult.text;
|
|
2851
2946
|
trackPromptContext(
|
|
@@ -2941,12 +3036,14 @@ export async function buildCompleteSlicePrompt(
|
|
|
2941
3036
|
trackPromptContext(contextTelemetry, "prior-task-summaries", "skipped", null, "missing tasks dir");
|
|
2942
3037
|
return null;
|
|
2943
3038
|
}
|
|
2944
|
-
const summaryFiles = resolveTaskFiles(loc.dir, "SUMMARY")
|
|
3039
|
+
const summaryFiles = resolveTaskFiles(loc.dir, "SUMMARY")
|
|
3040
|
+
.filter((file) => summaryFileBelongsToSlice(file, base, mid, sid))
|
|
3041
|
+
.sort();
|
|
2945
3042
|
const blocks: string[] = [];
|
|
2946
3043
|
for (const file of summaryFiles) {
|
|
2947
3044
|
const absPath = join(loc.dir, file);
|
|
2948
3045
|
const relPath = `${loc.relPrefix}/${file}`;
|
|
2949
|
-
const taskId = file.replace(/-SUMMARY\.md$/i, "");
|
|
3046
|
+
const taskId = taskIdFromTaskFileName(file, "SUMMARY") ?? file.replace(/-SUMMARY\.md$/i, "");
|
|
2950
3047
|
blocks.push(await buildTaskSummaryExcerpt(absPath, relPath, taskId));
|
|
2951
3048
|
}
|
|
2952
3049
|
const body = blocks.length > 0 ? blocks.join("\n\n---\n\n") : null;
|
|
@@ -3559,7 +3656,9 @@ export async function buildReplanSlicePrompt(
|
|
|
3559
3656
|
let blockerTaskId = "";
|
|
3560
3657
|
const summaryLoc = resolveTaskSummariesLocation(base, mid, sid);
|
|
3561
3658
|
if (summaryLoc) {
|
|
3562
|
-
const summaryFiles = resolveTaskFiles(summaryLoc.dir, "SUMMARY")
|
|
3659
|
+
const summaryFiles = resolveTaskFiles(summaryLoc.dir, "SUMMARY")
|
|
3660
|
+
.filter((file) => summaryFileBelongsToSlice(file, base, mid, sid))
|
|
3661
|
+
.sort();
|
|
3563
3662
|
for (const file of summaryFiles) {
|
|
3564
3663
|
const absPath = join(summaryLoc.dir, file);
|
|
3565
3664
|
const content = await loadFile(absPath);
|
|
@@ -3567,7 +3666,7 @@ export async function buildReplanSlicePrompt(
|
|
|
3567
3666
|
const summary = parseSummary(content);
|
|
3568
3667
|
const relPath = `${summaryLoc.relPrefix}/${file}`;
|
|
3569
3668
|
if (summary.frontmatter.blocker_discovered) {
|
|
3570
|
-
blockerTaskId = summary.frontmatter.id || file.replace(/-SUMMARY\.md$/i, "");
|
|
3669
|
+
blockerTaskId = summary.frontmatter.id || taskIdFromTaskFileName(file, "SUMMARY") || file.replace(/-SUMMARY\.md$/i, "");
|
|
3571
3670
|
inlined.push(await buildTaskSummaryExcerpt(absPath, relPath, blockerTaskId, { blocker: true }));
|
|
3572
3671
|
}
|
|
3573
3672
|
}
|
|
@@ -39,8 +39,7 @@ import { isClosedStatus, isInactiveStatus } from "./status-guards.js";
|
|
|
39
39
|
import {
|
|
40
40
|
resolveSlicePath,
|
|
41
41
|
resolveSliceFile,
|
|
42
|
-
|
|
43
|
-
resolveTaskFiles,
|
|
42
|
+
resolveTaskFile,
|
|
44
43
|
relMilestoneFile,
|
|
45
44
|
relSliceFile,
|
|
46
45
|
buildSliceFileName,
|
|
@@ -324,13 +323,16 @@ export function writeReactiveExecuteBlocker(
|
|
|
324
323
|
const slicePath = resolveSlicePath(base, mid, sid);
|
|
325
324
|
if (!slicePath) return null;
|
|
326
325
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
)
|
|
326
|
+
// Resolve each batch task's SUMMARY with slice-qualified paths so flat-phase
|
|
327
|
+
// slices that reuse a task id (e.g. two T03s in one phase) don't collide: a
|
|
328
|
+
// sibling slice's summary must never make this slice's task look complete.
|
|
329
|
+
const hasSummary = (tid: string): boolean => {
|
|
330
|
+
const summaryPath = resolveTaskFile(base, mid, sid, tid, "SUMMARY");
|
|
331
|
+
return summaryPath !== null && existsSync(summaryPath);
|
|
332
|
+
};
|
|
331
333
|
|
|
332
|
-
const summaryPresent = batchIds.filter((tid) =>
|
|
333
|
-
const summaryMissing = batchIds.filter((tid) => !
|
|
334
|
+
const summaryPresent = batchIds.filter((tid) => hasSummary(tid));
|
|
335
|
+
const summaryMissing = batchIds.filter((tid) => !hasSummary(tid));
|
|
334
336
|
const completedTaskIds: string[] = [];
|
|
335
337
|
const skippedTaskIds: string[] = [];
|
|
336
338
|
const unchangedTaskIds: string[] = [];
|
|
@@ -3,11 +3,10 @@ import { AutoSession } from "./auto/session.js";
|
|
|
3
3
|
import type { CurrentUnit } from "./auto/session.js";
|
|
4
4
|
import type { SourceObservationStore } from "./source-observations.js";
|
|
5
5
|
import {
|
|
6
|
-
isDeterministicPolicyError,
|
|
7
|
-
isQueuedUserMessageSkip,
|
|
8
|
-
isToolInvocationError,
|
|
9
6
|
markToolEnd as markTrackedToolEnd,
|
|
10
7
|
markToolStart as markTrackedToolStart,
|
|
8
|
+
shouldClearToolInvocationErrorAfterSuccess,
|
|
9
|
+
updateToolInvocationError,
|
|
11
10
|
} from "./auto-tool-tracking.js";
|
|
12
11
|
// Re-exported as a pure pass-through. Must stay UNGATED (no autoSession.active
|
|
13
12
|
// argument, unlike markToolStart at the bottom of this file) so it is true in
|
|
@@ -99,13 +98,19 @@ export function markToolEnd(toolCallId: string): void {
|
|
|
99
98
|
|
|
100
99
|
export function recordToolInvocationError(toolName: string, errorMsg: string): void {
|
|
101
100
|
if (!autoSession.active) return;
|
|
102
|
-
|
|
103
|
-
autoSession.lastToolInvocationError
|
|
104
|
-
|
|
101
|
+
autoSession.lastToolInvocationError = updateToolInvocationError(
|
|
102
|
+
autoSession.lastToolInvocationError,
|
|
103
|
+
toolName,
|
|
104
|
+
errorMsg,
|
|
105
|
+
);
|
|
105
106
|
}
|
|
106
107
|
|
|
107
|
-
export function clearToolInvocationError(): void {
|
|
108
|
+
export function clearToolInvocationError(successfulToolName?: string): void {
|
|
108
109
|
if (!autoSession.active) return;
|
|
110
|
+
if (!shouldClearToolInvocationErrorAfterSuccess(
|
|
111
|
+
autoSession.lastToolInvocationError,
|
|
112
|
+
successfulToolName,
|
|
113
|
+
)) return;
|
|
109
114
|
autoSession.lastToolInvocationError = null;
|
|
110
115
|
}
|
|
111
116
|
|
|
@@ -88,6 +88,7 @@ import { classifyMilestoneSummaryContent } from "./milestone-summary-classifier.
|
|
|
88
88
|
import { extractVerdict } from "./verdict-parser.js";
|
|
89
89
|
import { auditOrphanedPreflightStashes } from "./orphan-stash-audit.js";
|
|
90
90
|
import { parseProject } from "./schemas/parsers.js";
|
|
91
|
+
import { LAYOUT_SEGMENTS } from "./layout-policy.js";
|
|
91
92
|
|
|
92
93
|
import {
|
|
93
94
|
debugLog,
|
|
@@ -152,6 +153,33 @@ export function hasGitIndexLockForTest(basePath: string): boolean {
|
|
|
152
153
|
return existsSync(join(basePath, ".git", "index.lock"));
|
|
153
154
|
}
|
|
154
155
|
|
|
156
|
+
function isEmptyDirectory(dirPath: string): boolean {
|
|
157
|
+
try {
|
|
158
|
+
return existsSync(dirPath) && readdirSync(dirPath).length === 0;
|
|
159
|
+
} catch {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function reconcileFlatPhaseBootstrapLayout(basePath: string): boolean {
|
|
165
|
+
const gsdDir = join(basePath, ".gsd");
|
|
166
|
+
const phasesPath = join(gsdDir, LAYOUT_SEGMENTS.level1);
|
|
167
|
+
const milestonesPath = join(gsdDir, "milestones");
|
|
168
|
+
|
|
169
|
+
if (isEmptyDirectory(milestonesPath)) {
|
|
170
|
+
if (!existsSync(phasesPath)) mkdirSync(phasesPath, { recursive: true });
|
|
171
|
+
rmSync(milestonesPath, { recursive: true, force: true });
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (!existsSync(phasesPath) && !existsSync(milestonesPath)) {
|
|
176
|
+
mkdirSync(phasesPath, { recursive: true });
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
|
|
155
183
|
export function _shouldAbortBootstrapForUnavailableDbForTest(
|
|
156
184
|
gsdDbPath: string,
|
|
157
185
|
dbAvailable: boolean,
|
|
@@ -1057,7 +1085,7 @@ export async function bootstrapAutoSession(
|
|
|
1057
1085
|
// provider the user is not logged into and surface as "Not logged in · Please
|
|
1058
1086
|
// run /login" before pausing and resetting to claude-code/claude-sonnet-4-6.
|
|
1059
1087
|
const manualSessionOverride = getSessionModelOverride(ctx.sessionManager.getSessionId());
|
|
1060
|
-
const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider);
|
|
1088
|
+
const sessionProviderIsCustom = isCustomProvider(ctx.model?.provider, ctx.modelRegistry);
|
|
1061
1089
|
const profileModelIds = modelIdsForProfileResolution(
|
|
1062
1090
|
ctx.modelRegistry,
|
|
1063
1091
|
resolveProfileAnchorProvider(ctx.model?.provider),
|
|
@@ -1152,19 +1180,14 @@ export async function bootstrapAutoSession(
|
|
|
1152
1180
|
ensureGitignore(base, { manageGitignore });
|
|
1153
1181
|
if (manageGitignore !== false) untrackRuntimeFiles(base);
|
|
1154
1182
|
|
|
1155
|
-
// Bootstrap
|
|
1156
|
-
|
|
1157
|
-
// so checking .gsd/ existence would be dead code (#2942).
|
|
1158
|
-
const gsdDir = join(base, ".gsd");
|
|
1159
|
-
const milestonesPath = join(gsdDir, "milestones");
|
|
1160
|
-
if (!existsSync(milestonesPath)) {
|
|
1161
|
-
mkdirSync(milestonesPath, { recursive: true });
|
|
1183
|
+
// Bootstrap the flat-phase projection root and clean empty legacy scaffolds.
|
|
1184
|
+
if (reconcileFlatPhaseBootstrapLayout(base)) {
|
|
1162
1185
|
try {
|
|
1163
1186
|
nativeAddAll(base);
|
|
1164
1187
|
nativeCommit(base, "chore: init gsd");
|
|
1165
1188
|
} catch (err) {
|
|
1166
1189
|
/* nothing to commit */
|
|
1167
|
-
logWarning("engine", `
|
|
1190
|
+
logWarning("engine", `layout bootstrap commit failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1168
1191
|
}
|
|
1169
1192
|
}
|
|
1170
1193
|
|
|
@@ -132,6 +132,8 @@ export function clearInFlightTools(): void {
|
|
|
132
132
|
*/
|
|
133
133
|
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;
|
|
134
134
|
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;
|
|
135
|
+
const SCHEDULE_WAKEUP_TOOL_NAME = "ScheduleWakeup";
|
|
136
|
+
const SCHEDULE_WAKEUP_CONTINUATION_ERROR = "`prompt` is required when `stop` is not true";
|
|
135
137
|
|
|
136
138
|
/**
|
|
137
139
|
* Matches the runtime's "tool not registered" error. Unlike the deterministic
|
|
@@ -151,6 +153,60 @@ export function isToolInvocationError(errorMsg: string): boolean {
|
|
|
151
153
|
return TOOL_INVOCATION_ERROR_RE.test(errorMsg) || isDeterministicPolicyError(errorMsg);
|
|
152
154
|
}
|
|
153
155
|
|
|
156
|
+
/**
|
|
157
|
+
* Claude Code validates its native ScheduleWakeup tool outside GSD's schema.
|
|
158
|
+
* Keep this exact and tool-scoped so similarly worded business validation from
|
|
159
|
+
* unrelated tools does not pause auto-mode.
|
|
160
|
+
*/
|
|
161
|
+
export function isScheduleWakeupContinuationError(toolName: string, errorMsg: string): boolean {
|
|
162
|
+
return stripMcpToolPrefix(toolName) === SCHEDULE_WAKEUP_TOOL_NAME
|
|
163
|
+
&& errorMsg.trim() === SCHEDULE_WAKEUP_CONTINUATION_ERROR;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function shouldRecordToolInvocationError(toolName: string, errorMsg: string): boolean {
|
|
167
|
+
return isScheduleWakeupContinuationError(toolName, errorMsg)
|
|
168
|
+
|| isToolInvocationError(errorMsg)
|
|
169
|
+
|| isQueuedUserMessageSkip(errorMsg);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function isRecordedScheduleWakeupContinuationError(recordedError: string | null): boolean {
|
|
173
|
+
if (!recordedError) return false;
|
|
174
|
+
|
|
175
|
+
const separator = recordedError.indexOf(": ");
|
|
176
|
+
return separator >= 0 && isScheduleWakeupContinuationError(
|
|
177
|
+
recordedError.slice(0, separator),
|
|
178
|
+
recordedError.slice(separator + 2),
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function updateToolInvocationError(
|
|
183
|
+
recordedError: string | null,
|
|
184
|
+
toolName: string,
|
|
185
|
+
errorMsg: string,
|
|
186
|
+
): string | null {
|
|
187
|
+
if (!shouldRecordToolInvocationError(toolName, errorMsg)) return recordedError;
|
|
188
|
+
if (
|
|
189
|
+
isRecordedScheduleWakeupContinuationError(recordedError)
|
|
190
|
+
&& !isScheduleWakeupContinuationError(toolName, errorMsg)
|
|
191
|
+
) return recordedError;
|
|
192
|
+
|
|
193
|
+
return `${toolName}: ${errorMsg}`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* A failed continuation must survive successful diagnostic/read calls in the
|
|
198
|
+
* same turn. Only a later successful ScheduleWakeup proves the continuation
|
|
199
|
+
* was armed; all other invocation errors retain their existing clear-on-success
|
|
200
|
+
* behavior.
|
|
201
|
+
*/
|
|
202
|
+
export function shouldClearToolInvocationErrorAfterSuccess(
|
|
203
|
+
recordedError: string | null,
|
|
204
|
+
successfulToolName?: string,
|
|
205
|
+
): boolean {
|
|
206
|
+
return !isRecordedScheduleWakeupContinuationError(recordedError)
|
|
207
|
+
|| stripMcpToolPrefix(successfulToolName ?? "") === SCHEDULE_WAKEUP_TOOL_NAME;
|
|
208
|
+
}
|
|
209
|
+
|
|
154
210
|
/**
|
|
155
211
|
* Returns true if the error message indicates the called tool was not on the
|
|
156
212
|
* session's tool surface (MCP startup race — see TOOL_UNAVAILABLE_ERROR_RE).
|