@opengsd/gsd-pi 1.3.0-dev.eed73bea → 1.4.0
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 -10
- package/dist/cli.js +17 -4
- package/dist/headless-answers.js +1 -1
- package/dist/headless-ui.d.ts +1 -1
- package/dist/headless-ui.js +1 -1
- package/dist/headless.js +1 -1
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/models.js +9 -0
- package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
- package/dist/resources/extensions/gsd/auto-artifact-paths.js +28 -1
- package/dist/resources/extensions/gsd/auto-budget.js +5 -1
- package/dist/resources/extensions/gsd/auto-dispatch.js +17 -6
- package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +8 -24
- package/dist/resources/extensions/gsd/auto-recovery.js +9 -517
- package/dist/resources/extensions/gsd/auto-runtime-state.js +4 -5
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
- package/dist/resources/extensions/gsd/auto-verification.js +5 -2
- package/dist/resources/extensions/gsd/auto.js +19 -10
- package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +5 -4
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +33 -18
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +48 -36
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +15 -4
- package/dist/resources/extensions/gsd/closeout-consistency-gate.js +3 -1
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +1 -1
- package/dist/resources/extensions/gsd/commands-usage.js +1 -1
- package/dist/resources/extensions/gsd/db/engine.js +4 -1
- package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
- package/dist/resources/extensions/gsd/db-workspace.js +55 -3
- package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
- package/dist/resources/extensions/gsd/doctor-engine-checks.js +192 -4
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +8 -2
- package/dist/resources/extensions/gsd/flat-phase-migration.js +45 -0
- package/dist/resources/extensions/gsd/git-service.js +57 -0
- package/dist/resources/extensions/gsd/gitignore.js +4 -1
- package/dist/resources/extensions/gsd/guided-flow-queue.js +20 -13
- package/dist/resources/extensions/gsd/json-persistence.js +20 -0
- package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
- package/dist/resources/extensions/gsd/layout-policy.js +3 -1
- package/dist/resources/extensions/gsd/markdown-renderer.js +2 -7
- package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
- package/dist/resources/extensions/gsd/metrics.js +4 -4
- package/dist/resources/extensions/gsd/migrate-external.js +11 -2
- package/dist/resources/extensions/gsd/migration-auto-check.js +22 -0
- package/dist/resources/extensions/gsd/milestone-ids.js +32 -2
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
- package/dist/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
- package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
- package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
- package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
- package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
- package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
- package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
- package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
- package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
- package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
- package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
- package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +27 -33
- package/dist/resources/extensions/gsd/state-reconciliation/index.js +48 -23
- package/dist/resources/extensions/gsd/state-reconciliation/registry.js +32 -28
- package/dist/resources/extensions/gsd/state.js +12 -611
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +4 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +3 -34
- package/dist/resources/extensions/gsd/tools/complete-task.js +8 -41
- package/dist/resources/extensions/gsd/tools/plan-slice.js +59 -44
- package/dist/resources/extensions/gsd/tools/plan-task.js +28 -5
- package/dist/resources/extensions/gsd/undo.js +43 -6
- package/dist/resources/extensions/gsd/unit-registry.js +11 -3
- package/dist/resources/extensions/gsd/verification-gate.js +7 -0
- package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
- package/dist/resources/extensions/gsd/workflow-projections.js +19 -14
- package/dist/resources/extensions/gsd/worktree-manager.js +44 -2
- 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 +10 -10
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
- 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 +10 -10
- package/dist/web/standalone/.next/server/chunks/2842.js +4 -4
- 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-react-loadable-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/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{4283.8e446784528ed9dc.js → 4283.d0d9e0a955e441cb.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{8785.481aa5869991b760.js → 8785.e29b3134cab1d153.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-49f565245e1e4afe.js +1 -0
- package/dist/web/standalone/.next/static/chunks/app/{layout-4ae2d68984392bbf.js → layout-b35cbfff38aaf4cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-bc4c723c6a19c6f0.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{main-app-90d1d8d5e5d2dc6b.js → main-app-590a74400e35f685.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ec3eaffc9785ba48.js +1 -0
- package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.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/package.json +6 -6
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
- package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/agent-session.js +3 -0
- package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
- package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
- package/packages/gsd-agent-core/dist/index.d.ts +2 -0
- package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/index.js +2 -0
- package/packages/gsd-agent-core/dist/index.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
- package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
- package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
- package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
- package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
- package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
- package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -841
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +23 -5
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
- package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/dist/workflow-tools.js +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-loop.js +3 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +46 -0
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +38 -0
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/README.md +3 -2
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
- package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
- package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
- package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
- package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
- package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
- package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
- package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
- package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
- 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-schema.d.ts +75 -75
- package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
- package/pkg/dist/theme/theme-schema.js +1 -1
- package/pkg/dist/theme/theme-schema.js.map +1 -1
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +11 -7
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/models.ts +9 -0
- package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
- package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
- package/src/resources/extensions/gsd/auto/session.ts +14 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
- package/src/resources/extensions/gsd/auto-artifact-paths.ts +47 -1
- package/src/resources/extensions/gsd/auto-budget.ts +12 -1
- package/src/resources/extensions/gsd/auto-dispatch.ts +17 -7
- package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +7 -23
- package/src/resources/extensions/gsd/auto-recovery.ts +13 -518
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -5
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
- package/src/resources/extensions/gsd/auto-verification.ts +5 -1
- package/src/resources/extensions/gsd/auto.ts +23 -8
- package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +5 -4
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +43 -18
- package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +50 -37
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +16 -4
- package/src/resources/extensions/gsd/closeout-consistency-gate.ts +2 -1
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +1 -1
- package/src/resources/extensions/gsd/commands-usage.ts +1 -1
- package/src/resources/extensions/gsd/db/engine.ts +8 -1
- package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
- package/src/resources/extensions/gsd/db-workspace.ts +61 -3
- package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
- package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
- package/src/resources/extensions/gsd/doctor-engine-checks.ts +233 -5
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +3 -0
- package/src/resources/extensions/gsd/doctor-types.ts +3 -0
- package/src/resources/extensions/gsd/exec-sandbox.ts +7 -2
- package/src/resources/extensions/gsd/flat-phase-migration.ts +44 -0
- package/src/resources/extensions/gsd/git-service.ts +64 -0
- package/src/resources/extensions/gsd/gitignore.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow-queue.ts +20 -13
- package/src/resources/extensions/gsd/json-persistence.ts +20 -0
- package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
- package/src/resources/extensions/gsd/layout-policy.ts +2 -1
- package/src/resources/extensions/gsd/markdown-renderer.ts +2 -10
- package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
- package/src/resources/extensions/gsd/metrics.ts +4 -4
- package/src/resources/extensions/gsd/migrate-external.ts +8 -2
- package/src/resources/extensions/gsd/migration-auto-check.ts +23 -0
- package/src/resources/extensions/gsd/milestone-ids.ts +31 -2
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
- package/src/resources/extensions/gsd/prompts/code-review.md +6 -4
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
- package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
- package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
- package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
- package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
- package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +1 -1
- package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
- package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
- package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
- package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
- package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
- package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +36 -30
- package/src/resources/extensions/gsd/state-reconciliation/index.ts +50 -24
- package/src/resources/extensions/gsd/state-reconciliation/registry.ts +43 -28
- package/src/resources/extensions/gsd/state.ts +32 -732
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +98 -1
- package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +69 -0
- package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
- package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +143 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +37 -2
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +11 -2
- package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
- package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
- package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +103 -4
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +44 -1
- package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
- package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +115 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
- package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
- package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -4
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +39 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +3 -2
- package/src/resources/extensions/gsd/tools/complete-slice.ts +3 -30
- package/src/resources/extensions/gsd/tools/complete-task.ts +7 -39
- package/src/resources/extensions/gsd/tools/plan-slice.ts +60 -47
- package/src/resources/extensions/gsd/tools/plan-task.ts +30 -5
- package/src/resources/extensions/gsd/undo.ts +47 -6
- package/src/resources/extensions/gsd/unit-registry.ts +11 -3
- package/src/resources/extensions/gsd/verification-gate.ts +8 -0
- package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
- package/src/resources/extensions/gsd/workflow-projections.ts +20 -14
- package/src/resources/extensions/gsd/worktree-manager.ts +41 -1
- package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
- package/dist/web/standalone/.next/static/chunks/796.3976108148518f7d.js +0 -10
- package/dist/web/standalone/.next/static/chunks/app/_not-found/page-a6fb1847f67f167c.js +0 -1
- package/dist/web/standalone/.next/static/chunks/app/page-6644fc6ee8ca1247.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-1115d46ac61b9823.js +0 -1
- package/dist/web/standalone/.next/static/chunks/webpack-7c1d97e39be2da11.js +0 -1
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → zQLcXm0Za8lexoXtgDpMG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{SzEuqWX37DR9MEpEuQjP1 → zQLcXm0Za8lexoXtgDpMG}/_ssgManifest.js +0 -0
|
@@ -97,8 +97,10 @@ import {
|
|
|
97
97
|
getNewBudgetAlertLevel,
|
|
98
98
|
getBudgetEnforcementAction,
|
|
99
99
|
getContextPauseAction,
|
|
100
|
+
HARD_CONTEXT_REROOT_THRESHOLD_PERCENT,
|
|
100
101
|
resolveCompactionThresholdPercent,
|
|
101
102
|
shouldRerootStepSessionForContext,
|
|
103
|
+
shouldWarnStepSessionForContext,
|
|
102
104
|
} from "./auto-budget.js";
|
|
103
105
|
import {
|
|
104
106
|
markToolStart as _markToolStart,
|
|
@@ -701,6 +703,7 @@ export {
|
|
|
701
703
|
getContextPauseAction,
|
|
702
704
|
resolveCompactionThresholdPercent,
|
|
703
705
|
shouldRerootStepSessionForContext,
|
|
706
|
+
shouldWarnStepSessionForContext,
|
|
704
707
|
} from "./auto-budget.js";
|
|
705
708
|
|
|
706
709
|
function closeOutSignalInterruptedUnit(currentBasePath: string): void {
|
|
@@ -1375,9 +1378,10 @@ export async function rerootCommandSession(
|
|
|
1375
1378
|
}
|
|
1376
1379
|
|
|
1377
1380
|
/**
|
|
1378
|
-
* After a completed step-mode unit,
|
|
1379
|
-
*
|
|
1380
|
-
* re-
|
|
1381
|
+
* After a completed step-mode unit, warn when usage reaches the configurable
|
|
1382
|
+
* soft context threshold. At the fixed hard boundary, write a context-mode
|
|
1383
|
+
* snapshot and re-root the visible command session while leaving the NEXT
|
|
1384
|
+
* progress surface.
|
|
1381
1385
|
*/
|
|
1382
1386
|
export async function maybeRerootStepSessionForHighContext(
|
|
1383
1387
|
ctx: ExtensionContext,
|
|
@@ -1392,7 +1396,19 @@ export async function maybeRerootStepSessionForHighContext(
|
|
|
1392
1396
|
const prefs = loadEffectiveGSDPreferences(workspaceRoot);
|
|
1393
1397
|
const compactionThreshold = prefs?.preferences.context_management?.compaction_threshold_percent;
|
|
1394
1398
|
|
|
1395
|
-
|
|
1399
|
+
const shouldWarn = shouldWarnStepSessionForContext(contextPercent, compactionThreshold);
|
|
1400
|
+
const shouldReroot = shouldRerootStepSessionForContext(contextPercent);
|
|
1401
|
+
if (!shouldWarn && !shouldReroot) {
|
|
1402
|
+
return { rerooted: false };
|
|
1403
|
+
}
|
|
1404
|
+
|
|
1405
|
+
const displayPercent = (contextPercent as number).toFixed(1);
|
|
1406
|
+
const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
|
|
1407
|
+
if (!shouldReroot) {
|
|
1408
|
+
ctx.ui.notify(
|
|
1409
|
+
`Step complete — context at ${displayPercent}% (soft threshold: ${thresholdDisplay}%). Use /compact when convenient; continuing in this session is still safe.`,
|
|
1410
|
+
"info",
|
|
1411
|
+
);
|
|
1396
1412
|
return { rerooted: false };
|
|
1397
1413
|
}
|
|
1398
1414
|
|
|
@@ -1401,12 +1417,10 @@ export async function maybeRerootStepSessionForHighContext(
|
|
|
1401
1417
|
const { writeContextModeCompactionSnapshot } = await import("./context-mode-snapshot.js");
|
|
1402
1418
|
await writeContextModeCompactionSnapshot(snapshotBase);
|
|
1403
1419
|
|
|
1404
|
-
const displayPercent = (contextPercent as number).toFixed(1);
|
|
1405
|
-
const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
|
|
1406
1420
|
const result = await rerootCommandSession(cmdCtx, workspaceRoot);
|
|
1407
1421
|
if (result.status === "ok") {
|
|
1408
1422
|
ctx.ui.notify(
|
|
1409
|
-
`Step complete — context at ${displayPercent}% (threshold: ${
|
|
1423
|
+
`Step complete — context at ${displayPercent}% (hard threshold: ${HARD_CONTEXT_REROOT_THRESHOLD_PERCENT}%). Fresh session ready for /gsd next.`,
|
|
1410
1424
|
"info",
|
|
1411
1425
|
);
|
|
1412
1426
|
return { rerooted: true };
|
|
@@ -2102,7 +2116,7 @@ export function _selectStopAutoWorktreeExit(args: {
|
|
|
2102
2116
|
/**
|
|
2103
2117
|
* Pause auto-mode without destroying state. Context is preserved.
|
|
2104
2118
|
* The user can interact with the agent, then `/gsd auto` resumes
|
|
2105
|
-
* from disk state. Called when the user presses Escape
|
|
2119
|
+
* from disk state. Called when the user presses Escape or runs `/gsd pause`.
|
|
2106
2120
|
*/
|
|
2107
2121
|
export async function pauseAuto(
|
|
2108
2122
|
ctx?: ExtensionContext,
|
|
@@ -2129,6 +2143,7 @@ export async function pauseAuto(
|
|
|
2129
2143
|
|
|
2130
2144
|
s.active = false;
|
|
2131
2145
|
s.paused = true;
|
|
2146
|
+
if (options.abortActiveTurn && ctx && !ctx.isIdle()) ctx.abort();
|
|
2132
2147
|
clearUnitTimeout();
|
|
2133
2148
|
stopAutoCommandPolling();
|
|
2134
2149
|
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Canonical core session tool surface shared by auto-mode scoping and loop guards.
|
|
3
|
+
|
|
4
|
+
/** Base tools available during auto-mode execution before unit-specific GSD tools are added. */
|
|
5
|
+
export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
|
|
6
|
+
"ask_user_questions",
|
|
7
|
+
"bash",
|
|
8
|
+
"bg_shell",
|
|
9
|
+
"edit",
|
|
10
|
+
"find",
|
|
11
|
+
"glob",
|
|
12
|
+
"grep",
|
|
13
|
+
"fetch_page",
|
|
14
|
+
"search-the-web",
|
|
15
|
+
"ls",
|
|
16
|
+
"read",
|
|
17
|
+
"subagent",
|
|
18
|
+
"write",
|
|
19
|
+
"ToolSearch",
|
|
20
|
+
] as const;
|
|
21
|
+
|
|
22
|
+
/** Tools excluded from the high per-turn loop-guard cap (strict or orchestration). */
|
|
23
|
+
const NON_REPEATABLE_FROM_MINIMAL_BASE = new Set<string>([
|
|
24
|
+
"ask_user_questions",
|
|
25
|
+
"subagent",
|
|
26
|
+
"ToolSearch",
|
|
27
|
+
]);
|
|
28
|
+
|
|
29
|
+
/** Additional core tools not in MINIMAL_AUTO_BASE but routinely multi-called per turn. */
|
|
30
|
+
const EXTRA_INHERENTLY_REPEATABLE = [
|
|
31
|
+
"gsd_exec",
|
|
32
|
+
"multi_edit",
|
|
33
|
+
"todo_write",
|
|
34
|
+
"notebook_edit",
|
|
35
|
+
"search_and_read",
|
|
36
|
+
] as const;
|
|
37
|
+
|
|
38
|
+
/** Core session tools that may be invoked many times per agent turn. */
|
|
39
|
+
export const INHERENTLY_REPEATABLE_TOOL_NAMES = [
|
|
40
|
+
...MINIMAL_AUTO_BASE_TOOL_NAMES.filter((name) => !NON_REPEATABLE_FROM_MINIMAL_BASE.has(name)),
|
|
41
|
+
...EXTRA_INHERENTLY_REPEATABLE,
|
|
42
|
+
] as const;
|
|
43
|
+
|
|
44
|
+
export const INHERENTLY_REPEATABLE_TOOL_SET = new Set<string>(INHERENTLY_REPEATABLE_TOOL_NAMES);
|
|
@@ -690,8 +690,9 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
690
690
|
promptSnippet: "Plan a slice via DB write + PLAN render + cache invalidation",
|
|
691
691
|
promptGuidelines: [
|
|
692
692
|
"Use gsd_plan_slice for slice planning instead of writing S##-PLAN.md or task PLAN files directly.",
|
|
693
|
-
"
|
|
694
|
-
"
|
|
693
|
+
"For incremental planning, call gsd_plan_slice with slice metadata only, then call gsd_plan_task once per task.",
|
|
694
|
+
"When tasks is omitted or empty, the tool writes only slice planning metadata and preserves existing tasks.",
|
|
695
|
+
"When tasks is non-empty, the tool validates input, requires an existing parent slice, writes slice/task planning data, renders PLAN.md and task plan files from DB, and clears both state and parse caches after success.",
|
|
695
696
|
"Use the canonical name gsd_plan_slice; gsd_slice_plan is only an alias.",
|
|
696
697
|
],
|
|
697
698
|
parameters: Type.Object({
|
|
@@ -699,7 +700,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
699
700
|
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
700
701
|
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
701
702
|
goal: Type.String({ description: "Slice goal" }),
|
|
702
|
-
tasks: Type.Array(Type.Object({
|
|
703
|
+
tasks: Type.Optional(Type.Array(Type.Object({
|
|
703
704
|
taskId: Type.String({ description: "Task ID (e.g. T01)" }),
|
|
704
705
|
title: Type.String({ description: "Task title" }),
|
|
705
706
|
description: Type.String({ description: "Task description / steps block" }),
|
|
@@ -709,7 +710,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
709
710
|
inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
|
|
710
711
|
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of files this task creates or overwrites; pass [\"path\"] or [], never prose or a single string" }),
|
|
711
712
|
observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
|
|
712
|
-
}), { description: "
|
|
713
|
+
}), { description: "Optional full task replacement for the slice. Omit for incremental planning, then call gsd_plan_task once per task." })),
|
|
713
714
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
714
715
|
successCriteria: Type.Optional(Type.String({ description: "Slice success criteria block" })),
|
|
715
716
|
proofLevel: Type.Optional(Type.String({ description: "Slice proof level" })),
|
|
@@ -18,6 +18,7 @@ import { registerShortcuts } from "./register-shortcuts.js";
|
|
|
18
18
|
import { writeCrashLog } from "./crash-log.js";
|
|
19
19
|
import { logWarning, isGsdExtensionStderrEnabled } from "../workflow-logger.js";
|
|
20
20
|
import { UNIT_TOOL_CONTRACTS } from "../unit-tool-contracts.js";
|
|
21
|
+
import { installManifestFlushOnProcessTeardown } from "../workflow-manifest.js";
|
|
21
22
|
// Static import so cmux event listeners are registered synchronously during
|
|
22
23
|
// extension bootstrap. Prior implementation used `void import().then()` which
|
|
23
24
|
// queued listener registration as a microtask — any CMUX_CHANNELS emit fired
|
|
@@ -196,6 +197,7 @@ export function registerGsdExtension(pi: ExtensionAPI): void {
|
|
|
196
197
|
});
|
|
197
198
|
|
|
198
199
|
installEpipeGuard();
|
|
200
|
+
installManifestFlushOnProcessTeardown();
|
|
199
201
|
|
|
200
202
|
// Ecosystem handlers captured by the GSDExtensionAPI wrapper for the
|
|
201
203
|
// GSD-owned `before_agent_start` dispatch step (#3338).
|
|
@@ -34,7 +34,8 @@ import {
|
|
|
34
34
|
} from "../auto-runtime-state.js";
|
|
35
35
|
import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
|
|
36
36
|
|
|
37
|
-
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
37
|
+
import { checkToolCallLoop, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
38
|
+
import { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
|
|
38
39
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
39
40
|
import { saveActivityLog } from "../activity-log.js";
|
|
40
41
|
import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
|
|
@@ -75,6 +76,7 @@ import { supportsSourceObservationsForUnit } from "../source-observations.js";
|
|
|
75
76
|
import { clearPendingAutoStart } from "../pending-auto-start.js";
|
|
76
77
|
import { resolveWorkflowToolBasePath } from "./dynamic-tools.js";
|
|
77
78
|
import { getRequiredWorkflowToolsForUnit } from "../unit-tool-contracts.js";
|
|
79
|
+
import { flushAllManifests } from "../workflow-manifest.js";
|
|
78
80
|
|
|
79
81
|
let approvalQuestionAbortInFlight = false;
|
|
80
82
|
|
|
@@ -178,22 +180,7 @@ export const MINIMAL_GSD_TOOL_NAMES = [
|
|
|
178
180
|
"gsd_capture_thought",
|
|
179
181
|
] as const;
|
|
180
182
|
|
|
181
|
-
export
|
|
182
|
-
"ask_user_questions",
|
|
183
|
-
"bash",
|
|
184
|
-
"bg_shell",
|
|
185
|
-
"edit",
|
|
186
|
-
"find",
|
|
187
|
-
"glob",
|
|
188
|
-
"grep",
|
|
189
|
-
"fetch_page",
|
|
190
|
-
"search-the-web",
|
|
191
|
-
"ls",
|
|
192
|
-
"read",
|
|
193
|
-
"subagent",
|
|
194
|
-
"write",
|
|
195
|
-
"ToolSearch",
|
|
196
|
-
] as const;
|
|
183
|
+
export { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
|
|
197
184
|
|
|
198
185
|
function withPreservedShimTools(toolNames: readonly string[]): string[] {
|
|
199
186
|
return [...new Set([...toolNames, ...ALWAYS_PRESERVED_SHIM_TOOL_NAMES])];
|
|
@@ -597,6 +584,21 @@ function contextBasePath(ctx?: { cwd?: string }): string {
|
|
|
597
584
|
return typeof ctx?.cwd === "string" ? ctx.cwd : process.cwd();
|
|
598
585
|
}
|
|
599
586
|
|
|
587
|
+
const LOOP_GUARD_INTERACTIVE_INSTRUCTIONS = [
|
|
588
|
+
"Do not retry this tool or call other tools this turn — stop and respond to the user in text.",
|
|
589
|
+
"Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.",
|
|
590
|
+
];
|
|
591
|
+
const LOOP_GUARD_AUTO_INSTRUCTION =
|
|
592
|
+
"Do not re-issue this blocked tool. In /gsd auto, stop tool calls for this turn and return control to the auto-mode recovery/replan path.";
|
|
593
|
+
|
|
594
|
+
function formatLoopGuardBlockReason(reason: string | undefined): string | undefined {
|
|
595
|
+
if (!reason || !getAutoRuntimeSnapshot().active) return reason;
|
|
596
|
+
return LOOP_GUARD_INTERACTIVE_INSTRUCTIONS.reduce(
|
|
597
|
+
(formatted, instruction) => formatted.replace(instruction, LOOP_GUARD_AUTO_INSTRUCTION),
|
|
598
|
+
reason,
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
|
|
600
602
|
function beginSourceObservationStoreForCurrentUnit(
|
|
601
603
|
ctx?: { cwd?: string },
|
|
602
604
|
): ReturnType<typeof getSourceObservationStore> | null {
|
|
@@ -920,6 +922,15 @@ export function registerHooks(
|
|
|
920
922
|
}
|
|
921
923
|
}
|
|
922
924
|
}
|
|
925
|
+
const projectRoot = resolveWorktreeProjectRoot(basePath);
|
|
926
|
+
const { pruneStaleFlatPhaseBackups } = await import("../flat-phase-migration.js");
|
|
927
|
+
const pruned = pruneStaleFlatPhaseBackups(projectRoot);
|
|
928
|
+
if (pruned > 0) {
|
|
929
|
+
safetyLogWarning(
|
|
930
|
+
"bootstrap",
|
|
931
|
+
`pruned ${pruned} stale flat-phase migration backup(s) from .gsd-backups/ (retention exceeded)`,
|
|
932
|
+
);
|
|
933
|
+
}
|
|
923
934
|
} catch (err) {
|
|
924
935
|
safetyLogWarning("bootstrap", `flat-phase migration: ${err instanceof Error ? err.message : String(err)}`);
|
|
925
936
|
}
|
|
@@ -1085,6 +1096,19 @@ export function registerHooks(
|
|
|
1085
1096
|
const { handleAgentEnd } = await import("./agent-end-recovery.js");
|
|
1086
1097
|
const agentEndBasePath = contextBasePath(ctx);
|
|
1087
1098
|
try {
|
|
1099
|
+
// The manifest is a non-critical projection (the append-only event log is
|
|
1100
|
+
// the authoritative recovery source), so a flush failure must not skip
|
|
1101
|
+
// agent_end recovery. drainManifestWrites still propagates write failures
|
|
1102
|
+
// to explicit flush callers; here we deliberately log and continue so
|
|
1103
|
+
// handleAgentEnd (and the finally below) always run.
|
|
1104
|
+
try {
|
|
1105
|
+
await flushAllManifests();
|
|
1106
|
+
} catch (err) {
|
|
1107
|
+
safetyLogWarning(
|
|
1108
|
+
"manifest",
|
|
1109
|
+
`flushAllManifests on agent_end failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1088
1112
|
await handleAgentEnd(pi, event, ctx);
|
|
1089
1113
|
} finally {
|
|
1090
1114
|
activateDeferredApprovalGate(agentEndBasePath);
|
|
@@ -1291,7 +1315,7 @@ export function registerHooks(
|
|
|
1291
1315
|
// ── Loop guard: block repeated identical tool calls ──
|
|
1292
1316
|
const loopCheck = checkToolCallLoop(toolName, event.input as Record<string, unknown>);
|
|
1293
1317
|
if (loopCheck.block) {
|
|
1294
|
-
return { block: true, reason: loopCheck.reason };
|
|
1318
|
+
return { block: true, reason: formatLoopGuardBlockReason(loopCheck.reason) };
|
|
1295
1319
|
}
|
|
1296
1320
|
|
|
1297
1321
|
const deferredGateGuard = shouldBlockDeferredApprovalTool(
|
|
@@ -1563,6 +1587,7 @@ export function registerHooks(
|
|
|
1563
1587
|
}
|
|
1564
1588
|
}
|
|
1565
1589
|
if (!event.isError) {
|
|
1590
|
+
recordToolCallLoopMutation(toolName);
|
|
1566
1591
|
refreshSourceObservationAfterMutation(toolName, event.input, ctx);
|
|
1567
1592
|
clearSourceObservationsAfterShell(toolName);
|
|
1568
1593
|
}
|
|
@@ -9,13 +9,14 @@
|
|
|
9
9
|
|
|
10
10
|
import { test, describe, before, after } from "node:test";
|
|
11
11
|
import assert from "node:assert/strict";
|
|
12
|
-
import { mkdtempSync, rmSync, existsSync } from "node:fs";
|
|
12
|
+
import { mkdtempSync, rmSync, existsSync, mkdirSync } from "node:fs";
|
|
13
13
|
import { tmpdir } from "node:os";
|
|
14
14
|
import { join } from "node:path";
|
|
15
15
|
|
|
16
16
|
import {
|
|
17
17
|
markDepthVerified,
|
|
18
18
|
loadWriteGateSnapshot,
|
|
19
|
+
shouldBlockContextArtifactSaveInSnapshot,
|
|
19
20
|
clearDiscussionFlowState,
|
|
20
21
|
} from "../write-gate.js";
|
|
21
22
|
|
|
@@ -100,4 +101,51 @@ describe("write-gate basePath regression", () => {
|
|
|
100
101
|
"loadWriteGateSnapshot(baseDirB) must not bleed state from baseDirA",
|
|
101
102
|
);
|
|
102
103
|
});
|
|
104
|
+
|
|
105
|
+
test("worktree basePath reads depth verification from project-root snapshot", (t) => {
|
|
106
|
+
const prev = process.env.GSD_PERSIST_WRITE_GATE_STATE;
|
|
107
|
+
t.after(() => {
|
|
108
|
+
if (prev === undefined) {
|
|
109
|
+
delete process.env.GSD_PERSIST_WRITE_GATE_STATE;
|
|
110
|
+
} else {
|
|
111
|
+
process.env.GSD_PERSIST_WRITE_GATE_STATE = prev;
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
process.env.GSD_PERSIST_WRITE_GATE_STATE = "1";
|
|
115
|
+
|
|
116
|
+
const projectRoot = makeTempDir();
|
|
117
|
+
const worktreePath = join(projectRoot, ".gsd-worktrees", "M020");
|
|
118
|
+
t.after(() => {
|
|
119
|
+
rmSync(projectRoot, { recursive: true, force: true });
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
clearDiscussionFlowState(projectRoot);
|
|
123
|
+
clearDiscussionFlowState(worktreePath);
|
|
124
|
+
|
|
125
|
+
// Simulate MCP routing: verification recorded at project root.
|
|
126
|
+
markDepthVerified("M020", projectRoot);
|
|
127
|
+
|
|
128
|
+
// Worktree has a local .gsd projection but no write-gate snapshot file.
|
|
129
|
+
mkdirSync(join(worktreePath, ".gsd", "runtime"), { recursive: true });
|
|
130
|
+
mkdirSync(join(projectRoot, ".gsd", "milestones"), { recursive: true });
|
|
131
|
+
|
|
132
|
+
const projectSnapshotPath = join(projectRoot, ".gsd", "runtime", "write-gate-state.json");
|
|
133
|
+
const worktreeSnapshotPath = join(worktreePath, ".gsd", "runtime", "write-gate-state.json");
|
|
134
|
+
assert.ok(existsSync(projectSnapshotPath), "verification snapshot lives at project root");
|
|
135
|
+
assert.ok(!existsSync(worktreeSnapshotPath), "worktree must not have its own snapshot file");
|
|
136
|
+
|
|
137
|
+
const snapshotFromWorktree = loadWriteGateSnapshot(worktreePath);
|
|
138
|
+
assert.ok(
|
|
139
|
+
snapshotFromWorktree.verifiedDepthMilestones.includes("M020"),
|
|
140
|
+
"loadWriteGateSnapshot(worktree) must inherit project-root verification",
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const guard = shouldBlockContextArtifactSaveInSnapshot(
|
|
144
|
+
snapshotFromWorktree,
|
|
145
|
+
"CONTEXT",
|
|
146
|
+
"M020",
|
|
147
|
+
null,
|
|
148
|
+
);
|
|
149
|
+
assert.equal(guard.block, false, "CONTEXT save must unblock once project-root gate is verified");
|
|
150
|
+
});
|
|
103
151
|
});
|
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool-call loop guard.
|
|
3
3
|
*
|
|
4
|
-
* Detects when a model calls
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Detects when a model repeats tool calls within a single Agent Turn.
|
|
5
|
+
* Works in both auto-mode and interactive sessions by hooking into the
|
|
6
|
+
* native engine's `tool_call` event, which fires before execution and can
|
|
7
|
+
* block the call.
|
|
8
8
|
*
|
|
9
|
-
* The guard
|
|
10
|
-
* and
|
|
11
|
-
*
|
|
12
|
-
* and
|
|
9
|
+
* The guard has two independent checks: a sliding window for identical
|
|
10
|
+
* tool signatures, and a per-tool-name cap for repeated calls with varied
|
|
11
|
+
* arguments. State resets at Agent Turn boundaries (session_start,
|
|
12
|
+
* agent_end) and the identical-signature streak also resets when a
|
|
13
|
+
* different tool call breaks the streak. Block messages instruct the model
|
|
14
|
+
* to stop tooling for the rest of that turn and answer in text.
|
|
13
15
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
+
* The per-tool-name check (#783 Brief C) tracks call counts within a
|
|
17
|
+
* turn regardless of args, decaying after successful state-mutating tools.
|
|
18
|
+
* This catches improvisation
|
|
16
19
|
* loops where the model attempts the same missing workflow tool through
|
|
17
20
|
* varied surfaces (bash → `node -e` → CLI), each with a different
|
|
18
|
-
* signature, so the identical-args streak never trips
|
|
21
|
+
* signature, so the identical-args streak never trips, while allowing
|
|
22
|
+
* tool-heavy turns that are making file-mutation progress. Whichever guard
|
|
19
23
|
* trips first blocks.
|
|
20
24
|
*/
|
|
21
25
|
|
|
22
26
|
import { createHash } from "node:crypto";
|
|
27
|
+
import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
|
|
23
28
|
|
|
24
29
|
const MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
|
|
25
30
|
|
|
@@ -39,27 +44,8 @@ const MAX_CONSECUTIVE_STRICT = 1;
|
|
|
39
44
|
*/
|
|
40
45
|
const PER_TOOL_DEFAULT_CAP = 6;
|
|
41
46
|
const PER_TOOL_REPEATABLE_CAP = 15;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
* Inherently-repeatable tools: called many times per turn in normal work
|
|
45
|
-
* (reading/writing several files, running several commands, searching). These
|
|
46
|
-
* get PER_TOOL_REPEATABLE_CAP rather than the default. Keep this list
|
|
47
|
-
* conservative — a tool here can be invoked up to PER_TOOL_REPEATABLE_CAP times
|
|
48
|
-
* per turn before the guard blocks.
|
|
49
|
-
*/
|
|
50
|
-
const REPEATABLE_TOOLS = new Set([
|
|
51
|
-
"read",
|
|
52
|
-
"write",
|
|
53
|
-
"edit",
|
|
54
|
-
"multi_edit",
|
|
55
|
-
"bash",
|
|
56
|
-
"grep",
|
|
57
|
-
"glob",
|
|
58
|
-
"search-the-web",
|
|
59
|
-
"fetch_page",
|
|
60
|
-
"todo_write",
|
|
61
|
-
"notebook_edit",
|
|
62
|
-
]);
|
|
47
|
+
const PER_TOOL_CAP_EXEMPT_TOOLS = new Set(["find", "glob", "grep", "ls", "read", "search_and_read"]);
|
|
48
|
+
const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
|
|
63
49
|
|
|
64
50
|
let consecutiveCount = 0;
|
|
65
51
|
let lastSignature = "";
|
|
@@ -68,6 +54,8 @@ let enabled = true;
|
|
|
68
54
|
|
|
69
55
|
/** Per-tool-name call counts within the current turn (#783 Brief C). */
|
|
70
56
|
const perToolCounts = new Map<string, number>();
|
|
57
|
+
let mutationEpoch = 0;
|
|
58
|
+
const perToolLastMutationEpoch = new Map<string, number>();
|
|
71
59
|
|
|
72
60
|
/** Hash tool name + args into a compact signature for comparison. */
|
|
73
61
|
function hashToolCall(toolName: string, args: Record<string, unknown>): string {
|
|
@@ -95,7 +83,8 @@ function hashToolCall(toolName: string, args: Record<string, unknown>): string {
|
|
|
95
83
|
* 1. Identical-signature streak (MAX_CONSECUTIVE_IDENTICAL_CALLS, strict for
|
|
96
84
|
* ask_user_questions).
|
|
97
85
|
* 2. Per-tool-name cap (PER_TOOL_DEFAULT_CAP / PER_TOOL_REPEATABLE_CAP),
|
|
98
|
-
* independent of args
|
|
86
|
+
* independent of args, reset after file-mutation progress — catches
|
|
87
|
+
* improvisation loops (#783).
|
|
99
88
|
*/
|
|
100
89
|
export function checkToolCallLoop(
|
|
101
90
|
toolName: string,
|
|
@@ -124,7 +113,7 @@ export function checkToolCallLoop(
|
|
|
124
113
|
reason:
|
|
125
114
|
`Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
|
|
126
115
|
`with identical arguments. Blocking to prevent infinite loop. ` +
|
|
127
|
-
`
|
|
116
|
+
`Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
|
|
128
117
|
count: consecutiveCount,
|
|
129
118
|
};
|
|
130
119
|
}
|
|
@@ -132,9 +121,21 @@ export function checkToolCallLoop(
|
|
|
132
121
|
// ── Guard 2: per-tool-name cap, independent of args (#783 Brief C) ──
|
|
133
122
|
// Catches improvisation loops where the same tool is invoked many times with
|
|
134
123
|
// varied args (e.g. retrying a missing workflow tool via bash/node -e/CLI).
|
|
135
|
-
const
|
|
124
|
+
const priorPerToolCount =
|
|
125
|
+
(perToolLastMutationEpoch.get(toolName) ?? mutationEpoch) < mutationEpoch
|
|
126
|
+
? 0
|
|
127
|
+
: (perToolCounts.get(toolName) ?? 0);
|
|
128
|
+
const perToolCount = priorPerToolCount + 1;
|
|
136
129
|
perToolCounts.set(toolName, perToolCount);
|
|
137
|
-
|
|
130
|
+
perToolLastMutationEpoch.set(toolName, mutationEpoch);
|
|
131
|
+
|
|
132
|
+
// Read-only navigation tools are normal context gathering; Guard 1 still
|
|
133
|
+
// catches true reread loops with identical arguments.
|
|
134
|
+
if (PER_TOOL_CAP_EXEMPT_TOOLS.has(toolName)) {
|
|
135
|
+
return { block: false, count: consecutiveCount };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const perToolCap = INHERENTLY_REPEATABLE_TOOL_SET.has(toolName)
|
|
138
139
|
? PER_TOOL_REPEATABLE_CAP
|
|
139
140
|
: PER_TOOL_DEFAULT_CAP;
|
|
140
141
|
|
|
@@ -144,7 +145,8 @@ export function checkToolCallLoop(
|
|
|
144
145
|
reason:
|
|
145
146
|
`Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
|
|
146
147
|
`this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
|
|
147
|
-
`The tool may be unavailable or failing repeatedly
|
|
148
|
+
`The tool may be unavailable or failing repeatedly. ` +
|
|
149
|
+
`Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.`,
|
|
148
150
|
count: perToolCount,
|
|
149
151
|
};
|
|
150
152
|
}
|
|
@@ -152,6 +154,13 @@ export function checkToolCallLoop(
|
|
|
152
154
|
return { block: false, count: consecutiveCount };
|
|
153
155
|
}
|
|
154
156
|
|
|
157
|
+
/** Record successful mutation progress so Guard 2 can decay on the next count. */
|
|
158
|
+
export function recordToolCallLoopMutation(toolName: string): void {
|
|
159
|
+
if (!enabled) return;
|
|
160
|
+
if (!STATE_MUTATING_TOOL_SET.has(toolName)) return;
|
|
161
|
+
mutationEpoch++;
|
|
162
|
+
}
|
|
163
|
+
|
|
155
164
|
/** Reset the guard state. Call at agent turn boundaries. */
|
|
156
165
|
export function resetToolCallLoopGuard(): void {
|
|
157
166
|
consecutiveCount = 0;
|
|
@@ -159,6 +168,8 @@ export function resetToolCallLoopGuard(): void {
|
|
|
159
168
|
lastToolName = "";
|
|
160
169
|
enabled = true;
|
|
161
170
|
perToolCounts.clear();
|
|
171
|
+
mutationEpoch = 0;
|
|
172
|
+
perToolLastMutationEpoch.clear();
|
|
162
173
|
}
|
|
163
174
|
|
|
164
175
|
/** Disable the guard (e.g. during shutdown). */
|
|
@@ -168,6 +179,8 @@ export function disableToolCallLoopGuard(): void {
|
|
|
168
179
|
lastSignature = "";
|
|
169
180
|
lastToolName = "";
|
|
170
181
|
perToolCounts.clear();
|
|
182
|
+
mutationEpoch = 0;
|
|
183
|
+
perToolLastMutationEpoch.clear();
|
|
171
184
|
}
|
|
172
185
|
|
|
173
186
|
/** Get current consecutive count for diagnostics. */
|
|
@@ -97,8 +97,19 @@ function createEmptyWriteGateState(): InMemoryWriteGateState {
|
|
|
97
97
|
|
|
98
98
|
const writeGateStatesByBasePath = new Map<string, InMemoryWriteGateState>();
|
|
99
99
|
|
|
100
|
+
/**
|
|
101
|
+
* Write-gate snapshots are project-scoped, not worktree-scoped. When auto-mode
|
|
102
|
+
* routes MCP tool writes to `.gsd-worktrees/<MID>/`, depth verification still
|
|
103
|
+
* lands in the authoritative project `.gsd/runtime/` tree (or external-state
|
|
104
|
+
* symlink target). Without this canonicalization, `loadWriteGateSnapshot(worktree)`
|
|
105
|
+
* sees an empty snapshot and CONTEXT saves loop forever (#M020 gate loop).
|
|
106
|
+
*/
|
|
107
|
+
function resolveWriteGateSnapshotRoot(basePath: string): string {
|
|
108
|
+
return resolve(resolveWorktreeProjectRoot(basePath));
|
|
109
|
+
}
|
|
110
|
+
|
|
100
111
|
function writeGateStateKey(basePath: string): string {
|
|
101
|
-
return
|
|
112
|
+
return resolveWriteGateSnapshotRoot(basePath);
|
|
102
113
|
}
|
|
103
114
|
|
|
104
115
|
function getWriteGateState(basePath: string = process.cwd()): InMemoryWriteGateState {
|
|
@@ -161,17 +172,18 @@ function shouldPersistWriteGateSnapshot(env: NodeJS.ProcessEnv = process.env): b
|
|
|
161
172
|
}
|
|
162
173
|
|
|
163
174
|
function writeGateSnapshotPath(basePath: string): string {
|
|
164
|
-
return join(basePath, ".gsd", "runtime", "write-gate-state.json");
|
|
175
|
+
return join(resolveWriteGateSnapshotRoot(basePath), ".gsd", "runtime", "write-gate-state.json");
|
|
165
176
|
}
|
|
166
177
|
|
|
167
178
|
function ensureWriteGateSnapshotDirectory(basePath: string): void {
|
|
168
|
-
const
|
|
179
|
+
const snapshotRoot = resolveWriteGateSnapshotRoot(basePath);
|
|
180
|
+
const gsdPath = join(snapshotRoot, ".gsd");
|
|
169
181
|
if (!existsSync(gsdPath)) {
|
|
170
182
|
try {
|
|
171
183
|
const stat = lstatSync(gsdPath);
|
|
172
184
|
if (stat.isSymbolicLink()) {
|
|
173
185
|
const target = readlinkSync(gsdPath);
|
|
174
|
-
mkdirSync(isAbsolute(target) ? target : resolve(
|
|
186
|
+
mkdirSync(isAbsolute(target) ? target : resolve(snapshotRoot, target), { recursive: true });
|
|
175
187
|
}
|
|
176
188
|
} catch {
|
|
177
189
|
// If .gsd truly does not exist, the runtime mkdir below will create it.
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
getWorkflowDatabasePath,
|
|
19
19
|
refreshWorkflowDatabaseFromDisk,
|
|
20
20
|
} from "./db-workspace.js";
|
|
21
|
-
import { isClosedStatus } from "./status-guards.js";
|
|
21
|
+
import { isClosedStatus, isDeferredStatus } from "./status-guards.js";
|
|
22
22
|
import { closeQualityGatesFromEvidence } from "./quality-gate-closure.js";
|
|
23
23
|
import { insertMilestoneValidationGates } from "./milestone-validation-gates.js";
|
|
24
24
|
import { relMilestoneFile, resolveSliceFile } from "./paths.js";
|
|
@@ -229,6 +229,7 @@ export function checkCloseoutConsistencyGate(
|
|
|
229
229
|
}
|
|
230
230
|
|
|
231
231
|
for (const slice of slices) {
|
|
232
|
+
if (isDeferredStatus(slice.status)) continue;
|
|
232
233
|
if (!isClosedStatus(slice.status)) {
|
|
233
234
|
return blocked(
|
|
234
235
|
"slice-open",
|
|
@@ -1228,7 +1228,7 @@ async function configureContextCodebase(ctx: ExtensionCommandContext, prefs: Rec
|
|
|
1228
1228
|
const maskTurns = await promptInteger(ctx, "Observation mask turns (1–50)", cm.observation_mask_turns, "8");
|
|
1229
1229
|
if (maskTurns !== undefined && maskTurns !== "clear") cm.observation_mask_turns = maskTurns;
|
|
1230
1230
|
else if (maskTurns === "clear") delete cm.observation_mask_turns;
|
|
1231
|
-
const thresh = await promptNumber(ctx, "
|
|
1231
|
+
const thresh = await promptNumber(ctx, "Soft context warning threshold percent (0.5–0.95)", cm.compaction_threshold_percent, "0.60");
|
|
1232
1232
|
if (thresh !== undefined && thresh !== "clear") cm.compaction_threshold_percent = thresh;
|
|
1233
1233
|
else if (thresh === "clear") delete cm.compaction_threshold_percent;
|
|
1234
1234
|
const toolMax = await promptInteger(ctx, "Tool result max chars (200–10000)", cm.tool_result_max_chars, "800");
|
|
@@ -112,7 +112,7 @@ function formatThresholdLines(): string[] {
|
|
|
112
112
|
|
|
113
113
|
const compactionThreshold = prefs?.context_management?.compaction_threshold_percent;
|
|
114
114
|
if (typeof compactionThreshold === "number") {
|
|
115
|
-
lines.push(`
|
|
115
|
+
lines.push(`Soft context warning: ${Math.round(compactionThreshold * 100)}%`);
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
return lines;
|
|
@@ -47,7 +47,11 @@ import {
|
|
|
47
47
|
applyMigrationV28MemoryLastHitAt,
|
|
48
48
|
applyMigrationV29RepositoryTargets,
|
|
49
49
|
} from "../db-migration-steps.js";
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
isMemoriesFtsAvailableSchema,
|
|
52
|
+
rebuildMemoriesFtsSchemaOnce,
|
|
53
|
+
tryCreateMemoriesFtsSchema,
|
|
54
|
+
} from "../db-memory-fts-schema.js";
|
|
51
55
|
import { createDbOpenState, type DbOpenPhase } from "../db-open-state.js";
|
|
52
56
|
import { createRuntimeKvTableV25 } from "../db-runtime-kv-schema.js";
|
|
53
57
|
import { getCurrentSchemaVersion, recordSchemaVersion } from "../db-schema-metadata.js";
|
|
@@ -134,6 +138,9 @@ function initSchema(db: DbAdapter, fileBacked: boolean, dbPath: string | null):
|
|
|
134
138
|
}
|
|
135
139
|
|
|
136
140
|
migrateSchema(db, dbPath);
|
|
141
|
+
rebuildMemoriesFtsSchemaOnce(db, {
|
|
142
|
+
onRebuildFailed: (message) => logWarning("db", message),
|
|
143
|
+
});
|
|
137
144
|
}
|
|
138
145
|
|
|
139
146
|
export function _isLikelyWslDrvFsPathForTest(dbPath: string | null): boolean {
|