@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
|
@@ -27,7 +27,7 @@ import { writeLock, clearLock, clearStaleWorkerLock, readCrashLock, isLockProces
|
|
|
27
27
|
import { acquireSessionLock, getSessionLockStatus, releaseSessionLock, updateSessionLock, } from "./session-lock.js";
|
|
28
28
|
import { resolveAutoSupervisorConfig, loadEffectiveGSDPreferences, loadEffectiveGSDPreferencesWithRegistry, resolveProfileAnchorProvider, getIsolationMode, resolveEffectiveUnitIsolationMode, } from "./preferences.js";
|
|
29
29
|
import { playNotificationBell, sendDesktopNotification } from "./notifications.js";
|
|
30
|
-
import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, } from "./auto-budget.js";
|
|
30
|
+
import { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, HARD_CONTEXT_REROOT_THRESHOLD_PERCENT, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, shouldWarnStepSessionForContext, } from "./auto-budget.js";
|
|
31
31
|
import { markToolStart as _markToolStart, markToolEnd as _markToolEnd, getOldestInFlightToolAgeMs as _getOldestInFlightToolAgeMs, clearInFlightTools, isToolInvocationError, isQueuedUserMessageSkip, isDeterministicPolicyError, } from "./auto-tool-tracking.js";
|
|
32
32
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
33
33
|
import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
|
|
@@ -369,7 +369,7 @@ function getEffectiveUnitIsolationMode(basePath) {
|
|
|
369
369
|
* running suspiciously long (e.g., a Bash command hung because `&` kept stdout open).
|
|
370
370
|
*/
|
|
371
371
|
// Re-export budget utilities for external consumers
|
|
372
|
-
export { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, getContextPauseAction, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, } from "./auto-budget.js";
|
|
372
|
+
export { getBudgetAlertLevel, getNewBudgetAlertLevel, getBudgetEnforcementAction, getContextPauseAction, resolveCompactionThresholdPercent, shouldRerootStepSessionForContext, shouldWarnStepSessionForContext, } from "./auto-budget.js";
|
|
373
373
|
function closeOutSignalInterruptedUnit(currentBasePath) {
|
|
374
374
|
const currentUnit = s.currentUnit;
|
|
375
375
|
if (!currentUnit)
|
|
@@ -904,9 +904,10 @@ export async function rerootCommandSession(cmdCtx, workspaceRoot) {
|
|
|
904
904
|
}
|
|
905
905
|
}
|
|
906
906
|
/**
|
|
907
|
-
* After a completed step-mode unit,
|
|
908
|
-
*
|
|
909
|
-
* re-
|
|
907
|
+
* After a completed step-mode unit, warn when usage reaches the configurable
|
|
908
|
+
* soft context threshold. At the fixed hard boundary, write a context-mode
|
|
909
|
+
* snapshot and re-root the visible command session while leaving the NEXT
|
|
910
|
+
* progress surface.
|
|
910
911
|
*/
|
|
911
912
|
export async function maybeRerootStepSessionForHighContext(ctx, workspaceRoot, cmdCtx, originalBasePath) {
|
|
912
913
|
if (!cmdCtx)
|
|
@@ -915,18 +916,24 @@ export async function maybeRerootStepSessionForHighContext(ctx, workspaceRoot, c
|
|
|
915
916
|
const { loadEffectiveGSDPreferences } = await import("./preferences.js");
|
|
916
917
|
const prefs = loadEffectiveGSDPreferences(workspaceRoot);
|
|
917
918
|
const compactionThreshold = prefs?.preferences.context_management?.compaction_threshold_percent;
|
|
918
|
-
|
|
919
|
+
const shouldWarn = shouldWarnStepSessionForContext(contextPercent, compactionThreshold);
|
|
920
|
+
const shouldReroot = shouldRerootStepSessionForContext(contextPercent);
|
|
921
|
+
if (!shouldWarn && !shouldReroot) {
|
|
922
|
+
return { rerooted: false };
|
|
923
|
+
}
|
|
924
|
+
const displayPercent = contextPercent.toFixed(1);
|
|
925
|
+
const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
|
|
926
|
+
if (!shouldReroot) {
|
|
927
|
+
ctx.ui.notify(`Step complete — context at ${displayPercent}% (soft threshold: ${thresholdDisplay}%). Use /compact when convenient; continuing in this session is still safe.`, "info");
|
|
919
928
|
return { rerooted: false };
|
|
920
929
|
}
|
|
921
930
|
const { resolveWorktreeProjectRoot } = await import("./worktree-root.js");
|
|
922
931
|
const snapshotBase = resolveWorktreeProjectRoot(workspaceRoot, originalBasePath);
|
|
923
932
|
const { writeContextModeCompactionSnapshot } = await import("./context-mode-snapshot.js");
|
|
924
933
|
await writeContextModeCompactionSnapshot(snapshotBase);
|
|
925
|
-
const displayPercent = contextPercent.toFixed(1);
|
|
926
|
-
const thresholdDisplay = resolveCompactionThresholdPercent(compactionThreshold).toFixed(0);
|
|
927
934
|
const result = await rerootCommandSession(cmdCtx, workspaceRoot);
|
|
928
935
|
if (result.status === "ok") {
|
|
929
|
-
ctx.ui.notify(`Step complete — context at ${displayPercent}% (threshold: ${
|
|
936
|
+
ctx.ui.notify(`Step complete — context at ${displayPercent}% (hard threshold: ${HARD_CONTEXT_REROOT_THRESHOLD_PERCENT}%). Fresh session ready for /gsd next.`, "info");
|
|
930
937
|
return { rerooted: true };
|
|
931
938
|
}
|
|
932
939
|
if (result.status === "cancelled") {
|
|
@@ -1545,7 +1552,7 @@ export function _selectStopAutoWorktreeExit(args) {
|
|
|
1545
1552
|
/**
|
|
1546
1553
|
* Pause auto-mode without destroying state. Context is preserved.
|
|
1547
1554
|
* The user can interact with the agent, then `/gsd auto` resumes
|
|
1548
|
-
* from disk state. Called when the user presses Escape
|
|
1555
|
+
* from disk state. Called when the user presses Escape or runs `/gsd pause`.
|
|
1549
1556
|
*/
|
|
1550
1557
|
export async function pauseAuto(ctx, _pi, _errorContext, options = {}) {
|
|
1551
1558
|
if (!s.active)
|
|
@@ -1564,6 +1571,8 @@ export async function pauseAuto(ctx, _pi, _errorContext, options = {}) {
|
|
|
1564
1571
|
].filter((path) => Boolean(path)));
|
|
1565
1572
|
s.active = false;
|
|
1566
1573
|
s.paused = true;
|
|
1574
|
+
if (options.abortActiveTurn && ctx && !ctx.isIdle())
|
|
1575
|
+
ctx.abort();
|
|
1567
1576
|
clearUnitTimeout();
|
|
1568
1577
|
stopAutoCommandPolling();
|
|
1569
1578
|
// Flush queued follow-up messages (#3512).
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Canonical core session tool surface shared by auto-mode scoping and loop guards.
|
|
3
|
+
/** Base tools available during auto-mode execution before unit-specific GSD tools are added. */
|
|
4
|
+
export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
|
|
5
|
+
"ask_user_questions",
|
|
6
|
+
"bash",
|
|
7
|
+
"bg_shell",
|
|
8
|
+
"edit",
|
|
9
|
+
"find",
|
|
10
|
+
"glob",
|
|
11
|
+
"grep",
|
|
12
|
+
"fetch_page",
|
|
13
|
+
"search-the-web",
|
|
14
|
+
"ls",
|
|
15
|
+
"read",
|
|
16
|
+
"subagent",
|
|
17
|
+
"write",
|
|
18
|
+
"ToolSearch",
|
|
19
|
+
];
|
|
20
|
+
/** Tools excluded from the high per-turn loop-guard cap (strict or orchestration). */
|
|
21
|
+
const NON_REPEATABLE_FROM_MINIMAL_BASE = new Set([
|
|
22
|
+
"ask_user_questions",
|
|
23
|
+
"subagent",
|
|
24
|
+
"ToolSearch",
|
|
25
|
+
]);
|
|
26
|
+
/** Additional core tools not in MINIMAL_AUTO_BASE but routinely multi-called per turn. */
|
|
27
|
+
const EXTRA_INHERENTLY_REPEATABLE = [
|
|
28
|
+
"gsd_exec",
|
|
29
|
+
"multi_edit",
|
|
30
|
+
"todo_write",
|
|
31
|
+
"notebook_edit",
|
|
32
|
+
"search_and_read",
|
|
33
|
+
];
|
|
34
|
+
/** Core session tools that may be invoked many times per agent turn. */
|
|
35
|
+
export const INHERENTLY_REPEATABLE_TOOL_NAMES = [
|
|
36
|
+
...MINIMAL_AUTO_BASE_TOOL_NAMES.filter((name) => !NON_REPEATABLE_FROM_MINIMAL_BASE.has(name)),
|
|
37
|
+
...EXTRA_INHERENTLY_REPEATABLE,
|
|
38
|
+
];
|
|
39
|
+
export const INHERENTLY_REPEATABLE_TOOL_SET = new Set(INHERENTLY_REPEATABLE_TOOL_NAMES);
|
|
@@ -654,8 +654,9 @@ export function registerDbTools(pi) {
|
|
|
654
654
|
promptSnippet: "Plan a slice via DB write + PLAN render + cache invalidation",
|
|
655
655
|
promptGuidelines: [
|
|
656
656
|
"Use gsd_plan_slice for slice planning instead of writing S##-PLAN.md or task PLAN files directly.",
|
|
657
|
-
"
|
|
658
|
-
"
|
|
657
|
+
"For incremental planning, call gsd_plan_slice with slice metadata only, then call gsd_plan_task once per task.",
|
|
658
|
+
"When tasks is omitted or empty, the tool writes only slice planning metadata and preserves existing tasks.",
|
|
659
|
+
"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.",
|
|
659
660
|
"Use the canonical name gsd_plan_slice; gsd_slice_plan is only an alias.",
|
|
660
661
|
],
|
|
661
662
|
parameters: Type.Object({
|
|
@@ -663,7 +664,7 @@ export function registerDbTools(pi) {
|
|
|
663
664
|
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
664
665
|
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
665
666
|
goal: Type.String({ description: "Slice goal" }),
|
|
666
|
-
tasks: Type.Array(Type.Object({
|
|
667
|
+
tasks: Type.Optional(Type.Array(Type.Object({
|
|
667
668
|
taskId: Type.String({ description: "Task ID (e.g. T01)" }),
|
|
668
669
|
title: Type.String({ description: "Task title" }),
|
|
669
670
|
description: Type.String({ description: "Task description / steps block" }),
|
|
@@ -673,7 +674,7 @@ export function registerDbTools(pi) {
|
|
|
673
674
|
inputs: Type.Array(Type.String(), { description: "Array<string> of input files or references; pass [\"path\"] or [], never a single string" }),
|
|
674
675
|
expectedOutput: Type.Array(Type.String(), { description: "Array<string> of files this task creates or overwrites; pass [\"path\"] or [], never prose or a single string" }),
|
|
675
676
|
observabilityImpact: Type.Optional(Type.String({ description: "Task observability impact" })),
|
|
676
|
-
}), { description: "
|
|
677
|
+
}), { description: "Optional full task replacement for the slice. Omit for incremental planning, then call gsd_plan_task once per task." })),
|
|
677
678
|
// ── Enrichment metadata (optional — defaults to empty) ────────────
|
|
678
679
|
successCriteria: Type.Optional(Type.String({ description: "Slice success criteria block" })),
|
|
679
680
|
proofLevel: Type.Optional(Type.String({ description: "Slice proof level" })),
|
|
@@ -14,6 +14,7 @@ import { registerShortcuts } from "./register-shortcuts.js";
|
|
|
14
14
|
import { writeCrashLog } from "./crash-log.js";
|
|
15
15
|
import { logWarning, isGsdExtensionStderrEnabled } from "../workflow-logger.js";
|
|
16
16
|
import { UNIT_TOOL_CONTRACTS } from "../unit-tool-contracts.js";
|
|
17
|
+
import { installManifestFlushOnProcessTeardown } from "../workflow-manifest.js";
|
|
17
18
|
// Static import so cmux event listeners are registered synchronously during
|
|
18
19
|
// extension bootstrap. Prior implementation used `void import().then()` which
|
|
19
20
|
// queued listener registration as a microtask — any CMUX_CHANNELS emit fired
|
|
@@ -177,6 +178,7 @@ export function registerGsdExtension(pi) {
|
|
|
177
178
|
process.stderr.write(`[gsd] Failed to bootstrap hook-emitter bridge: ${err instanceof Error ? err.stack ?? err.message : String(err)}\n`);
|
|
178
179
|
});
|
|
179
180
|
installEpipeGuard();
|
|
181
|
+
installManifestFlushOnProcessTeardown();
|
|
180
182
|
// Ecosystem handlers captured by the GSDExtensionAPI wrapper for the
|
|
181
183
|
// GSD-owned `before_agent_start` dispatch step (#3338).
|
|
182
184
|
const ecosystemHandlers = [];
|
|
@@ -14,7 +14,8 @@ import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from
|
|
|
14
14
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
15
15
|
import { clearAutoCompletionStopInProgress, clearToolInvocationError, getAutoRuntimeSnapshot, getSourceObservationStore, isAutoActive, isAutoCompletionStopInProgress, isAutoPaused, isInteractiveElicitationInFlight, markToolEnd, markToolStart, recordAutoToolSurfaceSnapshot, recordToolInvocationError, } from "../auto-runtime-state.js";
|
|
16
16
|
import { applyProviderPayloadPolicy } from "../provider-payload-policy.js";
|
|
17
|
-
import { checkToolCallLoop, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
17
|
+
import { checkToolCallLoop, recordToolCallLoopMutation, resetToolCallLoopGuard } from "./tool-call-loop-guard.js";
|
|
18
|
+
import { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
|
|
18
19
|
import { maybePauseAutoForApprovalGate, resetPendingGatePauseGuard } from "./pending-gate-pause.js";
|
|
19
20
|
import { saveActivityLog } from "../activity-log.js";
|
|
20
21
|
import { recordToolCall as safetyRecordToolCall, recordToolResult as safetyRecordToolResult, saveEvidenceToDisk } from "../safety/evidence-collector.js";
|
|
@@ -42,6 +43,7 @@ import { supportsSourceObservationsForUnit } from "../source-observations.js";
|
|
|
42
43
|
import { clearPendingAutoStart } from "../pending-auto-start.js";
|
|
43
44
|
import { resolveWorkflowToolBasePath } from "./dynamic-tools.js";
|
|
44
45
|
import { getRequiredWorkflowToolsForUnit } from "../unit-tool-contracts.js";
|
|
46
|
+
import { flushAllManifests } from "../workflow-manifest.js";
|
|
45
47
|
let approvalQuestionAbortInFlight = false;
|
|
46
48
|
async function loadWelcomeScreenModule() {
|
|
47
49
|
const candidates = [];
|
|
@@ -138,22 +140,7 @@ export const MINIMAL_GSD_TOOL_NAMES = [
|
|
|
138
140
|
"capture_thought",
|
|
139
141
|
"gsd_capture_thought",
|
|
140
142
|
];
|
|
141
|
-
export
|
|
142
|
-
"ask_user_questions",
|
|
143
|
-
"bash",
|
|
144
|
-
"bg_shell",
|
|
145
|
-
"edit",
|
|
146
|
-
"find",
|
|
147
|
-
"glob",
|
|
148
|
-
"grep",
|
|
149
|
-
"fetch_page",
|
|
150
|
-
"search-the-web",
|
|
151
|
-
"ls",
|
|
152
|
-
"read",
|
|
153
|
-
"subagent",
|
|
154
|
-
"write",
|
|
155
|
-
"ToolSearch",
|
|
156
|
-
];
|
|
143
|
+
export { MINIMAL_AUTO_BASE_TOOL_NAMES } from "./core-session-tools.js";
|
|
157
144
|
function withPreservedShimTools(toolNames) {
|
|
158
145
|
return [...new Set([...toolNames, ...ALWAYS_PRESERVED_SHIM_TOOL_NAMES])];
|
|
159
146
|
}
|
|
@@ -449,6 +436,16 @@ function deferApprovalGateFromSnapshot(gateId, basePath, snapshot) {
|
|
|
449
436
|
function contextBasePath(ctx) {
|
|
450
437
|
return typeof ctx?.cwd === "string" ? ctx.cwd : process.cwd();
|
|
451
438
|
}
|
|
439
|
+
const LOOP_GUARD_INTERACTIVE_INSTRUCTIONS = [
|
|
440
|
+
"Do not retry this tool or call other tools this turn — stop and respond to the user in text.",
|
|
441
|
+
"Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.",
|
|
442
|
+
];
|
|
443
|
+
const LOOP_GUARD_AUTO_INSTRUCTION = "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.";
|
|
444
|
+
function formatLoopGuardBlockReason(reason) {
|
|
445
|
+
if (!reason || !getAutoRuntimeSnapshot().active)
|
|
446
|
+
return reason;
|
|
447
|
+
return LOOP_GUARD_INTERACTIVE_INSTRUCTIONS.reduce((formatted, instruction) => formatted.replace(instruction, LOOP_GUARD_AUTO_INSTRUCTION), reason);
|
|
448
|
+
}
|
|
452
449
|
function beginSourceObservationStoreForCurrentUnit(ctx) {
|
|
453
450
|
if (!isAutoActive())
|
|
454
451
|
return null;
|
|
@@ -717,6 +714,12 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
717
714
|
}
|
|
718
715
|
}
|
|
719
716
|
}
|
|
717
|
+
const projectRoot = resolveWorktreeProjectRoot(basePath);
|
|
718
|
+
const { pruneStaleFlatPhaseBackups } = await import("../flat-phase-migration.js");
|
|
719
|
+
const pruned = pruneStaleFlatPhaseBackups(projectRoot);
|
|
720
|
+
if (pruned > 0) {
|
|
721
|
+
safetyLogWarning("bootstrap", `pruned ${pruned} stale flat-phase migration backup(s) from .gsd-backups/ (retention exceeded)`);
|
|
722
|
+
}
|
|
720
723
|
}
|
|
721
724
|
catch (err) {
|
|
722
725
|
safetyLogWarning("bootstrap", `flat-phase migration: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -874,6 +877,17 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
874
877
|
const { handleAgentEnd } = await import("./agent-end-recovery.js");
|
|
875
878
|
const agentEndBasePath = contextBasePath(ctx);
|
|
876
879
|
try {
|
|
880
|
+
// The manifest is a non-critical projection (the append-only event log is
|
|
881
|
+
// the authoritative recovery source), so a flush failure must not skip
|
|
882
|
+
// agent_end recovery. drainManifestWrites still propagates write failures
|
|
883
|
+
// to explicit flush callers; here we deliberately log and continue so
|
|
884
|
+
// handleAgentEnd (and the finally below) always run.
|
|
885
|
+
try {
|
|
886
|
+
await flushAllManifests();
|
|
887
|
+
}
|
|
888
|
+
catch (err) {
|
|
889
|
+
safetyLogWarning("manifest", `flushAllManifests on agent_end failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
890
|
+
}
|
|
877
891
|
await handleAgentEnd(pi, event, ctx);
|
|
878
892
|
}
|
|
879
893
|
finally {
|
|
@@ -1063,7 +1077,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1063
1077
|
// ── Loop guard: block repeated identical tool calls ──
|
|
1064
1078
|
const loopCheck = checkToolCallLoop(toolName, event.input);
|
|
1065
1079
|
if (loopCheck.block) {
|
|
1066
|
-
return { block: true, reason: loopCheck.reason };
|
|
1080
|
+
return { block: true, reason: formatLoopGuardBlockReason(loopCheck.reason) };
|
|
1067
1081
|
}
|
|
1068
1082
|
const deferredGateGuard = shouldBlockDeferredApprovalTool(toolName, event.input, discussionBasePath);
|
|
1069
1083
|
if (deferredGateGuard.block) {
|
|
@@ -1269,6 +1283,7 @@ export function registerHooks(pi, ecosystemHandlers) {
|
|
|
1269
1283
|
}
|
|
1270
1284
|
}
|
|
1271
1285
|
if (!event.isError) {
|
|
1286
|
+
recordToolCallLoopMutation(toolName);
|
|
1272
1287
|
refreshSourceObservationAfterMutation(toolName, event.input, ctx);
|
|
1273
1288
|
clearSourceObservationsAfterShell(toolName);
|
|
1274
1289
|
}
|
|
@@ -1,24 +1,29 @@
|
|
|
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
|
import { createHash } from "node:crypto";
|
|
26
|
+
import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
|
|
22
27
|
const MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
|
|
23
28
|
/** Interactive/user-facing tools where even 1 duplicate is confusing. */
|
|
24
29
|
const STRICT_LOOP_TOOLS = new Set(["ask_user_questions"]);
|
|
@@ -35,32 +40,16 @@ const MAX_CONSECUTIVE_STRICT = 1;
|
|
|
35
40
|
*/
|
|
36
41
|
const PER_TOOL_DEFAULT_CAP = 6;
|
|
37
42
|
const PER_TOOL_REPEATABLE_CAP = 15;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* (reading/writing several files, running several commands, searching). These
|
|
41
|
-
* get PER_TOOL_REPEATABLE_CAP rather than the default. Keep this list
|
|
42
|
-
* conservative — a tool here can be invoked up to PER_TOOL_REPEATABLE_CAP times
|
|
43
|
-
* per turn before the guard blocks.
|
|
44
|
-
*/
|
|
45
|
-
const REPEATABLE_TOOLS = new Set([
|
|
46
|
-
"read",
|
|
47
|
-
"write",
|
|
48
|
-
"edit",
|
|
49
|
-
"multi_edit",
|
|
50
|
-
"bash",
|
|
51
|
-
"grep",
|
|
52
|
-
"glob",
|
|
53
|
-
"search-the-web",
|
|
54
|
-
"fetch_page",
|
|
55
|
-
"todo_write",
|
|
56
|
-
"notebook_edit",
|
|
57
|
-
]);
|
|
43
|
+
const PER_TOOL_CAP_EXEMPT_TOOLS = new Set(["find", "glob", "grep", "ls", "read", "search_and_read"]);
|
|
44
|
+
const STATE_MUTATING_TOOL_SET = new Set(["edit", "write", "multi_edit", "notebook_edit"]);
|
|
58
45
|
let consecutiveCount = 0;
|
|
59
46
|
let lastSignature = "";
|
|
60
47
|
let lastToolName = "";
|
|
61
48
|
let enabled = true;
|
|
62
49
|
/** Per-tool-name call counts within the current turn (#783 Brief C). */
|
|
63
50
|
const perToolCounts = new Map();
|
|
51
|
+
let mutationEpoch = 0;
|
|
52
|
+
const perToolLastMutationEpoch = new Map();
|
|
64
53
|
/** Hash tool name + args into a compact signature for comparison. */
|
|
65
54
|
function hashToolCall(toolName, args) {
|
|
66
55
|
const h = createHash("sha256");
|
|
@@ -84,7 +73,8 @@ function hashToolCall(toolName, args) {
|
|
|
84
73
|
* 1. Identical-signature streak (MAX_CONSECUTIVE_IDENTICAL_CALLS, strict for
|
|
85
74
|
* ask_user_questions).
|
|
86
75
|
* 2. Per-tool-name cap (PER_TOOL_DEFAULT_CAP / PER_TOOL_REPEATABLE_CAP),
|
|
87
|
-
* independent of args
|
|
76
|
+
* independent of args, reset after file-mutation progress — catches
|
|
77
|
+
* improvisation loops (#783).
|
|
88
78
|
*/
|
|
89
79
|
export function checkToolCallLoop(toolName, args) {
|
|
90
80
|
if (!enabled)
|
|
@@ -107,16 +97,25 @@ export function checkToolCallLoop(toolName, args) {
|
|
|
107
97
|
block: true,
|
|
108
98
|
reason: `Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
|
|
109
99
|
`with identical arguments. Blocking to prevent infinite loop. ` +
|
|
110
|
-
`
|
|
100
|
+
`Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
|
|
111
101
|
count: consecutiveCount,
|
|
112
102
|
};
|
|
113
103
|
}
|
|
114
104
|
// ── Guard 2: per-tool-name cap, independent of args (#783 Brief C) ──
|
|
115
105
|
// Catches improvisation loops where the same tool is invoked many times with
|
|
116
106
|
// varied args (e.g. retrying a missing workflow tool via bash/node -e/CLI).
|
|
117
|
-
const
|
|
107
|
+
const priorPerToolCount = (perToolLastMutationEpoch.get(toolName) ?? mutationEpoch) < mutationEpoch
|
|
108
|
+
? 0
|
|
109
|
+
: (perToolCounts.get(toolName) ?? 0);
|
|
110
|
+
const perToolCount = priorPerToolCount + 1;
|
|
118
111
|
perToolCounts.set(toolName, perToolCount);
|
|
119
|
-
|
|
112
|
+
perToolLastMutationEpoch.set(toolName, mutationEpoch);
|
|
113
|
+
// Read-only navigation tools are normal context gathering; Guard 1 still
|
|
114
|
+
// catches true reread loops with identical arguments.
|
|
115
|
+
if (PER_TOOL_CAP_EXEMPT_TOOLS.has(toolName)) {
|
|
116
|
+
return { block: false, count: consecutiveCount };
|
|
117
|
+
}
|
|
118
|
+
const perToolCap = INHERENTLY_REPEATABLE_TOOL_SET.has(toolName)
|
|
120
119
|
? PER_TOOL_REPEATABLE_CAP
|
|
121
120
|
: PER_TOOL_DEFAULT_CAP;
|
|
122
121
|
if (perToolCount > perToolCap) {
|
|
@@ -124,12 +123,21 @@ export function checkToolCallLoop(toolName, args) {
|
|
|
124
123
|
block: true,
|
|
125
124
|
reason: `Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
|
|
126
125
|
`this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
|
|
127
|
-
`The tool may be unavailable or failing repeatedly
|
|
126
|
+
`The tool may be unavailable or failing repeatedly. ` +
|
|
127
|
+
`Do not retry this tool or pivot to other tools this turn — stop and respond to the user in text.`,
|
|
128
128
|
count: perToolCount,
|
|
129
129
|
};
|
|
130
130
|
}
|
|
131
131
|
return { block: false, count: consecutiveCount };
|
|
132
132
|
}
|
|
133
|
+
/** Record successful mutation progress so Guard 2 can decay on the next count. */
|
|
134
|
+
export function recordToolCallLoopMutation(toolName) {
|
|
135
|
+
if (!enabled)
|
|
136
|
+
return;
|
|
137
|
+
if (!STATE_MUTATING_TOOL_SET.has(toolName))
|
|
138
|
+
return;
|
|
139
|
+
mutationEpoch++;
|
|
140
|
+
}
|
|
133
141
|
/** Reset the guard state. Call at agent turn boundaries. */
|
|
134
142
|
export function resetToolCallLoopGuard() {
|
|
135
143
|
consecutiveCount = 0;
|
|
@@ -137,6 +145,8 @@ export function resetToolCallLoopGuard() {
|
|
|
137
145
|
lastToolName = "";
|
|
138
146
|
enabled = true;
|
|
139
147
|
perToolCounts.clear();
|
|
148
|
+
mutationEpoch = 0;
|
|
149
|
+
perToolLastMutationEpoch.clear();
|
|
140
150
|
}
|
|
141
151
|
/** Disable the guard (e.g. during shutdown). */
|
|
142
152
|
export function disableToolCallLoopGuard() {
|
|
@@ -145,6 +155,8 @@ export function disableToolCallLoopGuard() {
|
|
|
145
155
|
lastSignature = "";
|
|
146
156
|
lastToolName = "";
|
|
147
157
|
perToolCounts.clear();
|
|
158
|
+
mutationEpoch = 0;
|
|
159
|
+
perToolLastMutationEpoch.clear();
|
|
148
160
|
}
|
|
149
161
|
/** Get current consecutive count for diagnostics. */
|
|
150
162
|
export function getToolCallLoopCount() {
|
|
@@ -81,8 +81,18 @@ function createEmptyWriteGateState() {
|
|
|
81
81
|
};
|
|
82
82
|
}
|
|
83
83
|
const writeGateStatesByBasePath = new Map();
|
|
84
|
+
/**
|
|
85
|
+
* Write-gate snapshots are project-scoped, not worktree-scoped. When auto-mode
|
|
86
|
+
* routes MCP tool writes to `.gsd-worktrees/<MID>/`, depth verification still
|
|
87
|
+
* lands in the authoritative project `.gsd/runtime/` tree (or external-state
|
|
88
|
+
* symlink target). Without this canonicalization, `loadWriteGateSnapshot(worktree)`
|
|
89
|
+
* sees an empty snapshot and CONTEXT saves loop forever (#M020 gate loop).
|
|
90
|
+
*/
|
|
91
|
+
function resolveWriteGateSnapshotRoot(basePath) {
|
|
92
|
+
return resolve(resolveWorktreeProjectRoot(basePath));
|
|
93
|
+
}
|
|
84
94
|
function writeGateStateKey(basePath) {
|
|
85
|
-
return
|
|
95
|
+
return resolveWriteGateSnapshotRoot(basePath);
|
|
86
96
|
}
|
|
87
97
|
function getWriteGateState(basePath = process.cwd()) {
|
|
88
98
|
const key = writeGateStateKey(basePath);
|
|
@@ -123,16 +133,17 @@ function shouldPersistWriteGateSnapshot(env = process.env) {
|
|
|
123
133
|
return v !== "0" && v !== "false";
|
|
124
134
|
}
|
|
125
135
|
function writeGateSnapshotPath(basePath) {
|
|
126
|
-
return join(basePath, ".gsd", "runtime", "write-gate-state.json");
|
|
136
|
+
return join(resolveWriteGateSnapshotRoot(basePath), ".gsd", "runtime", "write-gate-state.json");
|
|
127
137
|
}
|
|
128
138
|
function ensureWriteGateSnapshotDirectory(basePath) {
|
|
129
|
-
const
|
|
139
|
+
const snapshotRoot = resolveWriteGateSnapshotRoot(basePath);
|
|
140
|
+
const gsdPath = join(snapshotRoot, ".gsd");
|
|
130
141
|
if (!existsSync(gsdPath)) {
|
|
131
142
|
try {
|
|
132
143
|
const stat = lstatSync(gsdPath);
|
|
133
144
|
if (stat.isSymbolicLink()) {
|
|
134
145
|
const target = readlinkSync(gsdPath);
|
|
135
|
-
mkdirSync(isAbsolute(target) ? target : resolve(
|
|
146
|
+
mkdirSync(isAbsolute(target) ? target : resolve(snapshotRoot, target), { recursive: true });
|
|
136
147
|
}
|
|
137
148
|
}
|
|
138
149
|
catch {
|
|
@@ -4,7 +4,7 @@ import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
|
|
|
4
4
|
import { dirname, join } from "node:path";
|
|
5
5
|
import { getLatestAssessmentByScope, getMilestone, getMilestoneSlices, getPendingGates, getSliceTasks, insertAssessment, isDbAvailable, transaction, } from "./gsd-db.js";
|
|
6
6
|
import { getWorkflowDatabasePath, refreshWorkflowDatabaseFromDisk, } from "./db-workspace.js";
|
|
7
|
-
import { isClosedStatus } from "./status-guards.js";
|
|
7
|
+
import { isClosedStatus, isDeferredStatus } from "./status-guards.js";
|
|
8
8
|
import { closeQualityGatesFromEvidence } from "./quality-gate-closure.js";
|
|
9
9
|
import { insertMilestoneValidationGates } from "./milestone-validation-gates.js";
|
|
10
10
|
import { relMilestoneFile, resolveSliceFile } from "./paths.js";
|
|
@@ -144,6 +144,8 @@ export function checkCloseoutConsistencyGate(milestoneId, options = {}) {
|
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
146
|
for (const slice of slices) {
|
|
147
|
+
if (isDeferredStatus(slice.status))
|
|
148
|
+
continue;
|
|
147
149
|
if (!isClosedStatus(slice.status)) {
|
|
148
150
|
return blocked("slice-open", `Closeout consistency blocked for ${milestoneId}: slice ${slice.id} status is "${slice.status}".`);
|
|
149
151
|
}
|
|
@@ -190,7 +190,7 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
|
190
190
|
}
|
|
191
191
|
return true;
|
|
192
192
|
}
|
|
193
|
-
await pauseAuto(ctx, pi);
|
|
193
|
+
await pauseAuto(ctx, pi, undefined, { abortActiveTurn: true });
|
|
194
194
|
return true;
|
|
195
195
|
}
|
|
196
196
|
if (trimmed === "rate" || trimmed.startsWith("rate ")) {
|
|
@@ -1164,7 +1164,7 @@ async function configureContextCodebase(ctx, prefs) {
|
|
|
1164
1164
|
cm.observation_mask_turns = maskTurns;
|
|
1165
1165
|
else if (maskTurns === "clear")
|
|
1166
1166
|
delete cm.observation_mask_turns;
|
|
1167
|
-
const thresh = await promptNumber(ctx, "
|
|
1167
|
+
const thresh = await promptNumber(ctx, "Soft context warning threshold percent (0.5–0.95)", cm.compaction_threshold_percent, "0.60");
|
|
1168
1168
|
if (thresh !== undefined && thresh !== "clear")
|
|
1169
1169
|
cm.compaction_threshold_percent = thresh;
|
|
1170
1170
|
else if (thresh === "clear")
|
|
@@ -83,7 +83,7 @@ function formatThresholdLines() {
|
|
|
83
83
|
}
|
|
84
84
|
const compactionThreshold = prefs?.context_management?.compaction_threshold_percent;
|
|
85
85
|
if (typeof compactionThreshold === "number") {
|
|
86
|
-
lines.push(`
|
|
86
|
+
lines.push(`Soft context warning: ${Math.round(compactionThreshold * 100)}%`);
|
|
87
87
|
}
|
|
88
88
|
return lines;
|
|
89
89
|
}
|
|
@@ -19,7 +19,7 @@ import { createCoordinationTablesV24 } from "../db-coordination-schema.js";
|
|
|
19
19
|
import { createDbConnectionCache } from "../db-connection-cache.js";
|
|
20
20
|
import { backupDatabaseBeforeMigration, isMigrationBackupError } from "../db-migration-backup.js";
|
|
21
21
|
import { applyMigrationV2Artifacts, applyMigrationV3Memories, applyMigrationV4DecisionMadeBy, applyMigrationV5HierarchyTables, applyMigrationV6SliceSummaries, applyMigrationV7Dependencies, applyMigrationV8PlanningFields, applyMigrationV9Ordering, applyMigrationV10ReplanTrigger, applyMigrationV11TaskPlanning, applyMigrationV12QualityGates, applyMigrationV13HotPathIndexes, applyMigrationV14SliceDependencies, applyMigrationV15AuditTables, applyMigrationV16EscalationSource, applyMigrationV17TaskEscalation, applyMigrationV18MemorySources, applyMigrationV19MemoryFts, applyMigrationV20MemoryRelations, applyMigrationV21StructuredMemories, applyMigrationV22QualityGateRepair, applyMigrationV23MilestoneQueue, applyMigrationV26MilestoneCommitAttributions, applyMigrationV27ArtifactHash, applyMigrationV28MemoryLastHitAt, applyMigrationV29RepositoryTargets, } from "../db-migration-steps.js";
|
|
22
|
-
import { isMemoriesFtsAvailableSchema, tryCreateMemoriesFtsSchema } from "../db-memory-fts-schema.js";
|
|
22
|
+
import { isMemoriesFtsAvailableSchema, rebuildMemoriesFtsSchemaOnce, tryCreateMemoriesFtsSchema, } from "../db-memory-fts-schema.js";
|
|
23
23
|
import { createDbOpenState } from "../db-open-state.js";
|
|
24
24
|
import { createRuntimeKvTableV25 } from "../db-runtime-kv-schema.js";
|
|
25
25
|
import { getCurrentSchemaVersion, recordSchemaVersion } from "../db-schema-metadata.js";
|
|
@@ -101,6 +101,9 @@ function initSchema(db, fileBacked, dbPath) {
|
|
|
101
101
|
throw err;
|
|
102
102
|
}
|
|
103
103
|
migrateSchema(db, dbPath);
|
|
104
|
+
rebuildMemoriesFtsSchemaOnce(db, {
|
|
105
|
+
onRebuildFailed: (message) => logWarning("db", message),
|
|
106
|
+
});
|
|
104
107
|
}
|
|
105
108
|
export function _isLikelyWslDrvFsPathForTest(dbPath) {
|
|
106
109
|
if (!dbPath || process.platform !== "linux")
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// Project/App: gsd-pi
|
|
2
2
|
// File Purpose: Memory FTS5 SQLite schema helpers for the GSD database facade.
|
|
3
|
+
import { createRuntimeKvTableV25 } from "./db-runtime-kv-schema.js";
|
|
4
|
+
export const MEMORIES_FTS_REBUILT_KEY = "memories_fts_rebuilt_at";
|
|
3
5
|
function formatFtsUnavailableError(err) {
|
|
4
6
|
const message = err instanceof Error ? err.message : String(err);
|
|
5
7
|
return message.replace(/\bmoduel\s*:\s*/gi, "module: ");
|
|
@@ -54,3 +56,35 @@ export function isMemoriesFtsAvailableSchema(db) {
|
|
|
54
56
|
return false;
|
|
55
57
|
}
|
|
56
58
|
}
|
|
59
|
+
export function rebuildMemoriesFtsSchemaOnce(db, options = {}) {
|
|
60
|
+
if (!isMemoriesFtsAvailableSchema(db))
|
|
61
|
+
return;
|
|
62
|
+
createRuntimeKvTableV25(db);
|
|
63
|
+
const marker = db.prepare("SELECT 1 as present FROM runtime_kv WHERE scope = 'global' AND scope_id = '' AND key = :key").get({ ":key": MEMORIES_FTS_REBUILT_KEY });
|
|
64
|
+
if (marker)
|
|
65
|
+
return;
|
|
66
|
+
const now = new Date().toISOString();
|
|
67
|
+
try {
|
|
68
|
+
db.exec("BEGIN");
|
|
69
|
+
db.exec("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
70
|
+
db.prepare(`INSERT INTO runtime_kv (scope, scope_id, key, value_json, updated_at)
|
|
71
|
+
VALUES ('global', '', :key, :value_json, :updated_at)
|
|
72
|
+
ON CONFLICT (scope, scope_id, key) DO UPDATE SET
|
|
73
|
+
value_json = excluded.value_json,
|
|
74
|
+
updated_at = excluded.updated_at`).run({
|
|
75
|
+
":key": MEMORIES_FTS_REBUILT_KEY,
|
|
76
|
+
":value_json": JSON.stringify(now),
|
|
77
|
+
":updated_at": now,
|
|
78
|
+
});
|
|
79
|
+
db.exec("COMMIT");
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
try {
|
|
83
|
+
db.exec("ROLLBACK");
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Best effort: leave startup alive and retry the rebuild on next open.
|
|
87
|
+
}
|
|
88
|
+
options.onRebuildFailed?.(`FTS5 rebuild failed: ${err.message}`);
|
|
89
|
+
}
|
|
90
|
+
}
|