gsd-pi 2.70.1 → 2.71.0-dev.246c32d
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 +5 -2
- 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 +19 -19
- 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 +4 -4
- 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 +19 -19
- 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/retry-handler.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +55 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +57 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- 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/retry-handler.test.ts +83 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +60 -1
- 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 +5 -2
- 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 +16 -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 → hnGGkVMxIGGpxSJkf5jIV}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{9pw9EXtXjdM7EFrCXUEPf → hnGGkVMxIGGpxSJkf5jIV}/_ssgManifest.js +0 -0
|
@@ -12,6 +12,7 @@ import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.j
|
|
|
12
12
|
import { buildWorkflowMcpServers } from "../gsd/workflow-mcp.js";
|
|
13
13
|
import { showInterviewRound } from "../shared/tui.js";
|
|
14
14
|
const OTHER_OPTION_LABEL = "None of the above";
|
|
15
|
+
const SENSITIVE_FIELD_PATTERN = /(password|passphrase|secret|token|api[_\s-]*key|private[_\s-]*key|credential)/i;
|
|
15
16
|
// ---------------------------------------------------------------------------
|
|
16
17
|
// Stream factory
|
|
17
18
|
// ---------------------------------------------------------------------------
|
|
@@ -28,6 +29,15 @@ function createAssistantStream() {
|
|
|
28
29
|
throw new Error("Unexpected event type for final result");
|
|
29
30
|
});
|
|
30
31
|
}
|
|
32
|
+
export function getResultErrorMessage(result) {
|
|
33
|
+
if ("errors" in result && Array.isArray(result.errors) && result.errors.length > 0) {
|
|
34
|
+
return result.errors.join("; ");
|
|
35
|
+
}
|
|
36
|
+
if ("result" in result && typeof result.result === "string" && result.result.trim().length > 0) {
|
|
37
|
+
return result.result.trim();
|
|
38
|
+
}
|
|
39
|
+
return result.subtype === "success" ? "claude_code_request_failed" : result.subtype;
|
|
40
|
+
}
|
|
31
41
|
// ---------------------------------------------------------------------------
|
|
32
42
|
// Claude binary resolution
|
|
33
43
|
// ---------------------------------------------------------------------------
|
|
@@ -182,6 +192,56 @@ export function parseAskUserQuestionsElicitation(request) {
|
|
|
182
192
|
}
|
|
183
193
|
return questions.length > 0 ? questions : null;
|
|
184
194
|
}
|
|
195
|
+
function isSecureElicitationField(requestMessage, fieldId, field) {
|
|
196
|
+
if (field.format === "password")
|
|
197
|
+
return true;
|
|
198
|
+
if (field.writeOnly === true)
|
|
199
|
+
return true;
|
|
200
|
+
const rawField = field;
|
|
201
|
+
if (rawField.sensitive === true || rawField["x-sensitive"] === true)
|
|
202
|
+
return true;
|
|
203
|
+
const haystack = [
|
|
204
|
+
requestMessage,
|
|
205
|
+
fieldId.replace(/[_-]+/g, " "),
|
|
206
|
+
typeof field.title === "string" ? field.title : "",
|
|
207
|
+
typeof field.description === "string" ? field.description : "",
|
|
208
|
+
]
|
|
209
|
+
.join(" ")
|
|
210
|
+
.toLowerCase();
|
|
211
|
+
return SENSITIVE_FIELD_PATTERN.test(haystack);
|
|
212
|
+
}
|
|
213
|
+
export function parseTextInputElicitation(request) {
|
|
214
|
+
if (request.mode && request.mode !== "form")
|
|
215
|
+
return null;
|
|
216
|
+
const schema = request.requestedSchema;
|
|
217
|
+
const fieldsSource = schema?.properties && typeof schema.properties === "object"
|
|
218
|
+
? schema.properties
|
|
219
|
+
: schema?.keys && typeof schema.keys === "object"
|
|
220
|
+
? schema.keys
|
|
221
|
+
: undefined;
|
|
222
|
+
if (!fieldsSource)
|
|
223
|
+
return null;
|
|
224
|
+
const requiredSet = new Set(Array.isArray(request.requestedSchema?.required)
|
|
225
|
+
? request.requestedSchema.required.filter((value) => typeof value === "string")
|
|
226
|
+
: []);
|
|
227
|
+
const fields = [];
|
|
228
|
+
for (const [fieldId, field] of Object.entries(fieldsSource)) {
|
|
229
|
+
if (!field || typeof field !== "object")
|
|
230
|
+
continue;
|
|
231
|
+
if (field.type !== "string")
|
|
232
|
+
continue;
|
|
233
|
+
if (Array.isArray(field.oneOf) && field.oneOf.length > 0)
|
|
234
|
+
continue;
|
|
235
|
+
fields.push({
|
|
236
|
+
id: fieldId,
|
|
237
|
+
title: typeof field.title === "string" && field.title.length > 0 ? field.title : fieldId,
|
|
238
|
+
description: typeof field.description === "string" ? field.description : "",
|
|
239
|
+
required: requiredSet.has(fieldId),
|
|
240
|
+
secure: isSecureElicitationField(request.message, fieldId, field),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return fields.length > 0 ? fields : null;
|
|
244
|
+
}
|
|
185
245
|
export function roundResultToElicitationContent(questions, result) {
|
|
186
246
|
const content = {};
|
|
187
247
|
for (const question of questions) {
|
|
@@ -246,6 +306,38 @@ async function promptElicitationWithDialogs(request, questions, ui, signal) {
|
|
|
246
306
|
}
|
|
247
307
|
return { action: "accept", content };
|
|
248
308
|
}
|
|
309
|
+
function buildTextInputPromptTitle(request, field) {
|
|
310
|
+
const parts = [
|
|
311
|
+
request.serverName ? `[${request.serverName}]` : "",
|
|
312
|
+
field.title,
|
|
313
|
+
field.description,
|
|
314
|
+
].filter((part) => typeof part === "string" && part.trim().length > 0);
|
|
315
|
+
return parts.join("\n\n");
|
|
316
|
+
}
|
|
317
|
+
function buildTextInputPlaceholder(field) {
|
|
318
|
+
const desc = field.description.trim();
|
|
319
|
+
if (!desc)
|
|
320
|
+
return field.required ? "Required" : "Leave empty to skip";
|
|
321
|
+
const formatLine = desc
|
|
322
|
+
.split(/\r?\n/)
|
|
323
|
+
.map((line) => line.trim())
|
|
324
|
+
.find((line) => /^format:/i.test(line));
|
|
325
|
+
if (!formatLine)
|
|
326
|
+
return field.required ? "Required" : "Leave empty to skip";
|
|
327
|
+
const hint = formatLine.replace(/^format:\s*/i, "").trim();
|
|
328
|
+
return hint.length > 0 ? hint : field.required ? "Required" : "Leave empty to skip";
|
|
329
|
+
}
|
|
330
|
+
async function promptTextInputElicitation(request, fields, ui, signal) {
|
|
331
|
+
const content = {};
|
|
332
|
+
for (const field of fields) {
|
|
333
|
+
const value = await ui.input(buildTextInputPromptTitle(request, field), buildTextInputPlaceholder(field), { signal, ...(field.secure ? { secure: true } : {}) });
|
|
334
|
+
if (value === undefined) {
|
|
335
|
+
return { action: "cancel" };
|
|
336
|
+
}
|
|
337
|
+
content[field.id] = value;
|
|
338
|
+
}
|
|
339
|
+
return { action: "accept", content };
|
|
340
|
+
}
|
|
249
341
|
export function createClaudeCodeElicitationHandler(ui) {
|
|
250
342
|
if (!ui)
|
|
251
343
|
return undefined;
|
|
@@ -254,40 +346,102 @@ export function createClaudeCodeElicitationHandler(ui) {
|
|
|
254
346
|
return { action: "decline" };
|
|
255
347
|
}
|
|
256
348
|
const questions = parseAskUserQuestionsElicitation(request);
|
|
257
|
-
if (
|
|
258
|
-
|
|
349
|
+
if (questions) {
|
|
350
|
+
const interviewResult = await showInterviewRound(questions, { signal }, { ui }).catch(() => undefined);
|
|
351
|
+
if (interviewResult && Object.keys(interviewResult.answers).length > 0) {
|
|
352
|
+
return {
|
|
353
|
+
action: "accept",
|
|
354
|
+
content: roundResultToElicitationContent(questions, interviewResult),
|
|
355
|
+
};
|
|
356
|
+
}
|
|
357
|
+
return promptElicitationWithDialogs(request, questions, ui, signal);
|
|
259
358
|
}
|
|
260
|
-
const
|
|
261
|
-
if (
|
|
262
|
-
return
|
|
263
|
-
action: "accept",
|
|
264
|
-
content: roundResultToElicitationContent(questions, interviewResult),
|
|
265
|
-
};
|
|
359
|
+
const textFields = parseTextInputElicitation(request);
|
|
360
|
+
if (textFields) {
|
|
361
|
+
return promptTextInputElicitation(request, textFields, ui, signal);
|
|
266
362
|
}
|
|
267
|
-
return
|
|
363
|
+
return { action: "decline" };
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Aborted by the caller's AbortSignal — distinct from exhaustion. GSD's
|
|
368
|
+
* agent loop keys off `stopReason === "aborted"` to treat this as a clean
|
|
369
|
+
* user cancel instead of a retry-eligible provider failure.
|
|
370
|
+
*/
|
|
371
|
+
export function makeAbortedMessage(model, lastTextContent) {
|
|
372
|
+
const message = {
|
|
373
|
+
role: "assistant",
|
|
374
|
+
content: lastTextContent
|
|
375
|
+
? [{ type: "text", text: lastTextContent }]
|
|
376
|
+
: [{ type: "text", text: "Claude Code stream aborted by caller" }],
|
|
377
|
+
api: "anthropic-messages",
|
|
378
|
+
provider: "claude-code",
|
|
379
|
+
model,
|
|
380
|
+
usage: { ...ZERO_USAGE },
|
|
381
|
+
stopReason: "aborted",
|
|
382
|
+
timestamp: Date.now(),
|
|
268
383
|
};
|
|
384
|
+
return message;
|
|
269
385
|
}
|
|
270
386
|
// ---------------------------------------------------------------------------
|
|
271
387
|
// SDK options builder
|
|
272
388
|
// ---------------------------------------------------------------------------
|
|
389
|
+
/**
|
|
390
|
+
* Resolve the Claude Code permission mode for the current run.
|
|
391
|
+
*
|
|
392
|
+
* - Auto-mode / headless runs bypass permissions so tool calls don't block
|
|
393
|
+
* on prompts the user isn't watching.
|
|
394
|
+
* - Interactive runs default to `acceptEdits` so file/bash writes still
|
|
395
|
+
* land quickly but the SDK retains a permission gate.
|
|
396
|
+
* - `GSD_CLAUDE_CODE_PERMISSION_MODE` forces a specific mode when set.
|
|
397
|
+
*
|
|
398
|
+
* Cross-extension coupling is kept minimal by dynamically importing
|
|
399
|
+
* `isAutoActive` and falling back to the bypass default if the import
|
|
400
|
+
* fails (e.g. in unit tests that load stream-adapter in isolation).
|
|
401
|
+
*/
|
|
402
|
+
export async function resolveClaudePermissionMode(env = process.env) {
|
|
403
|
+
const override = env.GSD_CLAUDE_CODE_PERMISSION_MODE?.trim();
|
|
404
|
+
if (override === "bypassPermissions" || override === "acceptEdits" || override === "default" || override === "plan") {
|
|
405
|
+
return override;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
const autoMod = (await import("../gsd/auto.js"));
|
|
409
|
+
if (typeof autoMod.isAutoActive === "function" && autoMod.isAutoActive()) {
|
|
410
|
+
return "bypassPermissions";
|
|
411
|
+
}
|
|
412
|
+
return "acceptEdits";
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
// auto.ts unavailable (tests, non-GSD contexts) — stay permissive.
|
|
416
|
+
return "bypassPermissions";
|
|
417
|
+
}
|
|
418
|
+
}
|
|
273
419
|
/**
|
|
274
420
|
* Build the options object passed to the Claude Agent SDK's `query()` call.
|
|
275
421
|
*
|
|
276
422
|
* Extracted for testability — callers can verify session persistence,
|
|
277
423
|
* beta flags, and other configuration without mocking the full SDK.
|
|
424
|
+
*
|
|
425
|
+
* `permissionMode` / `allowDangerouslySkipPermissions` are resolved through
|
|
426
|
+
* {@link resolveClaudePermissionMode} so interactive runs don't silently
|
|
427
|
+
* bypass the SDK's permission gate. Callers that want the old always-bypass
|
|
428
|
+
* behaviour pass `permissionMode: "bypassPermissions"` explicitly.
|
|
278
429
|
*/
|
|
279
|
-
export function buildSdkOptions(modelId, prompt, extraOptions = {}) {
|
|
430
|
+
export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
280
431
|
const mcpServers = buildWorkflowMcpServers();
|
|
432
|
+
const permissionMode = overrides?.permissionMode ?? "bypassPermissions";
|
|
433
|
+
const disallowedTools = ["AskUserQuestion"];
|
|
281
434
|
return {
|
|
282
435
|
pathToClaudeCodeExecutable: getClaudePath(),
|
|
283
436
|
model: modelId,
|
|
284
437
|
includePartialMessages: true,
|
|
285
438
|
persistSession: true,
|
|
286
439
|
cwd: process.cwd(),
|
|
287
|
-
permissionMode
|
|
288
|
-
allowDangerouslySkipPermissions:
|
|
440
|
+
permissionMode,
|
|
441
|
+
allowDangerouslySkipPermissions: permissionMode === "bypassPermissions",
|
|
289
442
|
settingSources: ["project"],
|
|
290
443
|
systemPrompt: { type: "preset", preset: "claude_code" },
|
|
444
|
+
disallowedTools,
|
|
291
445
|
...(mcpServers ? { mcpServers } : {}),
|
|
292
446
|
betas: modelId.includes("sonnet") ? ["context-1m-2025-08-07"] : [],
|
|
293
447
|
...extraOptions,
|
|
@@ -371,9 +525,9 @@ export function extractToolResultsFromSdkUserMessage(message) {
|
|
|
371
525
|
}
|
|
372
526
|
return extracted;
|
|
373
527
|
}
|
|
374
|
-
function
|
|
375
|
-
for (const block of
|
|
376
|
-
if (block.type !== "toolCall")
|
|
528
|
+
function attachExternalResultsToToolBlocks(toolBlocks, toolResultsById) {
|
|
529
|
+
for (const block of toolBlocks) {
|
|
530
|
+
if (block.type !== "toolCall" && block.type !== "serverToolUse")
|
|
377
531
|
continue;
|
|
378
532
|
const externalResult = toolResultsById.get(block.id);
|
|
379
533
|
if (!externalResult)
|
|
@@ -381,6 +535,28 @@ function attachExternalResultsToToolCalls(toolCalls, toolResultsById) {
|
|
|
381
535
|
block.externalResult = externalResult;
|
|
382
536
|
}
|
|
383
537
|
}
|
|
538
|
+
/**
|
|
539
|
+
* Merge tool-call blocks from the active partial-message builder into the
|
|
540
|
+
* running list of intermediate tool calls, preserving order and de-duping
|
|
541
|
+
* by tool-call id. Exposed for testing the F3 fix (final-turn tool calls
|
|
542
|
+
* dropped when `result` arrives without a preceding synthetic `user`).
|
|
543
|
+
*/
|
|
544
|
+
export function mergePendingToolCalls(intermediate, pending) {
|
|
545
|
+
const alreadyIncluded = new Set();
|
|
546
|
+
for (const block of intermediate) {
|
|
547
|
+
if (block.type === "toolCall")
|
|
548
|
+
alreadyIncluded.add(block.id);
|
|
549
|
+
}
|
|
550
|
+
for (const block of pending) {
|
|
551
|
+
if (block.type !== "toolCall")
|
|
552
|
+
continue;
|
|
553
|
+
if (alreadyIncluded.has(block.id))
|
|
554
|
+
continue;
|
|
555
|
+
alreadyIncluded.add(block.id);
|
|
556
|
+
intermediate.push(block);
|
|
557
|
+
}
|
|
558
|
+
return intermediate;
|
|
559
|
+
}
|
|
384
560
|
// ---------------------------------------------------------------------------
|
|
385
561
|
// streamSimple implementation
|
|
386
562
|
// ---------------------------------------------------------------------------
|
|
@@ -402,8 +578,8 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
402
578
|
/** Track the last text content seen across all assistant turns for the final message. */
|
|
403
579
|
let lastTextContent = "";
|
|
404
580
|
let lastThinkingContent = "";
|
|
405
|
-
/** Collect tool
|
|
406
|
-
const
|
|
581
|
+
/** Collect tool blocks from intermediate SDK turns for tool execution rendering. */
|
|
582
|
+
const intermediateToolBlocks = [];
|
|
407
583
|
/** Preserve real external tool results from Claude Code's synthetic user messages. */
|
|
408
584
|
const toolResultsById = new Map();
|
|
409
585
|
try {
|
|
@@ -416,7 +592,8 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
416
592
|
options.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
417
593
|
}
|
|
418
594
|
const prompt = buildPromptFromContext(context);
|
|
419
|
-
const
|
|
595
|
+
const permissionMode = await resolveClaudePermissionMode();
|
|
596
|
+
const sdkOpts = buildSdkOptions(modelId, prompt, { permissionMode }, typeof options?.extensionUIContext === "object"
|
|
420
597
|
? {
|
|
421
598
|
onElicitation: createClaudeCodeElicitationHandler(options?.extensionUIContext),
|
|
422
599
|
}
|
|
@@ -441,8 +618,17 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
441
618
|
};
|
|
442
619
|
stream.push({ type: "start", partial: initialPartial });
|
|
443
620
|
for await (const msg of queryResult) {
|
|
444
|
-
if (options?.signal?.aborted)
|
|
445
|
-
|
|
621
|
+
if (options?.signal?.aborted) {
|
|
622
|
+
// User-initiated cancel — emit an aborted error so the agent
|
|
623
|
+
// loop classifies this as a deliberate stop, not a transient
|
|
624
|
+
// provider failure that should be retried.
|
|
625
|
+
stream.push({
|
|
626
|
+
type: "error",
|
|
627
|
+
reason: "aborted",
|
|
628
|
+
error: makeAbortedMessage(modelId, lastTextContent),
|
|
629
|
+
});
|
|
630
|
+
return;
|
|
631
|
+
}
|
|
446
632
|
switch (msg.type) {
|
|
447
633
|
// -- Init --
|
|
448
634
|
case "system": {
|
|
@@ -491,9 +677,9 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
491
677
|
else if (block.type === "thinking" && block.thinking) {
|
|
492
678
|
lastThinkingContent = block.thinking;
|
|
493
679
|
}
|
|
494
|
-
else if (block.type === "toolCall") {
|
|
495
|
-
// Collect tool
|
|
496
|
-
|
|
680
|
+
else if (block.type === "toolCall" || block.type === "serverToolUse") {
|
|
681
|
+
// Collect tool blocks for externalToolExecution rendering
|
|
682
|
+
intermediateToolBlocks.push(block);
|
|
497
683
|
}
|
|
498
684
|
}
|
|
499
685
|
}
|
|
@@ -502,25 +688,35 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
502
688
|
for (const { toolUseId, result } of extractToolResultsFromSdkUserMessage(msg)) {
|
|
503
689
|
toolResultsById.set(toolUseId, result);
|
|
504
690
|
}
|
|
505
|
-
|
|
691
|
+
attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
|
|
506
692
|
// Push a synthetic toolcall_end for each tool call from this turn
|
|
507
693
|
// so the TUI can render tool results in real-time during the SDK
|
|
508
694
|
// session instead of waiting until the entire session completes.
|
|
509
695
|
if (builder) {
|
|
510
696
|
for (const block of builder.message.content) {
|
|
511
|
-
if (block.type !== "toolCall")
|
|
512
|
-
continue;
|
|
513
697
|
const extResult = block.externalResult;
|
|
514
698
|
if (!extResult)
|
|
515
699
|
continue;
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
700
|
+
const contentIndex = builder.message.content.indexOf(block);
|
|
701
|
+
if (contentIndex < 0)
|
|
702
|
+
continue;
|
|
703
|
+
// Push synthetic completion events with result attached so the
|
|
704
|
+
// chat-controller can update pending ToolExecutionComponents.
|
|
705
|
+
if (block.type === "toolCall") {
|
|
706
|
+
stream.push({
|
|
707
|
+
type: "toolcall_end",
|
|
708
|
+
contentIndex,
|
|
709
|
+
toolCall: block,
|
|
710
|
+
partial: builder.message,
|
|
711
|
+
});
|
|
712
|
+
}
|
|
713
|
+
else if (block.type === "serverToolUse") {
|
|
714
|
+
stream.push({
|
|
715
|
+
type: "server_tool_use",
|
|
716
|
+
contentIndex,
|
|
717
|
+
partial: builder.message,
|
|
718
|
+
});
|
|
719
|
+
}
|
|
524
720
|
}
|
|
525
721
|
}
|
|
526
722
|
builder = null;
|
|
@@ -533,9 +729,18 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
533
729
|
// agent loop's externalToolExecution path emits tool_execution
|
|
534
730
|
// events for proper TUI rendering, followed by the text response.
|
|
535
731
|
const finalContent = [];
|
|
732
|
+
// If the final turn ended without a synthetic user message
|
|
733
|
+
// (e.g. stop_reason: "tool_use" followed directly by result,
|
|
734
|
+
// or a turn with text but no tool execution), the `builder`
|
|
735
|
+
// still holds toolCall blocks that were never pushed into
|
|
736
|
+
// `intermediateToolBlocks`. Fold them in here so they aren't
|
|
737
|
+
// dropped from the final AssistantMessage.
|
|
738
|
+
if (builder) {
|
|
739
|
+
mergePendingToolCalls(intermediateToolBlocks, builder.message.content);
|
|
740
|
+
}
|
|
536
741
|
// Add tool calls from intermediate turns first (renders above text)
|
|
537
|
-
|
|
538
|
-
finalContent.push(...
|
|
742
|
+
attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
|
|
743
|
+
finalContent.push(...intermediateToolBlocks);
|
|
539
744
|
// Add text/thinking from the last turn
|
|
540
745
|
if (builder && builder.message.content.length > 0) {
|
|
541
746
|
for (const block of builder.message.content) {
|
|
@@ -567,10 +772,7 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
567
772
|
timestamp: Date.now(),
|
|
568
773
|
};
|
|
569
774
|
if (result.is_error) {
|
|
570
|
-
|
|
571
|
-
? result.errors?.join("; ")
|
|
572
|
-
: result.subtype;
|
|
573
|
-
finalMessage.errorMessage = errText;
|
|
775
|
+
finalMessage.errorMessage = getResultErrorMessage(result);
|
|
574
776
|
stream.push({ type: "error", reason: "error", error: finalMessage });
|
|
575
777
|
}
|
|
576
778
|
else {
|
|
@@ -93,7 +93,7 @@ export function detectDestination(basePath) {
|
|
|
93
93
|
async function collectOneSecret(ctx, pageIndex, totalPages, keyName, hint, guidance) {
|
|
94
94
|
if (!ctx.hasUI)
|
|
95
95
|
return null;
|
|
96
|
-
|
|
96
|
+
const customResult = await ctx.ui.custom((tui, theme, _kb, done) => {
|
|
97
97
|
let value = "";
|
|
98
98
|
let cachedLines;
|
|
99
99
|
const editorTheme = {
|
|
@@ -178,6 +178,22 @@ async function collectOneSecret(ctx, pageIndex, totalPages, keyName, hint, guida
|
|
|
178
178
|
handleInput,
|
|
179
179
|
};
|
|
180
180
|
});
|
|
181
|
+
// RPC/web surfaces may not implement ctx.ui.custom(). Fall back to a
|
|
182
|
+
// standard input prompt so users can still provide the secret.
|
|
183
|
+
if (customResult !== undefined) {
|
|
184
|
+
return customResult;
|
|
185
|
+
}
|
|
186
|
+
if (typeof ctx.ui?.input !== "function") {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const inputTitle = `Secure value for ${keyName} (${pageIndex + 1}/${totalPages})`;
|
|
190
|
+
const inputPlaceholder = hint || "Enter secret value";
|
|
191
|
+
const inputResult = await ctx.ui.input(inputTitle, inputPlaceholder, { secure: true });
|
|
192
|
+
if (typeof inputResult !== "string") {
|
|
193
|
+
return null;
|
|
194
|
+
}
|
|
195
|
+
const trimmed = inputResult.trim();
|
|
196
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
181
197
|
}
|
|
182
198
|
/**
|
|
183
199
|
* Exported wrapper around collectOneSecret for testing.
|
|
@@ -47,3 +47,37 @@ export function isInfrastructureError(err) {
|
|
|
47
47
|
return "SQLITE_CORRUPT";
|
|
48
48
|
return null;
|
|
49
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Default wait duration when a cooldown error is detected but no specific
|
|
52
|
+
* expiry is available from AuthStorage (e.g., error propagated across
|
|
53
|
+
* process boundary without structured backoff data).
|
|
54
|
+
*/
|
|
55
|
+
export const COOLDOWN_FALLBACK_WAIT_MS = 35_000; // 35s — slightly longer than the 30s rate-limit backoff
|
|
56
|
+
/** Maximum consecutive cooldown retries before the auto-loop gives up. */
|
|
57
|
+
export const MAX_COOLDOWN_RETRIES = 5;
|
|
58
|
+
/**
|
|
59
|
+
* Detect whether an error is a transient credential cooldown that should
|
|
60
|
+
* be waited out rather than counted as a consecutive failure.
|
|
61
|
+
*
|
|
62
|
+
* Prefers the structured `CredentialCooldownError` (code: AUTH_COOLDOWN)
|
|
63
|
+
* thrown by sdk.ts. Falls back to message matching for errors that
|
|
64
|
+
* propagated across process boundaries without the typed class.
|
|
65
|
+
*/
|
|
66
|
+
export function isTransientCooldownError(err) {
|
|
67
|
+
if (err && typeof err === "object" && err.code === "AUTH_COOLDOWN") {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
// Fallback: message match for cross-process error propagation
|
|
71
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
72
|
+
return /in a cooldown window/i.test(msg);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Extract retryAfterMs from a CredentialCooldownError, if available.
|
|
76
|
+
* Returns undefined for unstructured errors or when no retry hint exists.
|
|
77
|
+
*/
|
|
78
|
+
export function getCooldownRetryAfterMs(err) {
|
|
79
|
+
if (err && typeof err === "object" && err.code === "AUTH_COOLDOWN") {
|
|
80
|
+
return err.retryAfterMs;
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
@@ -11,7 +11,7 @@ import { MAX_LOOP_ITERATIONS, } from "./types.js";
|
|
|
11
11
|
import { _clearCurrentResolve } from "./resolve.js";
|
|
12
12
|
import { runPreDispatch, runDispatch, runGuards, runUnitPhase, runFinalize, } from "./phases.js";
|
|
13
13
|
import { debugLog } from "../debug-logger.js";
|
|
14
|
-
import { isInfrastructureError } from "./infra-errors.js";
|
|
14
|
+
import { isInfrastructureError, isTransientCooldownError, getCooldownRetryAfterMs, COOLDOWN_FALLBACK_WAIT_MS, MAX_COOLDOWN_RETRIES } from "./infra-errors.js";
|
|
15
15
|
import { resolveEngine } from "../engine-resolver.js";
|
|
16
16
|
/**
|
|
17
17
|
* Main auto-mode execution loop. Iterates: derive → dispatch → guards →
|
|
@@ -26,6 +26,7 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
26
26
|
let iteration = 0;
|
|
27
27
|
const loopState = { recentUnits: [], stuckRecoveryAttempts: 0, consecutiveFinalizeTimeouts: 0 };
|
|
28
28
|
let consecutiveErrors = 0;
|
|
29
|
+
let consecutiveCooldowns = 0;
|
|
29
30
|
const recentErrorMessages = [];
|
|
30
31
|
while (s.active) {
|
|
31
32
|
iteration++;
|
|
@@ -158,6 +159,7 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
158
159
|
});
|
|
159
160
|
deps.clearUnitTimeout();
|
|
160
161
|
consecutiveErrors = 0;
|
|
162
|
+
consecutiveCooldowns = 0;
|
|
161
163
|
recentErrorMessages.length = 0;
|
|
162
164
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration } });
|
|
163
165
|
debugLog("autoLoop", { phase: "iteration-complete", iteration });
|
|
@@ -220,6 +222,7 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
220
222
|
if (finalizeResult.action === "continue")
|
|
221
223
|
continue;
|
|
222
224
|
consecutiveErrors = 0; // Iteration completed successfully
|
|
225
|
+
consecutiveCooldowns = 0;
|
|
223
226
|
recentErrorMessages.length = 0;
|
|
224
227
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration } });
|
|
225
228
|
debugLog("autoLoop", { phase: "iteration-complete", iteration });
|
|
@@ -246,6 +249,34 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
246
249
|
await deps.stopAuto(ctx, pi, `Infrastructure error (${infraCode}): not recoverable by retry`);
|
|
247
250
|
break;
|
|
248
251
|
}
|
|
252
|
+
// ── Credential cooldown: wait and retry with bounded budget ──
|
|
253
|
+
// A 429 triggers a 30s credential backoff in AuthStorage. If the SDK's
|
|
254
|
+
// getApiKey() retries couldn't outlast the window, the error surfaces
|
|
255
|
+
// here. Wait for the cooldown to clear rather than counting it as a
|
|
256
|
+
// consecutive failure — but cap retries so we don't spin for hours
|
|
257
|
+
// on persistent quota exhaustion.
|
|
258
|
+
if (isTransientCooldownError(loopErr)) {
|
|
259
|
+
consecutiveCooldowns++;
|
|
260
|
+
const retryAfterMs = getCooldownRetryAfterMs(loopErr);
|
|
261
|
+
debugLog("autoLoop", {
|
|
262
|
+
phase: "cooldown-wait",
|
|
263
|
+
iteration,
|
|
264
|
+
consecutiveCooldowns,
|
|
265
|
+
retryAfterMs,
|
|
266
|
+
error: msg,
|
|
267
|
+
});
|
|
268
|
+
if (consecutiveCooldowns > MAX_COOLDOWN_RETRIES) {
|
|
269
|
+
ctx.ui.notify(`Auto-mode stopped: ${consecutiveCooldowns} consecutive credential cooldowns — rate limit or quota may be persistently exhausted.`, "error");
|
|
270
|
+
await deps.stopAuto(ctx, pi, `${consecutiveCooldowns} consecutive credential cooldowns exceeded retry budget`);
|
|
271
|
+
break;
|
|
272
|
+
}
|
|
273
|
+
const waitMs = (retryAfterMs !== undefined && retryAfterMs > 0 && retryAfterMs <= 60_000)
|
|
274
|
+
? retryAfterMs + 500 // Use structured hint + small buffer
|
|
275
|
+
: COOLDOWN_FALLBACK_WAIT_MS;
|
|
276
|
+
ctx.ui.notify(`Credentials in cooldown (${consecutiveCooldowns}/${MAX_COOLDOWN_RETRIES}) — waiting ${Math.round(waitMs / 1000)}s before retrying.`, "warning");
|
|
277
|
+
await new Promise(resolve => setTimeout(resolve, waitMs));
|
|
278
|
+
continue; // Retry iteration without incrementing consecutiveErrors
|
|
279
|
+
}
|
|
249
280
|
consecutiveErrors++;
|
|
250
281
|
recentErrorMessages.push(msg.length > 120 ? msg.slice(0, 120) + "..." : msg);
|
|
251
282
|
debugLog("autoLoop", {
|
|
@@ -13,6 +13,7 @@ import { runUnit } from "./run-unit.js";
|
|
|
13
13
|
import { debugLog } from "../debug-logger.js";
|
|
14
14
|
import { PROJECT_FILES } from "../detection.js";
|
|
15
15
|
import { MergeConflictError } from "../git-service.js";
|
|
16
|
+
import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
|
|
16
17
|
import { join, basename, dirname, parse as parsePath } from "node:path";
|
|
17
18
|
import { existsSync, cpSync, readdirSync } from "node:fs";
|
|
18
19
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
@@ -770,6 +771,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
770
771
|
s.currentUnit.id === unitId);
|
|
771
772
|
const previousTier = s.currentUnitRouting?.tier;
|
|
772
773
|
s.currentUnit = { type: unitType, id: unitId, startedAt: Date.now() };
|
|
774
|
+
setCurrentPhase(unitType);
|
|
773
775
|
s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
|
|
774
776
|
const unitStartSeq = ic.nextSeq();
|
|
775
777
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
|
|
@@ -857,7 +859,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
857
859
|
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
858
860
|
}
|
|
859
861
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
860
|
-
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier });
|
|
862
|
+
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier }, undefined, s.manualSessionModelOverride);
|
|
861
863
|
s.currentUnitRouting =
|
|
862
864
|
modelResult.routing;
|
|
863
865
|
s.currentUnitModel =
|
|
@@ -1115,6 +1117,7 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1115
1117
|
// Detach session from the timed-out unit so late async completions
|
|
1116
1118
|
// cannot mutate state for the next unit (#3757).
|
|
1117
1119
|
s.currentUnit = null;
|
|
1120
|
+
clearCurrentPhase();
|
|
1118
1121
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1119
1122
|
debugLog("autoLoop", {
|
|
1120
1123
|
phase: "pre-verification-timeout",
|
|
@@ -1189,6 +1192,7 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1189
1192
|
// Detach session from the timed-out unit so late async completions
|
|
1190
1193
|
// cannot mutate state for the next unit (#3757).
|
|
1191
1194
|
s.currentUnit = null;
|
|
1195
|
+
clearCurrentPhase();
|
|
1192
1196
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1193
1197
|
debugLog("autoLoop", {
|
|
1194
1198
|
phase: "post-verification-timeout",
|
|
@@ -36,6 +36,10 @@ export class AutoSession {
|
|
|
36
36
|
previousProjectRootEnv = null;
|
|
37
37
|
hadProjectRootEnv = false;
|
|
38
38
|
projectRootEnvCaptured = false;
|
|
39
|
+
previousMilestoneLockEnv = null;
|
|
40
|
+
hadMilestoneLockEnv = false;
|
|
41
|
+
milestoneLockEnvCaptured = false;
|
|
42
|
+
sessionMilestoneLock = null;
|
|
39
43
|
gitService = null;
|
|
40
44
|
// ── Dispatch counters ────────────────────────────────────────────────────
|
|
41
45
|
unitDispatchCount = new Map();
|
|
@@ -52,6 +56,8 @@ export class AutoSession {
|
|
|
52
56
|
currentMilestoneId = null;
|
|
53
57
|
// ── Model state ──────────────────────────────────────────────────────────
|
|
54
58
|
autoModeStartModel = null;
|
|
59
|
+
/** Explicit /gsd model pin captured at bootstrap (session-scoped policy override). */
|
|
60
|
+
manualSessionModelOverride = null;
|
|
55
61
|
currentUnitModel = null;
|
|
56
62
|
/** Fully-qualified model ID (provider/id) set after selectAndApplyModel + hook overrides (#2899). */
|
|
57
63
|
currentDispatchedModelId = null;
|
|
@@ -140,6 +146,10 @@ export class AutoSession {
|
|
|
140
146
|
this.previousProjectRootEnv = null;
|
|
141
147
|
this.hadProjectRootEnv = false;
|
|
142
148
|
this.projectRootEnvCaptured = false;
|
|
149
|
+
this.previousMilestoneLockEnv = null;
|
|
150
|
+
this.hadMilestoneLockEnv = false;
|
|
151
|
+
this.milestoneLockEnvCaptured = false;
|
|
152
|
+
this.sessionMilestoneLock = null;
|
|
143
153
|
this.gitService = null;
|
|
144
154
|
// Dispatch
|
|
145
155
|
this.unitDispatchCount.clear();
|
|
@@ -151,6 +161,7 @@ export class AutoSession {
|
|
|
151
161
|
this.currentMilestoneId = null;
|
|
152
162
|
// Model
|
|
153
163
|
this.autoModeStartModel = null;
|
|
164
|
+
this.manualSessionModelOverride = null;
|
|
154
165
|
this.currentUnitModel = null;
|
|
155
166
|
this.currentDispatchedModelId = null;
|
|
156
167
|
this.originalModelId = null;
|