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
|
@@ -387,6 +387,126 @@ export function formatAskUserQuestionsElicitResult(
|
|
|
387
387
|
return JSON.stringify({ answers });
|
|
388
388
|
}
|
|
389
389
|
|
|
390
|
+
// ---------------------------------------------------------------------------
|
|
391
|
+
// secure_env_collect handler (extracted so tests can drive it directly)
|
|
392
|
+
// ---------------------------------------------------------------------------
|
|
393
|
+
|
|
394
|
+
export type ElicitInputFn = (params: {
|
|
395
|
+
message: string;
|
|
396
|
+
requestedSchema: { type: 'object'; properties: Record<string, unknown>; required: string[] };
|
|
397
|
+
}) => Promise<{ action: 'accept' | 'cancel' | 'decline'; content?: Record<string, unknown> }>;
|
|
398
|
+
|
|
399
|
+
type ToolContent =
|
|
400
|
+
| { content: Array<{ type: 'text'; text: string }> }
|
|
401
|
+
| { isError: true; content: Array<{ type: 'text'; text: string }> };
|
|
402
|
+
|
|
403
|
+
export async function secureEnvCollectHandler(
|
|
404
|
+
args: Record<string, unknown>,
|
|
405
|
+
elicitInput: ElicitInputFn,
|
|
406
|
+
): Promise<ToolContent> {
|
|
407
|
+
const { projectDir, keys, destination, envFilePath, environment } = args as {
|
|
408
|
+
projectDir: string;
|
|
409
|
+
keys: Array<{ key: string; hint?: string; guidance?: string[] }>;
|
|
410
|
+
destination?: 'dotenv' | 'vercel' | 'convex';
|
|
411
|
+
envFilePath?: string;
|
|
412
|
+
environment?: 'development' | 'preview' | 'production';
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
try {
|
|
416
|
+
const resolvedProjectDir = validateProjectDir(projectDir);
|
|
417
|
+
const resolvedEnvPath = resolveProjectEnvFilePath(resolvedProjectDir, envFilePath ?? '.env');
|
|
418
|
+
|
|
419
|
+
// (1) Check which keys already exist
|
|
420
|
+
const allKeyNames = keys.map((k) => k.key);
|
|
421
|
+
const existingKeys = await checkExistingEnvKeys(allKeyNames, resolvedEnvPath);
|
|
422
|
+
const existingSet = new Set(existingKeys);
|
|
423
|
+
const pendingKeys = keys.filter((k) => !existingSet.has(k.key));
|
|
424
|
+
|
|
425
|
+
// If all keys already exist, return immediately
|
|
426
|
+
if (pendingKeys.length === 0) {
|
|
427
|
+
const lines = existingKeys.map((k) => `• ${k}: already set`);
|
|
428
|
+
return textContent(`All ${existingKeys.length} key(s) already set.\n${lines.join('\n')}`);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
// (2) Build elicitation form — one string field per pending key
|
|
432
|
+
const properties: Record<string, Record<string, unknown>> = {};
|
|
433
|
+
const required: string[] = [];
|
|
434
|
+
|
|
435
|
+
for (const item of pendingKeys) {
|
|
436
|
+
const descParts: string[] = [];
|
|
437
|
+
if (item.hint) descParts.push(`Format: ${item.hint}`);
|
|
438
|
+
if (item.guidance && item.guidance.length > 0) {
|
|
439
|
+
descParts.push('How to get this:');
|
|
440
|
+
item.guidance.forEach((step, i) => descParts.push(`${i + 1}. ${step}`));
|
|
441
|
+
}
|
|
442
|
+
descParts.push('Leave empty to skip.');
|
|
443
|
+
|
|
444
|
+
properties[item.key] = {
|
|
445
|
+
type: 'string',
|
|
446
|
+
title: item.key,
|
|
447
|
+
description: descParts.join('\n'),
|
|
448
|
+
};
|
|
449
|
+
// Don't mark as required — empty string = skip
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// (3) Elicit input from the MCP client
|
|
453
|
+
const elicitation = await withElicitTimeout(
|
|
454
|
+
elicitInput({
|
|
455
|
+
message: `Enter values for ${pendingKeys.length} environment variable(s). Values are written directly to the project and never shown to the AI.`,
|
|
456
|
+
requestedSchema: {
|
|
457
|
+
type: 'object',
|
|
458
|
+
properties,
|
|
459
|
+
required,
|
|
460
|
+
},
|
|
461
|
+
}),
|
|
462
|
+
'secure_env_collect',
|
|
463
|
+
);
|
|
464
|
+
|
|
465
|
+
if (elicitation.action !== 'accept' || !elicitation.content) {
|
|
466
|
+
return textContent('secure_env_collect was cancelled by user.');
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// (4) Separate provided vs skipped from form response
|
|
470
|
+
const provided: Array<{ key: string; value: string }> = [];
|
|
471
|
+
const skipped: string[] = [];
|
|
472
|
+
|
|
473
|
+
for (const item of pendingKeys) {
|
|
474
|
+
const raw = elicitation.content[item.key];
|
|
475
|
+
const value = typeof raw === 'string' ? raw.trim() : '';
|
|
476
|
+
if (value.length > 0) {
|
|
477
|
+
provided.push({ key: item.key, value });
|
|
478
|
+
} else {
|
|
479
|
+
skipped.push(item.key);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
// (5) Auto-detect destination if not specified
|
|
484
|
+
const resolvedDestination = destination ?? detectDestination(resolvedProjectDir);
|
|
485
|
+
|
|
486
|
+
// (6) Write secrets to destination
|
|
487
|
+
const { applied, errors } = await applySecrets(provided, resolvedDestination, {
|
|
488
|
+
envFilePath: resolvedEnvPath,
|
|
489
|
+
environment,
|
|
490
|
+
execFn: defaultExecFn,
|
|
491
|
+
});
|
|
492
|
+
|
|
493
|
+
// (7) Build result — NEVER include secret values
|
|
494
|
+
const lines: string[] = [
|
|
495
|
+
`destination: ${resolvedDestination}${!destination ? ' (auto-detected)' : ''}${environment ? ` (${environment})` : ''}`,
|
|
496
|
+
];
|
|
497
|
+
for (const k of applied) lines.push(`✓ ${k}: applied`);
|
|
498
|
+
for (const k of skipped) lines.push(`• ${k}: skipped`);
|
|
499
|
+
for (const k of existingKeys) lines.push(`• ${k}: already set`);
|
|
500
|
+
for (const e of errors) lines.push(`✗ ${e}`);
|
|
501
|
+
|
|
502
|
+
return errors.length > 0 && applied.length === 0
|
|
503
|
+
? errorContent(lines.join('\n'))
|
|
504
|
+
: textContent(lines.join('\n'));
|
|
505
|
+
} catch (err) {
|
|
506
|
+
return errorContent(err instanceof Error ? err.message : String(err));
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
390
510
|
// ---------------------------------------------------------------------------
|
|
391
511
|
// createMcpServer
|
|
392
512
|
// ---------------------------------------------------------------------------
|
|
@@ -397,12 +517,17 @@ export function formatAskUserQuestionsElicitResult(
|
|
|
397
517
|
* Returns the McpServer instance — call `connect(transport)` to start serving.
|
|
398
518
|
* Uses dynamic imports for the MCP SDK to avoid TS subpath resolution issues.
|
|
399
519
|
*/
|
|
400
|
-
export async function createMcpServer(
|
|
520
|
+
export async function createMcpServer(
|
|
521
|
+
sessionManager: SessionManager,
|
|
522
|
+
): Promise<{
|
|
401
523
|
server: McpServerInstance;
|
|
402
524
|
}> {
|
|
403
525
|
// Dynamic import — same workaround as src/mcp-server.ts
|
|
404
526
|
const mcpMod = await import(`${MCP_PKG}/server/mcp.js`);
|
|
405
|
-
const McpServer = mcpMod.McpServer
|
|
527
|
+
const McpServer = mcpMod.McpServer as new (
|
|
528
|
+
info: { name: string; version: string },
|
|
529
|
+
opts: { capabilities: Record<string, unknown> },
|
|
530
|
+
) => McpServerInstance;
|
|
406
531
|
|
|
407
532
|
const server: McpServerInstance = new McpServer(
|
|
408
533
|
{ name: SERVER_NAME, version: SERVER_VERSION },
|
|
@@ -678,109 +803,10 @@ export async function createMcpServer(sessionManager: SessionManager): Promise<{
|
|
|
678
803
|
envFilePath: z.string().optional().describe('Path to .env file (dotenv only). Defaults to .env in projectDir.'),
|
|
679
804
|
environment: z.enum(['development', 'preview', 'production']).optional().describe('Target environment (vercel/convex only)'),
|
|
680
805
|
},
|
|
681
|
-
async (args: Record<string, unknown>) =>
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
destination?: 'dotenv' | 'vercel' | 'convex';
|
|
686
|
-
envFilePath?: string;
|
|
687
|
-
environment?: 'development' | 'preview' | 'production';
|
|
688
|
-
};
|
|
689
|
-
|
|
690
|
-
try {
|
|
691
|
-
const resolvedProjectDir = validateProjectDir(projectDir);
|
|
692
|
-
const resolvedEnvPath = resolveProjectEnvFilePath(resolvedProjectDir, envFilePath ?? '.env');
|
|
693
|
-
|
|
694
|
-
// (1) Check which keys already exist
|
|
695
|
-
const allKeyNames = keys.map((k) => k.key);
|
|
696
|
-
const existingKeys = await checkExistingEnvKeys(allKeyNames, resolvedEnvPath);
|
|
697
|
-
const existingSet = new Set(existingKeys);
|
|
698
|
-
const pendingKeys = keys.filter((k) => !existingSet.has(k.key));
|
|
699
|
-
|
|
700
|
-
// If all keys already exist, return immediately
|
|
701
|
-
if (pendingKeys.length === 0) {
|
|
702
|
-
const lines = existingKeys.map((k) => `• ${k}: already set`);
|
|
703
|
-
return textContent(`All ${existingKeys.length} key(s) already set.\n${lines.join('\n')}`);
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
// (2) Build elicitation form — one string field per pending key
|
|
707
|
-
const properties: Record<string, Record<string, unknown>> = {};
|
|
708
|
-
const required: string[] = [];
|
|
709
|
-
|
|
710
|
-
for (const item of pendingKeys) {
|
|
711
|
-
const descParts: string[] = [];
|
|
712
|
-
if (item.hint) descParts.push(`Format: ${item.hint}`);
|
|
713
|
-
if (item.guidance && item.guidance.length > 0) {
|
|
714
|
-
descParts.push('How to get this:');
|
|
715
|
-
item.guidance.forEach((step, i) => descParts.push(`${i + 1}. ${step}`));
|
|
716
|
-
}
|
|
717
|
-
descParts.push('Leave empty to skip.');
|
|
718
|
-
|
|
719
|
-
properties[item.key] = {
|
|
720
|
-
type: 'string',
|
|
721
|
-
title: item.key,
|
|
722
|
-
description: descParts.join('\n'),
|
|
723
|
-
};
|
|
724
|
-
// Don't mark as required — empty string = skip
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
// (3) Elicit input from the MCP client
|
|
728
|
-
const elicitation = await withElicitTimeout(
|
|
729
|
-
server.server.elicitInput({
|
|
730
|
-
message: `Enter values for ${pendingKeys.length} environment variable(s). Values are written directly to the project and never shown to the AI.`,
|
|
731
|
-
requestedSchema: {
|
|
732
|
-
type: 'object',
|
|
733
|
-
properties,
|
|
734
|
-
required,
|
|
735
|
-
},
|
|
736
|
-
}),
|
|
737
|
-
'secure_env_collect',
|
|
738
|
-
);
|
|
739
|
-
|
|
740
|
-
if (elicitation.action !== 'accept' || !elicitation.content) {
|
|
741
|
-
return textContent('secure_env_collect was cancelled by user.');
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
// (4) Separate provided vs skipped from form response
|
|
745
|
-
const provided: Array<{ key: string; value: string }> = [];
|
|
746
|
-
const skipped: string[] = [];
|
|
747
|
-
|
|
748
|
-
for (const item of pendingKeys) {
|
|
749
|
-
const raw = elicitation.content[item.key];
|
|
750
|
-
const value = typeof raw === 'string' ? raw.trim() : '';
|
|
751
|
-
if (value.length > 0) {
|
|
752
|
-
provided.push({ key: item.key, value });
|
|
753
|
-
} else {
|
|
754
|
-
skipped.push(item.key);
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
// (5) Auto-detect destination if not specified
|
|
759
|
-
const resolvedDestination = destination ?? detectDestination(resolvedProjectDir);
|
|
760
|
-
|
|
761
|
-
// (6) Write secrets to destination
|
|
762
|
-
const { applied, errors } = await applySecrets(provided, resolvedDestination, {
|
|
763
|
-
envFilePath: resolvedEnvPath,
|
|
764
|
-
environment,
|
|
765
|
-
execFn: defaultExecFn,
|
|
766
|
-
});
|
|
767
|
-
|
|
768
|
-
// (7) Build result — NEVER include secret values
|
|
769
|
-
const lines: string[] = [
|
|
770
|
-
`destination: ${resolvedDestination}${!destination ? ' (auto-detected)' : ''}${environment ? ` (${environment})` : ''}`,
|
|
771
|
-
];
|
|
772
|
-
for (const k of applied) lines.push(`✓ ${k}: applied`);
|
|
773
|
-
for (const k of skipped) lines.push(`• ${k}: skipped`);
|
|
774
|
-
for (const k of existingKeys) lines.push(`• ${k}: already set`);
|
|
775
|
-
for (const e of errors) lines.push(`✗ ${e}`);
|
|
776
|
-
|
|
777
|
-
return errors.length > 0 && applied.length === 0
|
|
778
|
-
? errorContent(lines.join('\n'))
|
|
779
|
-
: textContent(lines.join('\n'));
|
|
780
|
-
} catch (err) {
|
|
781
|
-
return errorContent(err instanceof Error ? err.message : String(err));
|
|
782
|
-
}
|
|
783
|
-
},
|
|
806
|
+
async (args: Record<string, unknown>) =>
|
|
807
|
+
secureEnvCollectHandler(args, (params) =>
|
|
808
|
+
server.server.elicitInput(params as ElicitRequestFormParams),
|
|
809
|
+
),
|
|
784
810
|
);
|
|
785
811
|
|
|
786
812
|
// =======================================================================
|
|
@@ -712,6 +712,91 @@ export const executeTaskComplete = async (params, projectDir) => {
|
|
|
712
712
|
}
|
|
713
713
|
});
|
|
714
714
|
|
|
715
|
+
it("gsd_plan_milestone rejects a full slice with missing heavy fields via a behavioral round-trip", async () => {
|
|
716
|
+
// Behavioral guard for the full-vs-sketch conditional. The original
|
|
717
|
+
// regression (invisible "required unless isSketch" requirement) is
|
|
718
|
+
// surfaced to users through two distinct runtime channels:
|
|
719
|
+
// 1. A parse-time rejection when the tool is called with empty heavy
|
|
720
|
+
// fields on a non-sketch slice (no isSketch=true).
|
|
721
|
+
// 2. An acceptance when isSketch=true + sketchScope is supplied and
|
|
722
|
+
// heavy fields are omitted.
|
|
723
|
+
// Both arms are exercised below against the live handler — any schema
|
|
724
|
+
// refactor that preserves the user-observable contract (rejection +
|
|
725
|
+
// acceptance) passes, and any refactor that breaks the contract
|
|
726
|
+
// fails, regardless of whether internal `.describe()` prose changes.
|
|
727
|
+
const base = makeTmpBase();
|
|
728
|
+
try {
|
|
729
|
+
const server = makeMockServer();
|
|
730
|
+
registerWorkflowTools(server as any);
|
|
731
|
+
const milestoneTool = server.tools.find((t) => t.name === "gsd_plan_milestone");
|
|
732
|
+
assert.ok(milestoneTool, "milestone planning tool should be registered");
|
|
733
|
+
|
|
734
|
+
// Arm 1: full slice (isSketch omitted) with the heavy fields missing
|
|
735
|
+
// must reject and name ALL four fields so the agent can self-correct.
|
|
736
|
+
let fullError: unknown;
|
|
737
|
+
try {
|
|
738
|
+
await milestoneTool!.handler({
|
|
739
|
+
projectDir: base,
|
|
740
|
+
milestoneId: "M001",
|
|
741
|
+
title: "Full slice path",
|
|
742
|
+
vision: "Behavioral test for isSketch conditional.",
|
|
743
|
+
slices: [
|
|
744
|
+
{
|
|
745
|
+
sliceId: "S01",
|
|
746
|
+
title: "Heavy slice",
|
|
747
|
+
risk: "medium",
|
|
748
|
+
depends: [],
|
|
749
|
+
demo: "Demo.",
|
|
750
|
+
goal: "Goal.",
|
|
751
|
+
// heavy fields intentionally omitted
|
|
752
|
+
},
|
|
753
|
+
],
|
|
754
|
+
});
|
|
755
|
+
} catch (err) {
|
|
756
|
+
fullError = err;
|
|
757
|
+
}
|
|
758
|
+
assert.ok(fullError, "a non-sketch slice without heavy fields must reject");
|
|
759
|
+
const fullMsg = fullError instanceof Error ? fullError.message : String(fullError);
|
|
760
|
+
for (const field of ["successCriteria", "proofLevel", "integrationClosure", "observabilityImpact"]) {
|
|
761
|
+
assert.ok(
|
|
762
|
+
fullMsg.includes(field),
|
|
763
|
+
`rejection must name ${field} so agents can recover without a second round-trip; got: ${fullMsg}`,
|
|
764
|
+
);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Arm 2: sketch slice (isSketch=true + sketchScope) with heavy fields
|
|
768
|
+
// omitted must be accepted — proving the conditional is live. Assert
|
|
769
|
+
// success directly rather than just checking a thrown message omits
|
|
770
|
+
// the heavy-field names: a generic failure would otherwise silently
|
|
771
|
+
// pass this arm.
|
|
772
|
+
const sketchResult = await milestoneTool!.handler({
|
|
773
|
+
projectDir: base,
|
|
774
|
+
milestoneId: "M002",
|
|
775
|
+
title: "Sketch slice path",
|
|
776
|
+
vision: "Behavioral test for isSketch conditional.",
|
|
777
|
+
slices: [
|
|
778
|
+
{
|
|
779
|
+
sliceId: "S01",
|
|
780
|
+
title: "Sketch slice",
|
|
781
|
+
risk: "medium",
|
|
782
|
+
depends: [],
|
|
783
|
+
demo: "Demo.",
|
|
784
|
+
goal: "Goal.",
|
|
785
|
+
isSketch: true,
|
|
786
|
+
sketchScope: "Two-sentence scope. Boundary defined.",
|
|
787
|
+
},
|
|
788
|
+
],
|
|
789
|
+
});
|
|
790
|
+
assert.match(
|
|
791
|
+
(sketchResult as any).content[0].text as string,
|
|
792
|
+
/Planned milestone M002/,
|
|
793
|
+
"sketch slice with isSketch=true must be accepted by the handler",
|
|
794
|
+
);
|
|
795
|
+
} finally {
|
|
796
|
+
cleanup(base);
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
|
|
715
800
|
it("gsd_plan_milestone requires sketchScope when isSketch=true and skips heavy fields", async () => {
|
|
716
801
|
const base = makeTmpBase();
|
|
717
802
|
try {
|
|
@@ -875,6 +875,17 @@ const nonEmptyStringArray = (field: string) =>
|
|
|
875
875
|
// empty/whitespace fields at parse time. Without this, MCP callers pass "" for
|
|
876
876
|
// the heavy planning fields, Zod accepts it, and the executor rejects one
|
|
877
877
|
// field per call — forcing the agent into a retry loop to discover every gap.
|
|
878
|
+
//
|
|
879
|
+
// #4759 follow-up: the four heavy fields are Zod-optional because sketch
|
|
880
|
+
// slices (isSketch=true) legitimately omit them, but they are REQUIRED for
|
|
881
|
+
// every other slice. The conditional requirement is invisible in the JSON
|
|
882
|
+
// Schema `required` array, so callers can only discover it from the
|
|
883
|
+
// descriptions or by hitting the runtime superRefine below. The `.describe()`
|
|
884
|
+
// calls below make that contract unmistakable in the tool schema sent to
|
|
885
|
+
// agents; the superRefine enforces it at parse time.
|
|
886
|
+
const HEAVY_FIELD_DESCRIBE = (field: string) =>
|
|
887
|
+
`${field} for this slice. REQUIRED unless isSketch=true (sketch slices defer this to refine-slice).`;
|
|
888
|
+
|
|
878
889
|
const planMilestoneSliceSchema = z.object({
|
|
879
890
|
sliceId: nonEmptyString("sliceId"),
|
|
880
891
|
title: nonEmptyString("title"),
|
|
@@ -883,14 +894,16 @@ const planMilestoneSliceSchema = z.object({
|
|
|
883
894
|
demo: nonEmptyString("demo"),
|
|
884
895
|
goal: nonEmptyString("goal"),
|
|
885
896
|
// ADR-011: heavy planning fields are optional for sketch slices; required for full slices.
|
|
886
|
-
successCriteria: z.string().optional(),
|
|
887
|
-
proofLevel: z.string().optional(),
|
|
888
|
-
integrationClosure: z.string().optional(),
|
|
889
|
-
observabilityImpact: z.string().optional(),
|
|
897
|
+
successCriteria: z.string().optional().describe(HEAVY_FIELD_DESCRIBE("successCriteria")),
|
|
898
|
+
proofLevel: z.string().optional().describe(HEAVY_FIELD_DESCRIBE("proofLevel")),
|
|
899
|
+
integrationClosure: z.string().optional().describe(HEAVY_FIELD_DESCRIBE("integrationClosure")),
|
|
900
|
+
observabilityImpact: z.string().optional().describe(HEAVY_FIELD_DESCRIBE("observabilityImpact")),
|
|
890
901
|
// ADR-011 sketch-then-refine fields.
|
|
891
|
-
isSketch: z.boolean().optional().describe("ADR-011: true marks this slice as a sketch awaiting refine-slice expansion"),
|
|
902
|
+
isSketch: z.boolean().optional().describe("ADR-011: true marks this slice as a sketch awaiting refine-slice expansion. When true, successCriteria/proofLevel/integrationClosure/observabilityImpact may be omitted and sketchScope becomes required."),
|
|
892
903
|
sketchScope: z.string().optional().describe("ADR-011: 2-3 sentence scope boundary, required when isSketch=true"),
|
|
893
|
-
}).
|
|
904
|
+
}).describe(
|
|
905
|
+
"Planned slice. For full slices (isSketch omitted or false): successCriteria, proofLevel, integrationClosure, and observabilityImpact are all required. For sketch slices (isSketch=true): those four fields may be omitted, but sketchScope is required.",
|
|
906
|
+
).superRefine((slice, ctx) => {
|
|
894
907
|
if (slice.isSketch === true) {
|
|
895
908
|
if (typeof slice.sketchScope !== "string" || slice.sketchScope.trim().length === 0) {
|
|
896
909
|
ctx.addIssue({
|