gsd-pi 2.77.0-dev.eaa4973bc → 2.78.0-dev.aeeb2ca00
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 +53 -17
- package/dist/claude-cli-check.js +46 -10
- package/dist/headless.js +49 -4
- package/dist/resource-loader.d.ts +40 -0
- package/dist/resource-loader.js +32 -13
- package/dist/resources/extensions/browser-tools/capture.js +9 -0
- package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
- package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
- package/dist/resources/extensions/claude-code-cli/readiness.js +72 -16
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +481 -17
- package/dist/resources/extensions/github-sync/templates.js +103 -0
- package/dist/resources/extensions/google-search/index.js +3 -2
- package/dist/resources/extensions/gsd/auto/loop.js +124 -2
- package/dist/resources/extensions/gsd/auto/phases.js +57 -39
- package/dist/resources/extensions/gsd/auto/session.js +6 -2
- package/dist/resources/extensions/gsd/auto-dispatch.js +142 -29
- package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
- package/dist/resources/extensions/gsd/auto-post-unit.js +150 -64
- package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
- package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
- package/dist/resources/extensions/gsd/auto-start.js +107 -29
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
- package/dist/resources/extensions/gsd/auto-worktree.js +122 -26
- package/dist/resources/extensions/gsd/auto.js +76 -21
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
- package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +3 -6
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
- package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
- package/dist/resources/extensions/gsd/component-loader.js +447 -0
- package/dist/resources/extensions/gsd/component-types.js +69 -0
- package/dist/resources/extensions/gsd/context-store.js +23 -7
- package/dist/resources/extensions/gsd/detection.js +49 -1
- package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
- package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/dist/resources/extensions/gsd/forensics.js +106 -0
- package/dist/resources/extensions/gsd/gate-registry.js +2 -2
- package/dist/resources/extensions/gsd/git-constants.js +28 -1
- package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
- package/dist/resources/extensions/gsd/git-service.js +126 -2
- package/dist/resources/extensions/gsd/gsd-db.js +6 -3
- package/dist/resources/extensions/gsd/guided-flow.js +39 -13
- package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
- package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
- package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
- package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
- package/dist/resources/extensions/gsd/model-router.js +6 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
- package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
- package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
- package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
- package/dist/resources/extensions/gsd/service-tier.js +5 -2
- package/dist/resources/extensions/gsd/session-lock.js +19 -10
- package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
- package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
- package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
- package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
- package/dist/resources/extensions/gsd/state.js +69 -58
- package/dist/resources/extensions/gsd/sync-lock.js +98 -42
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
- package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
- package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
- package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
- package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
- package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
- package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
- package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
- package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
- package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
- package/dist/resources/extensions/gsd/uok/writer.js +82 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +85 -8
- package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
- package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
- package/dist/resources/extensions/mcp-client/index.js +3 -1
- package/dist/resources/extensions/ollama/index.js +5 -1
- package/dist/resources/extensions/remote-questions/manager.js +11 -5
- 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 +11 -11
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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-paths-manifest.json +11 -11
- package/dist/web/standalone/.next/server/chunks/1926.js +1 -1
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
- 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/package.json +2 -3
- package/packages/daemon/package.json +2 -2
- package/packages/daemon/src/logger.ts +4 -3
- package/packages/mcp-server/dist/server.d.ts +24 -0
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +88 -87
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +15 -6
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +2 -2
- package/packages/mcp-server/src/mcp-server.test.ts +25 -3
- package/packages/mcp-server/src/readers/graph.test.ts +87 -15
- package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
- package/packages/mcp-server/src/server.ts +131 -105
- package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
- package/packages/mcp-server/src/workflow-tools.ts +19 -6
- package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
- package/packages/native/package.json +2 -2
- package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
- package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
- package/packages/native/src/__tests__/ps.test.mjs +14 -8
- package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
- package/packages/native/src/__tests__/truncate.test.mjs +17 -2
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
- package/packages/pi-agent-core/src/agent.test.ts +96 -102
- package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/capability-patches.js +9 -2
- package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
- package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
- package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
- package/packages/pi-ai/dist/models/generated/openai.js +17 -0
- package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.js +43 -70
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
- package/packages/pi-ai/dist/models.test.js +36 -11
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-ai/scripts/generate-models.ts +44 -0
- package/packages/pi-ai/src/models/capability-patches.ts +10 -2
- package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
- package/packages/pi-ai/src/models/generated/openai.ts +17 -0
- package/packages/pi-ai/src/models.generated.test.ts +46 -73
- package/packages/pi-ai/src/models.test.ts +48 -11
- package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
- 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-model-switch.test.js +75 -12
- package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
- package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -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 +61 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
- package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
- package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
- package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
- package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
- package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
- package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -0
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
- 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/dynamic-border.test.js +20 -13
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -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 +30 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -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 +105 -13
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
- package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
- package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
- package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
- package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
- package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
- package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
- package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
- package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
- package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
- package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
- package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
- package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
- package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
- package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +37 -11
- package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
- package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
- package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
- package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
- package/packages/pi-tui/dist/components/editor.d.ts +14 -0
- package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/editor.js +19 -0
- package/packages/pi-tui/dist/components/editor.js.map +1 -1
- package/packages/pi-tui/dist/components/image.test.js +6 -5
- package/packages/pi-tui/dist/components/image.test.js.map +1 -1
- package/packages/pi-tui/dist/editor-component.d.ts +2 -0
- package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
- package/packages/pi-tui/dist/editor-component.js.map +1 -1
- package/packages/pi-tui/package.json +1 -1
- package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
- package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
- package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +42 -11
- package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
- package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
- package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
- package/packages/pi-tui/src/components/editor.ts +22 -0
- package/packages/pi-tui/src/components/image.test.ts +10 -5
- package/packages/pi-tui/src/editor-component.ts +3 -0
- package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
- package/packages/rpc-client/dist/rpc-client.test.js +101 -51
- package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
- package/packages/rpc-client/package.json +1 -1
- package/packages/rpc-client/src/rpc-client.test.ts +109 -52
- package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
- package/pkg/package.json +1 -1
- package/scripts/install.js +15 -1
- package/src/resources/extensions/browser-tools/capture.ts +12 -0
- package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
- package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
- package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
- package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
- package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
- package/src/resources/extensions/claude-code-cli/readiness.ts +75 -16
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +518 -19
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +919 -75
- package/src/resources/extensions/github-sync/templates.ts +151 -0
- package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
- package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
- package/src/resources/extensions/google-search/index.ts +3 -2
- package/src/resources/extensions/gsd/auto/loop.ts +142 -2
- package/src/resources/extensions/gsd/auto/phases.ts +62 -38
- package/src/resources/extensions/gsd/auto/session.ts +7 -2
- package/src/resources/extensions/gsd/auto-dispatch.ts +156 -29
- package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
- package/src/resources/extensions/gsd/auto-post-unit.ts +163 -73
- package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
- package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
- package/src/resources/extensions/gsd/auto-start.ts +127 -9
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
- package/src/resources/extensions/gsd/auto-worktree.ts +130 -26
- package/src/resources/extensions/gsd/auto.ts +90 -23
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
- package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +3 -7
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
- package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
- package/src/resources/extensions/gsd/component-loader.ts +598 -0
- package/src/resources/extensions/gsd/component-types.ts +362 -0
- package/src/resources/extensions/gsd/context-store.ts +25 -8
- package/src/resources/extensions/gsd/detection.ts +58 -1
- package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
- package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
- package/src/resources/extensions/gsd/forensics.ts +118 -1
- package/src/resources/extensions/gsd/gate-registry.ts +2 -2
- package/src/resources/extensions/gsd/git-constants.ts +30 -1
- package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
- package/src/resources/extensions/gsd/git-service.ts +149 -2
- package/src/resources/extensions/gsd/gsd-db.ts +6 -3
- package/src/resources/extensions/gsd/guided-flow.ts +57 -14
- package/src/resources/extensions/gsd/journal.ts +11 -1
- package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
- package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
- package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
- package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
- package/src/resources/extensions/gsd/model-router.ts +6 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
- package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
- package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
- package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
- package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
- package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
- package/src/resources/extensions/gsd/service-tier.ts +5 -2
- package/src/resources/extensions/gsd/session-lock.ts +20 -10
- package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
- package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
- package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
- package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
- package/src/resources/extensions/gsd/state.ts +76 -66
- package/src/resources/extensions/gsd/sync-lock.ts +97 -39
- package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
- package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
- package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +133 -292
- package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
- package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
- package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
- package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
- package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
- package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
- package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
- package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
- package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
- package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
- package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
- package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
- package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
- package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
- package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
- package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
- package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
- package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
- package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
- package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
- package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +14 -4
- package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
- package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
- package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
- package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
- package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
- package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
- package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
- package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
- package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +8 -37
- package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
- package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
- package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
- package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
- package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
- package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
- package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
- package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
- package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
- package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +23 -24
- package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +32 -0
- package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
- package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
- package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
- package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
- package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
- package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
- package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
- package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
- package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
- package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
- package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
- package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
- package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
- package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
- package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
- package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
- package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
- package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
- package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
- package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
- package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
- package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
- package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
- package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
- package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
- package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
- package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
- package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
- package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
- package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
- package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
- package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
- package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
- package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
- package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
- package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
- package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
- package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
- package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
- package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
- package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
- package/src/resources/extensions/gsd/types.ts +3 -3
- package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
- package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
- package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
- package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
- package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
- package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
- package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
- package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
- package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
- package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
- package/src/resources/extensions/gsd/uok/writer.ts +113 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +108 -7
- package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
- package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
- package/src/resources/extensions/mcp-client/index.ts +3 -1
- package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
- package/src/resources/extensions/ollama/index.ts +5 -1
- package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
- package/src/resources/extensions/remote-questions/manager.ts +36 -4
- package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
- package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
- package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
- package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
- package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
- package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
- package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
- package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
- package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
- package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
- package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
- package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
- package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
- package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
- package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
- package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
- /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{5wbu35_C2_MQ3Jj1lEVDx → cAJH99yNS1UPbeSEiNRrV}/_ssgManifest.js +0 -0
|
@@ -277,6 +277,14 @@ function buildDispatchCtx(
|
|
|
277
277
|
};
|
|
278
278
|
}
|
|
279
279
|
|
|
280
|
+
function getUatVerdictGate(): import("../../auto-dispatch.ts").DispatchRule {
|
|
281
|
+
const rule = DISPATCH_RULES.find(
|
|
282
|
+
r => r.name === "uat-verdict-gate (non-PASS blocks progression)",
|
|
283
|
+
);
|
|
284
|
+
assert.ok(rule, "uat-verdict-gate rule should be registered");
|
|
285
|
+
return rule;
|
|
286
|
+
}
|
|
287
|
+
|
|
280
288
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
281
289
|
// Test Suite
|
|
282
290
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -355,10 +363,13 @@ describe("state derivation failures", () => {
|
|
|
355
363
|
const state2 = await deriveState(base);
|
|
356
364
|
assert.equal(state2.phase, "executing", "cached result should still show executing");
|
|
357
365
|
|
|
358
|
-
// After explicit invalidation, should reflect the DB mutation
|
|
366
|
+
// After explicit invalidation, should reflect the DB mutation and reconcile
|
|
367
|
+
// missing plan tasks instead of prematurely summarizing a partial DB row set.
|
|
359
368
|
invalidateStateCache();
|
|
360
369
|
const state3 = await deriveState(base);
|
|
361
|
-
assert.equal(state3.phase, "
|
|
370
|
+
assert.equal(state3.phase, "executing", "after cache invalidation should continue with the missing plan task");
|
|
371
|
+
assert.equal(state3.activeTask?.id, "T02", "missing plan task T02 should be imported and selected");
|
|
372
|
+
assert.deepEqual(state3.progress?.tasks, { done: 1, total: 2 });
|
|
362
373
|
});
|
|
363
374
|
|
|
364
375
|
test("corrupt ROADMAP: binary content does not crash deriveState", async () => {
|
|
@@ -691,7 +702,7 @@ describe("transition boundary failures", () => {
|
|
|
691
702
|
);
|
|
692
703
|
});
|
|
693
704
|
|
|
694
|
-
test("blocked state: all slices have unmet deps →
|
|
705
|
+
test("blocked state: all slices have unmet deps → blocks", async () => {
|
|
695
706
|
base = makeTempDir();
|
|
696
707
|
const mDir = join(base, ".gsd", "milestones", "M001");
|
|
697
708
|
mkdirSync(join(mDir, "slices", "S01", "tasks"), { recursive: true });
|
|
@@ -736,9 +747,9 @@ describe("transition boundary failures", () => {
|
|
|
736
747
|
|
|
737
748
|
invalidateAllCaches();
|
|
738
749
|
const state = await deriveStateFromDb(base);
|
|
739
|
-
|
|
740
|
-
assert.equal(state.
|
|
741
|
-
assert.ok(state.
|
|
750
|
+
assert.equal(state.phase, "blocked", "circular deps: no slice should be selected through unmet deps");
|
|
751
|
+
assert.equal(state.activeSlice, null, "activeSlice should remain null when all deps are blocked");
|
|
752
|
+
assert.ok(state.blockers.some(b => b.includes("No slice eligible")));
|
|
742
753
|
});
|
|
743
754
|
});
|
|
744
755
|
|
|
@@ -868,6 +879,132 @@ describe("dispatch failure modes", () => {
|
|
|
868
879
|
// run-uat should come before uat-verdict-gate
|
|
869
880
|
assert.ok(runUatIdx < uatGateIdx, "run-uat should precede uat-verdict-gate");
|
|
870
881
|
});
|
|
882
|
+
|
|
883
|
+
test("UAT verdict gate: ASSESSMENT FAIL blocks closed slice progression", async () => {
|
|
884
|
+
base = createFullFixture();
|
|
885
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
886
|
+
insertMilestone({ id: "M001", title: "Active", status: "active" });
|
|
887
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "complete" });
|
|
888
|
+
insertSlice({ id: "S02", milestoneId: "M001", title: "Second", status: "pending" });
|
|
889
|
+
|
|
890
|
+
const s01Dir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
891
|
+
writeFileSync(
|
|
892
|
+
join(s01Dir, "S01-UAT.md"),
|
|
893
|
+
"# UAT File\n\n## UAT Type\n\n- UAT mode: artifact-driven\n",
|
|
894
|
+
);
|
|
895
|
+
writeFileSync(
|
|
896
|
+
join(s01Dir, "S01-ASSESSMENT.md"),
|
|
897
|
+
"---\nverdict: FAIL\n---\n# UAT Assessment\n",
|
|
898
|
+
);
|
|
899
|
+
|
|
900
|
+
const ctx = buildDispatchCtx(base, "M001", {
|
|
901
|
+
phase: "planning",
|
|
902
|
+
activeSlice: { id: "S02", title: "Second" },
|
|
903
|
+
activeTask: null,
|
|
904
|
+
});
|
|
905
|
+
ctx.prefs = { uat_dispatch: true } as any;
|
|
906
|
+
|
|
907
|
+
const result = await getUatVerdictGate().match(ctx);
|
|
908
|
+
assert.equal(result?.action, "stop", "ASSESSMENT FAIL should block progression");
|
|
909
|
+
assert.ok(
|
|
910
|
+
(result as any).reason?.includes('UAT verdict for S01 is "fail"'),
|
|
911
|
+
"stop reason should report normalized ASSESSMENT verdict",
|
|
912
|
+
);
|
|
913
|
+
});
|
|
914
|
+
|
|
915
|
+
test("UAT verdict gate: ROADMAP fallback gates done slices when DB is unavailable", async () => {
|
|
916
|
+
base = createFullFixture();
|
|
917
|
+
const mDir = join(base, ".gsd", "milestones", "M001");
|
|
918
|
+
writeFileSync(
|
|
919
|
+
join(mDir, "M001-ROADMAP.md"),
|
|
920
|
+
[
|
|
921
|
+
"# M001: Edge Case Milestone",
|
|
922
|
+
"",
|
|
923
|
+
"## Vision",
|
|
924
|
+
"Prove edge case correctness.",
|
|
925
|
+
"",
|
|
926
|
+
"## Success Criteria",
|
|
927
|
+
"- All edge cases handled",
|
|
928
|
+
"",
|
|
929
|
+
"## Slices",
|
|
930
|
+
"",
|
|
931
|
+
"- [x] **S01: First Feature** `risk:low` `depends:[]`",
|
|
932
|
+
" - After this: First feature proven.",
|
|
933
|
+
"",
|
|
934
|
+
"- [ ] **S02: Second Feature** `risk:low` `depends:[]`",
|
|
935
|
+
" - After this: Second feature proven.",
|
|
936
|
+
"",
|
|
937
|
+
"## Boundary Map",
|
|
938
|
+
"",
|
|
939
|
+
"| From | To | Produces | Consumes |",
|
|
940
|
+
"|------|----|----------|----------|",
|
|
941
|
+
"| S01 | terminal | feature-a | nothing |",
|
|
942
|
+
"| S02 | terminal | feature-b | nothing |",
|
|
943
|
+
].join("\n"),
|
|
944
|
+
);
|
|
945
|
+
|
|
946
|
+
const s01Dir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
947
|
+
writeFileSync(
|
|
948
|
+
join(s01Dir, "S01-UAT.md"),
|
|
949
|
+
"# UAT File\n\n## UAT Type\n\n- UAT mode: artifact-driven\n",
|
|
950
|
+
);
|
|
951
|
+
writeFileSync(
|
|
952
|
+
join(s01Dir, "S01-ASSESSMENT.md"),
|
|
953
|
+
"---\nverdict: needs-remediation\n---\n# UAT Assessment\n",
|
|
954
|
+
);
|
|
955
|
+
|
|
956
|
+
const ctx = buildDispatchCtx(base, "M001", {
|
|
957
|
+
phase: "planning",
|
|
958
|
+
activeSlice: { id: "S02", title: "Second" },
|
|
959
|
+
activeTask: null,
|
|
960
|
+
});
|
|
961
|
+
ctx.prefs = { uat_dispatch: true } as any;
|
|
962
|
+
|
|
963
|
+
const result = await getUatVerdictGate().match(ctx);
|
|
964
|
+
assert.equal(result?.action, "stop", "ROADMAP done slices should be gated without DB");
|
|
965
|
+
assert.ok(
|
|
966
|
+
(result as any).reason?.includes('UAT verdict for S01 is "needs-remediation"'),
|
|
967
|
+
"stop reason should report normalized ASSESSMENT verdict from disk fallback",
|
|
968
|
+
);
|
|
969
|
+
});
|
|
970
|
+
|
|
971
|
+
for (const status of ["done", "skipped"]) {
|
|
972
|
+
test(`UAT verdict gate: legacy closed status "${status}" is gated`, async () => {
|
|
973
|
+
base = createFullFixture();
|
|
974
|
+
openDatabase(join(base, ".gsd", "gsd.db"));
|
|
975
|
+
insertMilestone({ id: "M001", title: "Active", status: "active" });
|
|
976
|
+
insertSlice({ id: "S01", milestoneId: "M001", title: "First", status });
|
|
977
|
+
insertSlice({ id: "S02", milestoneId: "M001", title: "Second", status: "pending" });
|
|
978
|
+
|
|
979
|
+
const s01Dir = join(base, ".gsd", "milestones", "M001", "slices", "S01");
|
|
980
|
+
writeFileSync(
|
|
981
|
+
join(s01Dir, "S01-UAT.md"),
|
|
982
|
+
"# UAT File\n\n## UAT Type\n\n- UAT mode: artifact-driven\n",
|
|
983
|
+
);
|
|
984
|
+
writeFileSync(
|
|
985
|
+
join(s01Dir, "S01-ASSESSMENT.md"),
|
|
986
|
+
"---\nverdict: needs-remediation\n---\n# UAT Assessment\n",
|
|
987
|
+
);
|
|
988
|
+
|
|
989
|
+
const ctx = buildDispatchCtx(base, "M001", {
|
|
990
|
+
phase: "planning",
|
|
991
|
+
activeSlice: { id: "S02", title: "Second" },
|
|
992
|
+
activeTask: null,
|
|
993
|
+
});
|
|
994
|
+
ctx.prefs = { uat_dispatch: true } as any;
|
|
995
|
+
|
|
996
|
+
const result = await getUatVerdictGate().match(ctx);
|
|
997
|
+
assert.equal(
|
|
998
|
+
result?.action,
|
|
999
|
+
"stop",
|
|
1000
|
+
`${status} slices should be treated as closed for UAT verdict gating`,
|
|
1001
|
+
);
|
|
1002
|
+
assert.ok(
|
|
1003
|
+
(result as any).reason?.includes('UAT verdict for S01 is "needs-remediation"'),
|
|
1004
|
+
"stop reason should report normalized ASSESSMENT verdict",
|
|
1005
|
+
);
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
871
1008
|
});
|
|
872
1009
|
|
|
873
1010
|
// ─────────────────────────────────────────────────────────────────────────
|
|
@@ -1155,7 +1292,7 @@ describe("dispatch guard integration", () => {
|
|
|
1155
1292
|
assert.ok(existsSync(validationPath), "VALIDATION file should be written");
|
|
1156
1293
|
const content = readFileSync(validationPath, "utf-8");
|
|
1157
1294
|
assert.ok(content.includes("verdict: pass"), "should contain pass verdict");
|
|
1158
|
-
assert.ok(content.includes("
|
|
1295
|
+
assert.ok(content.includes("`skip_milestone_validation` preference"), "should note it was skipped via the preference path (#4781)");
|
|
1159
1296
|
});
|
|
1160
1297
|
|
|
1161
1298
|
test("rewrite-docs circuit breaker: exceeding MAX attempts resolves all overrides", async () => {
|
package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts
CHANGED
|
@@ -936,9 +936,11 @@ describe("state-machine-live-validation", () => {
|
|
|
936
936
|
insertMilestone({ id: "M001", title: "Active", status: "active" });
|
|
937
937
|
insertSlice({ id: "S01", milestoneId: "M001", title: "First", status: "in_progress" });
|
|
938
938
|
insertTask({ id: "T01", sliceId: "S01", milestoneId: "M001", status: "pending" });
|
|
939
|
+
insertTask({ id: "T02", sliceId: "S01", milestoneId: "M001", status: "pending" });
|
|
939
940
|
|
|
940
941
|
// Complete task + slice
|
|
941
942
|
await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
|
|
943
|
+
await handleCompleteTask(makeTaskParams("T02", "S01", "M001") as any, base);
|
|
942
944
|
await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
|
|
943
945
|
assert.ok(isClosedStatus(getSlice("M001", "S01")!.status));
|
|
944
946
|
|
|
@@ -946,9 +948,11 @@ describe("state-machine-live-validation", () => {
|
|
|
946
948
|
await handleReopenSlice({ milestoneId: "M001", sliceId: "S01" }, base);
|
|
947
949
|
assert.equal(getSlice("M001", "S01")!.status, "in_progress");
|
|
948
950
|
assert.equal(getTask("M001", "S01", "T01")!.status, "pending");
|
|
951
|
+
assert.equal(getTask("M001", "S01", "T02")!.status, "pending");
|
|
949
952
|
|
|
950
953
|
// Re-complete task + slice succeeds
|
|
951
954
|
await handleCompleteTask(makeTaskParams("T01", "S01", "M001") as any, base);
|
|
955
|
+
await handleCompleteTask(makeTaskParams("T02", "S01", "M001") as any, base);
|
|
952
956
|
const r = await handleCompleteSlice(makeSliceParams("S01", "M001") as any, base);
|
|
953
957
|
assert.ok(!("error" in r), `re-complete slice: ${JSON.stringify(r)}`);
|
|
954
958
|
assert.ok(isClosedStatus(getSlice("M001", "S01")!.status));
|
package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts
CHANGED
|
@@ -48,9 +48,7 @@ import type { WindowEntry } from "../../auto/types.ts";
|
|
|
48
48
|
import {
|
|
49
49
|
AutoSession,
|
|
50
50
|
NEW_SESSION_TIMEOUT_MS,
|
|
51
|
-
MAX_UNIT_DISPATCHES,
|
|
52
51
|
STUB_RECOVERY_THRESHOLD,
|
|
53
|
-
MAX_LIFETIME_DISPATCHES,
|
|
54
52
|
} from "../../auto/session.ts";
|
|
55
53
|
|
|
56
54
|
// ── Auto-loop types ──────────────────────────────────────────────────────
|
|
@@ -364,14 +362,6 @@ describe("session management", () => {
|
|
|
364
362
|
assert.equal(NEW_SESSION_TIMEOUT_MS, 120_000, "session timeout should be 120s");
|
|
365
363
|
});
|
|
366
364
|
|
|
367
|
-
test("MAX_UNIT_DISPATCHES limits retries for a single unit", () => {
|
|
368
|
-
assert.equal(MAX_UNIT_DISPATCHES, 3, "max unit dispatches should be 3");
|
|
369
|
-
});
|
|
370
|
-
|
|
371
|
-
test("MAX_LIFETIME_DISPATCHES is the absolute limit per unit", () => {
|
|
372
|
-
assert.equal(MAX_LIFETIME_DISPATCHES, 6, "max lifetime dispatches should be 6");
|
|
373
|
-
});
|
|
374
|
-
|
|
375
365
|
test("STUB_RECOVERY_THRESHOLD triggers recovery after N stub completions", () => {
|
|
376
366
|
assert.equal(STUB_RECOVERY_THRESHOLD, 2, "stub recovery threshold should be 2");
|
|
377
367
|
});
|
|
@@ -392,12 +382,8 @@ describe("session management", () => {
|
|
|
392
382
|
s.unitDispatchCount.set(unitId, 2);
|
|
393
383
|
assert.equal(s.unitDispatchCount.get(unitId), 2);
|
|
394
384
|
|
|
395
|
-
|
|
396
|
-
s.unitDispatchCount.
|
|
397
|
-
assert.ok(
|
|
398
|
-
s.unitDispatchCount.get(unitId)! > MAX_UNIT_DISPATCHES,
|
|
399
|
-
"should track count beyond max for detection",
|
|
400
|
-
);
|
|
385
|
+
s.unitDispatchCount.set(unitId, 4);
|
|
386
|
+
assert.equal(s.unitDispatchCount.get(unitId), 4);
|
|
401
387
|
});
|
|
402
388
|
|
|
403
389
|
test("AutoSession toJSON() provides diagnostic snapshot", () => {
|
|
@@ -8,6 +8,7 @@ import assert from "node:assert/strict";
|
|
|
8
8
|
import { readFileSync } from "node:fs";
|
|
9
9
|
import { join, dirname } from "node:path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
+
import { extractSourceRegion } from "./test-helpers.ts";
|
|
11
12
|
|
|
12
13
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
14
|
|
|
@@ -62,7 +63,7 @@ describe("interactive routing bypass (#3962)", () => {
|
|
|
62
63
|
);
|
|
63
64
|
// The function should check isAutoMode before routing synthesis
|
|
64
65
|
const fnIdx = modelSelectionSrc.indexOf("function resolvePreferredModelConfig");
|
|
65
|
-
const fnBody = modelSelectionSrc
|
|
66
|
+
const fnBody = extractSourceRegion(modelSelectionSrc, "function resolvePreferredModelConfig");
|
|
66
67
|
assert.ok(
|
|
67
68
|
fnBody.includes("isAutoMode"),
|
|
68
69
|
"resolvePreferredModelConfig should accept isAutoMode parameter",
|
|
@@ -137,8 +138,13 @@ describe("model downgrade notifications always visible (#3962)", () => {
|
|
|
137
138
|
const escalatedIdx = modelSelectionSrc.indexOf("if (escalated)");
|
|
138
139
|
assert.ok(escalatedIdx > 0, "escalation block should exist");
|
|
139
140
|
|
|
140
|
-
// Get the block from "if (escalated)" to the next
|
|
141
|
-
|
|
141
|
+
// Get the block from "if (escalated)" to the next distinctive marker
|
|
142
|
+
// (the capability-override loading that immediately follows).
|
|
143
|
+
const block = extractSourceRegion(
|
|
144
|
+
modelSelectionSrc,
|
|
145
|
+
"if (escalated)",
|
|
146
|
+
"// Load user capability overrides",
|
|
147
|
+
);
|
|
142
148
|
assert.ok(
|
|
143
149
|
block.includes("Tier escalation:"),
|
|
144
150
|
"escalation block should contain the notification",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdirSync,
|
|
3
|
+
import { mkdirSync, rmSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
@@ -126,11 +126,8 @@ test("guided-flow stale paused-session scenario is suppressed when no resumable
|
|
|
126
126
|
}
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
assert.ok(source.includes('unlinkSync(join(gsdRoot(basePath), "runtime", "paused-session.json"))'));
|
|
135
|
-
assert.ok(source.includes('pendingAutoStartMap.set(basePath,'));
|
|
136
|
-
});
|
|
129
|
+
// Note: the prior source-grep test that scanned guided-flow.ts for five
|
|
130
|
+
// string literals was removed under #4827. The invariants it encoded
|
|
131
|
+
// (step-aware resume + stale paused-session cleanup + pendingAutoStartMap
|
|
132
|
+
// side effect) should be covered by a runtime drive of guided-flow —
|
|
133
|
+
// tracked as a follow-up.
|
|
@@ -21,6 +21,13 @@ import type { IterationContext, LoopState, PreDispatchData, IterationData } from
|
|
|
21
21
|
import type { SessionLockStatus } from "../session-lock.js";
|
|
22
22
|
import { runDispatch, runUnitPhase, runPreDispatch, runFinalize } from "../auto/phases.js";
|
|
23
23
|
import { readUnitRuntimeRecord } from "../unit-runtime.js";
|
|
24
|
+
import {
|
|
25
|
+
closeDatabase,
|
|
26
|
+
insertMilestone,
|
|
27
|
+
insertSlice,
|
|
28
|
+
insertTask,
|
|
29
|
+
openDatabase,
|
|
30
|
+
} from "../gsd-db.js";
|
|
24
31
|
|
|
25
32
|
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
26
33
|
|
|
@@ -644,6 +651,63 @@ test("terminal event is emitted on blocked state", async () => {
|
|
|
644
651
|
assert.deepEqual((terminalEvents[0].data as any).blockers, ["Missing API key"]);
|
|
645
652
|
});
|
|
646
653
|
|
|
654
|
+
test("#4671: plan-v2 missing CONTEXT.md reaches dispatch recovery instead of pausing", async () => {
|
|
655
|
+
const basePath = mkdtempSync(join(tmpdir(), "gsd-4671-predispatch-"));
|
|
656
|
+
mkdirSync(join(basePath, ".gsd", "milestones", "M001", "slices", "S01", "tasks"), { recursive: true });
|
|
657
|
+
openDatabase(join(basePath, ".gsd", "gsd.db"));
|
|
658
|
+
try {
|
|
659
|
+
insertMilestone({ id: "M001", title: "Test", status: "active" });
|
|
660
|
+
insertSlice({
|
|
661
|
+
id: "S01",
|
|
662
|
+
milestoneId: "M001",
|
|
663
|
+
title: "Slice 1",
|
|
664
|
+
status: "in_progress",
|
|
665
|
+
sequence: 1,
|
|
666
|
+
});
|
|
667
|
+
insertTask({
|
|
668
|
+
id: "T01",
|
|
669
|
+
milestoneId: "M001",
|
|
670
|
+
sliceId: "S01",
|
|
671
|
+
title: "Task 1",
|
|
672
|
+
status: "pending",
|
|
673
|
+
keyFiles: ["src/task.ts"],
|
|
674
|
+
sequence: 1,
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
let pauseCalls = 0;
|
|
678
|
+
const capture = createEventCapture();
|
|
679
|
+
const deps = makeMockDeps(capture, {
|
|
680
|
+
pauseAuto: async () => { pauseCalls++; },
|
|
681
|
+
deriveState: async () => ({
|
|
682
|
+
phase: "executing",
|
|
683
|
+
activeMilestone: { id: "M001", title: "Test", status: "active" },
|
|
684
|
+
activeSlice: { id: "S01", title: "Slice 1" },
|
|
685
|
+
activeTask: { id: "T01", title: "Task 1" },
|
|
686
|
+
registry: [{ id: "M001", status: "active" }],
|
|
687
|
+
blockers: [],
|
|
688
|
+
recentDecisions: [],
|
|
689
|
+
nextAction: "dispatch",
|
|
690
|
+
}) as any,
|
|
691
|
+
});
|
|
692
|
+
const ic = makeIC(deps, {
|
|
693
|
+
prefs: { uok: { plan_v2: { enabled: true } } } as any,
|
|
694
|
+
});
|
|
695
|
+
ic.s.basePath = basePath;
|
|
696
|
+
|
|
697
|
+
const result = await runPreDispatch(ic, {
|
|
698
|
+
recentUnits: [],
|
|
699
|
+
stuckRecoveryAttempts: 0,
|
|
700
|
+
consecutiveFinalizeTimeouts: 0,
|
|
701
|
+
});
|
|
702
|
+
|
|
703
|
+
assert.equal(result.action, "next");
|
|
704
|
+
assert.equal(pauseCalls, 0, "missing CONTEXT.md should be handled by dispatch recovery, not plan gate pause");
|
|
705
|
+
} finally {
|
|
706
|
+
closeDatabase();
|
|
707
|
+
rmSync(basePath, { recursive: true, force: true });
|
|
708
|
+
}
|
|
709
|
+
});
|
|
710
|
+
|
|
647
711
|
test("milestone-transition event is emitted when milestone changes", async () => {
|
|
648
712
|
const capture = createEventCapture();
|
|
649
713
|
const deps = makeMockDeps(capture, {
|
|
@@ -15,7 +15,7 @@ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync, realpathSy
|
|
|
15
15
|
import { join } from 'node:path';
|
|
16
16
|
import { tmpdir } from 'node:os';
|
|
17
17
|
import { GSD_ROOT_FILES, resolveGsdRootFile } from '../paths.ts';
|
|
18
|
-
import { inlineGsdRootFile } from '../auto-prompts.ts';
|
|
18
|
+
import { inlineGsdRootFile, inlineKnowledgeBudgeted } from '../auto-prompts.ts';
|
|
19
19
|
import { appendKnowledge } from '../files.ts';
|
|
20
20
|
import { loadKnowledgeBlock } from '../bootstrap/system-context.ts';
|
|
21
21
|
|
|
@@ -248,3 +248,95 @@ test('loadKnowledgeBlock: reports globalSizeKb above 4KB threshold', () => {
|
|
|
248
248
|
|
|
249
249
|
rmSync(tmp, { recursive: true, force: true });
|
|
250
250
|
});
|
|
251
|
+
|
|
252
|
+
// ─── inlineKnowledgeBudgeted — issue #4719 ─────────────────────────────────
|
|
253
|
+
// Milestone-phase prompts must not inject the full KNOWLEDGE.md. The budgeted
|
|
254
|
+
// helper scopes by milestone-level keywords and caps the injected size.
|
|
255
|
+
|
|
256
|
+
test('inlineKnowledgeBudgeted: returns scoped H3 entries for single-H2 file', async () => {
|
|
257
|
+
const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-knowledge-')));
|
|
258
|
+
const gsdDir = join(tmp, '.gsd');
|
|
259
|
+
mkdirSync(gsdDir, { recursive: true });
|
|
260
|
+
|
|
261
|
+
const content = `# Project Knowledge
|
|
262
|
+
|
|
263
|
+
## Patterns
|
|
264
|
+
|
|
265
|
+
### Database: prepared statements
|
|
266
|
+
Always use prepared statements with SQLite.
|
|
267
|
+
|
|
268
|
+
### API: versioned paths
|
|
269
|
+
Use /v1/resource style versioning.
|
|
270
|
+
|
|
271
|
+
### Testing: node:test
|
|
272
|
+
Prefer node:test over external frameworks.
|
|
273
|
+
`;
|
|
274
|
+
writeFileSync(join(gsdDir, 'KNOWLEDGE.md'), content);
|
|
275
|
+
|
|
276
|
+
const result = await inlineKnowledgeBudgeted(tmp, ['database']);
|
|
277
|
+
assert.ok(result !== null, 'should return content');
|
|
278
|
+
assert.ok(result!.includes('Database: prepared statements'), 'includes matching H3');
|
|
279
|
+
assert.ok(!result!.includes('API: versioned paths'), 'excludes non-matching H3');
|
|
280
|
+
|
|
281
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
test('inlineKnowledgeBudgeted: caps payload below budget for large files', async () => {
|
|
285
|
+
const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-knowledge-')));
|
|
286
|
+
const gsdDir = join(tmp, '.gsd');
|
|
287
|
+
mkdirSync(gsdDir, { recursive: true });
|
|
288
|
+
|
|
289
|
+
// Build a 200KB KNOWLEDGE with 500 H3 entries all matching 'shared'
|
|
290
|
+
const entries = Array.from({ length: 500 }, (_, i) =>
|
|
291
|
+
`### Entry ${i}: shared topic\n${'filler text '.repeat(30)}\n`,
|
|
292
|
+
).join('\n');
|
|
293
|
+
const content = `# Project Knowledge\n\n## Patterns\n\n${entries}`;
|
|
294
|
+
writeFileSync(join(gsdDir, 'KNOWLEDGE.md'), content);
|
|
295
|
+
|
|
296
|
+
const BUDGET_CHARS = 30_000;
|
|
297
|
+
const result = await inlineKnowledgeBudgeted(tmp, ['shared'], { maxChars: BUDGET_CHARS });
|
|
298
|
+
assert.ok(result !== null, 'should return content');
|
|
299
|
+
// Allow some overhead for header formatting, but must stay close to budget
|
|
300
|
+
assert.ok(
|
|
301
|
+
result!.length <= BUDGET_CHARS + 500,
|
|
302
|
+
`payload ${result!.length} chars should be <= budget ${BUDGET_CHARS} (+overhead)`,
|
|
303
|
+
);
|
|
304
|
+
// Far smaller than the raw file
|
|
305
|
+
assert.ok(
|
|
306
|
+
result!.length < content.length / 4,
|
|
307
|
+
`payload should be much smaller than full content (${content.length} chars)`,
|
|
308
|
+
);
|
|
309
|
+
assert.match(
|
|
310
|
+
result!,
|
|
311
|
+
/\[\.\.\.truncated \d+ chars; rerun with narrower scope if needed\]/,
|
|
312
|
+
'should include truncation note when budget is exceeded',
|
|
313
|
+
);
|
|
314
|
+
|
|
315
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
test('inlineKnowledgeBudgeted: returns null when no KNOWLEDGE.md exists', async () => {
|
|
319
|
+
const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-knowledge-')));
|
|
320
|
+
const gsdDir = join(tmp, '.gsd');
|
|
321
|
+
mkdirSync(gsdDir, { recursive: true });
|
|
322
|
+
|
|
323
|
+
const result = await inlineKnowledgeBudgeted(tmp, ['database']);
|
|
324
|
+
assert.strictEqual(result, null);
|
|
325
|
+
|
|
326
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
test('inlineKnowledgeBudgeted: returns null when no entries match', async () => {
|
|
330
|
+
const tmp = realpathSync(mkdtempSync(join(tmpdir(), 'gsd-knowledge-')));
|
|
331
|
+
const gsdDir = join(tmp, '.gsd');
|
|
332
|
+
mkdirSync(gsdDir, { recursive: true });
|
|
333
|
+
writeFileSync(
|
|
334
|
+
join(gsdDir, 'KNOWLEDGE.md'),
|
|
335
|
+
'# Project Knowledge\n\n## Patterns\n\n### Database\nuse it\n',
|
|
336
|
+
);
|
|
337
|
+
|
|
338
|
+
const result = await inlineKnowledgeBudgeted(tmp, ['nonexistent']);
|
|
339
|
+
assert.strictEqual(result, null);
|
|
340
|
+
|
|
341
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
342
|
+
});
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
3
|
|
|
5
4
|
import {
|
|
6
5
|
_buildMcpChildEnvForTest,
|
|
7
6
|
_buildMcpTrustConfirmOptionsForTest,
|
|
8
7
|
} from "../../mcp-client/index.ts";
|
|
9
8
|
|
|
9
|
+
// Note: four source-grep tests that scanned `mcp-client/index.ts` for
|
|
10
|
+
// Map<> shapes, catch-block structure, and closeAll body were removed
|
|
11
|
+
// under #4827. They encoded implementation shape rather than behaviour —
|
|
12
|
+
// any refactor (extracted helper, different Map key type, rearranged
|
|
13
|
+
// cleanup order) broke the greps without a real regression. Runtime
|
|
14
|
+
// coverage of connectServer/closeAll with a mocked failing transport
|
|
15
|
+
// is tracked as a follow-up.
|
|
16
|
+
|
|
10
17
|
test("MCP stdio child env only includes safe inherited keys plus explicit config env", () => {
|
|
11
18
|
const previousSecret = process.env.SECRET_MCP_TEST_TOKEN;
|
|
12
19
|
const previousPath = process.env.PATH;
|
|
@@ -38,39 +45,3 @@ test("MCP stdio trust confirmation is abort-aware", () => {
|
|
|
38
45
|
assert.equal(options.timeout, 120_000);
|
|
39
46
|
assert.equal(options.signal, controller.signal);
|
|
40
47
|
});
|
|
41
|
-
|
|
42
|
-
test("MCP client uses a single in-flight connection per canonical server", () => {
|
|
43
|
-
const source = readFileSync(new URL("../../mcp-client/index.ts", import.meta.url), "utf8");
|
|
44
|
-
|
|
45
|
-
assert.match(source, /const pendingConnections = new Map<string, Promise<Client>>\(\)/);
|
|
46
|
-
assert.match(source, /const pending = pendingConnections\.get\(config\.name\)/);
|
|
47
|
-
assert.match(source, /pendingConnections\.set\(config\.name, connectionPromise\)/);
|
|
48
|
-
assert.match(source, /pendingConnections\.delete\(config\.name\)/);
|
|
49
|
-
assert.match(source, /env: config\.env \?\? \{\}/);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test("MCP stdio trust is persisted only after a successful connection", () => {
|
|
53
|
-
const source = readFileSync(new URL("../../mcp-client/index.ts", import.meta.url), "utf8");
|
|
54
|
-
const connectIndex = source.indexOf("await client.connect(transport");
|
|
55
|
-
const trustIndex = source.indexOf("trustedStdioServers.add(approvedTrustKey)");
|
|
56
|
-
|
|
57
|
-
assert.ok(connectIndex > -1, "connectServer should await client.connect");
|
|
58
|
-
assert.ok(trustIndex > connectIndex, "trust should be recorded after client.connect succeeds");
|
|
59
|
-
assert.doesNotMatch(source, /assertTrustedStdioServer[\s\S]*trustedStdioServers\.add\(trustKey\)/);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test("MCP client closes transports after failed connection attempts", () => {
|
|
63
|
-
const source = readFileSync(new URL("../../mcp-client/index.ts", import.meta.url), "utf8");
|
|
64
|
-
|
|
65
|
-
assert.match(source, /catch \(err\) \{[\s\S]*await transport\.close\(\)/);
|
|
66
|
-
assert.match(source, /catch \(err\) \{[\s\S]*await client\.close\(\)/);
|
|
67
|
-
assert.match(source, /catch \(err\) \{[\s\S]*throw err/);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("MCP client clears process-local trust and closes transports on session cleanup", () => {
|
|
71
|
-
const source = readFileSync(new URL("../../mcp-client/index.ts", import.meta.url), "utf8");
|
|
72
|
-
|
|
73
|
-
assert.match(source, /async function closeAll\(\)[\s\S]*await conn\.transport\.close\(\)/);
|
|
74
|
-
assert.match(source, /async function closeAll\(\)[\s\S]*pendingConnections\.clear\(\)/);
|
|
75
|
-
assert.match(source, /async function closeAll\(\)[\s\S]*trustedStdioServers\.clear\(\)/);
|
|
76
|
-
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseMemoryResponse,
|
|
1
|
+
import { parseMemoryResponse, buildMemoryLLMCall } from '../memory-extractor.ts';
|
|
2
2
|
import {
|
|
3
3
|
openDatabase,
|
|
4
4
|
closeDatabase,
|
|
@@ -159,16 +159,6 @@ test('integration: mixed action lifecycle', () => {
|
|
|
159
159
|
closeDatabase();
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
163
|
-
// memory-extractor: _resetExtractionState
|
|
164
|
-
// ═══════════════════════════════════════════════════════════════════════════
|
|
165
|
-
|
|
166
|
-
test('memory-extractor: reset extraction state', () => {
|
|
167
|
-
// Just verify it doesn't throw
|
|
168
|
-
_resetExtractionState();
|
|
169
|
-
assert.ok(true, '_resetExtractionState should not throw');
|
|
170
|
-
});
|
|
171
|
-
|
|
172
162
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
173
163
|
// memory-extractor: buildMemoryLLMCall resolves OAuth API key via modelRegistry
|
|
174
164
|
// Regression test for #2959 — OAuth users had broken memory extraction
|
|
@@ -200,8 +190,8 @@ test('memory-extractor: buildMemoryLLMCall resolves API key from modelRegistry f
|
|
|
200
190
|
assert.ok(llmCallFn !== null, 'buildMemoryLLMCall should return a function when models are available');
|
|
201
191
|
|
|
202
192
|
// The function should have resolved the API key eagerly via modelRegistry.getApiKey.
|
|
203
|
-
//
|
|
204
|
-
await
|
|
193
|
+
// Await the exposed promise deterministically instead of polling via setTimeout.
|
|
194
|
+
await llmCallFn!.apiKeyReady;
|
|
205
195
|
assert.ok(getApiKeyCalled, 'buildMemoryLLMCall must call modelRegistry.getApiKey() to resolve OAuth tokens');
|
|
206
196
|
});
|
|
207
197
|
|
|
@@ -246,8 +236,8 @@ test('memory-extractor: buildMemoryLLMCall prefers haiku model', async () => {
|
|
|
246
236
|
const llmCallFn = buildMemoryLLMCall(ctx);
|
|
247
237
|
assert.ok(llmCallFn !== null, 'should return a function');
|
|
248
238
|
|
|
249
|
-
//
|
|
250
|
-
await
|
|
239
|
+
// Await the exposed API-key-ready promise deterministically.
|
|
240
|
+
await llmCallFn!.apiKeyReady;
|
|
251
241
|
assert.strictEqual(resolvedModelId, 'claude-3-5-haiku-20241022',
|
|
252
242
|
'should resolve API key for haiku model, not sonnet');
|
|
253
243
|
});
|