gsd-pi 2.80.0-dev.fbe7c8c6f → 2.81.0-dev.3cddbbba2
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 +47 -59
- package/dist/claude-cli-check.d.ts +30 -0
- package/dist/claude-cli-check.js +18 -7
- package/dist/cli.js +0 -19
- package/dist/headless-query.d.ts +10 -0
- package/dist/headless-query.js +6 -4
- package/dist/loader-entrypoint.d.ts +8 -0
- package/dist/loader-entrypoint.js +27 -0
- package/dist/loader.js +2 -11
- package/dist/mcp-server.d.ts +1 -0
- package/dist/mcp-server.js +6 -3
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +40 -3
- package/dist/resources/extensions/github-sync/sync.js +4 -1
- package/dist/resources/extensions/gsd/auto/contracts.js +2 -0
- package/dist/resources/extensions/gsd/auto/loop.js +214 -17
- package/dist/resources/extensions/gsd/auto/orchestrator.js +48 -4
- package/dist/resources/extensions/gsd/auto/phases.js +372 -134
- package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
- package/dist/resources/extensions/gsd/auto/run-unit.js +88 -33
- package/dist/resources/extensions/gsd/auto/session.js +18 -1
- package/dist/resources/extensions/gsd/auto/unit-runner-events.js +7 -0
- package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +43 -0
- package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
- package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
- package/dist/resources/extensions/gsd/auto-dashboard.js +199 -177
- package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
- package/dist/resources/extensions/gsd/auto-dispatch.js +30 -11
- package/dist/resources/extensions/gsd/auto-post-unit.js +119 -79
- package/dist/resources/extensions/gsd/auto-prompts.js +103 -16
- package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
- package/dist/resources/extensions/gsd/auto-runtime-state.js +5 -0
- package/dist/resources/extensions/gsd/auto-start.js +251 -16
- package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
- package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +33 -5
- package/dist/resources/extensions/gsd/auto-verification.js +12 -6
- package/dist/resources/extensions/gsd/auto-worktree.js +237 -336
- package/dist/resources/extensions/gsd/auto.js +493 -129
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +133 -12
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +44 -37
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -10
- package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +30 -20
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +4 -1
- package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +6 -4
- package/dist/resources/extensions/gsd/bootstrap/query-tools.js +5 -3
- package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +337 -55
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +4 -8
- package/dist/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.js +4 -0
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +19 -2
- package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +4 -10
- package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
- package/dist/resources/extensions/gsd/commands-config.js +1 -1
- package/dist/resources/extensions/gsd/commands-eval-review.js +2 -2
- package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
- package/dist/resources/extensions/gsd/context-budget.js +37 -2
- package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
- package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
- package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
- package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
- package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
- package/dist/resources/extensions/gsd/git-service.js +75 -6
- package/dist/resources/extensions/gsd/gsd-db.js +46 -13
- package/dist/resources/extensions/gsd/guided-flow.js +119 -42
- package/dist/resources/extensions/gsd/health-widget-core.js +1 -1
- package/dist/resources/extensions/gsd/health-widget.js +6 -9
- package/dist/resources/extensions/gsd/init-wizard.js +4 -1
- package/dist/resources/extensions/gsd/memory-store.js +69 -12
- package/dist/resources/extensions/gsd/migrate/command.js +40 -1
- package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +46 -22
- package/dist/resources/extensions/gsd/notification-overlay.js +35 -40
- package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
- package/dist/resources/extensions/gsd/parallel-merge.js +53 -30
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +25 -33
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
- package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
- package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
- package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +22 -17
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +20 -2
- package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/dist/resources/extensions/gsd/quick.js +34 -2
- package/dist/resources/extensions/gsd/recovery-classification.js +94 -0
- package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
- package/dist/resources/extensions/gsd/state-reconciliation.js +27 -0
- package/dist/resources/extensions/gsd/tool-contract.js +50 -0
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -7
- package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
- package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
- package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
- package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
- package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
- package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
- package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
- package/dist/resources/extensions/gsd/tui/render-kit.js +74 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
- package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
- package/dist/resources/extensions/gsd/watch/header-renderer.js +92 -69
- package/dist/resources/extensions/gsd/watch/splash-palette.js +10 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
- package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
- package/dist/resources/extensions/gsd/worktree-lifecycle.js +1364 -0
- package/dist/resources/extensions/gsd/worktree-safety.js +119 -0
- package/dist/resources/extensions/gsd/worktree-state-projection.js +317 -0
- package/dist/resources/extensions/gsd/worktree-telemetry.js +3 -1
- package/dist/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
- 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 +13 -13
- 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 +2 -2
- 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/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 +13 -13
- 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/8359.e059d86b255fce1c.js +10 -0
- package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
- package/dist/welcome-screen.d.ts +2 -7
- package/dist/welcome-screen.js +68 -75
- package/package.json +3 -3
- package/packages/daemon/package.json +2 -2
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -17
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
- package/packages/mcp-server/src/workflow-tools.ts +30 -16
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +1 -1
- package/packages/native/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +4 -1
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/dist/agent.d.ts +9 -2
- package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/agent.js +43 -11
- package/packages/pi-agent-core/dist/agent.js.map +1 -1
- package/packages/pi-agent-core/dist/index.d.ts +1 -0
- package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/index.js +2 -0
- package/packages/pi-agent-core/dist/index.js.map +1 -1
- package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
- package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
- package/packages/pi-agent-core/dist/token-audit.js +221 -0
- package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
- package/packages/pi-agent-core/dist/types.d.ts +31 -0
- package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
- package/packages/pi-agent-core/dist/types.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
- package/packages/pi-agent-core/src/agent-loop.ts +4 -1
- package/packages/pi-agent-core/src/agent.ts +52 -11
- package/packages/pi-agent-core/src/index.ts +2 -0
- package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
- package/packages/pi-agent-core/src/token-audit.ts +287 -0
- package/packages/pi-agent-core/src/types.ts +26 -10
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
- package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +9 -7
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
- package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +2 -0
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
- package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
- package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
- package/packages/pi-ai/src/providers/anthropic.ts +22 -9
- package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
- package/packages/pi-ai/src/types.ts +3 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
- package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
- package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +36 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +30 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts +21 -2
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +94 -16
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +6 -2
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
- package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
- package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
- package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +6 -6
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +5 -3
- package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +60 -4
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
- package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
- package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +81 -4
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
- package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
- package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
- package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
- package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
- package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
- package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
- package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
- package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
- package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
- package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
- package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
- package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
- package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
- package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js +47 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/assistant-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +161 -7
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js +40 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/user-message-design.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +0 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +30 -29
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +10 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js +13 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts +1 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js +58 -3
- package/packages/pi-coding-agent/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts +2 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js +12 -6
- package/packages/pi-coding-agent/dist/modes/interactive/components/diff.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -41
- package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +25 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +225 -73
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts +35 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js +152 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/transcript-design.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts +16 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js +73 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tui-style-kit.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js +12 -8
- package/packages/pi-coding-agent/dist/modes/interactive/components/user-message.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +31 -6
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +25 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +105 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +27 -26
- package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +9 -6
- package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
- package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +40 -1
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +40 -1
- package/packages/pi-coding-agent/src/core/agent-session.ts +102 -16
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +6 -2
- package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
- package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
- package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
- package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +5 -3
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +8 -5
- package/packages/pi-coding-agent/src/core/extensions/types.ts +63 -2
- package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
- package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +92 -4
- package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
- package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
- package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
- package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
- package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
- package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
- package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
- package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
- package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
- package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
- package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
- package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
- package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/assistant-message-design.test.ts +56 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +228 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/user-message-design.test.ts +48 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +10 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +43 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +14 -14
- package/packages/pi-coding-agent/src/modes/interactive/components/bash-execution.ts +64 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/diff.ts +13 -7
- package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +15 -42
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +31 -1
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +247 -94
- package/packages/pi-coding-agent/src/modes/interactive/components/transcript-design.ts +196 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tui-style-kit.ts +94 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/user-message.ts +14 -9
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +39 -8
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +27 -3
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme-highlight.test.ts +23 -0
- package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +106 -1
- package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +27 -26
- package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +9 -6
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
- package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +14 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.d.ts.map +1 -1
- package/packages/pi-tui/dist/overlay-layout.js +9 -6
- package/packages/pi-tui/dist/overlay-layout.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +18 -8
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +20 -1
- package/packages/pi-tui/src/overlay-layout.ts +10 -7
- package/packages/pi-tui/src/tui.ts +20 -8
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/README.md +7 -0
- package/packages/rpc-client/package.json +1 -1
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts +2 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.d.ts.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js +17 -0
- package/pkg/dist/modes/interactive/theme/theme-highlight.test.js.map +1 -0
- package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/theme.js +105 -1
- package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
- package/pkg/dist/modes/interactive/theme/themes.js +27 -26
- package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +42 -3
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +67 -0
- package/src/resources/extensions/github-sync/sync.ts +8 -1
- package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
- package/src/resources/extensions/gsd/auto/contracts.ts +19 -2
- package/src/resources/extensions/gsd/auto/loop-deps.ts +19 -16
- package/src/resources/extensions/gsd/auto/loop.ts +247 -25
- package/src/resources/extensions/gsd/auto/orchestrator.ts +52 -4
- package/src/resources/extensions/gsd/auto/phases.ts +512 -202
- package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
- package/src/resources/extensions/gsd/auto/run-unit.ts +97 -34
- package/src/resources/extensions/gsd/auto/session.ts +19 -1
- package/src/resources/extensions/gsd/auto/types.ts +3 -0
- package/src/resources/extensions/gsd/auto/unit-runner-events.ts +15 -0
- package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +82 -0
- package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
- package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
- package/src/resources/extensions/gsd/auto-dashboard.ts +249 -182
- package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
- package/src/resources/extensions/gsd/auto-dispatch.ts +31 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +131 -81
- package/src/resources/extensions/gsd/auto-prompts.ts +112 -15
- package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
- package/src/resources/extensions/gsd/auto-runtime-state.ts +5 -0
- package/src/resources/extensions/gsd/auto-start.ts +321 -21
- package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
- package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +51 -0
- package/src/resources/extensions/gsd/auto-verification.ts +12 -6
- package/src/resources/extensions/gsd/auto-worktree.ts +267 -360
- package/src/resources/extensions/gsd/auto.ts +578 -126
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +166 -12
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +45 -37
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +36 -10
- package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +32 -19
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +5 -1
- package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +7 -4
- package/src/resources/extensions/gsd/bootstrap/query-tools.ts +6 -3
- package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +384 -55
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +5 -8
- package/src/resources/extensions/gsd/bootstrap/sanitize-complete-milestone.ts +4 -0
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -2
- package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +4 -10
- package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
- package/src/resources/extensions/gsd/commands-config.ts +1 -1
- package/src/resources/extensions/gsd/commands-eval-review.ts +2 -2
- package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
- package/src/resources/extensions/gsd/context-budget.ts +44 -2
- package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
- package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
- package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
- package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
- package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
- package/src/resources/extensions/gsd/git-service.ts +89 -10
- package/src/resources/extensions/gsd/gsd-db.ts +50 -13
- package/src/resources/extensions/gsd/guided-flow.ts +148 -49
- package/src/resources/extensions/gsd/health-widget-core.ts +1 -1
- package/src/resources/extensions/gsd/health-widget.ts +8 -9
- package/src/resources/extensions/gsd/init-wizard.ts +5 -1
- package/src/resources/extensions/gsd/journal.ts +2 -0
- package/src/resources/extensions/gsd/memory-store.ts +77 -12
- package/src/resources/extensions/gsd/migrate/command.ts +47 -1
- package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +53 -19
- package/src/resources/extensions/gsd/notification-overlay.ts +50 -46
- package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
- package/src/resources/extensions/gsd/parallel-merge.ts +61 -34
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +33 -35
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
- package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
- package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
- package/src/resources/extensions/gsd/preferences-types.ts +1 -1
- package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +22 -17
- package/src/resources/extensions/gsd/prompts/complete-slice.md +14 -12
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +20 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +20 -2
- package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
- package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
- package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
- package/src/resources/extensions/gsd/quick.ts +37 -2
- package/src/resources/extensions/gsd/recovery-classification.ts +122 -0
- package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
- package/src/resources/extensions/gsd/state-reconciliation.ts +57 -0
- package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
- package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +134 -9
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +1125 -215
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +119 -2
- package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +363 -18
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +175 -11
- package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
- package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
- package/src/resources/extensions/gsd/tests/auto-runtime-state.test.ts +16 -1
- package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
- package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
- package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +160 -0
- package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
- package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +68 -0
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
- package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
- package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
- package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
- package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
- package/src/resources/extensions/gsd/tests/cmux.test.ts +51 -53
- package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
- package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
- package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
- package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
- package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
- package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
- package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +46 -11
- package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
- package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +24 -11
- package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
- package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +100 -38
- package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
- package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
- package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
- package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
- package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
- package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
- package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +151 -0
- package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
- package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
- package/src/resources/extensions/gsd/tests/header-renderer.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +10 -0
- package/src/resources/extensions/gsd/tests/health-widget.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
- package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +116 -24
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
- package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +248 -11
- package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
- package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
- package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +77 -12
- package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
- package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +267 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +88 -98
- package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
- package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
- package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
- package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +78 -41
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +12 -182
- package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +144 -0
- package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +38 -6
- package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
- package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +95 -75
- package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
- package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
- package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
- package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +74 -4
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
- package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
- package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
- package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
- package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -1
- package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
- package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
- package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
- package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
- package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
- package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
- package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +36 -164
- package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +91 -0
- package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
- package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
- package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +222 -0
- package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
- package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
- package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
- package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
- package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -77
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
- package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
- package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
- package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +65 -56
- package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
- package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +48 -46
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
- package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +295 -0
- package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
- package/src/resources/extensions/gsd/tests/tui-header-lifecycle.test.ts +330 -0
- package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
- package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
- package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
- package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
- package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +83 -0
- package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
- package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
- package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +8 -57
- package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
- package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
- package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +14 -13
- package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +197 -78
- package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +888 -0
- package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
- package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +327 -0
- package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +120 -0
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +40 -1
- package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
- package/src/resources/extensions/gsd/tool-contract.ts +82 -0
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +14 -15
- package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
- package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
- package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
- package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
- package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
- package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
- package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
- package/src/resources/extensions/gsd/tui/render-kit.ts +109 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
- package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
- package/src/resources/extensions/gsd/watch/header-renderer.ts +121 -79
- package/src/resources/extensions/gsd/watch/splash-palette.ts +11 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
- package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
- package/src/resources/extensions/gsd/worktree-lifecycle.ts +1882 -0
- package/src/resources/extensions/gsd/worktree-safety.ts +282 -0
- package/src/resources/extensions/gsd/worktree-state-projection.ts +404 -0
- package/src/resources/extensions/gsd/worktree-telemetry.ts +7 -2
- package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
- package/src/resources/skills/web-quality-audit/scripts/analyze.sh +0 -0
- package/dist/resources/extensions/gsd/worktree-resolver.js +0 -733
- package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
- package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +0 -434
- package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +0 -1247
- package/src/resources/extensions/gsd/worktree-resolver.ts +0 -909
- /package/dist/web/standalone/.next/static/{yTuahMMuJzVnsov5PreWl → F5x9E6H9k_52fjqyql93y}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{yTuahMMuJzVnsov5PreWl → F5x9E6H9k_52fjqyql93y}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../../src/resources/extensions/memory/storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SQLite storage for the memory extraction pipeline.\n *\n * Tables:\n * - threads: tracks session files and their processing state\n * - stage1_outputs: stores per-thread extraction results\n * - jobs: lease-based job queue for pipeline phases\n */\n\nimport initSqlJs, { type Database as SqlJsDatabase } from \"sql.js\";\nimport { randomUUID } from \"crypto\";\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname } from \"path\";\n\nexport interface ThreadRow {\n\tthread_id: string;\n\tfile_path: string;\n\tfile_size: number;\n\tfile_mtime: number;\n\tcwd: string;\n\tstatus: \"pending\" | \"processing\" | \"done\" | \"error\";\n\terror_message: string | null;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\nexport interface Stage1OutputRow {\n\tthread_id: string;\n\textraction_json: string;\n\tcreated_at: string;\n}\n\nexport interface JobRow {\n\tid: string;\n\tphase: \"stage1\" | \"stage2\";\n\tthread_id: string | null;\n\tstatus: \"pending\" | \"claimed\" | \"done\" | \"error\";\n\tworker_id: string | null;\n\townership_token: string | null;\n\tlease_expires_at: string | null;\n\terror_message: string | null;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\nexport class MemoryStorage {\n\tprivate db: SqlJsDatabase;\n\tprivate dbPath: string;\n\tprivate persistTimer: ReturnType<typeof setTimeout> | null = null;\n\n\tprivate constructor(db: SqlJsDatabase, dbPath: string) {\n\t\tthis.db = db;\n\t\tthis.dbPath = dbPath;\n\t}\n\n\tstatic async create(dbPath: string): Promise<MemoryStorage> {\n\t\tconst dir = dirname(dbPath);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t}\n\n\t\tconst SQL = await initSqlJs();\n\t\tconst buffer = existsSync(dbPath) ? readFileSync(dbPath) : undefined;\n\t\tconst db = buffer ? new SQL.Database(buffer) : new SQL.Database();\n\n\t\tdb.run(\"PRAGMA journal_mode = WAL\");\n\t\tdb.run(\"PRAGMA synchronous = NORMAL\");\n\t\tdb.run(\"PRAGMA busy_timeout = 5000\");\n\n\t\tconst storage = new MemoryStorage(db, dbPath);\n\t\tstorage.initSchema();\n\t\treturn storage;\n\t}\n\n\tprivate persist(): void {\n\t\tconst data = this.db.export();\n\t\twriteFileSync(this.dbPath, Buffer.from(data));\n\t}\n\n\tprivate schedulePersist(): void {\n\t\tif (this.persistTimer) {\n\t\t\tclearTimeout(this.persistTimer);\n\t\t}\n\t\tthis.persistTimer = setTimeout(() => {\n\t\t\tthis.persistTimer = null;\n\t\t\tthis.persist();\n\t\t}, 500);\n\t}\n\n\tprivate initSchema(): void {\n\t\tthis.db.run(`\n\t\t\tCREATE TABLE IF NOT EXISTS threads (\n\t\t\t\tthread_id TEXT PRIMARY KEY,\n\t\t\t\tfile_path TEXT NOT NULL,\n\t\t\t\tfile_size INTEGER NOT NULL DEFAULT 0,\n\t\t\t\tfile_mtime INTEGER NOT NULL DEFAULT 0,\n\t\t\t\tcwd TEXT NOT NULL DEFAULT '',\n\t\t\t\tstatus TEXT NOT NULL DEFAULT 'pending',\n\t\t\t\terror_message TEXT,\n\t\t\t\tcreated_at TEXT NOT NULL DEFAULT (datetime('now')),\n\t\t\t\tupdated_at TEXT NOT NULL DEFAULT (datetime('now'))\n\t\t\t)\n\t\t`);\n\t\tthis.db.run(`\n\t\t\tCREATE TABLE IF NOT EXISTS stage1_outputs (\n\t\t\t\tthread_id TEXT PRIMARY KEY,\n\t\t\t\textraction_json TEXT NOT NULL,\n\t\t\t\tcreated_at TEXT NOT NULL DEFAULT (datetime('now')),\n\t\t\t\tFOREIGN KEY (thread_id) REFERENCES threads(thread_id) ON DELETE CASCADE\n\t\t\t)\n\t\t`);\n\t\tthis.db.run(`\n\t\t\tCREATE TABLE IF NOT EXISTS jobs (\n\t\t\t\tid TEXT PRIMARY KEY,\n\t\t\t\tphase TEXT NOT NULL,\n\t\t\t\tthread_id TEXT,\n\t\t\t\tstatus TEXT NOT NULL DEFAULT 'pending',\n\t\t\t\tworker_id TEXT,\n\t\t\t\townership_token TEXT,\n\t\t\t\tlease_expires_at TEXT,\n\t\t\t\terror_message TEXT,\n\t\t\t\tcreated_at TEXT NOT NULL DEFAULT (datetime('now')),\n\t\t\t\tupdated_at TEXT NOT NULL DEFAULT (datetime('now'))\n\t\t\t)\n\t\t`);\n\t\tthis.db.run(\"CREATE INDEX IF NOT EXISTS idx_jobs_phase_status ON jobs(phase, status)\");\n\t\tthis.db.run(\"CREATE INDEX IF NOT EXISTS idx_threads_status ON threads(status)\");\n\t\tthis.db.run(\"CREATE INDEX IF NOT EXISTS idx_threads_cwd ON threads(cwd)\");\n\t\tthis.persist();\n\t}\n\n\tprivate queryAll<T>(sql: string, params: unknown[] = []): T[] {\n\t\tconst stmt = this.db.prepare(sql);\n\t\tstmt.bind(params as (string | number | null | Uint8Array)[]);\n\t\tconst rows: T[] = [];\n\t\twhile (stmt.step()) {\n\t\t\trows.push(stmt.getAsObject() as T);\n\t\t}\n\t\tstmt.free();\n\t\treturn rows;\n\t}\n\n\tprivate queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n\t\tconst rows = this.queryAll<T>(sql, params);\n\t\treturn rows[0];\n\t}\n\n\t/**\n\t * Insert or update thread records. Skips threads whose file hasn't changed\n\t * (same size + mtime = watermark match).\n\t */\n\tupsertThreads(\n\t\tthreads: Array<{\n\t\t\tthreadId: string;\n\t\t\tfilePath: string;\n\t\t\tfileSize: number;\n\t\t\tfileMtime: number;\n\t\t\tcwd: string;\n\t\t}>,\n\t): { inserted: number; updated: number; skipped: number } {\n\t\tlet inserted = 0;\n\t\tlet updated = 0;\n\t\tlet skipped = 0;\n\n\t\tfor (const t of threads) {\n\t\t\tconst existing = this.queryOne<{ file_size: number; file_mtime: number; status: string }>(\n\t\t\t\t\"SELECT file_size, file_mtime, status FROM threads WHERE thread_id = ?\",\n\t\t\t\t[t.threadId],\n\t\t\t);\n\n\t\t\tif (!existing) {\n\t\t\t\tthis.db.run(\n\t\t\t\t\t\"INSERT INTO threads (thread_id, file_path, file_size, file_mtime, cwd, status) VALUES (?, ?, ?, ?, ?, 'pending')\",\n\t\t\t\t\t[t.threadId, t.filePath, t.fileSize, t.fileMtime, t.cwd],\n\t\t\t\t);\n\t\t\t\tthis.db.run(\n\t\t\t\t\t\"INSERT OR IGNORE INTO jobs (id, phase, thread_id, status) VALUES (?, 'stage1', ?, 'pending')\",\n\t\t\t\t\t[randomUUID(), t.threadId],\n\t\t\t\t);\n\t\t\t\tinserted++;\n\t\t\t} else if (existing.file_size !== t.fileSize || existing.file_mtime !== t.fileMtime) {\n\t\t\t\tthis.db.run(\n\t\t\t\t\t\"UPDATE threads SET file_path = ?, file_size = ?, file_mtime = ?, cwd = ?, status = 'pending', updated_at = datetime('now') WHERE thread_id = ?\",\n\t\t\t\t\t[t.filePath, t.fileSize, t.fileMtime, t.cwd, t.threadId],\n\t\t\t\t);\n\t\t\t\tif (existing.status === \"done\" || existing.status === \"error\") {\n\t\t\t\t\tthis.db.run(\n\t\t\t\t\t\t\"INSERT OR IGNORE INTO jobs (id, phase, thread_id, status) VALUES (?, 'stage1', ?, 'pending')\",\n\t\t\t\t\t\t[randomUUID(), t.threadId],\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tupdated++;\n\t\t\t} else {\n\t\t\t\tskipped++;\n\t\t\t}\n\t\t}\n\n\t\tthis.schedulePersist();\n\t\treturn { inserted, updated, skipped };\n\t}\n\n\t/**\n\t * Claim up to `limit` stage1 jobs for the given worker.\n\t * Uses lease-based ownership with an ownership_token UUID.\n\t */\n\tclaimStage1Jobs(\n\t\tworkerId: string,\n\t\tlimit: number,\n\t\tleaseSeconds: number,\n\t): Array<{ jobId: string; threadId: string; ownershipToken: string }> {\n\t\tconst token = randomUUID();\n\t\tconst expiresAt = new Date(Date.now() + leaseSeconds * 1000).toISOString();\n\n\t\tthis.db.run(\n\t\t\t`UPDATE jobs SET\n\t\t\t\tstatus = 'claimed',\n\t\t\t\tworker_id = ?,\n\t\t\t\townership_token = ?,\n\t\t\t\tlease_expires_at = ?,\n\t\t\t\tupdated_at = datetime('now')\n\t\t\tWHERE id IN (\n\t\t\t\tSELECT id FROM jobs\n\t\t\t\tWHERE phase = 'stage1'\n\t\t\t\t\tAND (status = 'pending' OR (status = 'claimed' AND lease_expires_at < datetime('now')))\n\t\t\t\tLIMIT ?\n\t\t\t)`,\n\t\t\t[workerId, token, expiresAt, limit],\n\t\t);\n\n\t\tconst rows = this.queryAll<{ id: string; thread_id: string }>(\n\t\t\t\"SELECT id, thread_id FROM jobs WHERE ownership_token = ? AND status = 'claimed'\",\n\t\t\t[token],\n\t\t);\n\n\t\tthis.schedulePersist();\n\n\t\treturn rows.map((r) => ({\n\t\t\tjobId: r.id,\n\t\t\tthreadId: r.thread_id,\n\t\t\townershipToken: token,\n\t\t}));\n\t}\n\n\t/**\n\t * Mark a stage1 job as complete and store the extraction output.\n\t */\n\tcompleteStage1Job(threadId: string, output: string): void {\n\t\tthis.db.run(\n\t\t\t\"UPDATE jobs SET status = 'done', updated_at = datetime('now') WHERE thread_id = ? AND phase = 'stage1' AND status = 'claimed'\",\n\t\t\t[threadId],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"INSERT OR REPLACE INTO stage1_outputs (thread_id, extraction_json, created_at) VALUES (?, ?, datetime('now'))\",\n\t\t\t[threadId, output],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"UPDATE threads SET status = 'done', updated_at = datetime('now') WHERE thread_id = ?\",\n\t\t\t[threadId],\n\t\t);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Mark a stage1 job as errored.\n\t */\n\tfailStage1Job(threadId: string, errorMessage: string): void {\n\t\tthis.db.run(\n\t\t\t\"UPDATE jobs SET status = 'error', error_message = ?, updated_at = datetime('now') WHERE thread_id = ? AND phase = 'stage1' AND status = 'claimed'\",\n\t\t\t[errorMessage, threadId],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"UPDATE threads SET status = 'error', error_message = ?, updated_at = datetime('now') WHERE thread_id = ?\",\n\t\t\t[errorMessage, threadId],\n\t\t);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Try to claim the global phase 2 consolidation job.\n\t * Only one worker can hold this at a time.\n\t */\n\ttryClaimGlobalPhase2Job(\n\t\tworkerId: string,\n\t\tleaseSeconds: number,\n\t): { jobId: string; ownershipToken: string } | null {\n\t\tconst token = randomUUID();\n\t\tconst expiresAt = new Date(Date.now() + leaseSeconds * 1000).toISOString();\n\n\t\tconst pendingStage1 = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM jobs WHERE phase = 'stage1' AND status IN ('pending', 'claimed')\",\n\t\t);\n\n\t\tif (pendingStage1 && pendingStage1.cnt > 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst existingPhase2 = this.queryOne<{ id: string }>(\n\t\t\t\"SELECT id FROM jobs WHERE phase = 'stage2' AND status = 'claimed' AND lease_expires_at > datetime('now')\",\n\t\t);\n\n\t\tif (existingPhase2) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst outputCount = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM stage1_outputs\",\n\t\t);\n\n\t\tif (!outputCount || outputCount.cnt === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst jobId = randomUUID();\n\t\tthis.db.run(\n\t\t\t\"INSERT INTO jobs (id, phase, status, worker_id, ownership_token, lease_expires_at) VALUES (?, 'stage2', 'claimed', ?, ?, ?)\",\n\t\t\t[jobId, workerId, token, expiresAt],\n\t\t);\n\n\t\tthis.schedulePersist();\n\t\treturn { jobId, ownershipToken: token };\n\t}\n\n\t/**\n\t * Complete the phase 2 consolidation job.\n\t */\n\tcompletePhase2Job(jobId: string): void {\n\t\tthis.db.run(\n\t\t\t\"UPDATE jobs SET status = 'done', updated_at = datetime('now') WHERE id = ? AND phase = 'stage2'\",\n\t\t\t[jobId],\n\t\t);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Get all stage1 extraction outputs.\n\t */\n\tgetStage1Outputs(): Array<{ threadId: string; extractionJson: string }> {\n\t\tconst rows = this.queryAll<{ thread_id: string; extraction_json: string }>(\n\t\t\t\"SELECT thread_id, extraction_json FROM stage1_outputs\",\n\t\t);\n\n\t\treturn rows.map((r) => ({\n\t\t\tthreadId: r.thread_id,\n\t\t\textractionJson: r.extraction_json,\n\t\t}));\n\t}\n\n\t/**\n\t * Get all stage1 outputs for a specific cwd.\n\t */\n\tgetStage1OutputsForCwd(cwd: string): Array<{ threadId: string; extractionJson: string }> {\n\t\tconst rows = this.queryAll<{ thread_id: string; extraction_json: string }>(\n\t\t\t`SELECT s.thread_id, s.extraction_json FROM stage1_outputs s\n\t\t\tINNER JOIN threads t ON t.thread_id = s.thread_id\n\t\t\tWHERE t.cwd = ?`,\n\t\t\t[cwd],\n\t\t);\n\n\t\treturn rows.map((r) => ({\n\t\t\tthreadId: r.thread_id,\n\t\t\textractionJson: r.extraction_json,\n\t\t}));\n\t}\n\n\t/**\n\t * Get thread info by ID.\n\t */\n\tgetThread(threadId: string): ThreadRow | undefined {\n\t\treturn this.queryOne<ThreadRow>(\n\t\t\t\"SELECT * FROM threads WHERE thread_id = ?\",\n\t\t\t[threadId],\n\t\t);\n\t}\n\n\t/**\n\t * Get pipeline statistics.\n\t */\n\tgetStats(): {\n\t\ttotalThreads: number;\n\t\tpendingThreads: number;\n\t\tdoneThreads: number;\n\t\terrorThreads: number;\n\t\ttotalStage1Outputs: number;\n\t\tpendingStage1Jobs: number;\n\t} {\n\t\tconst threads = this.queryOne<{ total: number; pending: number; done: number; errors: number }>(`\n\t\t\tSELECT\n\t\t\t\tCOUNT(*) as total,\n\t\t\t\tSUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,\n\t\t\t\tSUM(CASE WHEN status = 'done' THEN 1 ELSE 0 END) as done,\n\t\t\t\tSUM(CASE WHEN status = 'error' THEN 1 ELSE 0 END) as errors\n\t\t\tFROM threads\n\t\t`)!;\n\n\t\tconst outputs = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM stage1_outputs\",\n\t\t)!;\n\n\t\tconst pendingJobs = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM jobs WHERE phase = 'stage1' AND status IN ('pending', 'claimed')\",\n\t\t)!;\n\n\t\treturn {\n\t\t\ttotalThreads: threads.total,\n\t\t\tpendingThreads: threads.pending,\n\t\t\tdoneThreads: threads.done,\n\t\t\terrorThreads: threads.errors,\n\t\t\ttotalStage1Outputs: outputs.cnt,\n\t\t\tpendingStage1Jobs: pendingJobs.cnt,\n\t\t};\n\t}\n\n\t/**\n\t * Clear all data (for /memory clear).\n\t */\n\tclearAll(): void {\n\t\tthis.db.run(\"DELETE FROM stage1_outputs\");\n\t\tthis.db.run(\"DELETE FROM jobs\");\n\t\tthis.db.run(\"DELETE FROM threads\");\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Clear data for a specific cwd (for /memory clear in project scope).\n\t */\n\tclearForCwd(cwd: string): void {\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM stage1_outputs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM jobs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\"DELETE FROM threads WHERE cwd = ?\", [cwd]);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Reset all threads to pending (for /memory rebuild).\n\t */\n\tresetAllForCwd(cwd: string): void {\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM stage1_outputs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM jobs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"UPDATE threads SET status = 'pending', updated_at = datetime('now') WHERE cwd = ?\",\n\t\t\t[cwd],\n\t\t);\n\n\t\tconst threads = this.queryAll<{ thread_id: string }>(\n\t\t\t\"SELECT thread_id FROM threads WHERE cwd = ?\",\n\t\t\t[cwd],\n\t\t);\n\n\t\tfor (const t of threads) {\n\t\t\tthis.db.run(\n\t\t\t\t\"INSERT INTO jobs (id, phase, thread_id, status) VALUES (?, 'stage1', ?, 'pending')\",\n\t\t\t\t[randomUUID(), t.thread_id],\n\t\t\t);\n\t\t}\n\t\tthis.schedulePersist();\n\t}\n\n\tclose(): void {\n\t\tif (this.persistTimer) {\n\t\t\tclearTimeout(this.persistTimer);\n\t\t\tthis.persistTimer = null;\n\t\t}\n\t\tthis.persist();\n\t\tthis.db.close();\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../../src/resources/extensions/memory/storage.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * SQLite storage for the memory extraction pipeline.\n *\n * Tables:\n * - threads: tracks session files and their processing state\n * - stage1_outputs: stores per-thread extraction results\n * - jobs: lease-based job queue for pipeline phases\n */\n\nimport initSqlJs, { type Database as SqlJsDatabase } from \"sql.js\";\nimport { randomUUID } from \"crypto\";\nimport { existsSync, mkdirSync, readFileSync } from \"fs\";\nimport { dirname } from \"path\";\nimport { atomicWriteDbSnapshotSync } from \"../../../core/db-snapshot.js\";\n\nexport interface ThreadRow {\n\tthread_id: string;\n\tfile_path: string;\n\tfile_size: number;\n\tfile_mtime: number;\n\tcwd: string;\n\tstatus: \"pending\" | \"processing\" | \"done\" | \"error\";\n\terror_message: string | null;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\nexport interface Stage1OutputRow {\n\tthread_id: string;\n\textraction_json: string;\n\tcreated_at: string;\n}\n\nexport interface JobRow {\n\tid: string;\n\tphase: \"stage1\" | \"stage2\";\n\tthread_id: string | null;\n\tstatus: \"pending\" | \"claimed\" | \"done\" | \"error\";\n\tworker_id: string | null;\n\townership_token: string | null;\n\tlease_expires_at: string | null;\n\terror_message: string | null;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\nexport class MemoryStorage {\n\tprivate db: SqlJsDatabase;\n\tprivate dbPath: string;\n\tprivate persistTimer: ReturnType<typeof setTimeout> | null = null;\n\n\tprivate constructor(db: SqlJsDatabase, dbPath: string) {\n\t\tthis.db = db;\n\t\tthis.dbPath = dbPath;\n\t}\n\n\tstatic async create(dbPath: string): Promise<MemoryStorage> {\n\t\tconst dir = dirname(dbPath);\n\t\tif (!existsSync(dir)) {\n\t\t\tmkdirSync(dir, { recursive: true });\n\t\t}\n\n\t\tconst SQL = await initSqlJs();\n\t\tconst buffer = existsSync(dbPath) ? readFileSync(dbPath) : undefined;\n\t\tconst db = buffer ? new SQL.Database(buffer) : new SQL.Database();\n\n\t\tdb.run(\"PRAGMA journal_mode = WAL\");\n\t\tdb.run(\"PRAGMA synchronous = NORMAL\");\n\t\tdb.run(\"PRAGMA busy_timeout = 5000\");\n\n\t\tconst storage = new MemoryStorage(db, dbPath);\n\t\tstorage.initSchema();\n\t\treturn storage;\n\t}\n\n\tprivate persist(): void {\n\t\tconst data = this.db.export();\n\t\tatomicWriteDbSnapshotSync(this.dbPath, data);\n\t}\n\n\tprivate schedulePersist(): void {\n\t\tif (this.persistTimer) {\n\t\t\tclearTimeout(this.persistTimer);\n\t\t}\n\t\tthis.persistTimer = setTimeout(() => {\n\t\t\tthis.persistTimer = null;\n\t\t\tthis.persist();\n\t\t}, 500);\n\t}\n\n\tprivate initSchema(): void {\n\t\tthis.db.run(`\n\t\t\tCREATE TABLE IF NOT EXISTS threads (\n\t\t\t\tthread_id TEXT PRIMARY KEY,\n\t\t\t\tfile_path TEXT NOT NULL,\n\t\t\t\tfile_size INTEGER NOT NULL DEFAULT 0,\n\t\t\t\tfile_mtime INTEGER NOT NULL DEFAULT 0,\n\t\t\t\tcwd TEXT NOT NULL DEFAULT '',\n\t\t\t\tstatus TEXT NOT NULL DEFAULT 'pending',\n\t\t\t\terror_message TEXT,\n\t\t\t\tcreated_at TEXT NOT NULL DEFAULT (datetime('now')),\n\t\t\t\tupdated_at TEXT NOT NULL DEFAULT (datetime('now'))\n\t\t\t)\n\t\t`);\n\t\tthis.db.run(`\n\t\t\tCREATE TABLE IF NOT EXISTS stage1_outputs (\n\t\t\t\tthread_id TEXT PRIMARY KEY,\n\t\t\t\textraction_json TEXT NOT NULL,\n\t\t\t\tcreated_at TEXT NOT NULL DEFAULT (datetime('now')),\n\t\t\t\tFOREIGN KEY (thread_id) REFERENCES threads(thread_id) ON DELETE CASCADE\n\t\t\t)\n\t\t`);\n\t\tthis.db.run(`\n\t\t\tCREATE TABLE IF NOT EXISTS jobs (\n\t\t\t\tid TEXT PRIMARY KEY,\n\t\t\t\tphase TEXT NOT NULL,\n\t\t\t\tthread_id TEXT,\n\t\t\t\tstatus TEXT NOT NULL DEFAULT 'pending',\n\t\t\t\tworker_id TEXT,\n\t\t\t\townership_token TEXT,\n\t\t\t\tlease_expires_at TEXT,\n\t\t\t\terror_message TEXT,\n\t\t\t\tcreated_at TEXT NOT NULL DEFAULT (datetime('now')),\n\t\t\t\tupdated_at TEXT NOT NULL DEFAULT (datetime('now'))\n\t\t\t)\n\t\t`);\n\t\tthis.db.run(\"CREATE INDEX IF NOT EXISTS idx_jobs_phase_status ON jobs(phase, status)\");\n\t\tthis.db.run(\"CREATE INDEX IF NOT EXISTS idx_threads_status ON threads(status)\");\n\t\tthis.db.run(\"CREATE INDEX IF NOT EXISTS idx_threads_cwd ON threads(cwd)\");\n\t\tthis.persist();\n\t}\n\n\tprivate queryAll<T>(sql: string, params: unknown[] = []): T[] {\n\t\tconst stmt = this.db.prepare(sql);\n\t\tstmt.bind(params as (string | number | null | Uint8Array)[]);\n\t\tconst rows: T[] = [];\n\t\twhile (stmt.step()) {\n\t\t\trows.push(stmt.getAsObject() as T);\n\t\t}\n\t\tstmt.free();\n\t\treturn rows;\n\t}\n\n\tprivate queryOne<T>(sql: string, params: unknown[] = []): T | undefined {\n\t\tconst rows = this.queryAll<T>(sql, params);\n\t\treturn rows[0];\n\t}\n\n\t/**\n\t * Insert or update thread records. Skips threads whose file hasn't changed\n\t * (same size + mtime = watermark match).\n\t */\n\tupsertThreads(\n\t\tthreads: Array<{\n\t\t\tthreadId: string;\n\t\t\tfilePath: string;\n\t\t\tfileSize: number;\n\t\t\tfileMtime: number;\n\t\t\tcwd: string;\n\t\t}>,\n\t): { inserted: number; updated: number; skipped: number } {\n\t\tlet inserted = 0;\n\t\tlet updated = 0;\n\t\tlet skipped = 0;\n\n\t\tfor (const t of threads) {\n\t\t\tconst existing = this.queryOne<{ file_size: number; file_mtime: number; status: string }>(\n\t\t\t\t\"SELECT file_size, file_mtime, status FROM threads WHERE thread_id = ?\",\n\t\t\t\t[t.threadId],\n\t\t\t);\n\n\t\t\tif (!existing) {\n\t\t\t\tthis.db.run(\n\t\t\t\t\t\"INSERT INTO threads (thread_id, file_path, file_size, file_mtime, cwd, status) VALUES (?, ?, ?, ?, ?, 'pending')\",\n\t\t\t\t\t[t.threadId, t.filePath, t.fileSize, t.fileMtime, t.cwd],\n\t\t\t\t);\n\t\t\t\tthis.db.run(\n\t\t\t\t\t\"INSERT OR IGNORE INTO jobs (id, phase, thread_id, status) VALUES (?, 'stage1', ?, 'pending')\",\n\t\t\t\t\t[randomUUID(), t.threadId],\n\t\t\t\t);\n\t\t\t\tinserted++;\n\t\t\t} else if (existing.file_size !== t.fileSize || existing.file_mtime !== t.fileMtime) {\n\t\t\t\tthis.db.run(\n\t\t\t\t\t\"UPDATE threads SET file_path = ?, file_size = ?, file_mtime = ?, cwd = ?, status = 'pending', updated_at = datetime('now') WHERE thread_id = ?\",\n\t\t\t\t\t[t.filePath, t.fileSize, t.fileMtime, t.cwd, t.threadId],\n\t\t\t\t);\n\t\t\t\tif (existing.status === \"done\" || existing.status === \"error\") {\n\t\t\t\t\tthis.db.run(\n\t\t\t\t\t\t\"INSERT OR IGNORE INTO jobs (id, phase, thread_id, status) VALUES (?, 'stage1', ?, 'pending')\",\n\t\t\t\t\t\t[randomUUID(), t.threadId],\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tupdated++;\n\t\t\t} else {\n\t\t\t\tskipped++;\n\t\t\t}\n\t\t}\n\n\t\tthis.schedulePersist();\n\t\treturn { inserted, updated, skipped };\n\t}\n\n\t/**\n\t * Claim up to `limit` stage1 jobs for the given worker.\n\t * Uses lease-based ownership with an ownership_token UUID.\n\t */\n\tclaimStage1Jobs(\n\t\tworkerId: string,\n\t\tlimit: number,\n\t\tleaseSeconds: number,\n\t): Array<{ jobId: string; threadId: string; ownershipToken: string }> {\n\t\tconst token = randomUUID();\n\t\tconst expiresAt = new Date(Date.now() + leaseSeconds * 1000).toISOString();\n\n\t\tthis.db.run(\n\t\t\t`UPDATE jobs SET\n\t\t\t\tstatus = 'claimed',\n\t\t\t\tworker_id = ?,\n\t\t\t\townership_token = ?,\n\t\t\t\tlease_expires_at = ?,\n\t\t\t\tupdated_at = datetime('now')\n\t\t\tWHERE id IN (\n\t\t\t\tSELECT id FROM jobs\n\t\t\t\tWHERE phase = 'stage1'\n\t\t\t\t\tAND (status = 'pending' OR (status = 'claimed' AND lease_expires_at < datetime('now')))\n\t\t\t\tLIMIT ?\n\t\t\t)`,\n\t\t\t[workerId, token, expiresAt, limit],\n\t\t);\n\n\t\tconst rows = this.queryAll<{ id: string; thread_id: string }>(\n\t\t\t\"SELECT id, thread_id FROM jobs WHERE ownership_token = ? AND status = 'claimed'\",\n\t\t\t[token],\n\t\t);\n\n\t\tthis.schedulePersist();\n\n\t\treturn rows.map((r) => ({\n\t\t\tjobId: r.id,\n\t\t\tthreadId: r.thread_id,\n\t\t\townershipToken: token,\n\t\t}));\n\t}\n\n\t/**\n\t * Mark a stage1 job as complete and store the extraction output.\n\t */\n\tcompleteStage1Job(threadId: string, output: string): void {\n\t\tthis.db.run(\n\t\t\t\"UPDATE jobs SET status = 'done', updated_at = datetime('now') WHERE thread_id = ? AND phase = 'stage1' AND status = 'claimed'\",\n\t\t\t[threadId],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"INSERT OR REPLACE INTO stage1_outputs (thread_id, extraction_json, created_at) VALUES (?, ?, datetime('now'))\",\n\t\t\t[threadId, output],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"UPDATE threads SET status = 'done', updated_at = datetime('now') WHERE thread_id = ?\",\n\t\t\t[threadId],\n\t\t);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Mark a stage1 job as errored.\n\t */\n\tfailStage1Job(threadId: string, errorMessage: string): void {\n\t\tthis.db.run(\n\t\t\t\"UPDATE jobs SET status = 'error', error_message = ?, updated_at = datetime('now') WHERE thread_id = ? AND phase = 'stage1' AND status = 'claimed'\",\n\t\t\t[errorMessage, threadId],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"UPDATE threads SET status = 'error', error_message = ?, updated_at = datetime('now') WHERE thread_id = ?\",\n\t\t\t[errorMessage, threadId],\n\t\t);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Try to claim the global phase 2 consolidation job.\n\t * Only one worker can hold this at a time.\n\t */\n\ttryClaimGlobalPhase2Job(\n\t\tworkerId: string,\n\t\tleaseSeconds: number,\n\t): { jobId: string; ownershipToken: string } | null {\n\t\tconst token = randomUUID();\n\t\tconst expiresAt = new Date(Date.now() + leaseSeconds * 1000).toISOString();\n\n\t\tconst pendingStage1 = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM jobs WHERE phase = 'stage1' AND status IN ('pending', 'claimed')\",\n\t\t);\n\n\t\tif (pendingStage1 && pendingStage1.cnt > 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst existingPhase2 = this.queryOne<{ id: string }>(\n\t\t\t\"SELECT id FROM jobs WHERE phase = 'stage2' AND status = 'claimed' AND lease_expires_at > datetime('now')\",\n\t\t);\n\n\t\tif (existingPhase2) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst outputCount = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM stage1_outputs\",\n\t\t);\n\n\t\tif (!outputCount || outputCount.cnt === 0) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst jobId = randomUUID();\n\t\tthis.db.run(\n\t\t\t\"INSERT INTO jobs (id, phase, status, worker_id, ownership_token, lease_expires_at) VALUES (?, 'stage2', 'claimed', ?, ?, ?)\",\n\t\t\t[jobId, workerId, token, expiresAt],\n\t\t);\n\n\t\tthis.schedulePersist();\n\t\treturn { jobId, ownershipToken: token };\n\t}\n\n\t/**\n\t * Complete the phase 2 consolidation job.\n\t */\n\tcompletePhase2Job(jobId: string): void {\n\t\tthis.db.run(\n\t\t\t\"UPDATE jobs SET status = 'done', updated_at = datetime('now') WHERE id = ? AND phase = 'stage2'\",\n\t\t\t[jobId],\n\t\t);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Get all stage1 extraction outputs.\n\t */\n\tgetStage1Outputs(): Array<{ threadId: string; extractionJson: string }> {\n\t\tconst rows = this.queryAll<{ thread_id: string; extraction_json: string }>(\n\t\t\t\"SELECT thread_id, extraction_json FROM stage1_outputs\",\n\t\t);\n\n\t\treturn rows.map((r) => ({\n\t\t\tthreadId: r.thread_id,\n\t\t\textractionJson: r.extraction_json,\n\t\t}));\n\t}\n\n\t/**\n\t * Get all stage1 outputs for a specific cwd.\n\t */\n\tgetStage1OutputsForCwd(cwd: string): Array<{ threadId: string; extractionJson: string }> {\n\t\tconst rows = this.queryAll<{ thread_id: string; extraction_json: string }>(\n\t\t\t`SELECT s.thread_id, s.extraction_json FROM stage1_outputs s\n\t\t\tINNER JOIN threads t ON t.thread_id = s.thread_id\n\t\t\tWHERE t.cwd = ?`,\n\t\t\t[cwd],\n\t\t);\n\n\t\treturn rows.map((r) => ({\n\t\t\tthreadId: r.thread_id,\n\t\t\textractionJson: r.extraction_json,\n\t\t}));\n\t}\n\n\t/**\n\t * Get thread info by ID.\n\t */\n\tgetThread(threadId: string): ThreadRow | undefined {\n\t\treturn this.queryOne<ThreadRow>(\n\t\t\t\"SELECT * FROM threads WHERE thread_id = ?\",\n\t\t\t[threadId],\n\t\t);\n\t}\n\n\t/**\n\t * Get pipeline statistics.\n\t */\n\tgetStats(): {\n\t\ttotalThreads: number;\n\t\tpendingThreads: number;\n\t\tdoneThreads: number;\n\t\terrorThreads: number;\n\t\ttotalStage1Outputs: number;\n\t\tpendingStage1Jobs: number;\n\t} {\n\t\tconst threads = this.queryOne<{ total: number; pending: number; done: number; errors: number }>(`\n\t\t\tSELECT\n\t\t\t\tCOUNT(*) as total,\n\t\t\t\tSUM(CASE WHEN status = 'pending' THEN 1 ELSE 0 END) as pending,\n\t\t\t\tSUM(CASE WHEN status = 'done' THEN 1 ELSE 0 END) as done,\n\t\t\t\tSUM(CASE WHEN status = 'error' THEN 1 ELSE 0 END) as errors\n\t\t\tFROM threads\n\t\t`)!;\n\n\t\tconst outputs = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM stage1_outputs\",\n\t\t)!;\n\n\t\tconst pendingJobs = this.queryOne<{ cnt: number }>(\n\t\t\t\"SELECT COUNT(*) as cnt FROM jobs WHERE phase = 'stage1' AND status IN ('pending', 'claimed')\",\n\t\t)!;\n\n\t\treturn {\n\t\t\ttotalThreads: threads.total,\n\t\t\tpendingThreads: threads.pending,\n\t\t\tdoneThreads: threads.done,\n\t\t\terrorThreads: threads.errors,\n\t\t\ttotalStage1Outputs: outputs.cnt,\n\t\t\tpendingStage1Jobs: pendingJobs.cnt,\n\t\t};\n\t}\n\n\t/**\n\t * Clear all data (for /memory clear).\n\t */\n\tclearAll(): void {\n\t\tthis.db.run(\"DELETE FROM stage1_outputs\");\n\t\tthis.db.run(\"DELETE FROM jobs\");\n\t\tthis.db.run(\"DELETE FROM threads\");\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Clear data for a specific cwd (for /memory clear in project scope).\n\t */\n\tclearForCwd(cwd: string): void {\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM stage1_outputs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM jobs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\"DELETE FROM threads WHERE cwd = ?\", [cwd]);\n\t\tthis.schedulePersist();\n\t}\n\n\t/**\n\t * Reset all threads to pending (for /memory rebuild).\n\t */\n\tresetAllForCwd(cwd: string): void {\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM stage1_outputs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"DELETE FROM jobs WHERE thread_id IN (SELECT thread_id FROM threads WHERE cwd = ?)\",\n\t\t\t[cwd],\n\t\t);\n\t\tthis.db.run(\n\t\t\t\"UPDATE threads SET status = 'pending', updated_at = datetime('now') WHERE cwd = ?\",\n\t\t\t[cwd],\n\t\t);\n\n\t\tconst threads = this.queryAll<{ thread_id: string }>(\n\t\t\t\"SELECT thread_id FROM threads WHERE cwd = ?\",\n\t\t\t[cwd],\n\t\t);\n\n\t\tfor (const t of threads) {\n\t\t\tthis.db.run(\n\t\t\t\t\"INSERT INTO jobs (id, phase, thread_id, status) VALUES (?, 'stage1', ?, 'pending')\",\n\t\t\t\t[randomUUID(), t.thread_id],\n\t\t\t);\n\t\t}\n\t\tthis.schedulePersist();\n\t}\n\n\tclose(): void {\n\t\tif (this.persistTimer) {\n\t\t\tclearTimeout(this.persistTimer);\n\t\t\tthis.persistTimer = null;\n\t\t}\n\t\tthis.persist();\n\t\tthis.db.close();\n\t}\n}\n"]}
|
|
@@ -120,6 +120,7 @@ describe("#4243 — abort() must run before _disconnectFromAgent()", () => {
|
|
|
120
120
|
|
|
121
121
|
it("newSession() invokes abort() before _disconnectFromAgent()", async () => {
|
|
122
122
|
const session = await createSession();
|
|
123
|
+
(session as any).agent.state.isStreaming = true;
|
|
123
124
|
const order = recordCallOrder(session as any, ["abort", "_disconnectFromAgent"]);
|
|
124
125
|
|
|
125
126
|
const ok = await session.newSession();
|
|
@@ -138,6 +139,40 @@ describe("#4243 — abort() must run before _disconnectFromAgent()", () => {
|
|
|
138
139
|
);
|
|
139
140
|
});
|
|
140
141
|
|
|
142
|
+
it("newSession() waits instead of aborting when the prior turn is idle but not settled", async () => {
|
|
143
|
+
const session = await createSession();
|
|
144
|
+
const order: string[] = [];
|
|
145
|
+
let releaseIdle!: () => void;
|
|
146
|
+
const idle = new Promise<void>((resolve) => {
|
|
147
|
+
releaseIdle = resolve;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
(session as any).agent.state.isStreaming = false;
|
|
151
|
+
(session as any).agent.waitForIdle = () => {
|
|
152
|
+
order.push("waitForIdle");
|
|
153
|
+
return idle;
|
|
154
|
+
};
|
|
155
|
+
(session as any).abort = async () => {
|
|
156
|
+
order.push("abort");
|
|
157
|
+
};
|
|
158
|
+
const originalDisconnect = (session as any)._disconnectFromAgent.bind(session);
|
|
159
|
+
(session as any)._disconnectFromAgent = () => {
|
|
160
|
+
order.push("_disconnectFromAgent");
|
|
161
|
+
originalDisconnect();
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const pendingNewSession = session.newSession();
|
|
165
|
+
await Promise.resolve();
|
|
166
|
+
assert.deepEqual(order, ["waitForIdle"]);
|
|
167
|
+
assert.equal(order.includes("abort"), false);
|
|
168
|
+
|
|
169
|
+
releaseIdle();
|
|
170
|
+
const ok = await pendingNewSession;
|
|
171
|
+
assert.equal(ok, true);
|
|
172
|
+
assert.deepEqual(order, ["waitForIdle", "_disconnectFromAgent"]);
|
|
173
|
+
assert.equal(order.includes("abort"), false);
|
|
174
|
+
});
|
|
175
|
+
|
|
141
176
|
it("newSession() waits instead of aborting while agent_end processing is still streaming", async () => {
|
|
142
177
|
const session = await createSession();
|
|
143
178
|
const order: string[] = [];
|
|
@@ -200,6 +235,7 @@ describe("#4243 — abort() must run before _disconnectFromAgent()", () => {
|
|
|
200
235
|
it("abort() marks synthetic agent_end processing while extension handlers run", async () => {
|
|
201
236
|
const session = await createSession();
|
|
202
237
|
const observedProcessingStates: boolean[] = [];
|
|
238
|
+
const observedOrigins: unknown[] = [];
|
|
203
239
|
|
|
204
240
|
(session as any).agent.abort = () => {};
|
|
205
241
|
(session as any).agent.waitForIdle = async () => {};
|
|
@@ -207,6 +243,7 @@ describe("#4243 — abort() must run before _disconnectFromAgent()", () => {
|
|
|
207
243
|
emit: async (event: any) => {
|
|
208
244
|
if (event.type === "agent_end") {
|
|
209
245
|
observedProcessingStates.push((session as any)._processingAgentEnd);
|
|
246
|
+
observedOrigins.push(event.abortOrigin);
|
|
210
247
|
}
|
|
211
248
|
},
|
|
212
249
|
emitStop: async () => {
|
|
@@ -214,9 +251,10 @@ describe("#4243 — abort() must run before _disconnectFromAgent()", () => {
|
|
|
214
251
|
},
|
|
215
252
|
};
|
|
216
253
|
|
|
217
|
-
await session.abort();
|
|
254
|
+
await session.abort({ origin: "session-transition" });
|
|
218
255
|
|
|
219
256
|
assert.deepEqual(observedProcessingStates, [true, true]);
|
|
257
|
+
assert.deepEqual(observedOrigins, ["session-transition"]);
|
|
220
258
|
assert.equal((session as any)._processingAgentEnd, false);
|
|
221
259
|
});
|
|
222
260
|
|
|
@@ -432,6 +470,7 @@ describe("#4243 — abort() must run before _disconnectFromAgent()", () => {
|
|
|
432
470
|
const sessionFile = session.sessionFile;
|
|
433
471
|
assert.ok(typeof sessionFile === "string" && sessionFile.length > 0, "need a session file to switch to");
|
|
434
472
|
|
|
473
|
+
(session as any).agent.state.isStreaming = true;
|
|
435
474
|
const order = recordCallOrder(session as any, ["abort", "_disconnectFromAgent"]);
|
|
436
475
|
|
|
437
476
|
const ok = await session.switchSession(sessionFile);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GSD2 - Agent session workspace-root refresh regression tests
|
|
1
2
|
// Regression test for #3616: newSession() must restore the full tool set
|
|
2
3
|
// when cwd is unchanged.
|
|
3
4
|
//
|
|
@@ -26,7 +27,7 @@ import { SettingsManager } from "./settings-manager.js";
|
|
|
26
27
|
|
|
27
28
|
let testDir: string;
|
|
28
29
|
|
|
29
|
-
async function createSession(): Promise<AgentSession> {
|
|
30
|
+
async function createSession(options: { workspaceRootRef?: { current: string } } = {}): Promise<AgentSession> {
|
|
30
31
|
const agentDir = join(testDir, "agent-home");
|
|
31
32
|
const authStorage = AuthStorage.inMemory({});
|
|
32
33
|
const modelRegistry = new ModelRegistry(authStorage, join(agentDir, "models.json"));
|
|
@@ -48,6 +49,7 @@ async function createSession(): Promise<AgentSession> {
|
|
|
48
49
|
cwd: testDir,
|
|
49
50
|
resourceLoader,
|
|
50
51
|
modelRegistry,
|
|
52
|
+
workspaceRootRef: options.workspaceRootRef,
|
|
51
53
|
});
|
|
52
54
|
}
|
|
53
55
|
|
|
@@ -130,4 +132,41 @@ describe("#3616 — newSession() restores narrowed tool set when cwd unchanged",
|
|
|
130
132
|
"cwd-changed branch must rebuild with includeAllExtensionTools: true",
|
|
131
133
|
);
|
|
132
134
|
});
|
|
135
|
+
|
|
136
|
+
it("uses explicit workspaceRoot option instead of process.cwd() when rebuilding runtime", async () => {
|
|
137
|
+
const session = await createSession();
|
|
138
|
+
const explicitWorkspaceRoot = mkdtempSync(join(testDir, "explicit-workspace-"));
|
|
139
|
+
(session as any)._cwd = process.cwd();
|
|
140
|
+
|
|
141
|
+
let buildRuntimeCalled = false;
|
|
142
|
+
let capturedBuildOptions: { includeAllExtensionTools?: boolean } | undefined;
|
|
143
|
+
const originalBuild = (session as any)._buildRuntime.bind(session);
|
|
144
|
+
(session as any)._buildRuntime = (options?: { includeAllExtensionTools?: boolean }) => {
|
|
145
|
+
buildRuntimeCalled = true;
|
|
146
|
+
capturedBuildOptions = options;
|
|
147
|
+
return originalBuild(options);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const ok = await session.newSession({ workspaceRoot: explicitWorkspaceRoot });
|
|
151
|
+
assert.equal(ok, true);
|
|
152
|
+
assert.equal((session as any)._cwd, explicitWorkspaceRoot);
|
|
153
|
+
assert.ok(buildRuntimeCalled, "explicit workspace root differing from prior root must rebuild runtime");
|
|
154
|
+
assert.strictEqual(
|
|
155
|
+
capturedBuildOptions?.includeAllExtensionTools,
|
|
156
|
+
true,
|
|
157
|
+
"explicit workspaceRoot rebuild must pass includeAllExtensionTools: true",
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("updates provider workspace root ref when newSession uses explicit workspaceRoot", async () => {
|
|
162
|
+
const workspaceRootRef = { current: "" };
|
|
163
|
+
const session = await createSession({ workspaceRootRef });
|
|
164
|
+
const explicitWorkspaceRoot = mkdtempSync(join(testDir, "provider-workspace-"));
|
|
165
|
+
|
|
166
|
+
assert.equal(workspaceRootRef.current, testDir);
|
|
167
|
+
|
|
168
|
+
const ok = await session.newSession({ workspaceRoot: explicitWorkspaceRoot });
|
|
169
|
+
assert.equal(ok, true);
|
|
170
|
+
assert.equal(workspaceRootRef.current, explicitWorkspaceRoot);
|
|
171
|
+
});
|
|
133
172
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// GSD2 - Agent session lifecycle and workspace runtime coordination
|
|
1
2
|
/**
|
|
2
3
|
* AgentSession - Core abstraction for agent lifecycle and session management.
|
|
3
4
|
*
|
|
@@ -17,6 +18,7 @@ import { readFileSync } from "node:fs";
|
|
|
17
18
|
import { basename, dirname, join } from "node:path";
|
|
18
19
|
import type {
|
|
19
20
|
Agent,
|
|
21
|
+
AgentAbortOrigin,
|
|
20
22
|
AgentEvent,
|
|
21
23
|
AgentMessage,
|
|
22
24
|
AgentState,
|
|
@@ -167,6 +169,8 @@ export interface AgentSessionConfig {
|
|
|
167
169
|
baseToolsOverride?: Record<string, AgentTool>;
|
|
168
170
|
/** Mutable ref used by Agent to access the current ExtensionRunner */
|
|
169
171
|
extensionRunnerRef?: { current?: ExtensionRunner };
|
|
172
|
+
/** Mutable ref used by providers to access the current workspace root. */
|
|
173
|
+
workspaceRootRef?: { current: string };
|
|
170
174
|
/** Optional: check if the claude-code CLI provider is ready (installed + authed).
|
|
171
175
|
* Passed through to RetryHandler for third-party block recovery (#3772). */
|
|
172
176
|
isClaudeCodeReady?: () => boolean;
|
|
@@ -284,6 +288,7 @@ export class AgentSession {
|
|
|
284
288
|
private _baseToolRegistry: Map<string, AgentTool> = new Map();
|
|
285
289
|
private _cwd: string;
|
|
286
290
|
private _extensionRunnerRef?: { current?: ExtensionRunner };
|
|
291
|
+
private _workspaceRootRef?: { current: string };
|
|
287
292
|
private _initialActiveToolNames?: string[];
|
|
288
293
|
private _baseToolsOverride?: Record<string, AgentTool>;
|
|
289
294
|
private _extensionUIContext?: ExtensionUIContext;
|
|
@@ -305,6 +310,8 @@ export class AgentSession {
|
|
|
305
310
|
|
|
306
311
|
// Base system prompt (without extension appends) - used to apply fresh appends each turn
|
|
307
312
|
private _baseSystemPrompt = "";
|
|
313
|
+
// Optional prompt-only skill catalog filter. Skills remain loaded and invocable by name.
|
|
314
|
+
private _visibleSkillNames: Set<string> | undefined = undefined;
|
|
308
315
|
|
|
309
316
|
constructor(config: AgentSessionConfig) {
|
|
310
317
|
this.agent = config.agent;
|
|
@@ -321,6 +328,10 @@ export class AgentSession {
|
|
|
321
328
|
this._modelRegistry,
|
|
322
329
|
);
|
|
323
330
|
this._extensionRunnerRef = config.extensionRunnerRef;
|
|
331
|
+
this._workspaceRootRef = config.workspaceRootRef;
|
|
332
|
+
if (this._workspaceRootRef) {
|
|
333
|
+
this._workspaceRootRef.current = this._cwd;
|
|
334
|
+
}
|
|
324
335
|
this._initialActiveToolNames = config.initialActiveToolNames;
|
|
325
336
|
this._baseToolsOverride = config.baseToolsOverride;
|
|
326
337
|
|
|
@@ -348,7 +359,7 @@ export class AgentSession {
|
|
|
348
359
|
emit: (event) => this._emit(event),
|
|
349
360
|
disconnectFromAgent: () => this._disconnectFromAgent(),
|
|
350
361
|
reconnectToAgent: () => this._reconnectToAgent(),
|
|
351
|
-
abort: () => this.abort(),
|
|
362
|
+
abort: () => this.abort({ origin: "user" }),
|
|
352
363
|
});
|
|
353
364
|
|
|
354
365
|
// Always subscribe to agent events for internal handling
|
|
@@ -655,11 +666,21 @@ export class AgentSession {
|
|
|
655
666
|
|
|
656
667
|
if (event.type === "agent_start") {
|
|
657
668
|
this._turnIndex = 0;
|
|
658
|
-
await extensionRunner.emit({
|
|
669
|
+
await extensionRunner.emit({
|
|
670
|
+
type: "agent_start",
|
|
671
|
+
sessionId: event.sessionId,
|
|
672
|
+
turnId: event.turnId,
|
|
673
|
+
});
|
|
659
674
|
} else if (event.type === "agent_end") {
|
|
660
675
|
this._processingAgentEnd = true;
|
|
661
676
|
try {
|
|
662
|
-
await extensionRunner.emit({
|
|
677
|
+
await extensionRunner.emit({
|
|
678
|
+
type: "agent_end",
|
|
679
|
+
messages: event.messages,
|
|
680
|
+
sessionId: event.sessionId,
|
|
681
|
+
turnId: event.turnId,
|
|
682
|
+
abortOrigin: event.abortOrigin,
|
|
683
|
+
});
|
|
663
684
|
// `stop` fires on true quiescence: the agent cleanly completed and is now
|
|
664
685
|
// waiting for the user. Use the last assistant message's stopReason to
|
|
665
686
|
// distinguish clean completion from error/cancellation.
|
|
@@ -672,7 +693,13 @@ export class AgentSession {
|
|
|
672
693
|
? "error"
|
|
673
694
|
: "completed"
|
|
674
695
|
: "completed";
|
|
675
|
-
await extensionRunner.emitStop({
|
|
696
|
+
await extensionRunner.emitStop({
|
|
697
|
+
reason: stopReason,
|
|
698
|
+
lastMessage: last,
|
|
699
|
+
sessionId: event.sessionId,
|
|
700
|
+
turnId: event.turnId,
|
|
701
|
+
abortOrigin: event.abortOrigin,
|
|
702
|
+
});
|
|
676
703
|
} finally {
|
|
677
704
|
this._processingAgentEnd = false;
|
|
678
705
|
}
|
|
@@ -681,6 +708,8 @@ export class AgentSession {
|
|
|
681
708
|
type: "turn_start",
|
|
682
709
|
turnIndex: this._turnIndex,
|
|
683
710
|
timestamp: Date.now(),
|
|
711
|
+
sessionId: event.sessionId,
|
|
712
|
+
turnId: event.turnId,
|
|
684
713
|
};
|
|
685
714
|
await extensionRunner.emit(extensionEvent);
|
|
686
715
|
} else if (event.type === "turn_end") {
|
|
@@ -689,6 +718,8 @@ export class AgentSession {
|
|
|
689
718
|
turnIndex: this._turnIndex,
|
|
690
719
|
message: event.message,
|
|
691
720
|
toolResults: event.toolResults,
|
|
721
|
+
sessionId: event.sessionId,
|
|
722
|
+
turnId: event.turnId,
|
|
692
723
|
};
|
|
693
724
|
await extensionRunner.emit(extensionEvent);
|
|
694
725
|
this._turnIndex++;
|
|
@@ -696,6 +727,8 @@ export class AgentSession {
|
|
|
696
727
|
const extensionEvent: MessageStartEvent = {
|
|
697
728
|
type: "message_start",
|
|
698
729
|
message: event.message,
|
|
730
|
+
sessionId: event.sessionId,
|
|
731
|
+
turnId: event.turnId,
|
|
699
732
|
};
|
|
700
733
|
await extensionRunner.emit(extensionEvent);
|
|
701
734
|
} else if (event.type === "message_update") {
|
|
@@ -703,12 +736,16 @@ export class AgentSession {
|
|
|
703
736
|
type: "message_update",
|
|
704
737
|
message: event.message,
|
|
705
738
|
assistantMessageEvent: event.assistantMessageEvent,
|
|
739
|
+
sessionId: event.sessionId,
|
|
740
|
+
turnId: event.turnId,
|
|
706
741
|
};
|
|
707
742
|
await extensionRunner.emit(extensionEvent);
|
|
708
743
|
} else if (event.type === "message_end") {
|
|
709
744
|
const extensionEvent: MessageEndEvent = {
|
|
710
745
|
type: "message_end",
|
|
711
746
|
message: event.message,
|
|
747
|
+
sessionId: event.sessionId,
|
|
748
|
+
turnId: event.turnId,
|
|
712
749
|
};
|
|
713
750
|
await extensionRunner.emit(extensionEvent);
|
|
714
751
|
} else if (event.type === "tool_execution_start") {
|
|
@@ -867,6 +904,25 @@ export class AgentSession {
|
|
|
867
904
|
this.agent.setSystemPrompt(this._baseSystemPrompt);
|
|
868
905
|
}
|
|
869
906
|
|
|
907
|
+
/**
|
|
908
|
+
* Set or clear a prompt-only filter for the <available_skills> catalog.
|
|
909
|
+
*
|
|
910
|
+
* This does not unload skills or disable the Skill tool. It only controls
|
|
911
|
+
* which loaded skills are advertised in the system prompt on rebuild.
|
|
912
|
+
*/
|
|
913
|
+
setVisibleSkillsByName(skillNames: string[] | undefined): void {
|
|
914
|
+
this._visibleSkillNames = skillNames === undefined
|
|
915
|
+
? undefined
|
|
916
|
+
: new Set(skillNames.map((name) => name.trim().toLowerCase()).filter(Boolean));
|
|
917
|
+
this._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());
|
|
918
|
+
this.agent.setSystemPrompt(this._baseSystemPrompt);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
/** Get the current prompt-only skill catalog filter, if one is active. */
|
|
922
|
+
getVisibleSkillNames(): string[] | undefined {
|
|
923
|
+
return this._visibleSkillNames ? [...this._visibleSkillNames] : undefined;
|
|
924
|
+
}
|
|
925
|
+
|
|
870
926
|
/** Whether compaction or branch summarization is currently running */
|
|
871
927
|
get isCompacting(): boolean {
|
|
872
928
|
return this._compactionOrchestrator.isCompacting;
|
|
@@ -1045,6 +1101,9 @@ export class AgentSession {
|
|
|
1045
1101
|
return buildSystemPrompt({
|
|
1046
1102
|
cwd: this._cwd,
|
|
1047
1103
|
skills: loadedSkills,
|
|
1104
|
+
skillFilter: this._visibleSkillNames
|
|
1105
|
+
? (skill) => this._visibleSkillNames!.has(skill.name.trim().toLowerCase())
|
|
1106
|
+
: undefined,
|
|
1048
1107
|
contextFiles: loadedContextFiles,
|
|
1049
1108
|
customPrompt: loaderSystemPrompt,
|
|
1050
1109
|
appendSystemPrompt,
|
|
@@ -1572,9 +1631,9 @@ export class AgentSession {
|
|
|
1572
1631
|
/**
|
|
1573
1632
|
* Abort current operation and wait for agent to become idle.
|
|
1574
1633
|
*/
|
|
1575
|
-
async abort(): Promise<void> {
|
|
1634
|
+
async abort(options?: { origin?: AgentAbortOrigin }): Promise<void> {
|
|
1576
1635
|
this._retryHandler.abortRetry();
|
|
1577
|
-
this.agent.abort();
|
|
1636
|
+
this.agent.abort(options?.origin);
|
|
1578
1637
|
await this.agent.waitForIdle();
|
|
1579
1638
|
// Ensure agent_end is emitted even when abort interrupts a tool call (#1414).
|
|
1580
1639
|
// The agent may go idle without emitting agent_end if the abort happens
|
|
@@ -1588,6 +1647,8 @@ export class AgentSession {
|
|
|
1588
1647
|
await this._extensionRunner.emit({
|
|
1589
1648
|
type: "agent_end",
|
|
1590
1649
|
messages,
|
|
1650
|
+
sessionId: this.sessionId,
|
|
1651
|
+
abortOrigin: options?.origin,
|
|
1591
1652
|
});
|
|
1592
1653
|
const last = messages[messages.length - 1];
|
|
1593
1654
|
const stopReason: "completed" | "cancelled" | "error" | "blocked" =
|
|
@@ -1598,7 +1659,12 @@ export class AgentSession {
|
|
|
1598
1659
|
? "error"
|
|
1599
1660
|
: "completed"
|
|
1600
1661
|
: "cancelled";
|
|
1601
|
-
await this._extensionRunner.emitStop({
|
|
1662
|
+
await this._extensionRunner.emitStop({
|
|
1663
|
+
reason: stopReason,
|
|
1664
|
+
lastMessage: last,
|
|
1665
|
+
sessionId: this.sessionId,
|
|
1666
|
+
abortOrigin: options?.origin,
|
|
1667
|
+
});
|
|
1602
1668
|
} finally {
|
|
1603
1669
|
this._processingAgentEnd = wasProcessingAgentEnd;
|
|
1604
1670
|
}
|
|
@@ -1626,7 +1692,12 @@ export class AgentSession {
|
|
|
1626
1692
|
// message_end/agent_end events fire while listeners are still connected.
|
|
1627
1693
|
// During agent_end handling the turn is already ending; aborting there can
|
|
1628
1694
|
// convert a successful auto-mode handoff into an aborted provider message.
|
|
1629
|
-
|
|
1695
|
+
if (!this.agent.state.isStreaming) {
|
|
1696
|
+
this._retryHandler.abortRetry();
|
|
1697
|
+
await this.agent.waitForIdle();
|
|
1698
|
+
return;
|
|
1699
|
+
}
|
|
1700
|
+
await this.abort({ origin: "session-transition" });
|
|
1630
1701
|
}
|
|
1631
1702
|
|
|
1632
1703
|
/**
|
|
@@ -1640,6 +1711,8 @@ export class AgentSession {
|
|
|
1640
1711
|
async newSession(options?: {
|
|
1641
1712
|
parentSession?: string;
|
|
1642
1713
|
setup?: (sessionManager: SessionManager) => Promise<void>;
|
|
1714
|
+
/** Explicit workspace root for the new session/tool runtime. */
|
|
1715
|
+
workspaceRoot?: string;
|
|
1643
1716
|
/** See ExtensionCommandContext.newSession for docs (#3731). */
|
|
1644
1717
|
abortSignal?: AbortSignal;
|
|
1645
1718
|
}): Promise<boolean> {
|
|
@@ -1661,10 +1734,10 @@ export class AgentSession {
|
|
|
1661
1734
|
try {
|
|
1662
1735
|
await this._settleCurrentTurnForSessionTransition();
|
|
1663
1736
|
|
|
1664
|
-
// #3731: If the caller aborted (e.g. runUnit() timed out
|
|
1665
|
-
//
|
|
1666
|
-
//
|
|
1667
|
-
//
|
|
1737
|
+
// #3731: If the caller aborted (e.g. runUnit() timed out while the
|
|
1738
|
+
// worktree was being torn down), discard this session before rebuilding
|
|
1739
|
+
// the tool runtime. Without this check, the late newSession() could
|
|
1740
|
+
// rebuild tools with a stale workspace root.
|
|
1668
1741
|
if (options?.abortSignal?.aborted) {
|
|
1669
1742
|
return false;
|
|
1670
1743
|
}
|
|
@@ -1674,15 +1747,21 @@ export class AgentSession {
|
|
|
1674
1747
|
} finally {
|
|
1675
1748
|
this._sessionSwitchPending = false;
|
|
1676
1749
|
}
|
|
1677
|
-
// Update
|
|
1678
|
-
//
|
|
1750
|
+
// Update the workspace root for the new tool runtime. Auto-mode passes
|
|
1751
|
+
// this explicitly so session routing does not depend on global
|
|
1752
|
+
// process.cwd() after worktree merge/teardown. Other callers keep the
|
|
1753
|
+
// historical default.
|
|
1679
1754
|
const previousCwd = this._cwd;
|
|
1680
|
-
this._cwd = process.cwd();
|
|
1755
|
+
this._cwd = options?.workspaceRoot ?? process.cwd();
|
|
1756
|
+
if (this._workspaceRootRef) {
|
|
1757
|
+
this._workspaceRootRef.current = this._cwd;
|
|
1758
|
+
}
|
|
1681
1759
|
this.sessionManager.newSession({ parentSession: options?.parentSession });
|
|
1682
1760
|
this.agent.sessionId = this.sessionManager.getSessionId();
|
|
1683
1761
|
this._steeringMessages = [];
|
|
1684
1762
|
this._followUpMessages = [];
|
|
1685
1763
|
this._pendingNextTurnMessages = [];
|
|
1764
|
+
this._visibleSkillNames = undefined;
|
|
1686
1765
|
|
|
1687
1766
|
this.sessionManager.appendThinkingLevelChange(this.thinkingLevel);
|
|
1688
1767
|
|
|
@@ -2180,6 +2259,8 @@ export class AgentSession {
|
|
|
2180
2259
|
getActiveTools: () => this.getActiveToolNames(),
|
|
2181
2260
|
getAllTools: () => this.getAllTools(),
|
|
2182
2261
|
setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
|
|
2262
|
+
getVisibleSkills: () => this.getVisibleSkillNames(),
|
|
2263
|
+
setVisibleSkills: (skillNames) => this.setVisibleSkillsByName(skillNames),
|
|
2183
2264
|
refreshTools: () => this._refreshToolRegistry(),
|
|
2184
2265
|
getCommands,
|
|
2185
2266
|
setModel: async (model, options) => {
|
|
@@ -2193,7 +2274,7 @@ export class AgentSession {
|
|
|
2193
2274
|
{
|
|
2194
2275
|
getModel: () => this.model,
|
|
2195
2276
|
isIdle: () => !this.isStreaming,
|
|
2196
|
-
abort: () => this.abort(),
|
|
2277
|
+
abort: () => this.abort({ origin: "user" }),
|
|
2197
2278
|
hasPendingMessages: () => this.pendingMessageCount > 0,
|
|
2198
2279
|
shutdown: () => {
|
|
2199
2280
|
this._extensionShutdownHandler?.();
|
|
@@ -2211,6 +2292,9 @@ export class AgentSession {
|
|
|
2211
2292
|
})();
|
|
2212
2293
|
},
|
|
2213
2294
|
getSystemPrompt: () => this.systemPrompt,
|
|
2295
|
+
setCompactionThresholdOverride: (percent) => {
|
|
2296
|
+
this.settingsManager.setCompactionThresholdOverride(percent);
|
|
2297
|
+
},
|
|
2214
2298
|
},
|
|
2215
2299
|
);
|
|
2216
2300
|
}
|
|
@@ -2345,6 +2429,7 @@ export class AgentSession {
|
|
|
2345
2429
|
this.settingsManager.reload();
|
|
2346
2430
|
resetApiProviders();
|
|
2347
2431
|
await this._resourceLoader.reload();
|
|
2432
|
+
this._visibleSkillNames = undefined;
|
|
2348
2433
|
this._buildRuntime({
|
|
2349
2434
|
activeToolNames: this.getActiveToolNames(),
|
|
2350
2435
|
flagValues: previousFlagValues,
|
|
@@ -2534,6 +2619,7 @@ export class AgentSession {
|
|
|
2534
2619
|
this._steeringMessages = [];
|
|
2535
2620
|
this._followUpMessages = [];
|
|
2536
2621
|
this._pendingNextTurnMessages = [];
|
|
2622
|
+
this._visibleSkillNames = undefined;
|
|
2537
2623
|
|
|
2538
2624
|
// Set new session
|
|
2539
2625
|
this.sessionManager.setSessionFile(sessionPath);
|
|
@@ -1049,7 +1049,9 @@ test("chat-controller rolls up only contiguous low-signal tool runs on message_e
|
|
|
1049
1049
|
assert.equal(host.chatContainer.children[1]?.constructor?.name, "AssistantMessageComponent");
|
|
1050
1050
|
assert.equal(host.chatContainer.children[2]?.constructor?.name, "ToolPhaseSummaryComponent");
|
|
1051
1051
|
assert.match(host.chatContainer.children[0].render(120).join("\n"), /Setup \/ shell 2 actions/);
|
|
1052
|
-
|
|
1052
|
+
const readSummary = host.chatContainer.children[2].render(120).join("\n");
|
|
1053
|
+
assert.match(readSummary, /Context reads · 2 files/);
|
|
1054
|
+
assert.match(readSummary, /\/tmp\/a · \/tmp\/b/);
|
|
1053
1055
|
assert.equal(host.chatContainer._prevRender, null, "summary reposition must invalidate the chat container render cache");
|
|
1054
1056
|
});
|
|
1055
1057
|
|
|
@@ -1080,7 +1082,9 @@ test("chat-controller rolls up low-signal direct tool execution events on agent_
|
|
|
1080
1082
|
} as any);
|
|
1081
1083
|
}
|
|
1082
1084
|
|
|
1083
|
-
assert.equal(host.chatContainer.children.length,
|
|
1085
|
+
assert.equal(host.chatContainer.children.length, 1, "direct tool events roll up as they finish");
|
|
1086
|
+
assert.equal(host.chatContainer.children[0]?.constructor?.name, "ToolPhaseSummaryComponent");
|
|
1087
|
+
assert.match(host.chatContainer.children[0].render(120).join("\n"), /Setup \/ shell 3 actions/);
|
|
1084
1088
|
|
|
1085
1089
|
await handleAgentEvent(host, { type: "agent_end" } as any);
|
|
1086
1090
|
|
|
@@ -86,6 +86,13 @@ export interface CompactionSettings {
|
|
|
86
86
|
enabled: boolean;
|
|
87
87
|
reserveTokens: number;
|
|
88
88
|
keepRecentTokens: number;
|
|
89
|
+
/**
|
|
90
|
+
* Optional percent-of-context-window threshold (0 < value < 1). When set,
|
|
91
|
+
* `shouldCompact()` fires once `contextTokens > contextWindow * thresholdPercent`,
|
|
92
|
+
* overriding the absolute `reserveTokens` calculation. Lets host integrations
|
|
93
|
+
* (e.g. GSD) express compaction policy as a fraction independent of model size.
|
|
94
|
+
*/
|
|
95
|
+
thresholdPercent?: number;
|
|
89
96
|
}
|
|
90
97
|
|
|
91
98
|
export const DEFAULT_COMPACTION_SETTINGS: CompactionSettings = {
|
|
@@ -185,9 +192,20 @@ export function estimateContextTokens(messages: AgentMessage[]): ContextUsageEst
|
|
|
185
192
|
|
|
186
193
|
/**
|
|
187
194
|
* Check if compaction should trigger based on context usage.
|
|
195
|
+
*
|
|
196
|
+
* When `thresholdPercent` is set (and within (0, 1)), it overrides the absolute
|
|
197
|
+
* `reserveTokens` calculation: compaction fires at `contextWindow * thresholdPercent`.
|
|
198
|
+
* Otherwise the legacy `contextWindow - reserveTokens` headroom is used.
|
|
188
199
|
*/
|
|
189
200
|
export function shouldCompact(contextTokens: number, contextWindow: number, settings: CompactionSettings): boolean {
|
|
190
201
|
if (!settings.enabled) return false;
|
|
202
|
+
if (
|
|
203
|
+
settings.thresholdPercent !== undefined &&
|
|
204
|
+
settings.thresholdPercent > 0 &&
|
|
205
|
+
settings.thresholdPercent < 1
|
|
206
|
+
) {
|
|
207
|
+
return contextTokens > contextWindow * settings.thresholdPercent;
|
|
208
|
+
}
|
|
191
209
|
return contextTokens > contextWindow - settings.reserveTokens;
|
|
192
210
|
}
|
|
193
211
|
|