gsd-pi 2.70.1 → 2.71.0-dev.4c35d99
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 +57 -17
- package/dist/cli.js +29 -3
- package/dist/headless-events.d.ts +2 -0
- package/dist/headless-events.js +7 -0
- package/dist/headless.js +16 -3
- package/dist/mcp-server.js +40 -17
- package/dist/provider-migrations.d.ts +10 -0
- package/dist/provider-migrations.js +12 -0
- package/dist/resource-loader.js +139 -13
- package/dist/resources/GSD-WORKFLOW.md +1 -1
- package/dist/resources/agents/debugger.md +58 -0
- package/dist/resources/agents/doc-writer.md +43 -0
- package/dist/resources/agents/git-ops.md +56 -0
- package/dist/resources/agents/javascript-pro.md +46 -271
- package/dist/resources/agents/planner.md +55 -0
- package/dist/resources/agents/refactorer.md +47 -0
- package/dist/resources/agents/reviewer.md +48 -0
- package/dist/resources/agents/security.md +59 -0
- package/dist/resources/agents/tester.md +50 -0
- package/dist/resources/agents/typescript-pro.md +41 -235
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +242 -40
- package/dist/resources/extensions/get-secrets-from-user.js +17 -1
- package/dist/resources/extensions/gsd/auto/infra-errors.js +34 -0
- package/dist/resources/extensions/gsd/auto/loop.js +32 -1
- package/dist/resources/extensions/gsd/auto/phases.js +5 -1
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +22 -16
- package/dist/resources/extensions/gsd/auto-model-selection.js +10 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +88 -33
- package/dist/resources/extensions/gsd/auto-start.js +37 -18
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +56 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +6 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +63 -51
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +6 -0
- package/dist/resources/extensions/gsd/commands/context.js +15 -6
- package/dist/resources/extensions/gsd/commands/dispatcher.js +12 -2
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -33
- package/dist/resources/extensions/gsd/commands/handlers/core.js +56 -11
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +15 -6
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +4 -10
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +16 -12
- package/dist/resources/extensions/gsd/dashboard-overlay.js +8 -3
- package/dist/resources/extensions/gsd/dispatch-guard.js +18 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +23 -0
- package/dist/resources/extensions/gsd/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/file-lock.js +60 -0
- package/dist/resources/extensions/gsd/forensics.js +19 -6
- package/dist/resources/extensions/gsd/gate-registry.js +208 -0
- package/dist/resources/extensions/gsd/gsd-db.js +41 -0
- package/dist/resources/extensions/gsd/guided-flow.js +17 -20
- package/dist/resources/extensions/gsd/init-wizard.js +3 -11
- package/dist/resources/extensions/gsd/metrics.js +1 -0
- package/dist/resources/extensions/gsd/milestone-actions.js +10 -4
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +11 -12
- package/dist/resources/extensions/gsd/notification-overlay.js +42 -13
- package/dist/resources/extensions/gsd/notification-store.js +56 -5
- package/dist/resources/extensions/gsd/notification-widget.js +5 -13
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +8 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +35 -2
- package/dist/resources/extensions/gsd/prompt-validation.js +126 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/dist/resources/extensions/gsd/prompts/discuss.md +33 -13
- package/dist/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +3 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/dist/resources/extensions/gsd/session-model-override.js +25 -0
- package/dist/resources/extensions/gsd/shortcut-defs.js +40 -0
- package/dist/resources/extensions/gsd/state.js +241 -332
- package/dist/resources/extensions/gsd/tools/complete-slice.js +52 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +51 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +38 -1
- package/dist/resources/extensions/gsd/workflow-events.js +25 -13
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +56 -0
- package/dist/resources/extensions/gsd/workflow-mcp.js +1 -1
- package/dist/resources/extensions/ollama/index.js +13 -5
- package/dist/resources/extensions/shared/gsd-phase-state.js +35 -0
- package/dist/resources/extensions/subagent/agents.js +8 -0
- package/dist/resources/extensions/subagent/index.js +17 -0
- package/dist/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/startup-model-validation.d.ts +0 -1
- package/dist/startup-model-validation.js +6 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +17 -17
- package/dist/web/standalone/.next/build-manifest.json +4 -4
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +17 -17
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- 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-react-loadable-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +9 -0
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/.next/static/chunks/{webpack-6e4d7e9a4f57bed4.js → webpack-b868033a5834586d.js} +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/dist/env-writer.d.ts +39 -0
- package/packages/mcp-server/dist/env-writer.d.ts.map +1 -0
- package/packages/mcp-server/dist/env-writer.js +158 -0
- package/packages/mcp-server/dist/env-writer.js.map +1 -0
- package/packages/mcp-server/dist/server.d.ts +23 -3
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +192 -44
- 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 +22 -12
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/env-writer.test.ts +280 -0
- package/packages/mcp-server/src/env-writer.ts +183 -0
- package/packages/mcp-server/src/secure-env-collect.test.ts +265 -0
- package/packages/mcp-server/src/server.ts +247 -41
- package/packages/mcp-server/src/workflow-tools.test.ts +110 -0
- package/packages/mcp-server/src/workflow-tools.ts +32 -12
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +11 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +20 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +4 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +8 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +44 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +2 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +7 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +11 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/src/providers/amazon-bedrock.ts +13 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +32 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +55 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +14 -3
- package/packages/pi-ai/src/providers/anthropic.ts +8 -4
- package/packages/pi-ai/src/providers/openai-completions.ts +14 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js +61 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +2 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +27 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +85 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +388 -0
- package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js +64 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +22 -18
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js +75 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +38 -5
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js +71 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +19 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +50 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +24 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +4 -0
- 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 +43 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +175 -25
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +6 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -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 +6 -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 +62 -5
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +1 -0
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-renderable-tools.test.ts +70 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +108 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -0
- package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +468 -0
- package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -0
- package/packages/pi-coding-agent/src/core/model-resolver-initial-model-auth.test.ts +78 -0
- package/packages/pi-coding-agent/src/core/model-resolver.test.ts +85 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +22 -18
- package/packages/pi-coding-agent/src/core/sdk.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +45 -9
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/login-dialog.test.ts +24 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +58 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +2 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +30 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +15 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +47 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +205 -31
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +6 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +70 -5
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +4 -2
- package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
- package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +1 -0
- package/packages/pi-tui/dist/components/__tests__/input.test.js +9 -0
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.d.ts +2 -0
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.d.ts.map +1 -0
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +66 -0
- package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -0
- package/packages/pi-tui/dist/components/input.d.ts +2 -0
- package/packages/pi-tui/dist/components/input.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/input.js +7 -4
- package/packages/pi-tui/dist/components/input.js.map +1 -1
- package/packages/pi-tui/dist/components/markdown.d.ts +3 -0
- package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
- package/packages/pi-tui/dist/components/markdown.js +17 -1
- package/packages/pi-tui/dist/components/markdown.js.map +1 -1
- package/packages/pi-tui/src/components/__tests__/input.test.ts +11 -0
- package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +75 -0
- package/packages/pi-tui/src/components/input.ts +7 -4
- package/packages/pi-tui/src/components/markdown.ts +22 -1
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +1 -1
- package/src/resources/agents/debugger.md +58 -0
- package/src/resources/agents/doc-writer.md +43 -0
- package/src/resources/agents/git-ops.md +56 -0
- package/src/resources/agents/javascript-pro.md +46 -271
- package/src/resources/agents/planner.md +55 -0
- package/src/resources/agents/refactorer.md +47 -0
- package/src/resources/agents/reviewer.md +48 -0
- package/src/resources/agents/security.md +59 -0
- package/src/resources/agents/tester.md +50 -0
- package/src/resources/agents/typescript-pro.md +41 -235
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +288 -39
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +330 -2
- package/src/resources/extensions/get-secrets-from-user.ts +24 -1
- package/src/resources/extensions/gsd/auto/infra-errors.ts +38 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +45 -1
- package/src/resources/extensions/gsd/auto/phases.ts +6 -0
- package/src/resources/extensions/gsd/auto/session.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +29 -18
- package/src/resources/extensions/gsd/auto-model-selection.ts +9 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +111 -33
- package/src/resources/extensions/gsd/auto-start.ts +44 -20
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +72 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +6 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +79 -60
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +7 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -5
- package/src/resources/extensions/gsd/commands/dispatcher.ts +14 -2
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +10 -36
- package/src/resources/extensions/gsd/commands/handlers/core.ts +58 -11
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +17 -7
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +4 -10
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +19 -14
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -3
- package/src/resources/extensions/gsd/dispatch-guard.ts +18 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +24 -0
- package/src/resources/extensions/gsd/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/file-lock.ts +59 -0
- package/src/resources/extensions/gsd/forensics.ts +23 -7
- package/src/resources/extensions/gsd/gate-registry.ts +251 -0
- package/src/resources/extensions/gsd/gsd-db.ts +51 -0
- package/src/resources/extensions/gsd/guided-flow.ts +17 -19
- package/src/resources/extensions/gsd/init-wizard.ts +3 -13
- package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
- package/src/resources/extensions/gsd/metrics.ts +12 -1
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -3
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +11 -13
- package/src/resources/extensions/gsd/notification-overlay.ts +47 -14
- package/src/resources/extensions/gsd/notification-store.ts +54 -5
- package/src/resources/extensions/gsd/notification-widget.ts +5 -14
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -3
- package/src/resources/extensions/gsd/pre-execution-checks.ts +39 -2
- package/src/resources/extensions/gsd/prompt-validation.ts +157 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/src/resources/extensions/gsd/prompts/discuss.md +33 -13
- package/src/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +3 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/src/resources/extensions/gsd/session-model-override.ts +36 -0
- package/src/resources/extensions/gsd/shortcut-defs.ts +56 -0
- package/src/resources/extensions/gsd/state.ts +285 -344
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +25 -9
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/complete-slice-gate-closure.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/complete-slice-prompt-task-summary-layout.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +436 -0
- package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +9 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/execute-task-prompt-existing-artifact-guard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/file-lock.test.ts +103 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/gate-registry.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +36 -51
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prompt-system-gate-coverage.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +63 -5
- package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +45 -0
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +76 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +155 -1
- package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +22 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +63 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +64 -26
- package/src/resources/extensions/gsd/types.ts +26 -0
- package/src/resources/extensions/gsd/workflow-events.ts +34 -25
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +76 -0
- package/src/resources/extensions/gsd/workflow-mcp.ts +1 -1
- package/src/resources/extensions/ollama/index.ts +13 -3
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
- package/src/resources/extensions/shared/gsd-phase-state.ts +42 -0
- package/src/resources/extensions/shared/tests/gsd-phase-state.test.ts +48 -0
- package/src/resources/extensions/subagent/agents.ts +10 -0
- package/src/resources/extensions/subagent/index.ts +18 -0
- package/src/resources/extensions/subagent/tests/agents-conflicts.test.ts +33 -0
- package/src/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/web/standalone/.next/static/chunks/2826.821e01b07d92e948.js +0 -9
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{9pw9EXtXjdM7EFrCXUEPf → OI4n_CKC-lM8IQbvGJ_tK}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{9pw9EXtXjdM7EFrCXUEPf → OI4n_CKC-lM8IQbvGJ_tK}/_ssgManifest.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import test from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { mkdirSync, rmSync } from "node:fs";
|
|
3
|
+
import { mkdirSync, realpathSync, rmSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
|
|
@@ -37,10 +37,10 @@ test("dashboard shortcut resolves the project root instead of the current worktr
|
|
|
37
37
|
});
|
|
38
38
|
|
|
39
39
|
let capturedHandler: ((ctx: any) => Promise<void>) | null = null;
|
|
40
|
-
const shortcuts: Array<{ description: string; handler: (ctx: any) => Promise<void> }> = [];
|
|
40
|
+
const shortcuts: Array<{ key: string; description: string; handler: (ctx: any) => Promise<void> }> = [];
|
|
41
41
|
const pi = {
|
|
42
|
-
registerShortcut: (
|
|
43
|
-
shortcuts.push(shortcut);
|
|
42
|
+
registerShortcut: (key: unknown, shortcut: { description: string; handler: (ctx: any) => Promise<void> }) => {
|
|
43
|
+
shortcuts.push({ key: String(key), ...shortcut });
|
|
44
44
|
if (!capturedHandler) {
|
|
45
45
|
capturedHandler = shortcut.handler;
|
|
46
46
|
}
|
|
@@ -69,5 +69,63 @@ test("dashboard shortcut resolves the project root instead of the current worktr
|
|
|
69
69
|
|
|
70
70
|
assert.ok(customCalls > 0, "shortcut opens the dashboard overlay when project root is resolved");
|
|
71
71
|
assert.equal(notices.length, 0, "shortcut does not fall back to the missing-.gsd warning");
|
|
72
|
-
assert.equal(shortcuts.length,
|
|
72
|
+
assert.equal(shortcuts.length, 5, "all GSD shortcuts are still registered");
|
|
73
|
+
const keys = shortcuts.map((shortcut) => shortcut.key);
|
|
74
|
+
assert.ok(keys.includes("ctrl+alt+g"), "primary dashboard shortcut is registered");
|
|
75
|
+
assert.ok(keys.includes("ctrl+shift+g"), "fallback dashboard shortcut is registered");
|
|
76
|
+
assert.ok(keys.includes("ctrl+alt+n"), "primary notifications shortcut is registered");
|
|
77
|
+
assert.ok(keys.includes("ctrl+shift+n"), "fallback notifications shortcut is registered");
|
|
78
|
+
assert.ok(keys.includes("ctrl+alt+p"), "primary parallel shortcut is registered");
|
|
79
|
+
// No Ctrl+Shift+P fallback — conflicts with cycleModelBackward (shift+ctrl+p)
|
|
80
|
+
assert.ok(!keys.includes("ctrl+shift+p"), "parallel fallback must not be registered (conflicts with cycleModelBackward)");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("parallel shortcut passes resolved project root into overlay", async (t) => {
|
|
84
|
+
const base = makeTempDir("parallel-root");
|
|
85
|
+
const worktreeRoot = join(base, ".gsd", "worktrees", "M001");
|
|
86
|
+
mkdirSync(join(base, ".gsd", "parallel"), { recursive: true });
|
|
87
|
+
mkdirSync(worktreeRoot, { recursive: true });
|
|
88
|
+
|
|
89
|
+
const originalCwd = process.cwd();
|
|
90
|
+
process.chdir(worktreeRoot);
|
|
91
|
+
t.after(() => {
|
|
92
|
+
process.chdir(originalCwd);
|
|
93
|
+
cleanup(base);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const shortcuts: Array<{ key: string; description: string; handler: (ctx: any) => Promise<void> }> = [];
|
|
97
|
+
registerShortcuts({
|
|
98
|
+
registerShortcut: (key: unknown, shortcut: { description: string; handler: (ctx: any) => Promise<void> }) => {
|
|
99
|
+
shortcuts.push({ key: String(key), ...shortcut });
|
|
100
|
+
},
|
|
101
|
+
} as any);
|
|
102
|
+
|
|
103
|
+
const parallelShortcut = shortcuts.find((shortcut) => shortcut.key === "ctrl+alt+p");
|
|
104
|
+
assert.ok(parallelShortcut, "parallel shortcut is registered");
|
|
105
|
+
|
|
106
|
+
let capturedBasePath: string | undefined;
|
|
107
|
+
await parallelShortcut!.handler({
|
|
108
|
+
hasUI: true,
|
|
109
|
+
ui: {
|
|
110
|
+
custom: async (factory: any) => {
|
|
111
|
+
const overlay = factory(
|
|
112
|
+
{ requestRender() {} },
|
|
113
|
+
{ fg: (_color: string, text: string) => text, bold: (text: string) => text },
|
|
114
|
+
null,
|
|
115
|
+
() => {},
|
|
116
|
+
);
|
|
117
|
+
capturedBasePath = (overlay as any).basePath;
|
|
118
|
+
overlay.dispose?.();
|
|
119
|
+
return true;
|
|
120
|
+
},
|
|
121
|
+
notify: () => {},
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
assert.ok(capturedBasePath, "parallel shortcut should construct overlay with a basePath");
|
|
126
|
+
assert.equal(
|
|
127
|
+
realpathSync(capturedBasePath),
|
|
128
|
+
realpathSync(base),
|
|
129
|
+
"parallel overlay should use the resolved project root, not the worktree cwd",
|
|
130
|
+
);
|
|
73
131
|
});
|
|
@@ -317,3 +317,48 @@ test("secure_env_collect #2997: null from ctx.ui.custom() is still treated as sk
|
|
|
317
317
|
"Key returning null must NOT be in applied list",
|
|
318
318
|
);
|
|
319
319
|
});
|
|
320
|
+
|
|
321
|
+
test("secure_env_collect: falls back to secure input prompt when custom UI is unavailable", async (t) => {
|
|
322
|
+
const { collectSecretsFromManifest } = await loadOrchestrator();
|
|
323
|
+
|
|
324
|
+
const tmp = makeTempDir("sec-input-fallback-test");
|
|
325
|
+
t.after(() => {
|
|
326
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
const manifest = makeManifest([
|
|
330
|
+
{ key: "SECRET_FROM_INPUT_FALLBACK", status: "pending", formatHint: "starts with sk-" },
|
|
331
|
+
]);
|
|
332
|
+
await writeManifestFile(tmp, manifest);
|
|
333
|
+
|
|
334
|
+
let callIndex = 0;
|
|
335
|
+
const inputCalls: Array<{ title: string; placeholder?: string; opts?: { secure?: boolean } }> = [];
|
|
336
|
+
const mockCtx = {
|
|
337
|
+
cwd: tmp,
|
|
338
|
+
hasUI: true,
|
|
339
|
+
ui: {
|
|
340
|
+
custom: async (_factory: any) => {
|
|
341
|
+
callIndex++;
|
|
342
|
+
if (callIndex <= 1) return null; // summary screen dismiss
|
|
343
|
+
return undefined; // collect screen unavailable on this surface
|
|
344
|
+
},
|
|
345
|
+
input: async (title: string, placeholder?: string, opts?: { secure?: boolean }) => {
|
|
346
|
+
inputCalls.push({ title, placeholder, opts });
|
|
347
|
+
return " sk-test-fallback-value ";
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
const result = await collectSecretsFromManifest(tmp, "M001", mockCtx as any);
|
|
353
|
+
|
|
354
|
+
assert.ok(
|
|
355
|
+
result.applied.includes("SECRET_FROM_INPUT_FALLBACK"),
|
|
356
|
+
"Fallback input should collect and apply the key",
|
|
357
|
+
);
|
|
358
|
+
assert.ok(
|
|
359
|
+
!result.skipped.includes("SECRET_FROM_INPUT_FALLBACK"),
|
|
360
|
+
"Fallback input should not mark the key as skipped",
|
|
361
|
+
);
|
|
362
|
+
assert.equal(inputCalls.length, 1, "Fallback input should be requested once");
|
|
363
|
+
assert.equal(inputCalls[0]?.opts?.secure, true, "Fallback input should request secure entry when supported");
|
|
364
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
clearSessionModelOverride,
|
|
8
|
+
getSessionModelOverride,
|
|
9
|
+
setSessionModelOverride,
|
|
10
|
+
} from "../session-model-override.js";
|
|
11
|
+
|
|
12
|
+
const phasesSource = readFileSync(join(import.meta.dirname, "..", "auto", "phases.ts"), "utf-8");
|
|
13
|
+
|
|
14
|
+
test("setSessionModelOverride stores provider/model for the session", () => {
|
|
15
|
+
const sessionId = `session-override-${Date.now()}`;
|
|
16
|
+
setSessionModelOverride(sessionId, { provider: "openai-codex", id: "gpt-5.4" });
|
|
17
|
+
|
|
18
|
+
const override = getSessionModelOverride(sessionId);
|
|
19
|
+
assert.equal(override?.provider, "openai-codex");
|
|
20
|
+
assert.equal(override?.id, "gpt-5.4");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("clearSessionModelOverride removes the session override", () => {
|
|
24
|
+
const sessionId = `session-clear-${Date.now()}`;
|
|
25
|
+
setSessionModelOverride(sessionId, { provider: "anthropic", id: "claude-sonnet-4-6" });
|
|
26
|
+
clearSessionModelOverride(sessionId);
|
|
27
|
+
assert.equal(getSessionModelOverride(sessionId), undefined);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("auto dispatch threads manual session model override into selectAndApplyModel", () => {
|
|
31
|
+
assert.ok(
|
|
32
|
+
phasesSource.includes("s.manualSessionModelOverride"),
|
|
33
|
+
"auto/phases.ts should pass s.manualSessionModelOverride into selectAndApplyModel",
|
|
34
|
+
);
|
|
35
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
|
|
6
|
+
const gsdDir = resolve(import.meta.dirname, "..");
|
|
7
|
+
|
|
8
|
+
function readGsdFile(relativePath: string): string {
|
|
9
|
+
return readFileSync(resolve(gsdDir, relativePath), "utf-8");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
test("command entrypoints use startAutoDetached instead of awaiting startAuto (#3733)", () => {
|
|
13
|
+
const autoHandlerSrc = readGsdFile("commands/handlers/auto.ts");
|
|
14
|
+
const workflowHandlerSrc = readGsdFile("commands/handlers/workflow.ts");
|
|
15
|
+
const guidedFlowSrc = readGsdFile("guided-flow.ts");
|
|
16
|
+
|
|
17
|
+
assert.ok(
|
|
18
|
+
!autoHandlerSrc.includes("await startAuto("),
|
|
19
|
+
"auto command handler should not await startAuto from the active agent turn",
|
|
20
|
+
);
|
|
21
|
+
assert.ok(
|
|
22
|
+
!workflowHandlerSrc.includes("await startAuto("),
|
|
23
|
+
"workflow command handler should not await startAuto from the active agent turn",
|
|
24
|
+
);
|
|
25
|
+
assert.ok(
|
|
26
|
+
!guidedFlowSrc.includes("await startAuto("),
|
|
27
|
+
"guided flow should not await startAuto from the active agent turn",
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
assert.ok(
|
|
31
|
+
autoHandlerSrc.includes("startAutoDetached("),
|
|
32
|
+
"auto command handler should launch auto-mode through startAutoDetached",
|
|
33
|
+
);
|
|
34
|
+
assert.ok(
|
|
35
|
+
workflowHandlerSrc.includes("startAutoDetached("),
|
|
36
|
+
"workflow handler should launch auto-mode through startAutoDetached",
|
|
37
|
+
);
|
|
38
|
+
assert.ok(
|
|
39
|
+
guidedFlowSrc.includes("startAutoDetached("),
|
|
40
|
+
"guided flow should launch auto-mode through startAutoDetached",
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("startAutoDetached reports failures asynchronously (#3733)", () => {
|
|
45
|
+
const autoSrc = readGsdFile("auto.ts");
|
|
46
|
+
|
|
47
|
+
assert.ok(
|
|
48
|
+
autoSrc.includes("export function startAutoDetached"),
|
|
49
|
+
"auto.ts should export startAutoDetached",
|
|
50
|
+
);
|
|
51
|
+
assert.ok(
|
|
52
|
+
autoSrc.includes("void startAuto(ctx, pi, base, verboseMode, options).catch"),
|
|
53
|
+
"startAutoDetached should launch startAuto without awaiting it",
|
|
54
|
+
);
|
|
55
|
+
assert.ok(
|
|
56
|
+
autoSrc.includes("ctx.ui.notify(`Auto-start failed: ${message}`, \"error\")"),
|
|
57
|
+
"startAutoDetached should surface async startup failures to the user",
|
|
58
|
+
);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("detached auto-start preserves milestone lock across pause/stop cleanup (#3733)", () => {
|
|
62
|
+
const autoSrc = readGsdFile("auto.ts");
|
|
63
|
+
const sessionSrc = readGsdFile("auto/session.ts");
|
|
64
|
+
|
|
65
|
+
assert.ok(
|
|
66
|
+
autoSrc.includes("milestoneLock?: string | null"),
|
|
67
|
+
"startAuto/startAutoDetached options should carry an explicit milestone lock",
|
|
68
|
+
);
|
|
69
|
+
assert.ok(
|
|
70
|
+
autoSrc.includes("s.sessionMilestoneLock = options.milestoneLock ?? null;"),
|
|
71
|
+
"startAuto should capture the requested milestone lock before async work begins",
|
|
72
|
+
);
|
|
73
|
+
assert.ok(
|
|
74
|
+
autoSrc.includes("milestoneLock: s.sessionMilestoneLock ?? undefined"),
|
|
75
|
+
"pause metadata should persist the detached milestone lock for resume",
|
|
76
|
+
);
|
|
77
|
+
assert.ok(
|
|
78
|
+
autoSrc.includes("s.sessionMilestoneLock = meta.milestoneLock ?? null;"),
|
|
79
|
+
"resume should restore the persisted milestone lock",
|
|
80
|
+
);
|
|
81
|
+
assert.ok(
|
|
82
|
+
autoSrc.includes("restoreMilestoneLockEnv();"),
|
|
83
|
+
"auto cleanup should restore the previous process milestone-lock env",
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
assert.ok(
|
|
87
|
+
sessionSrc.includes("sessionMilestoneLock: string | null = null;"),
|
|
88
|
+
"AutoSession should track the detached milestone lock explicitly",
|
|
89
|
+
);
|
|
90
|
+
});
|
|
@@ -61,6 +61,13 @@ describe("#2883: isToolInvocationError classification", () => {
|
|
|
61
61
|
);
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
test("detects Node v18+ JSON parse variant with property-value text", () => {
|
|
65
|
+
assert.equal(
|
|
66
|
+
isToolInvocationError("Expected ',' or '}' after property value in JSON at position 4096"),
|
|
67
|
+
true,
|
|
68
|
+
);
|
|
69
|
+
});
|
|
70
|
+
|
|
64
71
|
test("detects Unexpected end of JSON input", () => {
|
|
65
72
|
assert.equal(
|
|
66
73
|
isToolInvocationError("Unexpected end of JSON input"),
|
package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
const promptPath = join(process.cwd(), "src/resources/extensions/gsd/prompts/validate-milestone.md");
|
|
7
|
+
const prompt = readFileSync(promptPath, "utf-8");
|
|
8
|
+
|
|
9
|
+
test("validate-milestone reviewer C requires canonical verification class names", () => {
|
|
10
|
+
assert.match(prompt, /\*\*Reviewer C[\s\S]*Verification Classes/i);
|
|
11
|
+
assert.match(prompt, /exact class names [`']?Contract[`']?, [`']?Integration[`']?, [`']?Operational[`']?, and [`']?UAT[`']?/i);
|
|
12
|
+
assert.match(prompt, /If no verification classes were planned, say that explicitly/i);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("validate-milestone prompt routes verification class analysis into verificationClasses", () => {
|
|
16
|
+
assert.match(prompt, /pass it in `verificationClasses`/i);
|
|
17
|
+
assert.match(prompt, /Extract the `Verification Classes` subsection from Reviewer C and pass it verbatim in `verificationClasses`/);
|
|
18
|
+
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
|
|
4
|
+
import { prepareWorkflowMcpForProject, shouldAutoPrepareWorkflowMcp } from "../workflow-mcp-auto-prep.ts";
|
|
5
|
+
|
|
6
|
+
test("shouldAutoPrepareWorkflowMcp enables prep for externalCli local transport", () => {
|
|
7
|
+
const result = shouldAutoPrepareWorkflowMcp({
|
|
8
|
+
model: { provider: "claude-code", baseUrl: "local://claude-code" },
|
|
9
|
+
modelRegistry: {
|
|
10
|
+
getProviderAuthMode: () => "externalCli",
|
|
11
|
+
isProviderRequestReady: () => false,
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
assert.equal(result, true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test("shouldAutoPrepareWorkflowMcp enables prep when claude-code provider is ready", () => {
|
|
19
|
+
const result = shouldAutoPrepareWorkflowMcp({
|
|
20
|
+
model: { provider: "openai", baseUrl: "https://api.openai.com" },
|
|
21
|
+
modelRegistry: {
|
|
22
|
+
getProviderAuthMode: () => "apiKey",
|
|
23
|
+
isProviderRequestReady: (provider: string) => provider === "claude-code",
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
assert.equal(result, true);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test("shouldAutoPrepareWorkflowMcp enables prep when claude-code provider is registered", () => {
|
|
31
|
+
const result = shouldAutoPrepareWorkflowMcp({
|
|
32
|
+
model: { provider: "openai", baseUrl: "https://api.openai.com" },
|
|
33
|
+
modelRegistry: {
|
|
34
|
+
getProviderAuthMode: (provider: string) => provider === "claude-code" ? "externalCli" : "apiKey",
|
|
35
|
+
isProviderRequestReady: () => false,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
assert.equal(result, true);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("shouldAutoPrepareWorkflowMcp stays disabled when neither transport nor provider readiness match", () => {
|
|
43
|
+
const result = shouldAutoPrepareWorkflowMcp({
|
|
44
|
+
model: { provider: "openai", baseUrl: "https://api.openai.com" },
|
|
45
|
+
modelRegistry: {
|
|
46
|
+
getProviderAuthMode: () => "apiKey",
|
|
47
|
+
isProviderRequestReady: () => false,
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
assert.equal(result, false);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("prepareWorkflowMcpForProject warns with /gsd mcp init guidance when prep fails", () => {
|
|
55
|
+
const notifications: Array<{ message: string; level: "info" | "warning" | "error" | "success" }> = [];
|
|
56
|
+
const result = prepareWorkflowMcpForProject(
|
|
57
|
+
{
|
|
58
|
+
model: { provider: "claude-code", baseUrl: "local://claude-code" },
|
|
59
|
+
modelRegistry: {
|
|
60
|
+
getProviderAuthMode: () => "externalCli",
|
|
61
|
+
isProviderRequestReady: () => true,
|
|
62
|
+
},
|
|
63
|
+
ui: {
|
|
64
|
+
notify: (message: string, level?: "info" | "warning" | "error" | "success") => {
|
|
65
|
+
notifications.push({ message, level: level ?? "info" });
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
"/",
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
assert.equal(result, null);
|
|
73
|
+
assert.equal(notifications.length, 1);
|
|
74
|
+
assert.equal(notifications[0].level, "warning");
|
|
75
|
+
assert.match(notifications[0].message, /Please run \/gsd mcp init \./);
|
|
76
|
+
});
|
|
@@ -6,6 +6,7 @@ import { tmpdir } from "node:os";
|
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
8
8
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
9
|
+
import { ElicitRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
9
10
|
|
|
10
11
|
import {
|
|
11
12
|
buildWorkflowMcpServers,
|
|
@@ -20,10 +21,20 @@ import {
|
|
|
20
21
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
21
22
|
const gsdDir = join(__dirname, "..");
|
|
22
23
|
|
|
24
|
+
type ElicitPayload = {
|
|
25
|
+
message: string;
|
|
26
|
+
requestedSchema: { properties: Record<string, unknown>; required?: string[] };
|
|
27
|
+
};
|
|
28
|
+
|
|
23
29
|
function readSrc(file: string): string {
|
|
24
30
|
return readFileSync(join(gsdDir, file), "utf-8");
|
|
25
31
|
}
|
|
26
32
|
|
|
33
|
+
function extractElicitPayload(request: unknown): ElicitPayload {
|
|
34
|
+
const payload = (request as { params?: unknown }).params ?? request;
|
|
35
|
+
return payload as ElicitPayload;
|
|
36
|
+
}
|
|
37
|
+
|
|
27
38
|
test("guided execute-task requires canonical task completion tool", () => {
|
|
28
39
|
assert.deepEqual(getRequiredWorkflowToolsForGuidedUnit("execute-task"), ["gsd_task_complete"]);
|
|
29
40
|
});
|
|
@@ -185,7 +196,26 @@ test("workflow MCP launch config reaches mutation tools over stdio", async () =>
|
|
|
185
196
|
assert.match(launch.env?.NODE_OPTIONS ?? "", /resolve-ts\.mjs/);
|
|
186
197
|
}
|
|
187
198
|
|
|
188
|
-
const client = new Client(
|
|
199
|
+
const client = new Client(
|
|
200
|
+
{ name: "workflow-mcp-transport-test", version: "1.0.0" },
|
|
201
|
+
{ capabilities: { elicitation: {} } },
|
|
202
|
+
);
|
|
203
|
+
client.setRequestHandler(ElicitRequestSchema, async (request) => {
|
|
204
|
+
const elicitation = extractElicitPayload(request as unknown);
|
|
205
|
+
|
|
206
|
+
assert.match(elicitation.message, /Please answer the following question/);
|
|
207
|
+
assert.ok(elicitation.requestedSchema.properties.transport_mode);
|
|
208
|
+
assert.ok(elicitation.requestedSchema.properties["transport_mode__note"]);
|
|
209
|
+
assert.ok(elicitation.requestedSchema.required?.includes("transport_mode"));
|
|
210
|
+
|
|
211
|
+
return {
|
|
212
|
+
action: "accept",
|
|
213
|
+
content: {
|
|
214
|
+
transport_mode: "None of the above",
|
|
215
|
+
transport_mode__note: "Need Windows-safe MCP elicitation.",
|
|
216
|
+
},
|
|
217
|
+
};
|
|
218
|
+
});
|
|
189
219
|
const transport = new StdioClientTransport({
|
|
190
220
|
command: launch.command,
|
|
191
221
|
args: launch.args,
|
|
@@ -207,6 +237,38 @@ test("workflow MCP launch config reaches mutation tools over stdio", async () =>
|
|
|
207
237
|
"expected workflow MCP surface to expose ask_user_questions",
|
|
208
238
|
);
|
|
209
239
|
|
|
240
|
+
const askResult = await client.callTool(
|
|
241
|
+
{
|
|
242
|
+
name: "ask_user_questions",
|
|
243
|
+
arguments: {
|
|
244
|
+
questions: [
|
|
245
|
+
{
|
|
246
|
+
id: "transport_mode",
|
|
247
|
+
header: "Transport",
|
|
248
|
+
question: "How should the workflow prompt be delivered?",
|
|
249
|
+
options: [
|
|
250
|
+
{ label: "Local UI", description: "Use the host tool UI." },
|
|
251
|
+
{ label: "Remote UI", description: "Use a remote response channel." },
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
},
|
|
256
|
+
},
|
|
257
|
+
undefined,
|
|
258
|
+
{ timeout: 30_000 },
|
|
259
|
+
);
|
|
260
|
+
assert.equal(askResult.isError, undefined);
|
|
261
|
+
assert.equal(
|
|
262
|
+
((askResult.content as Array<{ text?: string }>)?.[0])?.text ?? "",
|
|
263
|
+
JSON.stringify({
|
|
264
|
+
answers: {
|
|
265
|
+
transport_mode: {
|
|
266
|
+
answers: ["None of the above", "user_note: Need Windows-safe MCP elicitation."],
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
}),
|
|
270
|
+
);
|
|
271
|
+
|
|
210
272
|
const milestoneResult = await client.callTool(
|
|
211
273
|
{
|
|
212
274
|
name: "gsd_plan_milestone",
|
|
@@ -286,6 +348,93 @@ test("workflow MCP launch config reaches mutation tools over stdio", async () =>
|
|
|
286
348
|
}
|
|
287
349
|
});
|
|
288
350
|
|
|
351
|
+
test("workflow MCP ask_user_questions uses stdio elicitation round-trip", async () => {
|
|
352
|
+
const projectRoot = mkdtempSync(join(tmpdir(), "gsd-workflow-elicit-"));
|
|
353
|
+
mkdirSync(join(projectRoot, ".gsd"), { recursive: true });
|
|
354
|
+
|
|
355
|
+
const launch = detectWorkflowMcpLaunchConfig(projectRoot, {});
|
|
356
|
+
assert.ok(launch, "expected a workflow MCP launch config");
|
|
357
|
+
|
|
358
|
+
const client = new Client(
|
|
359
|
+
{ name: "workflow-mcp-elicit-test", version: "1.0.0" },
|
|
360
|
+
{ capabilities: { elicitation: {} } },
|
|
361
|
+
);
|
|
362
|
+
let requestSeen: {
|
|
363
|
+
message: string;
|
|
364
|
+
requestedSchema: { properties: Record<string, unknown>; required?: string[] };
|
|
365
|
+
} | null = null;
|
|
366
|
+
|
|
367
|
+
client.setRequestHandler(ElicitRequestSchema, async (request) => {
|
|
368
|
+
const params = extractElicitPayload(request as unknown);
|
|
369
|
+
|
|
370
|
+
requestSeen = params;
|
|
371
|
+
|
|
372
|
+
return {
|
|
373
|
+
action: "accept",
|
|
374
|
+
content: {
|
|
375
|
+
deployment: "None of the above",
|
|
376
|
+
deployment__note: "Need hybrid deployment.",
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
const transport = new StdioClientTransport({
|
|
382
|
+
command: launch.command,
|
|
383
|
+
args: launch.args,
|
|
384
|
+
env: { ...process.env, ...launch.env } as Record<string, string>,
|
|
385
|
+
cwd: launch.cwd,
|
|
386
|
+
stderr: "pipe",
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
try {
|
|
390
|
+
await client.connect(transport, { timeout: 30_000 });
|
|
391
|
+
|
|
392
|
+
const result = await client.callTool(
|
|
393
|
+
{
|
|
394
|
+
name: "ask_user_questions",
|
|
395
|
+
arguments: {
|
|
396
|
+
questions: [
|
|
397
|
+
{
|
|
398
|
+
id: "deployment",
|
|
399
|
+
header: "Deploy",
|
|
400
|
+
question: "Where will this run?",
|
|
401
|
+
options: [
|
|
402
|
+
{ label: "Cloud", description: "Managed hosting." },
|
|
403
|
+
{ label: "On-prem", description: "Runs in customer infrastructure." },
|
|
404
|
+
],
|
|
405
|
+
},
|
|
406
|
+
],
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
undefined,
|
|
410
|
+
{ timeout: 30_000 },
|
|
411
|
+
);
|
|
412
|
+
|
|
413
|
+
assert.ok(requestSeen, "expected stdio transport to forward an elicitation request");
|
|
414
|
+
const seen = requestSeen as ElicitPayload;
|
|
415
|
+
assert.match(seen.message, /Please answer the following question/);
|
|
416
|
+
assert.ok(seen.requestedSchema.properties.deployment);
|
|
417
|
+
assert.ok(seen.requestedSchema.properties.deployment__note);
|
|
418
|
+
assert.ok(seen.requestedSchema.required?.includes("deployment"));
|
|
419
|
+
|
|
420
|
+
const content = (result as { content: Array<{ type: string; text?: string }> }).content;
|
|
421
|
+
const text = content.find((item: { type: string; text?: string }) => item.type === "text");
|
|
422
|
+
assert.ok(text && "text" in text);
|
|
423
|
+
assert.equal(
|
|
424
|
+
text.text,
|
|
425
|
+
JSON.stringify({
|
|
426
|
+
answers: {
|
|
427
|
+
deployment: {
|
|
428
|
+
answers: ["None of the above", "user_note: Need hybrid deployment."],
|
|
429
|
+
},
|
|
430
|
+
},
|
|
431
|
+
}),
|
|
432
|
+
);
|
|
433
|
+
} finally {
|
|
434
|
+
await client.close();
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
|
|
289
438
|
test("usesWorkflowMcpTransport matches local externalCli providers", () => {
|
|
290
439
|
assert.equal(usesWorkflowMcpTransport("externalCli", "local://claude-code"), true);
|
|
291
440
|
assert.equal(usesWorkflowMcpTransport("externalCli", "https://api.example.com"), false);
|
|
@@ -539,3 +688,8 @@ test("auto phases source enforces workflow compatibility preflight", () => {
|
|
|
539
688
|
assert.match(src, /getWorkflowTransportSupportError/);
|
|
540
689
|
assert.match(src, /workflow-capability/);
|
|
541
690
|
});
|
|
691
|
+
|
|
692
|
+
test("workflow transport error guidance includes /gsd mcp init hint", () => {
|
|
693
|
+
const src = readSrc("workflow-mcp.ts");
|
|
694
|
+
assert.match(src, /Please run \/gsd mcp init \./);
|
|
695
|
+
});
|
|
@@ -256,6 +256,28 @@ test("executePlanSlice writes task planning state and rendered plan artifacts",
|
|
|
256
256
|
}
|
|
257
257
|
});
|
|
258
258
|
|
|
259
|
+
test("executePlanSlice marks validation failures with isError", async () => {
|
|
260
|
+
const base = makeTmpBase();
|
|
261
|
+
try {
|
|
262
|
+
openTestDb(base);
|
|
263
|
+
|
|
264
|
+
const result = await inProjectDir(base, () => executePlanSlice({
|
|
265
|
+
milestoneId: "M001",
|
|
266
|
+
sliceId: "S01",
|
|
267
|
+
goal: "Trigger validation failure for empty tasks.",
|
|
268
|
+
tasks: [],
|
|
269
|
+
}, base));
|
|
270
|
+
|
|
271
|
+
assert.equal(result.isError, true);
|
|
272
|
+
assert.equal(result.details.operation, "plan_slice");
|
|
273
|
+
assert.match(String(result.details.error), /validation failed: tasks must be a non-empty array/);
|
|
274
|
+
assert.match(result.content[0].text, /Error planning slice:/);
|
|
275
|
+
} finally {
|
|
276
|
+
closeDatabase();
|
|
277
|
+
cleanup(base);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
|
|
259
281
|
test("executeSliceComplete coerces string enrichment entries and writes summary/UAT artifacts", async () => {
|
|
260
282
|
const base = makeTmpBase();
|
|
261
283
|
try {
|