@opengsd/gsd-pi 1.3.0-dev.65546769 → 1.3.0-dev.738160b9
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 +1 -1
- 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/claude-code-cli/stream-adapter.js +11 -2
- package/dist/resources/extensions/google-cli/stream-adapter.js +82 -15
- package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +12 -3
- 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 +34 -20
- package/dist/resources/extensions/gsd/auto-post-unit.js +1 -1
- package/dist/resources/extensions/gsd/auto-prompts.js +29 -14
- package/dist/resources/extensions/gsd/auto-recovery.js +9 -510
- 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/agent-end-recovery.js +103 -13
- package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +11 -5
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +41 -21
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +46 -19
- package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +96 -10
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
- 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-context.js +19 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.js +17 -11
- package/dist/resources/extensions/gsd/commands-usage.js +1 -1
- package/dist/resources/extensions/gsd/commands-worktree.js +12 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -3
- package/dist/resources/extensions/gsd/db/engine.js +4 -1
- package/dist/resources/extensions/gsd/db/queries.js +60 -0
- 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-providers.js +92 -8
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +3 -0
- package/dist/resources/extensions/gsd/exec-sandbox.js +53 -11
- package/dist/resources/extensions/gsd/flat-phase-migration.js +45 -0
- package/dist/resources/extensions/gsd/forensics.js +2 -32
- package/dist/resources/extensions/gsd/git-service.js +61 -4
- package/dist/resources/extensions/gsd/gitignore.js +4 -1
- package/dist/resources/extensions/gsd/guided-flow-queue.js +66 -5
- package/dist/resources/extensions/gsd/health-widget.js +55 -29
- 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 +8 -9
- package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
- package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +44 -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/milestone-implementation-evidence.js +26 -20
- 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/quick.js +45 -2
- 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/session-forensics.js +11 -1
- 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 +45 -2
- 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 +2 -2
- package/dist/resources/extensions/gsd/tools/complete-task.js +43 -14
- package/dist/resources/extensions/gsd/tools/exec-tool.js +7 -2
- 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-context-composer.js +23 -7
- package/dist/resources/extensions/gsd/unit-registry.js +36 -6
- package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +33 -3
- package/dist/resources/extensions/gsd/validation-block-guard.js +9 -4
- 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/workspace-git-preflight.js +30 -1
- 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 +3 -3
- 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/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_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 +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +2 -2
- 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 +2 -2
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- 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/8357.js +1 -1
- 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/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/{page-6644fc6ee8ca1247.js → page-72a856634ad14c10.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/package.json +1 -1
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/dist/workflow.d.ts +1 -0
- package/packages/contracts/dist/workflow.d.ts.map +1 -1
- package/packages/contracts/dist/workflow.js +2 -0
- package/packages/contracts/dist/workflow.js.map +1 -1
- 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 -829
- 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/README.md +1 -1
- package/packages/mcp-server/dist/server.d.ts +1 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +3 -3
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +35 -21
- 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/stream-adapter.ts +20 -2
- package/src/resources/extensions/claude-code-cli/tests/index.test.ts +14 -0
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +80 -0
- package/src/resources/extensions/google-cli/stream-adapter.ts +106 -19
- 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/orchestrator.ts +25 -11
- 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 +35 -24
- package/src/resources/extensions/gsd/auto-post-unit.ts +1 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +41 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +13 -511
- 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/agent-end-recovery.ts +125 -12
- package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +11 -5
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +52 -21
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +52 -18
- package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +104 -10
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
- 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-context.ts +18 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +15 -10
- package/src/resources/extensions/gsd/commands-usage.ts +1 -1
- package/src/resources/extensions/gsd/commands-worktree.ts +12 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +32 -3
- package/src/resources/extensions/gsd/db/engine.ts +8 -1
- package/src/resources/extensions/gsd/db/queries.ts +79 -0
- 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-providers.ts +103 -9
- 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 +56 -11
- package/src/resources/extensions/gsd/flat-phase-migration.ts +44 -0
- package/src/resources/extensions/gsd/forensics.ts +2 -33
- package/src/resources/extensions/gsd/git-service.ts +69 -5
- package/src/resources/extensions/gsd/gitignore.ts +4 -1
- package/src/resources/extensions/gsd/guided-flow-queue.ts +89 -4
- package/src/resources/extensions/gsd/health-widget.ts +69 -32
- 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 +8 -11
- package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
- package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +51 -19
- 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/milestone-implementation-evidence.ts +35 -21
- 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/quick.ts +43 -2
- 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/session-forensics.ts +11 -1
- 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 +81 -7
- 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 +146 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/commands-context.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +80 -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/complete-slice.test.ts +11 -0
- package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +48 -8
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +55 -2
- 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/dispatch-rule-coverage.test.ts +26 -1
- package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +70 -2
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +107 -0
- package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
- package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/exec-tool.test.ts +45 -1
- 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/forensics-error-filter.test.ts +88 -0
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +268 -3
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +130 -3
- package/src/resources/extensions/gsd/tests/integration/queue-active-milestone-context-budget.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +56 -9
- 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/knowledge-cold-start.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +78 -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/orchestrator-logs.test.ts +43 -1
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +1 -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/prefs-wizard-coverage.test.ts +54 -1
- 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/provider-errors.test.ts +195 -1
- package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +185 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +87 -0
- 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 +191 -0
- package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +32 -3
- package/src/resources/extensions/gsd/tests/undo.test.ts +74 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +193 -14
- package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +66 -0
- 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/workspace-git-preflight.test.ts +151 -2
- 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 +2 -2
- package/src/resources/extensions/gsd/tools/complete-task.ts +53 -15
- package/src/resources/extensions/gsd/tools/exec-tool.ts +7 -3
- 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-context-composer.ts +33 -7
- package/src/resources/extensions/gsd/unit-registry.ts +36 -6
- package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +41 -5
- package/src/resources/extensions/gsd/validation-block-guard.ts +13 -7
- 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/workspace-git-preflight.ts +31 -0
- 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.e0bdc932325d7e03.js +0 -10
- package/dist/web/standalone/.next/static/chunks/webpack-f46ea08200a0227e.js +0 -1
- /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{BTKtGFF1Y-hvVJEGhBRo9 → 2A_WqqCS-EoYZxN9_v3d2}/_ssgManifest.js +0 -0
|
@@ -28,9 +28,10 @@ const DEFAULT_CODEBASE_MAX_CHARS = 8_000;
|
|
|
28
28
|
const MIN_CONTEXT_MESSAGE_MAX_CHARS = 1_000;
|
|
29
29
|
const MIN_KNOWLEDGE_MAX_CHARS = 1_000;
|
|
30
30
|
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
31
|
+
const CONTEXT_MAINTENANCE_KEY_SEPARATOR = "\0";
|
|
32
|
+
const contextMaintenanceCompletedForSession = new Set<string>();
|
|
33
|
+
const contextMaintenanceInFlightBySession = new Map<string, Promise<boolean>>();
|
|
34
|
+
const deferredContextMaintenanceBySession = new Map<string, Promise<void>>();
|
|
34
35
|
|
|
35
36
|
/**
|
|
36
37
|
* Bundled skill triggers — resolved dynamically at runtime instead of
|
|
@@ -114,7 +115,8 @@ async function runSessionStartupMaintenanceOnce(
|
|
|
114
115
|
basePath: string,
|
|
115
116
|
ctx: ExtensionContext,
|
|
116
117
|
): Promise<boolean> {
|
|
117
|
-
|
|
118
|
+
const maintenanceKey = getContextMaintenanceKey(basePath, ctx);
|
|
119
|
+
if (contextMaintenanceCompletedForSession.has(maintenanceKey)) {
|
|
118
120
|
// Backfills are session-once, but memory queries and other DB-backed
|
|
119
121
|
// prompt assembly still need an active adapter on every turn.
|
|
120
122
|
try {
|
|
@@ -126,16 +128,16 @@ async function runSessionStartupMaintenanceOnce(
|
|
|
126
128
|
return false;
|
|
127
129
|
}
|
|
128
130
|
|
|
129
|
-
const existing =
|
|
131
|
+
const existing = contextMaintenanceInFlightBySession.get(maintenanceKey);
|
|
130
132
|
const isInitiator = !existing;
|
|
131
133
|
// Use a definite Promise<boolean> so `await inFlight` has a known return type.
|
|
132
134
|
let inFlight: Promise<boolean>;
|
|
133
135
|
if (isInitiator) {
|
|
134
|
-
inFlight = performSessionStartupMaintenance(basePath, ctx);
|
|
135
|
-
|
|
136
|
+
inFlight = performSessionStartupMaintenance(basePath, ctx, maintenanceKey);
|
|
137
|
+
contextMaintenanceInFlightBySession.set(maintenanceKey, inFlight);
|
|
136
138
|
void inFlight.finally(() => {
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
+
if (contextMaintenanceInFlightBySession.get(maintenanceKey) === inFlight) {
|
|
140
|
+
contextMaintenanceInFlightBySession.delete(maintenanceKey);
|
|
139
141
|
}
|
|
140
142
|
});
|
|
141
143
|
} else {
|
|
@@ -149,6 +151,7 @@ async function runSessionStartupMaintenanceOnce(
|
|
|
149
151
|
async function performSessionStartupMaintenance(
|
|
150
152
|
basePath: string,
|
|
151
153
|
ctx: ExtensionContext,
|
|
154
|
+
maintenanceKey: string,
|
|
152
155
|
): Promise<boolean> {
|
|
153
156
|
// DB-backed memory backfills run below. On a cold session the database file
|
|
154
157
|
// may exist without an active in-process adapter, so open the canonical
|
|
@@ -172,11 +175,40 @@ async function performSessionStartupMaintenance(
|
|
|
172
175
|
|
|
173
176
|
// Mark session complete before scheduling deferred work so any concurrent
|
|
174
177
|
// caller that observes the completed state does not re-enter maintenance.
|
|
175
|
-
|
|
176
|
-
scheduleDeferredContextMaintenance(basePath);
|
|
178
|
+
contextMaintenanceCompletedForSession.add(maintenanceKey);
|
|
179
|
+
scheduleDeferredContextMaintenance(basePath, maintenanceKey);
|
|
177
180
|
return true;
|
|
178
181
|
}
|
|
179
182
|
|
|
183
|
+
function getContextMaintenanceKey(basePath: string, ctx: ExtensionContext): string {
|
|
184
|
+
return `${basePath}${CONTEXT_MAINTENANCE_KEY_SEPARATOR}${getContextSessionPart(ctx)}`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function getContextSessionPart(ctx: ExtensionContext): string {
|
|
188
|
+
const sessionManager = (ctx as {
|
|
189
|
+
sessionManager?: {
|
|
190
|
+
getSessionId?: () => string | undefined;
|
|
191
|
+
getSessionFile?: () => string | undefined;
|
|
192
|
+
};
|
|
193
|
+
}).sessionManager;
|
|
194
|
+
|
|
195
|
+
try {
|
|
196
|
+
const sessionId = sessionManager?.getSessionId?.();
|
|
197
|
+
if (typeof sessionId === "string" && sessionId.length > 0) return `id:${sessionId}`;
|
|
198
|
+
} catch (e) {
|
|
199
|
+
logWarning("bootstrap", `session-id fetch failed: ${(e as Error).message}`);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
try {
|
|
203
|
+
const sessionFile = sessionManager?.getSessionFile?.();
|
|
204
|
+
if (typeof sessionFile === "string" && sessionFile.length > 0) return `file:${sessionFile}`;
|
|
205
|
+
} catch (e) {
|
|
206
|
+
logWarning("bootstrap", `session-file fetch failed: ${(e as Error).message}`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return "process";
|
|
210
|
+
}
|
|
211
|
+
|
|
180
212
|
async function runDecisionsMemoryBackfill(ctx: ExtensionContext): Promise<void> {
|
|
181
213
|
// ADR-013 step 5: opportunistic decisions->memories backfill. Idempotent
|
|
182
214
|
// and best-effort — first run absorbs the existing decisions table into
|
|
@@ -210,8 +242,8 @@ async function runKnowledgeMemoryBackfill(
|
|
|
210
242
|
}
|
|
211
243
|
}
|
|
212
244
|
|
|
213
|
-
function scheduleDeferredContextMaintenance(basePath: string): void {
|
|
214
|
-
if (
|
|
245
|
+
function scheduleDeferredContextMaintenance(basePath: string, maintenanceKey: string): void {
|
|
246
|
+
if (deferredContextMaintenanceBySession.has(maintenanceKey)) return;
|
|
215
247
|
|
|
216
248
|
const task = new Promise<void>((resolve) => {
|
|
217
249
|
setTimeout(() => {
|
|
@@ -219,10 +251,10 @@ function scheduleDeferredContextMaintenance(basePath: string): void {
|
|
|
219
251
|
}, 0);
|
|
220
252
|
});
|
|
221
253
|
|
|
222
|
-
|
|
254
|
+
deferredContextMaintenanceBySession.set(maintenanceKey, task);
|
|
223
255
|
void task.finally(() => {
|
|
224
|
-
if (
|
|
225
|
-
|
|
256
|
+
if (deferredContextMaintenanceBySession.get(maintenanceKey) === task) {
|
|
257
|
+
deferredContextMaintenanceBySession.delete(maintenanceKey);
|
|
226
258
|
}
|
|
227
259
|
});
|
|
228
260
|
}
|
|
@@ -257,8 +289,10 @@ async function reportConsolidationGapsDeferred(basePath: string): Promise<void>
|
|
|
257
289
|
|
|
258
290
|
export async function _flushDeferredContextMaintenanceForTest(basePath?: string): Promise<void> {
|
|
259
291
|
const tasks = basePath
|
|
260
|
-
? [
|
|
261
|
-
|
|
292
|
+
? [...deferredContextMaintenanceBySession.entries()]
|
|
293
|
+
.filter(([key]) => key.startsWith(`${basePath}${CONTEXT_MAINTENANCE_KEY_SEPARATOR}`))
|
|
294
|
+
.map(([, task]) => task)
|
|
295
|
+
: [...deferredContextMaintenanceBySession.values()];
|
|
262
296
|
await Promise.allSettled(tasks);
|
|
263
297
|
}
|
|
264
298
|
|
|
@@ -1,18 +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.
|
|
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
|
|
19
|
+
* loops where the model attempts the same missing workflow tool through
|
|
20
|
+
* varied surfaces (bash → `node -e` → CLI), each with a different
|
|
21
|
+
* signature, so the identical-args streak never trips, while allowing
|
|
22
|
+
* tool-heavy turns that are making file-mutation progress. Whichever guard
|
|
23
|
+
* trips first blocks.
|
|
13
24
|
*/
|
|
14
25
|
|
|
15
26
|
import { createHash } from "node:crypto";
|
|
27
|
+
import { INHERENTLY_REPEATABLE_TOOL_SET } from "./core-session-tools.js";
|
|
16
28
|
|
|
17
29
|
const MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
|
|
18
30
|
|
|
@@ -20,11 +32,31 @@ const MAX_CONSECUTIVE_IDENTICAL_CALLS = 4;
|
|
|
20
32
|
const STRICT_LOOP_TOOLS = new Set(["ask_user_questions"]);
|
|
21
33
|
const MAX_CONSECUTIVE_STRICT = 1;
|
|
22
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Per-turn cap on calls to the SAME tool name, regardless of args (#783).
|
|
37
|
+
*
|
|
38
|
+
* General-purpose execution tools are routinely called many times per turn
|
|
39
|
+
* (touching multiple files, running several commands), so they get a higher
|
|
40
|
+
* ceiling. Everything else — workflow one-shot tools (e.g. gsd_complete_milestone)
|
|
41
|
+
* and any non-allowlisted tool — gets the default cap. The default is generous
|
|
42
|
+
* enough to absorb legitimate retries but catches the reported improvisation
|
|
43
|
+
* loop (~51 calls) well before a cost spike.
|
|
44
|
+
*/
|
|
45
|
+
const PER_TOOL_DEFAULT_CAP = 6;
|
|
46
|
+
const PER_TOOL_REPEATABLE_CAP = 15;
|
|
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"]);
|
|
49
|
+
|
|
23
50
|
let consecutiveCount = 0;
|
|
24
51
|
let lastSignature = "";
|
|
25
52
|
let lastToolName = "";
|
|
26
53
|
let enabled = true;
|
|
27
54
|
|
|
55
|
+
/** Per-tool-name call counts within the current turn (#783 Brief C). */
|
|
56
|
+
const perToolCounts = new Map<string, number>();
|
|
57
|
+
let mutationEpoch = 0;
|
|
58
|
+
const perToolLastMutationEpoch = new Map<string, number>();
|
|
59
|
+
|
|
28
60
|
/** Hash tool name + args into a compact signature for comparison. */
|
|
29
61
|
function hashToolCall(toolName: string, args: Record<string, unknown>): string {
|
|
30
62
|
const h = createHash("sha256");
|
|
@@ -46,6 +78,13 @@ function hashToolCall(toolName: string, args: Record<string, unknown>): string {
|
|
|
46
78
|
*
|
|
47
79
|
* Returns `{ block: false }` for allowed calls.
|
|
48
80
|
* Returns `{ block: true, reason }` when the loop threshold is exceeded.
|
|
81
|
+
*
|
|
82
|
+
* Two independent guards run; whichever trips first blocks:
|
|
83
|
+
* 1. Identical-signature streak (MAX_CONSECUTIVE_IDENTICAL_CALLS, strict for
|
|
84
|
+
* ask_user_questions).
|
|
85
|
+
* 2. Per-tool-name cap (PER_TOOL_DEFAULT_CAP / PER_TOOL_REPEATABLE_CAP),
|
|
86
|
+
* independent of args, reset after file-mutation progress — catches
|
|
87
|
+
* improvisation loops (#783).
|
|
49
88
|
*/
|
|
50
89
|
export function checkToolCallLoop(
|
|
51
90
|
toolName: string,
|
|
@@ -63,6 +102,7 @@ export function checkToolCallLoop(
|
|
|
63
102
|
lastToolName = toolName;
|
|
64
103
|
}
|
|
65
104
|
|
|
105
|
+
// ── Guard 1: identical-signature streak ──
|
|
66
106
|
const threshold = STRICT_LOOP_TOOLS.has(toolName)
|
|
67
107
|
? MAX_CONSECUTIVE_STRICT
|
|
68
108
|
: MAX_CONSECUTIVE_IDENTICAL_CALLS;
|
|
@@ -71,22 +111,65 @@ export function checkToolCallLoop(
|
|
|
71
111
|
return {
|
|
72
112
|
block: true,
|
|
73
113
|
reason:
|
|
74
|
-
`Tool loop detected: ${toolName} called ${consecutiveCount} times ` +
|
|
114
|
+
`Tool loop detected (identical args): ${toolName} called ${consecutiveCount} times ` +
|
|
75
115
|
`with identical arguments. Blocking to prevent infinite loop. ` +
|
|
76
|
-
`
|
|
116
|
+
`Do not retry this tool or call other tools this turn — stop and respond to the user in text.`,
|
|
77
117
|
count: consecutiveCount,
|
|
78
118
|
};
|
|
79
119
|
}
|
|
80
120
|
|
|
121
|
+
// ── Guard 2: per-tool-name cap, independent of args (#783 Brief C) ──
|
|
122
|
+
// Catches improvisation loops where the same tool is invoked many times with
|
|
123
|
+
// varied args (e.g. retrying a missing workflow tool via bash/node -e/CLI).
|
|
124
|
+
const priorPerToolCount =
|
|
125
|
+
(perToolLastMutationEpoch.get(toolName) ?? mutationEpoch) < mutationEpoch
|
|
126
|
+
? 0
|
|
127
|
+
: (perToolCounts.get(toolName) ?? 0);
|
|
128
|
+
const perToolCount = priorPerToolCount + 1;
|
|
129
|
+
perToolCounts.set(toolName, perToolCount);
|
|
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)
|
|
139
|
+
? PER_TOOL_REPEATABLE_CAP
|
|
140
|
+
: PER_TOOL_DEFAULT_CAP;
|
|
141
|
+
|
|
142
|
+
if (perToolCount > perToolCap) {
|
|
143
|
+
return {
|
|
144
|
+
block: true,
|
|
145
|
+
reason:
|
|
146
|
+
`Tool loop detected (repeated tool): ${toolName} called ${perToolCount} times ` +
|
|
147
|
+
`this turn (cap ${perToolCap}). Blocking to prevent infinite loop. ` +
|
|
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.`,
|
|
150
|
+
count: perToolCount,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
81
154
|
return { block: false, count: consecutiveCount };
|
|
82
155
|
}
|
|
83
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
|
+
|
|
84
164
|
/** Reset the guard state. Call at agent turn boundaries. */
|
|
85
165
|
export function resetToolCallLoopGuard(): void {
|
|
86
166
|
consecutiveCount = 0;
|
|
87
167
|
lastSignature = "";
|
|
88
168
|
lastToolName = "";
|
|
89
169
|
enabled = true;
|
|
170
|
+
perToolCounts.clear();
|
|
171
|
+
mutationEpoch = 0;
|
|
172
|
+
perToolLastMutationEpoch.clear();
|
|
90
173
|
}
|
|
91
174
|
|
|
92
175
|
/** Disable the guard (e.g. during shutdown). */
|
|
@@ -95,9 +178,20 @@ export function disableToolCallLoopGuard(): void {
|
|
|
95
178
|
consecutiveCount = 0;
|
|
96
179
|
lastSignature = "";
|
|
97
180
|
lastToolName = "";
|
|
181
|
+
perToolCounts.clear();
|
|
182
|
+
mutationEpoch = 0;
|
|
183
|
+
perToolLastMutationEpoch.clear();
|
|
98
184
|
}
|
|
99
185
|
|
|
100
186
|
/** Get current consecutive count for diagnostics. */
|
|
101
187
|
export function getToolCallLoopCount(): number {
|
|
102
188
|
return consecutiveCount;
|
|
103
189
|
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get the per-tool-name call count for the current turn (#783 Brief C).
|
|
193
|
+
* Returns 0 for tools not yet called. Diagnostic only.
|
|
194
|
+
*/
|
|
195
|
+
export function getToolCallCountForTool(toolName: string): number {
|
|
196
|
+
return perToolCounts.get(toolName) ?? 0;
|
|
197
|
+
}
|
|
@@ -180,7 +180,7 @@ function ensureWriteGateSnapshotDirectory(basePath: string): void {
|
|
|
180
180
|
mkdirSync(join(gsdPath, "runtime"), { recursive: true });
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
-
function currentWriteGateSnapshot(basePath: string = process.cwd()): WriteGateSnapshot {
|
|
183
|
+
export function currentWriteGateSnapshot(basePath: string = process.cwd()): WriteGateSnapshot {
|
|
184
184
|
const state = getWriteGateState(basePath);
|
|
185
185
|
return {
|
|
186
186
|
verifiedDepthMilestones: [...state.verifiedDepthMilestones].sort(),
|
|
@@ -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",
|
|
@@ -11,6 +11,7 @@ import { formatPercent, formatTokenCount } from "./metrics.js";
|
|
|
11
11
|
import { countTokensSync, type TokenProvider } from "./token-counter.js";
|
|
12
12
|
import { writeContextChartHtml } from "./context-chart-html.js";
|
|
13
13
|
import { openInBrowser } from "./export.js";
|
|
14
|
+
import { truncateWithEllipsis } from "../shared/format-utils.js";
|
|
14
15
|
|
|
15
16
|
export interface ContextSectionBreakdown {
|
|
16
17
|
label: string;
|
|
@@ -34,6 +35,7 @@ export interface ContextBreakdownReport {
|
|
|
34
35
|
subagentSpawns: number;
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
const REDACTED_TOOL_ARGUMENT_KEYS = new Set(["content", "oldText", "newText"]);
|
|
37
39
|
|
|
38
40
|
function resolveProvider(provider: string | undefined): TokenProvider {
|
|
39
41
|
const normalized = (provider ?? "unknown").toLowerCase();
|
|
@@ -206,6 +208,21 @@ export function parseSystemPromptSections(systemPrompt: string, provider: TokenP
|
|
|
206
208
|
return sections;
|
|
207
209
|
}
|
|
208
210
|
|
|
211
|
+
function redactToolCallArguments(value: unknown): unknown {
|
|
212
|
+
if (Array.isArray(value)) return value.map(redactToolCallArguments);
|
|
213
|
+
if (!value || typeof value !== "object") return value;
|
|
214
|
+
|
|
215
|
+
const safe: Record<string, unknown> = {};
|
|
216
|
+
for (const [key, child] of Object.entries(value)) {
|
|
217
|
+
if (REDACTED_TOOL_ARGUMENT_KEYS.has(key)) {
|
|
218
|
+
safe[key] = typeof child === "string" ? truncateWithEllipsis(child, 101) : "[redacted]";
|
|
219
|
+
} else {
|
|
220
|
+
safe[key] = redactToolCallArguments(child);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return safe;
|
|
224
|
+
}
|
|
225
|
+
|
|
209
226
|
function messageToText(message: SessionMessageEntry["message"]): string {
|
|
210
227
|
const role = message.role;
|
|
211
228
|
|
|
@@ -220,7 +237,7 @@ function messageToText(message: SessionMessageEntry["message"]): string {
|
|
|
220
237
|
if (typed.type === "thinking" && typed.thinking) parts.push(typed.thinking);
|
|
221
238
|
if (typed.type === "toolCall") {
|
|
222
239
|
parts.push(typed.name ?? "tool");
|
|
223
|
-
parts.push(JSON.stringify(typed.arguments ?? {}));
|
|
240
|
+
parts.push(JSON.stringify(redactToolCallArguments(typed.arguments ?? {})));
|
|
224
241
|
}
|
|
225
242
|
}
|
|
226
243
|
}
|
|
@@ -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");
|
|
@@ -1724,17 +1724,22 @@ export function serializePreferencesToFrontmatter(prefs: Record<string, unknown>
|
|
|
1724
1724
|
const entries = Object.entries(item as Record<string, unknown>);
|
|
1725
1725
|
if (entries.length > 0) {
|
|
1726
1726
|
const [firstKey, firstVal] = entries[0];
|
|
1727
|
-
|
|
1727
|
+
if (Array.isArray(firstVal)) {
|
|
1728
|
+
lines.push(`${prefix} - ${firstKey}:`);
|
|
1729
|
+
for (const arrItem of firstVal) {
|
|
1730
|
+
lines.push(`${prefix} - ${yamlSafeString(arrItem)}`);
|
|
1731
|
+
}
|
|
1732
|
+
} else if (typeof firstVal === "object" && firstVal !== null) {
|
|
1733
|
+
lines.push(`${prefix} - ${firstKey}:`);
|
|
1734
|
+
for (const [k, v] of Object.entries(firstVal as Record<string, unknown>)) {
|
|
1735
|
+
serializeValue(k, v, indent + 3);
|
|
1736
|
+
}
|
|
1737
|
+
} else {
|
|
1738
|
+
lines.push(`${prefix} - ${firstKey}: ${yamlSafeString(firstVal)}`);
|
|
1739
|
+
}
|
|
1728
1740
|
for (let i = 1; i < entries.length; i++) {
|
|
1729
1741
|
const [k, v] = entries[i];
|
|
1730
|
-
|
|
1731
|
-
lines.push(`${prefix} ${k}:`);
|
|
1732
|
-
for (const arrItem of v) {
|
|
1733
|
-
lines.push(`${prefix} - ${yamlSafeString(arrItem)}`);
|
|
1734
|
-
}
|
|
1735
|
-
} else {
|
|
1736
|
-
lines.push(`${prefix} ${k}: ${yamlSafeString(v)}`);
|
|
1737
|
-
}
|
|
1742
|
+
serializeValue(k, v, indent + 2);
|
|
1738
1743
|
}
|
|
1739
1744
|
}
|
|
1740
1745
|
} else {
|
|
@@ -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;
|
|
@@ -42,9 +42,9 @@ export interface WorktreeStatus {
|
|
|
42
42
|
|
|
43
43
|
// ─── Status helper ─────────────────────────────────────────────────────────
|
|
44
44
|
|
|
45
|
-
function getStatus(basePath: string, name: string, wtPath: string): WorktreeStatus {
|
|
46
|
-
const diff = diffWorktreeAll(basePath, name);
|
|
47
|
-
const numstat = diffWorktreeNumstat(basePath, name);
|
|
45
|
+
function getStatus(basePath: string, name: string, wtPath: string, mainBranch: string): WorktreeStatus {
|
|
46
|
+
const diff = diffWorktreeAll(basePath, name, undefined, mainBranch);
|
|
47
|
+
const numstat = diffWorktreeNumstat(basePath, name, undefined, mainBranch);
|
|
48
48
|
const filesChanged = diff.added.length + diff.modified.length + diff.removed.length;
|
|
49
49
|
let linesAdded = 0;
|
|
50
50
|
let linesRemoved = 0;
|
|
@@ -62,8 +62,7 @@ function getStatus(basePath: string, name: string, wtPath: string): WorktreeStat
|
|
|
62
62
|
|
|
63
63
|
let commits = 0;
|
|
64
64
|
try {
|
|
65
|
-
|
|
66
|
-
commits = nativeCommitCountBetween(basePath, main, worktreeBranchName(name));
|
|
65
|
+
commits = nativeCommitCountBetween(basePath, mainBranch, worktreeBranchName(name));
|
|
67
66
|
} catch {
|
|
68
67
|
// commit count unavailable → leave at 0
|
|
69
68
|
}
|
|
@@ -129,7 +128,8 @@ export function formatCleanKeepReason(status: WorktreeStatus): string {
|
|
|
129
128
|
async function handleList(ctx: ExtensionCommandContext): Promise<void> {
|
|
130
129
|
const basePath = projectRoot();
|
|
131
130
|
const worktrees = listWorktrees(basePath);
|
|
132
|
-
const
|
|
131
|
+
const mainBranch = worktrees.length > 0 ? nativeDetectMainBranch(basePath) : "";
|
|
132
|
+
const statuses = worktrees.map((wt) => getStatus(basePath, wt.name, wt.path, mainBranch));
|
|
133
133
|
ctx.ui.notify(formatWorktreeList(statuses), "info");
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -161,7 +161,8 @@ async function handleMerge(args: string, ctx: ExtensionCommandContext): Promise<
|
|
|
161
161
|
return;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
const
|
|
164
|
+
const mainBranch = nativeDetectMainBranch(basePath);
|
|
165
|
+
const status = getStatus(basePath, target, wt.path, mainBranch);
|
|
165
166
|
if (status.filesChanged === 0 && !status.uncommitted) {
|
|
166
167
|
try {
|
|
167
168
|
removeWorktree(basePath, target, { deleteBranch: true });
|
|
@@ -194,7 +195,6 @@ async function handleMerge(args: string, ctx: ExtensionCommandContext): Promise<
|
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
const commitType = inferCommitType(target);
|
|
197
|
-
const mainBranch = nativeDetectMainBranch(basePath);
|
|
198
198
|
const commitMessage = `${commitType}: merge worktree ${target}\n\nGSD-Worktree: ${target}`;
|
|
199
199
|
|
|
200
200
|
try {
|
|
@@ -250,8 +250,9 @@ async function handleClean(ctx: ExtensionCommandContext): Promise<void> {
|
|
|
250
250
|
|
|
251
251
|
const removed: string[] = [];
|
|
252
252
|
const kept: string[] = [];
|
|
253
|
+
const mainBranch = nativeDetectMainBranch(basePath);
|
|
253
254
|
for (const wt of worktrees) {
|
|
254
|
-
const status = getStatus(basePath, wt.name, wt.path);
|
|
255
|
+
const status = getStatus(basePath, wt.name, wt.path, mainBranch);
|
|
255
256
|
if (status.filesChanged === 0 && !status.uncommitted) {
|
|
256
257
|
try {
|
|
257
258
|
removeWorktree(basePath, wt.name, { deleteBranch: true });
|
|
@@ -298,7 +299,8 @@ async function handleRemove(args: string, ctx: ExtensionCommandContext): Promise
|
|
|
298
299
|
return;
|
|
299
300
|
}
|
|
300
301
|
|
|
301
|
-
const
|
|
302
|
+
const mainBranch = nativeDetectMainBranch(basePath);
|
|
303
|
+
const status = getStatus(basePath, name, wt.path, mainBranch);
|
|
302
304
|
if ((status.filesChanged > 0 || status.uncommitted) && !force) {
|
|
303
305
|
ctx.ui.notify(
|
|
304
306
|
[
|
|
@@ -29,7 +29,7 @@ import { getWorkerBatches, hasActiveWorkers, type WorkerEntry } from "../subagen
|
|
|
29
29
|
import { formatDuration, padRight, joinColumns, centerLine, fitColumns, STATUS_GLYPH, STATUS_COLOR } from "../shared/mod.js";
|
|
30
30
|
import { estimateTimeRemaining } from "./auto-dashboard.js";
|
|
31
31
|
import { computeProgressScore, formatProgressLine } from "./progress-score.js";
|
|
32
|
-
import {
|
|
32
|
+
import { runEnvironmentChecksAsync, type EnvironmentCheckResult } from "./doctor-environment.js";
|
|
33
33
|
import { formattedShortcutPair } from "./shortcut-defs.js";
|
|
34
34
|
import { renderDialogFrame, renderKeyHints } from "./tui/render-kit.js";
|
|
35
35
|
|
|
@@ -71,6 +71,9 @@ export class GSDDashboardOverlay {
|
|
|
71
71
|
private loading = true;
|
|
72
72
|
private loadedDashboardIdentity?: string;
|
|
73
73
|
private refreshInFlight: Promise<void> | null = null;
|
|
74
|
+
private envRefreshInFlight: Promise<void> | null = null;
|
|
75
|
+
private cachedEnvBasePath?: string;
|
|
76
|
+
private cachedEnvIssues: EnvironmentCheckResult[] = [];
|
|
74
77
|
private disposed = false;
|
|
75
78
|
private resizeHandler: (() => void) | null = null;
|
|
76
79
|
private cachedMetrics: {
|
|
@@ -181,12 +184,39 @@ export class GSDDashboardOverlay {
|
|
|
181
184
|
this.loading = false;
|
|
182
185
|
}
|
|
183
186
|
|
|
187
|
+
this.scheduleEnvironmentRefresh(this.dashData.basePath || process.cwd());
|
|
188
|
+
|
|
184
189
|
if (identityChanged) {
|
|
185
190
|
this.invalidate();
|
|
186
191
|
}
|
|
187
192
|
this.tui.requestRender();
|
|
188
193
|
}
|
|
189
194
|
|
|
195
|
+
private scheduleEnvironmentRefresh(basePath: string): void {
|
|
196
|
+
if (this.cachedEnvBasePath !== basePath) {
|
|
197
|
+
this.cachedEnvBasePath = basePath;
|
|
198
|
+
this.cachedEnvIssues = [];
|
|
199
|
+
this.invalidate();
|
|
200
|
+
}
|
|
201
|
+
if (this.envRefreshInFlight || this.disposed) return;
|
|
202
|
+
this.envRefreshInFlight = this.refreshEnvironmentHealth(basePath)
|
|
203
|
+
.finally(() => {
|
|
204
|
+
this.envRefreshInFlight = null;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private async refreshEnvironmentHealth(basePath: string): Promise<void> {
|
|
209
|
+
try {
|
|
210
|
+
const envResults = await runEnvironmentChecksAsync(basePath);
|
|
211
|
+
if (this.disposed || this.cachedEnvBasePath !== basePath) return;
|
|
212
|
+
this.cachedEnvIssues = envResults.filter(r => r.status !== "ok");
|
|
213
|
+
this.invalidate();
|
|
214
|
+
this.tui.requestRender();
|
|
215
|
+
} catch {
|
|
216
|
+
// Non-fatal — keep last known environment issues
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
190
220
|
private async loadData(): Promise<boolean> {
|
|
191
221
|
const base = this.dashData.basePath || process.cwd();
|
|
192
222
|
try {
|
|
@@ -629,8 +659,7 @@ export class GSDDashboardOverlay {
|
|
|
629
659
|
}
|
|
630
660
|
|
|
631
661
|
// Environment health section (#1221) — only show issues
|
|
632
|
-
const
|
|
633
|
-
const envIssues = envResults.filter(r => r.status !== "ok");
|
|
662
|
+
const envIssues = this.cachedEnvIssues;
|
|
634
663
|
if (envIssues.length > 0) {
|
|
635
664
|
lines.push(blank());
|
|
636
665
|
lines.push(hr());
|
|
@@ -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 {
|