@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
|
@@ -23,7 +23,10 @@ import {
|
|
|
23
23
|
} from "../bootstrap/agent-end-recovery.ts";
|
|
24
24
|
import { blockModelUntil, clearTemporaryModelBlocksForTest } from "../blocked-models.ts";
|
|
25
25
|
import { _buildCancelledUnitStopReason } from "../auto/phase-helpers.ts";
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
_classifyZeroToolProviderMessageForTest,
|
|
28
|
+
_zeroToolPseudoToolCallSnippetForTest,
|
|
29
|
+
} from "../auto/unit-phase.ts";
|
|
27
30
|
import { autoSession } from "../auto-runtime-state.ts";
|
|
28
31
|
import { getNextFallbackModel } from "../preferences.ts";
|
|
29
32
|
import { clearGuidedUnitContext, getGuidedUnitContext, setGuidedUnitContext } from "../guided-unit-context.ts";
|
|
@@ -77,6 +80,21 @@ test("zero-tool provider classifier treats weekly limit wording as transient rat
|
|
|
77
80
|
assert.equal(result.kind, "rate-limit");
|
|
78
81
|
});
|
|
79
82
|
|
|
83
|
+
test("zero-tool pseudo tool-call detector identifies serialization drift", () => {
|
|
84
|
+
const snippet = _zeroToolPseudoToolCallSnippetForTest(
|
|
85
|
+
'bash<arg_key>command</arg_key><arg_value>ls -la /tmp && echo "---SRC---"</arg_value></tool_call>',
|
|
86
|
+
);
|
|
87
|
+
assert.ok(snippet, "pseudo tool-call text should be recognized");
|
|
88
|
+
assert.match(snippet, /bash<arg_key>command<\/arg_key>/);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("zero-tool provider classifier does not treat pseudo tool-call text as an error class", () => {
|
|
92
|
+
const result = _classifyZeroToolProviderMessageForTest(
|
|
93
|
+
'bash<arg_key>command</arg_key><arg_value>ls -la /tmp && echo "---SRC---"</arg_value></tool_call>',
|
|
94
|
+
);
|
|
95
|
+
assert.equal(result, null, "pseudo tool-call text is drift, not a provider error");
|
|
96
|
+
});
|
|
97
|
+
|
|
80
98
|
test("classifyError treats extra-usage phrasing as transient rate-limit (#4397)", () => {
|
|
81
99
|
const result = classifyError("You are out of extra usage. Please wait before retrying.");
|
|
82
100
|
assert.ok(isTransient(result));
|
|
@@ -651,6 +669,108 @@ test("rate-limit agent_end walks past unavailable fallback models before pausing
|
|
|
651
669
|
}
|
|
652
670
|
});
|
|
653
671
|
|
|
672
|
+
test("retry-exhausted abort/unknown provider stop reasons trigger model fallback (#1364)", async () => {
|
|
673
|
+
const originalCwd = process.cwd();
|
|
674
|
+
const originalSetTimeout = globalThis.setTimeout;
|
|
675
|
+
|
|
676
|
+
globalThis.setTimeout = ((fn: (...args: unknown[]) => void, delay?: number) => {
|
|
677
|
+
if ((delay ?? 0) === 0) {
|
|
678
|
+
fn();
|
|
679
|
+
}
|
|
680
|
+
return 0 as unknown as ReturnType<typeof setTimeout>;
|
|
681
|
+
}) as typeof setTimeout;
|
|
682
|
+
|
|
683
|
+
try {
|
|
684
|
+
for (const reason of ["abort", "unknown"]) {
|
|
685
|
+
const base = mkdtempSync(join(tmpdir(), `gsd-stop-reason-${reason}-`));
|
|
686
|
+
const notifications: Array<{ message: string; level?: string }> = [];
|
|
687
|
+
const setModelCalls: string[] = [];
|
|
688
|
+
const sendMessageCalls: unknown[][] = [];
|
|
689
|
+
|
|
690
|
+
try {
|
|
691
|
+
resetTransientRetryState();
|
|
692
|
+
clearTemporaryModelBlocksForTest();
|
|
693
|
+
autoSession.reset();
|
|
694
|
+
mkdirSync(join(base, ".gsd"), { recursive: true });
|
|
695
|
+
writeFileSync(
|
|
696
|
+
join(base, ".gsd", "PREFERENCES.md"),
|
|
697
|
+
[
|
|
698
|
+
"---",
|
|
699
|
+
"models:",
|
|
700
|
+
" execution:",
|
|
701
|
+
" model: gpt-5.5",
|
|
702
|
+
" provider: openai-codex",
|
|
703
|
+
" fallbacks:",
|
|
704
|
+
" - anthropic/claude-sonnet-4-6",
|
|
705
|
+
"---",
|
|
706
|
+
].join("\n"),
|
|
707
|
+
"utf-8",
|
|
708
|
+
);
|
|
709
|
+
process.chdir(base);
|
|
710
|
+
|
|
711
|
+
autoSession.active = true;
|
|
712
|
+
autoSession.basePath = base;
|
|
713
|
+
autoSession.currentUnit = { type: "execute-task", id: "M001/S01/T01", startedAt: Date.now() };
|
|
714
|
+
autoSession.autoModeStartModel = { provider: "openai-codex", id: "gpt-5.5" };
|
|
715
|
+
|
|
716
|
+
const availableModels = [
|
|
717
|
+
{ id: "gpt-5.5", provider: "openai-codex", api: "responses" },
|
|
718
|
+
{ id: "claude-sonnet-4-6", provider: "anthropic", api: "anthropic-messages" },
|
|
719
|
+
];
|
|
720
|
+
const ctx = {
|
|
721
|
+
model: availableModels[0],
|
|
722
|
+
modelRegistry: { getAvailable: () => availableModels },
|
|
723
|
+
ui: {
|
|
724
|
+
notify(message: string, level?: "info" | "warning" | "error" | "success") {
|
|
725
|
+
notifications.push({ message, level });
|
|
726
|
+
},
|
|
727
|
+
setStatus: () => {},
|
|
728
|
+
setWidget: () => {},
|
|
729
|
+
setWorkingMessage: () => {},
|
|
730
|
+
},
|
|
731
|
+
} as any;
|
|
732
|
+
const pi = {
|
|
733
|
+
setModel: async (model: { provider: string; id: string }) => {
|
|
734
|
+
setModelCalls.push(`${model.provider}/${model.id}`);
|
|
735
|
+
return true;
|
|
736
|
+
},
|
|
737
|
+
sendMessage: (...args: unknown[]) => {
|
|
738
|
+
sendMessageCalls.push(args);
|
|
739
|
+
},
|
|
740
|
+
} as any;
|
|
741
|
+
|
|
742
|
+
await handleAgentEnd(pi, {
|
|
743
|
+
messages: [{
|
|
744
|
+
role: "assistant",
|
|
745
|
+
stopReason: "error",
|
|
746
|
+
errorMessage: `Retry failed after 3 attempts: Unhandled stop reason: ${reason}`,
|
|
747
|
+
}],
|
|
748
|
+
} as any, ctx);
|
|
749
|
+
|
|
750
|
+
assert.deepEqual(setModelCalls, ["anthropic/claude-sonnet-4-6"], `${reason} should switch to configured fallback`);
|
|
751
|
+
assert.equal(sendMessageCalls.length, 1, `${reason} fallback recovery must trigger a continuation turn`);
|
|
752
|
+
assert.deepEqual(sendMessageCalls[0][1], { triggerTurn: true });
|
|
753
|
+
assert.ok(
|
|
754
|
+
notifications.some((n) => n.message.includes("anthropic/claude-sonnet-4-6")),
|
|
755
|
+
`${reason} notification should name the selected fallback`,
|
|
756
|
+
);
|
|
757
|
+
} finally {
|
|
758
|
+
process.chdir(originalCwd);
|
|
759
|
+
clearTemporaryModelBlocksForTest();
|
|
760
|
+
resetTransientRetryState();
|
|
761
|
+
autoSession.reset();
|
|
762
|
+
rmSync(base, { recursive: true, force: true });
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
} finally {
|
|
766
|
+
globalThis.setTimeout = originalSetTimeout;
|
|
767
|
+
process.chdir(originalCwd);
|
|
768
|
+
clearTemporaryModelBlocksForTest();
|
|
769
|
+
resetTransientRetryState();
|
|
770
|
+
autoSession.reset();
|
|
771
|
+
}
|
|
772
|
+
});
|
|
773
|
+
|
|
654
774
|
test("isTerminalDeletedWorktreeProviderError matches removed auto-worktree paths only", () => {
|
|
655
775
|
assert.equal(
|
|
656
776
|
isTerminalDeletedWorktreeProviderError('Path "/Users/dev/.gsd/projects/abc123/worktrees/M005" does not exist'),
|
|
@@ -608,3 +608,42 @@ test("getDependencyTaskSummaryPaths handles missing dependency summaries gracefu
|
|
|
608
608
|
rmSync(repo, { recursive: true, force: true });
|
|
609
609
|
}
|
|
610
610
|
});
|
|
611
|
+
|
|
612
|
+
test("#1343: getPriorTaskSummaryPaths excludes sibling-slice summaries in flat-phase", async () => {
|
|
613
|
+
const { getPriorTaskSummaryPaths } = await import("../auto-prompts.ts");
|
|
614
|
+
const repo = mkdtempSync(join(tmpdir(), "gsd-reactive-flat-prior-"));
|
|
615
|
+
try {
|
|
616
|
+
// Flat-phase: slices S01 and S02 share the phase dir and overlap task ids.
|
|
617
|
+
const phaseDir = join(repo, ".gsd", "phases", "01-test");
|
|
618
|
+
mkdirSync(phaseDir, { recursive: true });
|
|
619
|
+
writeFileSync(join(phaseDir, "S01-T01-SUMMARY.md"), "---\nid: T01\n---\n# S01 T01\n");
|
|
620
|
+
writeFileSync(join(phaseDir, "S02-T01-SUMMARY.md"), "---\nid: T01\n---\n# S02 T01\n");
|
|
621
|
+
|
|
622
|
+
// S02/T02 prior summaries must not pull the sibling S01-T01 summary.
|
|
623
|
+
const paths = await getPriorTaskSummaryPaths("M001", "S02", "T02", repo);
|
|
624
|
+
assert.equal(paths.length, 1, "Should only return the current slice's prior summary");
|
|
625
|
+
assert.ok(paths[0].includes("S02-T01-SUMMARY"), "Should include S02's T01");
|
|
626
|
+
assert.ok(!paths.some((p) => p.includes("S01-T01-SUMMARY")), "Should NOT include sibling S01's T01");
|
|
627
|
+
} finally {
|
|
628
|
+
rmSync(repo, { recursive: true, force: true });
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
test("#1343: getDependencyTaskSummaryPaths excludes sibling-slice summaries in flat-phase", async () => {
|
|
633
|
+
const { getDependencyTaskSummaryPaths } = await import("../auto-prompts.ts");
|
|
634
|
+
const repo = mkdtempSync(join(tmpdir(), "gsd-reactive-flat-dep-"));
|
|
635
|
+
try {
|
|
636
|
+
const phaseDir = join(repo, ".gsd", "phases", "01-test");
|
|
637
|
+
mkdirSync(phaseDir, { recursive: true });
|
|
638
|
+
writeFileSync(join(phaseDir, "S01-T01-SUMMARY.md"), "---\nid: T01\n---\n# S01 T01\n");
|
|
639
|
+
writeFileSync(join(phaseDir, "S02-T01-SUMMARY.md"), "---\nid: T01\n---\n# S02 T01\n");
|
|
640
|
+
|
|
641
|
+
// S02/T02 depends on T01 — must resolve S02's T01, not the sibling S01's.
|
|
642
|
+
const paths = await getDependencyTaskSummaryPaths("M001", "S02", "T02", ["T01"], repo);
|
|
643
|
+
assert.equal(paths.length, 1, "Should only return the current slice's dependency summary");
|
|
644
|
+
assert.ok(paths[0].includes("S02-T01-SUMMARY"), "Should include S02's T01");
|
|
645
|
+
assert.ok(!paths.some((p) => p.includes("S01-T01-SUMMARY")), "Should NOT include sibling S01's T01");
|
|
646
|
+
} finally {
|
|
647
|
+
rmSync(repo, { recursive: true, force: true });
|
|
648
|
+
}
|
|
649
|
+
});
|
|
@@ -6,8 +6,10 @@ import { join } from "node:path";
|
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
|
|
8
8
|
import { autoSession } from "../auto-runtime-state.ts";
|
|
9
|
+
import { postUnitPreVerification } from "../auto-post-unit.ts";
|
|
9
10
|
import { registerHooks } from "../bootstrap/register-hooks.ts";
|
|
10
11
|
import { resetToolCallLoopGuard } from "../bootstrap/tool-call-loop-guard.ts";
|
|
12
|
+
import { closeDatabase, openDatabase } from "../gsd-db.ts";
|
|
11
13
|
import { readUnitHarnessAbort } from "../unit-runtime.ts";
|
|
12
14
|
|
|
13
15
|
type Handler = (event: any, ctx?: any) => Promise<any> | any;
|
|
@@ -166,6 +168,109 @@ test("register-hooks does not record normal product tool failures as harness abo
|
|
|
166
168
|
assert.equal(abort, null);
|
|
167
169
|
});
|
|
168
170
|
|
|
171
|
+
test("tool_execution_end latches a failed ScheduleWakeup across unrelated tool success", async (t) => {
|
|
172
|
+
const base = makeRuntimeBase();
|
|
173
|
+
mkdirSync(join(base, ".gsd", "milestones", "M001"), { recursive: true });
|
|
174
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
175
|
+
autoSession.reset();
|
|
176
|
+
autoSession.active = true;
|
|
177
|
+
autoSession.basePath = base;
|
|
178
|
+
autoSession.currentUnit = { type: "discuss-milestone", id: "M001", startedAt: Date.now() };
|
|
179
|
+
t.after(() => {
|
|
180
|
+
closeDatabase();
|
|
181
|
+
autoSession.reset();
|
|
182
|
+
rmSync(base, { recursive: true, force: true });
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const { emitToolExecutionEnd } = makeHookHarness();
|
|
186
|
+
const error = "`prompt` is required when `stop` is not true";
|
|
187
|
+
|
|
188
|
+
await emitToolExecutionEnd({
|
|
189
|
+
toolName: "ScheduleWakeup",
|
|
190
|
+
isError: true,
|
|
191
|
+
result: error,
|
|
192
|
+
});
|
|
193
|
+
assert.equal(autoSession.lastToolInvocationError, `ScheduleWakeup: ${error}`);
|
|
194
|
+
|
|
195
|
+
await emitToolExecutionEnd({
|
|
196
|
+
toolName: "read",
|
|
197
|
+
isError: false,
|
|
198
|
+
result: "file contents",
|
|
199
|
+
});
|
|
200
|
+
assert.equal(
|
|
201
|
+
autoSession.lastToolInvocationError,
|
|
202
|
+
`ScheduleWakeup: ${error}`,
|
|
203
|
+
"an unrelated success must not erase a failed continuation before the unit boundary",
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
await emitToolExecutionEnd({
|
|
207
|
+
toolName: "parse_payload",
|
|
208
|
+
isError: true,
|
|
209
|
+
result: "Unexpected end of JSON input",
|
|
210
|
+
});
|
|
211
|
+
assert.equal(
|
|
212
|
+
autoSession.lastToolInvocationError,
|
|
213
|
+
`ScheduleWakeup: ${error}`,
|
|
214
|
+
"a later invocation error must not replace the failed continuation",
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
let pauseCalled = false;
|
|
218
|
+
const notifications: Array<{ message: string; severity?: string }> = [];
|
|
219
|
+
const result = await postUnitPreVerification(
|
|
220
|
+
{
|
|
221
|
+
s: autoSession,
|
|
222
|
+
ctx: {
|
|
223
|
+
ui: {
|
|
224
|
+
notify: (message: string, severity?: string) => notifications.push({ message, severity }),
|
|
225
|
+
},
|
|
226
|
+
} as any,
|
|
227
|
+
pi: {} as any,
|
|
228
|
+
buildSnapshotOpts: () => ({}) as any,
|
|
229
|
+
lockBase: () => base,
|
|
230
|
+
stopAuto: async () => {},
|
|
231
|
+
pauseAuto: async () => { pauseCalled = true; },
|
|
232
|
+
updateProgressWidget: () => {},
|
|
233
|
+
},
|
|
234
|
+
{ skipSettleDelay: true, skipWorktreeSync: true },
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
assert.equal(result, "dispatched");
|
|
238
|
+
assert.equal(pauseCalled, true);
|
|
239
|
+
assert.equal(autoSession.pendingVerificationRetry, null);
|
|
240
|
+
assert.ok(
|
|
241
|
+
notifications.some(({ message, severity }) => severity === "error" && message.includes(error)),
|
|
242
|
+
"the unit boundary must surface the rejected continuation",
|
|
243
|
+
);
|
|
244
|
+
assert.equal(autoSession.lastToolInvocationError, null);
|
|
245
|
+
|
|
246
|
+
await emitToolExecutionEnd({
|
|
247
|
+
toolName: "ScheduleWakeup",
|
|
248
|
+
isError: true,
|
|
249
|
+
result: error,
|
|
250
|
+
});
|
|
251
|
+
await emitToolExecutionEnd({
|
|
252
|
+
toolName: "ScheduleWakeup",
|
|
253
|
+
isError: false,
|
|
254
|
+
result: "Wakeup scheduled",
|
|
255
|
+
});
|
|
256
|
+
assert.equal(autoSession.lastToolInvocationError, null);
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test("tool_execution_end ignores ScheduleWakeup-shaped business validation from other tools", async (t) => {
|
|
260
|
+
autoSession.reset();
|
|
261
|
+
autoSession.active = true;
|
|
262
|
+
t.after(() => autoSession.reset());
|
|
263
|
+
|
|
264
|
+
const { emitToolExecutionEnd } = makeHookHarness();
|
|
265
|
+
await emitToolExecutionEnd({
|
|
266
|
+
toolName: "submit_review",
|
|
267
|
+
isError: true,
|
|
268
|
+
result: "`prompt` is required when `stop` is not true",
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
assert.equal(autoSession.lastToolInvocationError, null);
|
|
272
|
+
});
|
|
273
|
+
|
|
169
274
|
test("register-hooks does not classify normal gsd_uat_exec nonzero exits as harness aborts", async (t) => {
|
|
170
275
|
const base = makeRuntimeBase();
|
|
171
276
|
const startedAt = Date.now();
|
|
@@ -35,6 +35,10 @@ describe("supportsServiceTier", () => {
|
|
|
35
35
|
assert.equal(supportsServiceTier("gpt-5.5"), false);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
+
test("returns false for gpt-5.6 variants until service_tier payload support is verified", () => {
|
|
39
|
+
assert.equal(supportsServiceTier("gpt-5.6-sol"), false);
|
|
40
|
+
});
|
|
41
|
+
|
|
38
42
|
test("returns false for provider-only identifier without gpt-5.4 model suffix", () => {
|
|
39
43
|
assert.equal(supportsServiceTier("vibeproxy-openai"), false);
|
|
40
44
|
});
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
* self-identify (Stream 2: actor identity passthrough).
|
|
8
8
|
*
|
|
9
9
|
* 2. The 3 reversibility handlers (reopen-task/slice/milestone) are
|
|
10
|
-
* registered as MCP tools
|
|
11
|
-
*
|
|
10
|
+
* registered as MCP tools under their canonical names, and additionally
|
|
11
|
+
* under their alias names when GSD_ADVERTISE_TOOL_ALIASES=1 (plan 035
|
|
12
|
+
* suppresses alias schemas by default) (Stream 3: reversibility tools).
|
|
12
13
|
*
|
|
13
14
|
* 3. The reopen tools accept the documented core params plus optional
|
|
14
15
|
* reason/actorName/triggerReason without rejecting valid payloads.
|
|
@@ -36,6 +37,18 @@ function getTool(name: string) {
|
|
|
36
37
|
return pi.tools.find((t: any) => t.name === name);
|
|
37
38
|
}
|
|
38
39
|
|
|
40
|
+
function withEnv(name: string, value: string | undefined, fn: () => void): void {
|
|
41
|
+
const previous = process.env[name];
|
|
42
|
+
if (value === undefined) delete process.env[name];
|
|
43
|
+
else process.env[name] = value;
|
|
44
|
+
try {
|
|
45
|
+
fn();
|
|
46
|
+
} finally {
|
|
47
|
+
if (previous === undefined) delete process.env[name];
|
|
48
|
+
else process.env[name] = previous;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
39
52
|
function getRequiredProps(tool: any): string[] {
|
|
40
53
|
return tool.parameters.required ?? [];
|
|
41
54
|
}
|
|
@@ -78,7 +91,9 @@ for (const name of ACTOR_TOOLS) {
|
|
|
78
91
|
});
|
|
79
92
|
}
|
|
80
93
|
|
|
81
|
-
// ─── Stream 3: reopen tools registered
|
|
94
|
+
// ─── Stream 3: reopen tools registered under canonical names ────────────────
|
|
95
|
+
// Plan 035 suppresses alias schemas by default; the canonical reopen tools are
|
|
96
|
+
// always registered, and their aliases only when GSD_ADVERTISE_TOOL_ALIASES=1.
|
|
82
97
|
|
|
83
98
|
const REOPEN_TOOLS = [
|
|
84
99
|
{ canonical: "gsd_task_reopen", alias: "gsd_reopen_task" },
|
|
@@ -87,13 +102,24 @@ const REOPEN_TOOLS = [
|
|
|
87
102
|
];
|
|
88
103
|
|
|
89
104
|
for (const { canonical, alias } of REOPEN_TOOLS) {
|
|
90
|
-
test(`${canonical} — registered
|
|
105
|
+
test(`${canonical} — registered under its canonical name, no alias by default`, () => {
|
|
91
106
|
const canonicalTool = getTool(canonical);
|
|
92
|
-
const aliasTool = getTool(alias);
|
|
93
107
|
assert.ok(canonicalTool, `${canonical} must be registered`);
|
|
94
|
-
assert.ok(aliasTool, `${alias} must be registered as alias`);
|
|
95
108
|
assert.ok(typeof canonicalTool.execute === "function", `${canonical} must have an execute function`);
|
|
96
|
-
assert.ok(
|
|
109
|
+
assert.ok(!getTool(alias), `${alias} must not be registered by default (plan 035 alias suppression)`);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test(`${canonical} — registered with alias ${alias} when GSD_ADVERTISE_TOOL_ALIASES=1`, () => {
|
|
113
|
+
withEnv("GSD_ADVERTISE_TOOL_ALIASES", "1", () => {
|
|
114
|
+
const aliasPi = makeMockPi();
|
|
115
|
+
registerDbTools(aliasPi);
|
|
116
|
+
const canonicalTool = aliasPi.tools.find((t: any) => t.name === canonical);
|
|
117
|
+
const aliasTool = aliasPi.tools.find((t: any) => t.name === alias);
|
|
118
|
+
assert.ok(canonicalTool, `${canonical} must be registered`);
|
|
119
|
+
assert.ok(aliasTool, `${alias} must be registered as alias`);
|
|
120
|
+
assert.ok(typeof canonicalTool.execute === "function", `${canonical} must have an execute function`);
|
|
121
|
+
assert.ok(typeof aliasTool.execute === "function", `${alias} must have an execute function`);
|
|
122
|
+
});
|
|
97
123
|
});
|
|
98
124
|
}
|
|
99
125
|
|
|
@@ -56,6 +56,10 @@ function buildBlock(
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
function expectedSkillRead(base: string, name: string): string {
|
|
60
|
+
return `Read the skill file at \`${join(base, "skills", name, "SKILL.md")}\``;
|
|
61
|
+
}
|
|
62
|
+
|
|
59
63
|
test("buildSkillActivationBlock does not auto-activate skills via broad context heuristic", () => {
|
|
60
64
|
const base = makeTempBase();
|
|
61
65
|
try {
|
|
@@ -92,7 +96,7 @@ test("buildSkillActivationBlock activates skills via prefer_skills when context
|
|
|
92
96
|
prefer_skills: ["react"],
|
|
93
97
|
});
|
|
94
98
|
|
|
95
|
-
assert.
|
|
99
|
+
assert.ok(result.includes(expectedSkillRead(base, "react")));
|
|
96
100
|
assert.doesNotMatch(result, /swiftui/);
|
|
97
101
|
} finally {
|
|
98
102
|
cleanup(base);
|
|
@@ -111,7 +115,7 @@ test("buildSkillActivationBlock includes always_use_skills using read-based skil
|
|
|
111
115
|
|
|
112
116
|
assert.equal(
|
|
113
117
|
result,
|
|
114
|
-
|
|
118
|
+
`<skill_activation>Read the skill file at \`${join(base, "skills", "swift-testing", "SKILL.md")}\`.</skill_activation>`,
|
|
115
119
|
);
|
|
116
120
|
} finally {
|
|
117
121
|
cleanup(base);
|
|
@@ -140,8 +144,8 @@ test("buildSkillActivationBlock includes skill_rules matches and task-plan skill
|
|
|
140
144
|
skill_rules: [{ when: "prisma database schema", use: ["prisma"] }],
|
|
141
145
|
});
|
|
142
146
|
|
|
143
|
-
assert.
|
|
144
|
-
assert.
|
|
147
|
+
assert.ok(result.includes(expectedSkillRead(base, "accessibility")));
|
|
148
|
+
assert.ok(result.includes(expectedSkillRead(base, "prisma")));
|
|
145
149
|
} finally {
|
|
146
150
|
cleanup(base);
|
|
147
151
|
}
|
|
@@ -163,7 +167,7 @@ test("buildSkillActivationBlock matches skill_rules against exact unit type cont
|
|
|
163
167
|
],
|
|
164
168
|
});
|
|
165
169
|
|
|
166
|
-
assert.
|
|
170
|
+
assert.ok(result.includes(expectedSkillRead(base, "complete-slice-policies")));
|
|
167
171
|
assert.doesNotMatch(result, /slice-broad/);
|
|
168
172
|
} finally {
|
|
169
173
|
cleanup(base);
|
|
@@ -267,8 +271,8 @@ test("buildSkillActivationBlock allows valid skill names and rejects invalid one
|
|
|
267
271
|
});
|
|
268
272
|
|
|
269
273
|
assert.match(result, /skill_activation/);
|
|
270
|
-
assert.
|
|
271
|
-
assert.
|
|
274
|
+
assert.ok(result.includes(expectedSkillRead(base, "react")));
|
|
275
|
+
assert.ok(result.includes(expectedSkillRead(base, "good-skill-2")));
|
|
272
276
|
assert.doesNotMatch(result, /bad'name/);
|
|
273
277
|
} finally {
|
|
274
278
|
cleanup(base);
|
|
@@ -292,8 +296,8 @@ test("buildSkillActivationBlock: explicit always_use_skills bypass the unit-type
|
|
|
292
296
|
always_use_skills: ["write-docs", "swiftui"],
|
|
293
297
|
});
|
|
294
298
|
|
|
295
|
-
assert.
|
|
296
|
-
assert.
|
|
299
|
+
assert.ok(result.includes(expectedSkillRead(base, "write-docs")));
|
|
300
|
+
assert.ok(result.includes(expectedSkillRead(base, "swiftui")));
|
|
297
301
|
} finally {
|
|
298
302
|
cleanup(base);
|
|
299
303
|
}
|
|
@@ -310,7 +314,7 @@ test("buildSkillActivationBlock falls through to all skills for unknown unit typ
|
|
|
310
314
|
});
|
|
311
315
|
|
|
312
316
|
// Unknown unit type = wildcard fallback (pre-manifest behavior).
|
|
313
|
-
assert.
|
|
317
|
+
assert.ok(result.includes(expectedSkillRead(base, "swiftui")));
|
|
314
318
|
} finally {
|
|
315
319
|
cleanup(base);
|
|
316
320
|
}
|
|
@@ -327,7 +331,7 @@ test("buildSkillActivationBlock without unitType preserves pre-manifest behavior
|
|
|
327
331
|
always_use_skills: ["swiftui"],
|
|
328
332
|
});
|
|
329
333
|
|
|
330
|
-
assert.
|
|
334
|
+
assert.ok(result.includes(expectedSkillRead(base, "swiftui")));
|
|
331
335
|
} finally {
|
|
332
336
|
cleanup(base);
|
|
333
337
|
}
|
|
@@ -344,12 +348,12 @@ test("milestone prompt builders propagate always_use_skills through buildSkillAc
|
|
|
344
348
|
loadOnlyTestSkills(base);
|
|
345
349
|
|
|
346
350
|
const researchPrompt = await buildResearchMilestonePrompt("M001", "Test", base);
|
|
347
|
-
assert.
|
|
348
|
-
assert.
|
|
351
|
+
assert.ok(researchPrompt.includes(expectedSkillRead(base, "write-docs")));
|
|
352
|
+
assert.ok(researchPrompt.includes(expectedSkillRead(base, "swiftui")));
|
|
349
353
|
|
|
350
354
|
const planPrompt = await buildPlanMilestonePrompt("M001", "Test", base);
|
|
351
|
-
assert.
|
|
352
|
-
assert.
|
|
355
|
+
assert.ok(planPrompt.includes(expectedSkillRead(base, "write-docs")));
|
|
356
|
+
assert.ok(planPrompt.includes(expectedSkillRead(base, "swiftui")));
|
|
353
357
|
} finally {
|
|
354
358
|
cleanup(base);
|
|
355
359
|
}
|
|
@@ -380,7 +384,7 @@ test("complete-slice prompt propagates always_use_skills through buildSkillActiv
|
|
|
380
384
|
|
|
381
385
|
const prompt = await buildCompleteSlicePrompt("M001", "Test", "S01", "Slice", base);
|
|
382
386
|
|
|
383
|
-
assert.
|
|
387
|
+
assert.ok(prompt.includes(expectedSkillRead(base, "write-docs")));
|
|
384
388
|
} finally {
|
|
385
389
|
cleanup(base);
|
|
386
390
|
}
|
|
@@ -1618,6 +1618,58 @@ test("ADR-017 (#5705): in-sync ROADMAP and DB → no roadmap-divergence drift",
|
|
|
1618
1618
|
);
|
|
1619
1619
|
});
|
|
1620
1620
|
|
|
1621
|
+
test("ADR-017 (#1370): roadmap-divergence skips completed milestone sharing active worktree phase", async (t) => {
|
|
1622
|
+
const base = mkdtempSync(join(tmpdir(), "gsd-adr017-roadmap-shared-phase-"));
|
|
1623
|
+
const milestoneDir = join(base, ".gsd", "phases", "06-rlrbot-m006-rlrbot-tool-registry-and-command-sa");
|
|
1624
|
+
const roadmapPath = join(milestoneDir, "06-ROADMAP.md");
|
|
1625
|
+
mkdirSync(milestoneDir, { recursive: true });
|
|
1626
|
+
mkdirSync(join(base, ".gsd", "milestones", "M006"), { recursive: true });
|
|
1627
|
+
mkdirSync(join(base, ".gsd", "milestones", "M006-rlrbot"), { recursive: true });
|
|
1628
|
+
writeFileSync(join(base, ".gsd", "milestones", "M006", "M006-META.json"), "{}\n");
|
|
1629
|
+
writeFileSync(join(base, ".gsd", "milestones", "M006-rlrbot", "M006-rlrbot-META.json"), "{}\n");
|
|
1630
|
+
const activeRoadmap = [
|
|
1631
|
+
"# M006-rlrbot: Active worktree",
|
|
1632
|
+
"",
|
|
1633
|
+
"**Vision:** Keep the active worktree projection authoritative.",
|
|
1634
|
+
"",
|
|
1635
|
+
"## Slices",
|
|
1636
|
+
"",
|
|
1637
|
+
"- [ ] **S01: Shared slice** `risk:medium` `depends:[]`",
|
|
1638
|
+
" > After this: Active work remains pending.",
|
|
1639
|
+
"",
|
|
1640
|
+
].join("\n");
|
|
1641
|
+
writeFileSync(roadmapPath, activeRoadmap);
|
|
1642
|
+
t.after(() => {
|
|
1643
|
+
try { closeDatabase(); } catch { /* noop */ }
|
|
1644
|
+
rmSync(base, { recursive: true, force: true });
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
1648
|
+
insertMilestone({ id: "M006", title: "Completed source", status: "complete" });
|
|
1649
|
+
insertSlice({ id: "S01", milestoneId: "M006", title: "Shared slice", status: "complete", risk: "medium", depends: [], demo: "Completed.", sequence: 1 });
|
|
1650
|
+
insertMilestone({
|
|
1651
|
+
id: "M006-rlrbot",
|
|
1652
|
+
title: "Active worktree",
|
|
1653
|
+
status: "active",
|
|
1654
|
+
planning: { vision: "Keep the active worktree projection authoritative." },
|
|
1655
|
+
});
|
|
1656
|
+
insertSlice({ id: "S01", milestoneId: "M006-rlrbot", title: "Shared slice", status: "pending", risk: "medium", depends: [], demo: "Active work remains pending.", sequence: 1 });
|
|
1657
|
+
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M006-rlrbot", title: "Plan active work", status: "pending" });
|
|
1658
|
+
|
|
1659
|
+
const result = await reconcileBeforeDispatch(base, {
|
|
1660
|
+
invalidateStateCache: () => {},
|
|
1661
|
+
deriveState: async () => makeState({ activeMilestone: { id: "M006-rlrbot", title: "Active worktree" } }),
|
|
1662
|
+
});
|
|
1663
|
+
|
|
1664
|
+
assert.equal(result.ok, true);
|
|
1665
|
+
assert.equal(
|
|
1666
|
+
result.repaired.some((d) => d.kind === "roadmap-divergence"),
|
|
1667
|
+
false,
|
|
1668
|
+
"completed milestone sharing the phase dir must not trigger roadmap-divergence repair",
|
|
1669
|
+
);
|
|
1670
|
+
assert.equal(readFileSync(roadmapPath, "utf-8"), activeRoadmap);
|
|
1671
|
+
});
|
|
1672
|
+
|
|
1621
1673
|
// ─── #5706: missing-completion-timestamp drift ──────────────────────────────
|
|
1622
1674
|
|
|
1623
1675
|
test("ADR-017 (#5706): task with SUMMARY but null completed_at → backfilled", async (t) => {
|
|
@@ -7,6 +7,8 @@ import assert from "node:assert/strict";
|
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
9
|
formatStopNoticePrefix,
|
|
10
|
+
formatVerdictRecordedNotice,
|
|
11
|
+
formatVerdictRejectedNotice,
|
|
10
12
|
isBlockedStopReason,
|
|
11
13
|
stopNoticeDisplayReason,
|
|
12
14
|
stopNoticeKind,
|
|
@@ -63,6 +65,17 @@ describe("emitter↔detector round-trip", () => {
|
|
|
63
65
|
assert.ok(isBlockedNoticeMessage(message));
|
|
64
66
|
});
|
|
65
67
|
|
|
68
|
+
test("verdict notices classify as terminal with rejected notices blocked", () => {
|
|
69
|
+
const recorded = formatVerdictRecordedNotice("Milestone M001 verdict: needs-attention -> pass").toLowerCase();
|
|
70
|
+
const rejected = formatVerdictRejectedNotice("No milestone validation found for M001.").toLowerCase();
|
|
71
|
+
|
|
72
|
+
assert.ok(isTerminalNotice(recorded));
|
|
73
|
+
assert.equal(isBlockedNoticeMessage(recorded), false);
|
|
74
|
+
|
|
75
|
+
assert.ok(isTerminalNotice(rejected));
|
|
76
|
+
assert.ok(isBlockedNoticeMessage(rejected));
|
|
77
|
+
});
|
|
78
|
+
|
|
66
79
|
test("un-showable menu notices classify as blocked (#1294)", () => {
|
|
67
80
|
// Emitted verbatim by notifyCommandMenuUnavailable (next-action-ui.ts / command-feedback.ts).
|
|
68
81
|
const menuUnavailable =
|
|
@@ -80,7 +93,14 @@ describe("emitter↔detector round-trip", () => {
|
|
|
80
93
|
});
|
|
81
94
|
|
|
82
95
|
test("terminal prefixes cover the known stop vocabulary", () => {
|
|
83
|
-
for (const message of [
|
|
96
|
+
for (const message of [
|
|
97
|
+
"auto-mode stopped.",
|
|
98
|
+
"auto-mode complete",
|
|
99
|
+
"auto-mode idle",
|
|
100
|
+
"no active milestone",
|
|
101
|
+
"verdict recorded: milestone m001 verdict: needs-attention -> pass",
|
|
102
|
+
"verdict rejected: unexpected argument: x",
|
|
103
|
+
]) {
|
|
84
104
|
assert.ok(TERMINAL_NOTICE_PREFIXES.some((prefix) => message.startsWith(prefix)), message);
|
|
85
105
|
}
|
|
86
106
|
});
|
|
@@ -4,7 +4,13 @@
|
|
|
4
4
|
import { describe, test } from "node:test";
|
|
5
5
|
import assert from "node:assert/strict";
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
buildContextMessage,
|
|
9
|
+
GSD_CONTEXT_MESSAGE_SENTINEL,
|
|
10
|
+
stripVolatileCodebaseMetadata,
|
|
11
|
+
} from "../bootstrap/system-context.ts";
|
|
12
|
+
|
|
13
|
+
const SENTINEL = `${GSD_CONTEXT_MESSAGE_SENTINEL}\n`;
|
|
8
14
|
|
|
9
15
|
describe("stripVolatileCodebaseMetadata (#847 — KV cache stability)", () => {
|
|
10
16
|
const map = [
|
|
@@ -63,7 +69,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
63
69
|
});
|
|
64
70
|
assert.ok(result, "expected a context message");
|
|
65
71
|
assert.equal(result.customType, "gsd-memory");
|
|
66
|
-
assert.equal(result.content,
|
|
72
|
+
assert.equal(result.content, `${SENTINEL}[GSD Context Metadata]\n- Memory supplied: yes\n\n[MEMORY]\nrule one\nrule two`);
|
|
67
73
|
assert.equal(result.display, false);
|
|
68
74
|
});
|
|
69
75
|
|
|
@@ -75,7 +81,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
75
81
|
});
|
|
76
82
|
assert.ok(result);
|
|
77
83
|
assert.equal(result.customType, "gsd-guided-context");
|
|
78
|
-
assert.equal(result.content,
|
|
84
|
+
assert.equal(result.content, `${SENTINEL}[GUIDED]\nexecute T01`);
|
|
79
85
|
});
|
|
80
86
|
|
|
81
87
|
test("forensics injection alone emits gsd-forensics", () => {
|
|
@@ -86,7 +92,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
86
92
|
});
|
|
87
93
|
assert.ok(result);
|
|
88
94
|
assert.equal(result.customType, "gsd-forensics");
|
|
89
|
-
assert.equal(result.content,
|
|
95
|
+
assert.equal(result.content, `${SENTINEL}[FORENSICS]\ninvestigation context`);
|
|
90
96
|
});
|
|
91
97
|
|
|
92
98
|
test("memory + guided injection: memory prepended, customType is gsd-guided-context", () => {
|
|
@@ -97,7 +103,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
97
103
|
});
|
|
98
104
|
assert.ok(result);
|
|
99
105
|
assert.equal(result.customType, "gsd-guided-context");
|
|
100
|
-
assert.equal(result.content, `${markedMemory}\n\n[GUIDED]\nexecute T01`);
|
|
106
|
+
assert.equal(result.content, `${SENTINEL}${markedMemory}\n\n[GUIDED]\nexecute T01`);
|
|
101
107
|
});
|
|
102
108
|
|
|
103
109
|
test("memory + forensics: memory prepended, customType is gsd-forensics", () => {
|
|
@@ -108,7 +114,7 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
108
114
|
});
|
|
109
115
|
assert.ok(result);
|
|
110
116
|
assert.equal(result.customType, "gsd-forensics");
|
|
111
|
-
assert.equal(result.content, `${markedMemory}\n\n[FORENSICS]\ninvestigation context`);
|
|
117
|
+
assert.equal(result.content, `${SENTINEL}${markedMemory}\n\n[FORENSICS]\ninvestigation context`);
|
|
112
118
|
});
|
|
113
119
|
|
|
114
120
|
test("guided takes precedence over forensics when both are somehow present", () => {
|
|
@@ -122,6 +128,6 @@ describe("buildContextMessage (#5019 — memory routing)", () => {
|
|
|
122
128
|
});
|
|
123
129
|
assert.ok(result);
|
|
124
130
|
assert.equal(result.customType, "gsd-guided-context");
|
|
125
|
-
assert.equal(result.content,
|
|
131
|
+
assert.equal(result.content, `${SENTINEL}[GUIDED]`);
|
|
126
132
|
});
|
|
127
133
|
});
|