gsd-pi 2.71.0 → 2.72.0-dev.3118184
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 +69 -19
- package/dist/cli.js +88 -6
- 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/onboarding.js +10 -0
- 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/async-jobs/await-tool.js +7 -4
- package/dist/resources/extensions/async-jobs/job-manager.js +28 -3
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +40 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +142 -14
- package/dist/resources/extensions/gsd/auto/infra-errors.js +34 -0
- package/dist/resources/extensions/gsd/auto/loop.js +116 -2
- 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-post-unit.js +6 -0
- package/dist/resources/extensions/gsd/auto-prompts.js +88 -33
- package/dist/resources/extensions/gsd/auto-recovery.js +11 -0
- package/dist/resources/extensions/gsd/auto-start.js +34 -7
- 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 +81 -19
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +11 -11
- 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/commands-handlers.js +4 -1
- package/dist/resources/extensions/gsd/context-injector.js +1 -1
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -7
- package/dist/resources/extensions/gsd/dashboard-overlay.js +8 -3
- package/dist/resources/extensions/gsd/definition-io.js +15 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +22 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +23 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +6 -3
- package/dist/resources/extensions/gsd/error-classifier.js +5 -2
- package/dist/resources/extensions/gsd/forensics.js +19 -6
- package/dist/resources/extensions/gsd/gate-registry.js +208 -0
- package/dist/resources/extensions/gsd/git-service.js +11 -8
- package/dist/resources/extensions/gsd/gitignore.js +12 -6
- package/dist/resources/extensions/gsd/gsd-db.js +90 -6
- package/dist/resources/extensions/gsd/guided-flow.js +5 -10
- package/dist/resources/extensions/gsd/key-manager.js +2 -0
- 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/preferences-skills.js +2 -34
- package/dist/resources/extensions/gsd/preferences-types.js +15 -0
- package/dist/resources/extensions/gsd/preferences.js +16 -3
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- 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 +123 -12
- 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 +29 -2
- 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 +4 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +7 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +30 -3
- package/dist/resources/extensions/gsd/write-intercept.js +10 -1
- package/dist/resources/extensions/ollama/index.js +17 -10
- package/dist/resources/extensions/ollama/ollama-client.js +35 -6
- package/dist/resources/extensions/ollama/ollama-discovery.js +32 -6
- 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 +15 -15
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/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 +2 -2
- 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 +2 -2
- 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 +3 -3
- 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 +15 -15
- package/dist/web/standalone/.next/server/chunks/2331.js +16 -16
- package/dist/web/standalone/.next/server/chunks/4741.js +12 -12
- package/dist/web/standalone/.next/server/chunks/5822.js +2 -2
- package/dist/web/standalone/.next/server/chunks/63.js +8 -8
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/edge-runtime-webpack.js +2 -0
- package/dist/web/standalone/.next/server/functions-config-manifest.json +0 -9
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +29 -2
- package/dist/web/standalone/.next/server/middleware.js +4 -12
- 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/server/webpack-runtime.js +1 -1
- 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/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/server.d.ts +12 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +90 -42
- 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/server.ts +110 -38
- 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/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.custom.d.ts +105 -0
- package/packages/pi-ai/dist/models.custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.custom.js +97 -0
- package/packages/pi-ai/dist/models.custom.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +648 -140
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +867 -370
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.d.ts +2 -0
- package/packages/pi-ai/dist/models.generated.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/models.generated.test.js +334 -0
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -0
- package/packages/pi-ai/dist/models.test.js +105 -0
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- 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/dist/types.d.ts +1 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +5 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +57 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/models.custom.ts +98 -0
- package/packages/pi-ai/src/models.generated.test.ts +373 -0
- package/packages/pi-ai/src/models.generated.ts +867 -370
- package/packages/pi-ai/src/models.test.ts +135 -0
- 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-ai/src/types.ts +1 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +71 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +4 -1
- 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/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 +23 -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 +47 -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/__tests__/tool-execution.test.js +36 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/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 +130 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +7 -2
- 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.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -3
- 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/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/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 +23 -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 +55 -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/__tests__/tool-execution.test.ts +72 -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 +131 -12
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +6 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +4 -2
- package/packages/pi-tui/dist/components/__tests__/editor.test.js +12 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +12 -0
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +27 -0
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/src/components/__tests__/editor.test.ts +18 -0
- package/packages/pi-tui/src/components/__tests__/input.test.ts +18 -0
- package/packages/pi-tui/src/keys.ts +32 -0
- 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/async-jobs/await-tool.test.ts +40 -7
- package/src/resources/extensions/async-jobs/await-tool.ts +7 -4
- package/src/resources/extensions/async-jobs/job-manager.ts +33 -3
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +45 -12
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +152 -13
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +91 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +301 -6
- 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 +134 -2
- 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-post-unit.ts +7 -0
- package/src/resources/extensions/gsd/auto-prompts.ts +111 -33
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -0
- package/src/resources/extensions/gsd/auto-start.ts +41 -7
- 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 +97 -20
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +10 -10
- 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/commands-handlers.ts +5 -1
- package/src/resources/extensions/gsd/context-injector.ts +1 -1
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +4 -8
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -3
- package/src/resources/extensions/gsd/definition-io.ts +18 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +23 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +24 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +6 -3
- package/src/resources/extensions/gsd/error-classifier.ts +5 -2
- package/src/resources/extensions/gsd/forensics.ts +23 -7
- package/src/resources/extensions/gsd/gate-registry.ts +251 -0
- package/src/resources/extensions/gsd/git-service.ts +11 -8
- package/src/resources/extensions/gsd/gitignore.ts +12 -6
- package/src/resources/extensions/gsd/gsd-db.ts +105 -6
- package/src/resources/extensions/gsd/guided-flow.ts +5 -10
- package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
- package/src/resources/extensions/gsd/key-manager.ts +2 -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/preferences-skills.ts +2 -36
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +19 -6
- package/src/resources/extensions/gsd/prompt-loader.ts +6 -1
- 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 +123 -12
- 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 +33 -2
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +27 -0
- 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/block-db-writes.test.ts +63 -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/definition-io.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/doctor-heal-fixable-warnings.test.ts +14 -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/false-degraded-mode-warning.test.ts +104 -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-db.test.ts +107 -5
- 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/integration/git-service.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +54 -0
- 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/plan-milestone-artifact-verification.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/preferences-formatting.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +96 -1
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prompt-loader-working-directory.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-hooks-depth-verification.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +63 -5
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +41 -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/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 +4 -1
- package/src/resources/extensions/gsd/types.ts +26 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +8 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +29 -3
- package/src/resources/extensions/gsd/write-intercept.ts +10 -1
- package/src/resources/extensions/ollama/index.ts +17 -8
- package/src/resources/extensions/ollama/ollama-client.ts +35 -6
- package/src/resources/extensions/ollama/ollama-discovery.ts +37 -6
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +54 -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/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/{nPky_WQC28aBD77eZsRAB → NzO79SOz9jHX-VY5-0t2O}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → NzO79SOz9jHX-VY5-0t2O}/_ssgManifest.js +0 -0
|
@@ -29,6 +29,15 @@ function createAssistantStream() {
|
|
|
29
29
|
throw new Error("Unexpected event type for final result");
|
|
30
30
|
});
|
|
31
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
|
+
}
|
|
32
41
|
// ---------------------------------------------------------------------------
|
|
33
42
|
// Claude binary resolution
|
|
34
43
|
// ---------------------------------------------------------------------------
|
|
@@ -83,18 +92,34 @@ function extractMessageText(msg) {
|
|
|
83
92
|
* call effectively stateless. This version serialises the complete
|
|
84
93
|
* conversation history (system prompt + all user/assistant turns) so
|
|
85
94
|
* Claude Code has full context for multi-turn continuity.
|
|
95
|
+
*
|
|
96
|
+
* History is wrapped in XML-tag structure rather than `[User]`/`[Assistant]`
|
|
97
|
+
* bracket headers. Bracket headers read to the model as an in-context
|
|
98
|
+
* demonstration of how turns are delimited, causing it to fabricate fake
|
|
99
|
+
* user turns in its own output. XML tags read as document structure and
|
|
100
|
+
* don't get mirrored in free text.
|
|
86
101
|
*/
|
|
87
102
|
export function buildPromptFromContext(context) {
|
|
88
|
-
const
|
|
103
|
+
const hasContent = Boolean(context.systemPrompt) || context.messages.some((m) => extractMessageText(m));
|
|
104
|
+
if (!hasContent)
|
|
105
|
+
return "";
|
|
106
|
+
const parts = [
|
|
107
|
+
"Respond only to the final user message below. " +
|
|
108
|
+
"Do not emit <user_message>, <assistant_message>, or <prior_system_context> tags in your response.",
|
|
109
|
+
];
|
|
89
110
|
if (context.systemPrompt) {
|
|
90
|
-
parts.push(
|
|
111
|
+
parts.push(`<prior_system_context>\n${context.systemPrompt}\n</prior_system_context>`);
|
|
91
112
|
}
|
|
113
|
+
const turns = [];
|
|
92
114
|
for (const msg of context.messages) {
|
|
93
115
|
const text = extractMessageText(msg);
|
|
94
116
|
if (!text)
|
|
95
117
|
continue;
|
|
96
|
-
const
|
|
97
|
-
|
|
118
|
+
const tag = msg.role === "user" ? "user_message" : msg.role === "assistant" ? "assistant_message" : "system_message";
|
|
119
|
+
turns.push(`<${tag}>\n${text}\n</${tag}>`);
|
|
120
|
+
}
|
|
121
|
+
if (turns.length > 0) {
|
|
122
|
+
parts.push(`<conversation_history>\n${turns.join("\n")}\n</conversation_history>`);
|
|
98
123
|
}
|
|
99
124
|
return parts.join("\n\n");
|
|
100
125
|
}
|
|
@@ -354,29 +379,94 @@ export function createClaudeCodeElicitationHandler(ui) {
|
|
|
354
379
|
return { action: "decline" };
|
|
355
380
|
};
|
|
356
381
|
}
|
|
382
|
+
/**
|
|
383
|
+
* Aborted by the caller's AbortSignal — distinct from exhaustion. GSD's
|
|
384
|
+
* agent loop keys off `stopReason === "aborted"` to treat this as a clean
|
|
385
|
+
* user cancel instead of a retry-eligible provider failure.
|
|
386
|
+
*/
|
|
387
|
+
export function makeAbortedMessage(model, lastTextContent) {
|
|
388
|
+
const message = {
|
|
389
|
+
role: "assistant",
|
|
390
|
+
content: lastTextContent
|
|
391
|
+
? [{ type: "text", text: lastTextContent }]
|
|
392
|
+
: [{ type: "text", text: "Claude Code stream aborted by caller" }],
|
|
393
|
+
api: "anthropic-messages",
|
|
394
|
+
provider: "claude-code",
|
|
395
|
+
model,
|
|
396
|
+
usage: { ...ZERO_USAGE },
|
|
397
|
+
stopReason: "aborted",
|
|
398
|
+
timestamp: Date.now(),
|
|
399
|
+
};
|
|
400
|
+
return message;
|
|
401
|
+
}
|
|
357
402
|
// ---------------------------------------------------------------------------
|
|
358
403
|
// SDK options builder
|
|
359
404
|
// ---------------------------------------------------------------------------
|
|
405
|
+
/**
|
|
406
|
+
* Resolve the Claude Code permission mode for the current run.
|
|
407
|
+
*
|
|
408
|
+
* GSD subagents run underneath a host Claude Code session the user has
|
|
409
|
+
* already consented to, and their work (edits, shell inspection, MCP calls)
|
|
410
|
+
* spans the full workflow toolset. Defaulting the inner SDK to
|
|
411
|
+
* `bypassPermissions` avoids per-tool approval prompts that offer no
|
|
412
|
+
* meaningful safety beyond what the host session and the subagent prompts
|
|
413
|
+
* already enforce. `GSD_CLAUDE_CODE_PERMISSION_MODE` lets security-conscious
|
|
414
|
+
* users opt into a stricter mode (`acceptEdits`, `default`, `plan`).
|
|
415
|
+
*
|
|
416
|
+
* Tradeoff: bypass means a prompt-injection payload read from an untrusted
|
|
417
|
+
* file could trigger tool calls without a second gate. Accepted for GSD
|
|
418
|
+
* because the workflow is explicit user intent and the alternative
|
|
419
|
+
* (#4099) is continuous approval fatigue that blocks real work.
|
|
420
|
+
*/
|
|
421
|
+
export async function resolveClaudePermissionMode(env = process.env) {
|
|
422
|
+
const override = env.GSD_CLAUDE_CODE_PERMISSION_MODE?.trim();
|
|
423
|
+
if (override === "bypassPermissions" || override === "acceptEdits" || override === "default" || override === "plan") {
|
|
424
|
+
return override;
|
|
425
|
+
}
|
|
426
|
+
return "bypassPermissions";
|
|
427
|
+
}
|
|
360
428
|
/**
|
|
361
429
|
* Build the options object passed to the Claude Agent SDK's `query()` call.
|
|
362
430
|
*
|
|
363
431
|
* Extracted for testability — callers can verify session persistence,
|
|
364
432
|
* beta flags, and other configuration without mocking the full SDK.
|
|
433
|
+
*
|
|
434
|
+
* `permissionMode` / `allowDangerouslySkipPermissions` are resolved through
|
|
435
|
+
* {@link resolveClaudePermissionMode} so interactive runs don't silently
|
|
436
|
+
* bypass the SDK's permission gate. Callers that want the old always-bypass
|
|
437
|
+
* behaviour pass `permissionMode: "bypassPermissions"` explicitly.
|
|
365
438
|
*/
|
|
366
|
-
export function buildSdkOptions(modelId, prompt, extraOptions = {}) {
|
|
439
|
+
export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
367
440
|
const mcpServers = buildWorkflowMcpServers();
|
|
441
|
+
const permissionMode = overrides?.permissionMode ?? "bypassPermissions";
|
|
368
442
|
const disallowedTools = ["AskUserQuestion"];
|
|
443
|
+
// Pre-authorize the safe built-ins and every registered workflow MCP
|
|
444
|
+
// server's tools. `acceptEdits` mode (the interactive default) only
|
|
445
|
+
// auto-approves file edits — Read/Glob/Grep, basic shell inspection, and
|
|
446
|
+
// every `mcp__gsd-workflow__*` call still surface as "This command
|
|
447
|
+
// requires approval" and block GSD actions (#4099).
|
|
448
|
+
const allowedTools = [
|
|
449
|
+
"Read",
|
|
450
|
+
"Write",
|
|
451
|
+
"Edit",
|
|
452
|
+
"Glob",
|
|
453
|
+
"Grep",
|
|
454
|
+
"Bash(ls:*)",
|
|
455
|
+
"Bash(pwd)",
|
|
456
|
+
...(mcpServers ? Object.keys(mcpServers).map((serverName) => `mcp__${serverName}__*`) : []),
|
|
457
|
+
];
|
|
369
458
|
return {
|
|
370
459
|
pathToClaudeCodeExecutable: getClaudePath(),
|
|
371
460
|
model: modelId,
|
|
372
461
|
includePartialMessages: true,
|
|
373
462
|
persistSession: true,
|
|
374
463
|
cwd: process.cwd(),
|
|
375
|
-
permissionMode
|
|
376
|
-
allowDangerouslySkipPermissions:
|
|
464
|
+
permissionMode,
|
|
465
|
+
allowDangerouslySkipPermissions: permissionMode === "bypassPermissions",
|
|
377
466
|
settingSources: ["project"],
|
|
378
467
|
systemPrompt: { type: "preset", preset: "claude_code" },
|
|
379
468
|
disallowedTools,
|
|
469
|
+
...(allowedTools.length > 0 ? { allowedTools } : {}),
|
|
380
470
|
...(mcpServers ? { mcpServers } : {}),
|
|
381
471
|
betas: modelId.includes("sonnet") ? ["context-1m-2025-08-07"] : [],
|
|
382
472
|
...extraOptions,
|
|
@@ -470,6 +560,28 @@ function attachExternalResultsToToolBlocks(toolBlocks, toolResultsById) {
|
|
|
470
560
|
block.externalResult = externalResult;
|
|
471
561
|
}
|
|
472
562
|
}
|
|
563
|
+
/**
|
|
564
|
+
* Merge tool-call blocks from the active partial-message builder into the
|
|
565
|
+
* running list of intermediate tool calls, preserving order and de-duping
|
|
566
|
+
* by tool-call id. Exposed for testing the F3 fix (final-turn tool calls
|
|
567
|
+
* dropped when `result` arrives without a preceding synthetic `user`).
|
|
568
|
+
*/
|
|
569
|
+
export function mergePendingToolCalls(intermediate, pending) {
|
|
570
|
+
const alreadyIncluded = new Set();
|
|
571
|
+
for (const block of intermediate) {
|
|
572
|
+
if (block.type === "toolCall")
|
|
573
|
+
alreadyIncluded.add(block.id);
|
|
574
|
+
}
|
|
575
|
+
for (const block of pending) {
|
|
576
|
+
if (block.type !== "toolCall")
|
|
577
|
+
continue;
|
|
578
|
+
if (alreadyIncluded.has(block.id))
|
|
579
|
+
continue;
|
|
580
|
+
alreadyIncluded.add(block.id);
|
|
581
|
+
intermediate.push(block);
|
|
582
|
+
}
|
|
583
|
+
return intermediate;
|
|
584
|
+
}
|
|
473
585
|
// ---------------------------------------------------------------------------
|
|
474
586
|
// streamSimple implementation
|
|
475
587
|
// ---------------------------------------------------------------------------
|
|
@@ -505,7 +617,8 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
505
617
|
options.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
506
618
|
}
|
|
507
619
|
const prompt = buildPromptFromContext(context);
|
|
508
|
-
const
|
|
620
|
+
const permissionMode = await resolveClaudePermissionMode();
|
|
621
|
+
const sdkOpts = buildSdkOptions(modelId, prompt, { permissionMode }, typeof options?.extensionUIContext === "object"
|
|
509
622
|
? {
|
|
510
623
|
onElicitation: createClaudeCodeElicitationHandler(options?.extensionUIContext),
|
|
511
624
|
}
|
|
@@ -530,8 +643,17 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
530
643
|
};
|
|
531
644
|
stream.push({ type: "start", partial: initialPartial });
|
|
532
645
|
for await (const msg of queryResult) {
|
|
533
|
-
if (options?.signal?.aborted)
|
|
534
|
-
|
|
646
|
+
if (options?.signal?.aborted) {
|
|
647
|
+
// User-initiated cancel — emit an aborted error so the agent
|
|
648
|
+
// loop classifies this as a deliberate stop, not a transient
|
|
649
|
+
// provider failure that should be retried.
|
|
650
|
+
stream.push({
|
|
651
|
+
type: "error",
|
|
652
|
+
reason: "aborted",
|
|
653
|
+
error: makeAbortedMessage(modelId, lastTextContent),
|
|
654
|
+
});
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
535
657
|
switch (msg.type) {
|
|
536
658
|
// -- Init --
|
|
537
659
|
case "system": {
|
|
@@ -632,6 +754,15 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
632
754
|
// agent loop's externalToolExecution path emits tool_execution
|
|
633
755
|
// events for proper TUI rendering, followed by the text response.
|
|
634
756
|
const finalContent = [];
|
|
757
|
+
// If the final turn ended without a synthetic user message
|
|
758
|
+
// (e.g. stop_reason: "tool_use" followed directly by result,
|
|
759
|
+
// or a turn with text but no tool execution), the `builder`
|
|
760
|
+
// still holds toolCall blocks that were never pushed into
|
|
761
|
+
// `intermediateToolBlocks`. Fold them in here so they aren't
|
|
762
|
+
// dropped from the final AssistantMessage.
|
|
763
|
+
if (builder) {
|
|
764
|
+
mergePendingToolCalls(intermediateToolBlocks, builder.message.content);
|
|
765
|
+
}
|
|
635
766
|
// Add tool calls from intermediate turns first (renders above text)
|
|
636
767
|
attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
|
|
637
768
|
finalContent.push(...intermediateToolBlocks);
|
|
@@ -666,10 +797,7 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
666
797
|
timestamp: Date.now(),
|
|
667
798
|
};
|
|
668
799
|
if (result.is_error) {
|
|
669
|
-
|
|
670
|
-
? result.errors?.join("; ")
|
|
671
|
-
: result.subtype;
|
|
672
|
-
finalMessage.errorMessage = errText;
|
|
800
|
+
finalMessage.errorMessage = getResultErrorMessage(result);
|
|
673
801
|
stream.push({ type: "error", reason: "error", error: finalMessage });
|
|
674
802
|
}
|
|
675
803
|
else {
|
|
@@ -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,8 +11,71 @@ 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
|
+
import { logWarning } from "../workflow-logger.js";
|
|
17
|
+
import { gsdRoot } from "../paths.js";
|
|
18
|
+
import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
19
|
+
import { join } from "node:path";
|
|
20
|
+
// ── Stuck detection persistence (#3704) ──────────────────────────────────
|
|
21
|
+
// Persist stuck detection state to disk so it survives session restarts.
|
|
22
|
+
// Without this, restarting auto-mode resets all counters, allowing the
|
|
23
|
+
// same blocked unit to burn a full retry budget each session.
|
|
24
|
+
function stuckStatePath(basePath) {
|
|
25
|
+
return join(gsdRoot(basePath), "runtime", "stuck-state.json");
|
|
26
|
+
}
|
|
27
|
+
function loadStuckState(basePath) {
|
|
28
|
+
try {
|
|
29
|
+
const data = JSON.parse(readFileSync(stuckStatePath(basePath), "utf-8"));
|
|
30
|
+
return {
|
|
31
|
+
recentUnits: Array.isArray(data.recentUnits) ? data.recentUnits : [],
|
|
32
|
+
stuckRecoveryAttempts: typeof data.stuckRecoveryAttempts === "number" ? data.stuckRecoveryAttempts : 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
debugLog("autoLoop", { phase: "load-stuck-state-failed", error: err instanceof Error ? err.message : String(err) });
|
|
37
|
+
return { recentUnits: [], stuckRecoveryAttempts: 0 };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function saveStuckState(basePath, state) {
|
|
41
|
+
try {
|
|
42
|
+
const filePath = stuckStatePath(basePath);
|
|
43
|
+
mkdirSync(join(gsdRoot(basePath), "runtime"), { recursive: true });
|
|
44
|
+
writeFileSync(filePath, JSON.stringify({
|
|
45
|
+
recentUnits: state.recentUnits.slice(-20), // keep last 20 entries
|
|
46
|
+
stuckRecoveryAttempts: state.stuckRecoveryAttempts,
|
|
47
|
+
updatedAt: new Date().toISOString(),
|
|
48
|
+
}) + "\n");
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
debugLog("autoLoop", { phase: "save-stuck-state-failed", error: err instanceof Error ? err.message : String(err) });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
// ── Memory pressure monitoring (#3331) ──────────────────────────────────
|
|
55
|
+
// Check heap usage every N iterations and trigger graceful shutdown before
|
|
56
|
+
// the OS OOM killer sends SIGKILL. The threshold is 90% of the V8 heap
|
|
57
|
+
// limit (--max-old-space-size or default ~1.5-4GB depending on platform).
|
|
58
|
+
const MEMORY_CHECK_INTERVAL = 5; // check every 5 iterations
|
|
59
|
+
const MEMORY_PRESSURE_THRESHOLD = 0.85; // 85% of heap limit
|
|
60
|
+
function checkMemoryPressure() {
|
|
61
|
+
const mem = process.memoryUsage();
|
|
62
|
+
// v8.getHeapStatistics() gives heap_size_limit but requires import
|
|
63
|
+
// Use a conservative estimate: RSS > 3GB is danger zone on most systems
|
|
64
|
+
const heapMB = Math.round(mem.heapUsed / 1024 / 1024);
|
|
65
|
+
const rssMB = Math.round(mem.rss / 1024 / 1024);
|
|
66
|
+
// Try to get the actual V8 heap limit
|
|
67
|
+
let limitMB = 4096; // conservative default
|
|
68
|
+
try {
|
|
69
|
+
const v8 = require("node:v8");
|
|
70
|
+
const stats = v8.getHeapStatistics();
|
|
71
|
+
limitMB = Math.round(stats.heap_size_limit / 1024 / 1024);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
limitMB = 4096; /* v8 stats unavailable — use conservative default */
|
|
75
|
+
}
|
|
76
|
+
const pct = heapMB / limitMB;
|
|
77
|
+
return { pressured: pct > MEMORY_PRESSURE_THRESHOLD, heapMB, limitMB, pct };
|
|
78
|
+
}
|
|
16
79
|
/**
|
|
17
80
|
* Main auto-mode execution loop. Iterates: derive → dispatch → guards →
|
|
18
81
|
* runUnit → finalize → repeat. Exits when s.active becomes false or a
|
|
@@ -24,8 +87,15 @@ import { resolveEngine } from "../engine-resolver.js";
|
|
|
24
87
|
export async function autoLoop(ctx, pi, s, deps) {
|
|
25
88
|
debugLog("autoLoop", { phase: "enter" });
|
|
26
89
|
let iteration = 0;
|
|
27
|
-
|
|
90
|
+
// Load persisted stuck state so counters survive session restarts (#3704)
|
|
91
|
+
const persisted = loadStuckState(s.basePath);
|
|
92
|
+
const loopState = {
|
|
93
|
+
recentUnits: persisted.recentUnits,
|
|
94
|
+
stuckRecoveryAttempts: persisted.stuckRecoveryAttempts,
|
|
95
|
+
consecutiveFinalizeTimeouts: 0,
|
|
96
|
+
};
|
|
28
97
|
let consecutiveErrors = 0;
|
|
98
|
+
let consecutiveCooldowns = 0;
|
|
29
99
|
const recentErrorMessages = [];
|
|
30
100
|
while (s.active) {
|
|
31
101
|
iteration++;
|
|
@@ -43,6 +113,19 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
43
113
|
await deps.stopAuto(ctx, pi, `Safety: loop exceeded ${MAX_LOOP_ITERATIONS} iterations — possible runaway`);
|
|
44
114
|
break;
|
|
45
115
|
}
|
|
116
|
+
// ── Memory pressure check (#3331) ──
|
|
117
|
+
// Graceful shutdown before OOM killer sends SIGKILL.
|
|
118
|
+
if (iteration % MEMORY_CHECK_INTERVAL === 0) {
|
|
119
|
+
const mem = checkMemoryPressure();
|
|
120
|
+
debugLog("autoLoop", { phase: "memory-check", ...mem });
|
|
121
|
+
if (mem.pressured) {
|
|
122
|
+
logWarning("dispatch", `Memory pressure: ${mem.heapMB}MB / ${mem.limitMB}MB (${Math.round(mem.pct * 100)}%) — stopping auto-mode to prevent OOM kill`);
|
|
123
|
+
await deps.stopAuto(ctx, pi, `Memory pressure: heap at ${mem.heapMB}MB / ${mem.limitMB}MB (${Math.round(mem.pct * 100)}%). ` +
|
|
124
|
+
`Stopping gracefully to prevent OOM kill after ${iteration} iterations. ` +
|
|
125
|
+
`Resume with /gsd auto to continue from where you left off.`);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
46
129
|
if (!s.cmdCtx) {
|
|
47
130
|
debugLog("autoLoop", { phase: "exit", reason: "no-cmdCtx" });
|
|
48
131
|
break;
|
|
@@ -158,8 +241,10 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
158
241
|
});
|
|
159
242
|
deps.clearUnitTimeout();
|
|
160
243
|
consecutiveErrors = 0;
|
|
244
|
+
consecutiveCooldowns = 0;
|
|
161
245
|
recentErrorMessages.length = 0;
|
|
162
246
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration } });
|
|
247
|
+
saveStuckState(s.basePath, loopState); // persist across session restarts (#3704)
|
|
163
248
|
debugLog("autoLoop", { phase: "iteration-complete", iteration });
|
|
164
249
|
if (reconcileResult.outcome === "milestone-complete") {
|
|
165
250
|
await deps.stopAuto(ctx, pi, "Workflow complete");
|
|
@@ -220,6 +305,7 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
220
305
|
if (finalizeResult.action === "continue")
|
|
221
306
|
continue;
|
|
222
307
|
consecutiveErrors = 0; // Iteration completed successfully
|
|
308
|
+
consecutiveCooldowns = 0;
|
|
223
309
|
recentErrorMessages.length = 0;
|
|
224
310
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId, seq: nextSeq(), eventType: "iteration-end", data: { iteration } });
|
|
225
311
|
debugLog("autoLoop", { phase: "iteration-complete", iteration });
|
|
@@ -246,6 +332,34 @@ export async function autoLoop(ctx, pi, s, deps) {
|
|
|
246
332
|
await deps.stopAuto(ctx, pi, `Infrastructure error (${infraCode}): not recoverable by retry`);
|
|
247
333
|
break;
|
|
248
334
|
}
|
|
335
|
+
// ── Credential cooldown: wait and retry with bounded budget ──
|
|
336
|
+
// A 429 triggers a 30s credential backoff in AuthStorage. If the SDK's
|
|
337
|
+
// getApiKey() retries couldn't outlast the window, the error surfaces
|
|
338
|
+
// here. Wait for the cooldown to clear rather than counting it as a
|
|
339
|
+
// consecutive failure — but cap retries so we don't spin for hours
|
|
340
|
+
// on persistent quota exhaustion.
|
|
341
|
+
if (isTransientCooldownError(loopErr)) {
|
|
342
|
+
consecutiveCooldowns++;
|
|
343
|
+
const retryAfterMs = getCooldownRetryAfterMs(loopErr);
|
|
344
|
+
debugLog("autoLoop", {
|
|
345
|
+
phase: "cooldown-wait",
|
|
346
|
+
iteration,
|
|
347
|
+
consecutiveCooldowns,
|
|
348
|
+
retryAfterMs,
|
|
349
|
+
error: msg,
|
|
350
|
+
});
|
|
351
|
+
if (consecutiveCooldowns > MAX_COOLDOWN_RETRIES) {
|
|
352
|
+
ctx.ui.notify(`Auto-mode stopped: ${consecutiveCooldowns} consecutive credential cooldowns — rate limit or quota may be persistently exhausted.`, "error");
|
|
353
|
+
await deps.stopAuto(ctx, pi, `${consecutiveCooldowns} consecutive credential cooldowns exceeded retry budget`);
|
|
354
|
+
break;
|
|
355
|
+
}
|
|
356
|
+
const waitMs = (retryAfterMs !== undefined && retryAfterMs > 0 && retryAfterMs <= 60_000)
|
|
357
|
+
? retryAfterMs + 500 // Use structured hint + small buffer
|
|
358
|
+
: COOLDOWN_FALLBACK_WAIT_MS;
|
|
359
|
+
ctx.ui.notify(`Credentials in cooldown (${consecutiveCooldowns}/${MAX_COOLDOWN_RETRIES}) — waiting ${Math.round(waitMs / 1000)}s before retrying.`, "warning");
|
|
360
|
+
await new Promise(resolve => setTimeout(resolve, waitMs));
|
|
361
|
+
continue; // Retry iteration without incrementing consecutiveErrors
|
|
362
|
+
}
|
|
249
363
|
consecutiveErrors++;
|
|
250
364
|
recentErrorMessages.push(msg.length > 120 ? msg.slice(0, 120) + "..." : msg);
|
|
251
365
|
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;
|
|
@@ -10,7 +10,6 @@ import { getActiveHook } from "./post-unit-hooks.js";
|
|
|
10
10
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
11
11
|
import { getErrorMessage } from "./error-utils.js";
|
|
12
12
|
import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
13
|
-
import { formatShortcut } from "./files.js";
|
|
14
13
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
15
14
|
import { execFileSync } from "node:child_process";
|
|
16
15
|
import { truncateToWidth, visibleWidth } from "@gsd/pi-tui";
|
|
@@ -23,6 +22,7 @@ import { resolveServiceTierIcon, getEffectiveServiceTier } from "./service-tier.
|
|
|
23
22
|
import { parseUnitId } from "./unit-id.js";
|
|
24
23
|
import { formatRtkSavingsLabel, getRtkSessionSavings, } from "../shared/rtk-session-stats.js";
|
|
25
24
|
import { logWarning } from "./workflow-logger.js";
|
|
25
|
+
import { formattedShortcutPair } from "./shortcut-defs.js";
|
|
26
26
|
// ─── UAT Slice Extraction ─────────────────────────────────────────────────────
|
|
27
27
|
/**
|
|
28
28
|
* Extract the target slice ID from a run-uat unit ID (e.g. "M001/S01" → "S01").
|
|
@@ -282,12 +282,23 @@ function getLastCommit(basePath) {
|
|
|
282
282
|
}
|
|
283
283
|
// ─── Footer Factory ───────────────────────────────────────────────────────────
|
|
284
284
|
/**
|
|
285
|
-
* Footer factory
|
|
286
|
-
*
|
|
287
|
-
* progress widget instead, so there's no gap or redundancy.
|
|
285
|
+
* Footer factory used by auto-mode.
|
|
286
|
+
* Keep footer minimal but preserve extension status context from setStatus().
|
|
288
287
|
*/
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
function sanitizeFooterStatus(text) {
|
|
289
|
+
return text.replace(/\s+/g, " ").trim();
|
|
290
|
+
}
|
|
291
|
+
export const hideFooter = (_tui, theme, footerData) => ({
|
|
292
|
+
render(width) {
|
|
293
|
+
const extensionStatuses = footerData.getExtensionStatuses();
|
|
294
|
+
if (extensionStatuses.size === 0)
|
|
295
|
+
return [];
|
|
296
|
+
const statusLine = Array.from(extensionStatuses.entries())
|
|
297
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
298
|
+
.map(([, text]) => sanitizeFooterStatus(text))
|
|
299
|
+
.join(" ");
|
|
300
|
+
return [truncateToWidth(theme.fg("dim", statusLine), width, theme.fg("dim", "..."))];
|
|
301
|
+
},
|
|
291
302
|
invalidate() { },
|
|
292
303
|
dispose() { },
|
|
293
304
|
});
|
|
@@ -522,13 +533,6 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
522
533
|
: theme.fg("dim", elapsed))
|
|
523
534
|
: "";
|
|
524
535
|
lines.push(rightAlign(headerLeft, headerRight, width));
|
|
525
|
-
// Worktree/branch right-aligned below header
|
|
526
|
-
const branchLabel = worktreeName && cachedBranch
|
|
527
|
-
? `${worktreeName} (${cachedBranch})`
|
|
528
|
-
: cachedBranch ?? "";
|
|
529
|
-
if (branchLabel) {
|
|
530
|
-
lines.push(rightAlign("", theme.fg("dim", branchLabel), width));
|
|
531
|
-
}
|
|
532
536
|
// Show health signal details when degraded (yellow/red)
|
|
533
537
|
if (score.level !== "green" && score.signals.length > 0 && widgetMode !== "min") {
|
|
534
538
|
// Show up to 3 most relevant signals in compact form
|
|
@@ -776,16 +780,18 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
776
780
|
// Hints line
|
|
777
781
|
const hintParts = [];
|
|
778
782
|
hintParts.push("esc pause");
|
|
779
|
-
hintParts.push(`${
|
|
783
|
+
hintParts.push(`${formattedShortcutPair("dashboard")} dashboard`);
|
|
784
|
+
hintParts.push(`${formattedShortcutPair("parallel")} parallel`);
|
|
780
785
|
const hintStr = theme.fg("dim", hintParts.join(" | "));
|
|
781
786
|
const commitStr = lastCommit
|
|
782
787
|
? theme.fg("dim", `${lastCommit.timeAgo} ago: ${commitMsg}`)
|
|
783
788
|
: "";
|
|
789
|
+
const locationStr = theme.fg("dim", widgetPwd);
|
|
784
790
|
if (commitStr) {
|
|
785
|
-
lines.push(rightAlign(`${pad}${commitStr}`, hintStr, width));
|
|
791
|
+
lines.push(rightAlign(`${pad}${locationStr} · ${commitStr}`, hintStr, width));
|
|
786
792
|
}
|
|
787
793
|
else {
|
|
788
|
-
lines.push(rightAlign(
|
|
794
|
+
lines.push(rightAlign(`${pad}${locationStr}`, hintStr, width));
|
|
789
795
|
}
|
|
790
796
|
lines.push(...ui.bar());
|
|
791
797
|
cachedLines = lines;
|
|
@@ -8,6 +8,7 @@ import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
|
|
|
8
8
|
import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides, adjustToolSet } from "./model-router.js";
|
|
9
9
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
10
10
|
import { unitPhaseLabel } from "./auto-dashboard.js";
|
|
11
|
+
import { getSessionModelOverride } from "./session-model-override.js";
|
|
11
12
|
export function resolvePreferredModelConfig(unitType, autoModeStartModel,
|
|
12
13
|
/** When false, only return explicit per-phase model configs — do not
|
|
13
14
|
* synthesize a routing ceiling from dynamic_routing.tier_models (#3962). */
|
|
@@ -44,8 +45,15 @@ isAutoMode = true) {
|
|
|
44
45
|
export async function selectAndApplyModel(ctx, pi, unitType, unitId, basePath, prefs, verbose, autoModeStartModel, retryContext,
|
|
45
46
|
/** When false (interactive/guided-flow), skip dynamic routing and use the session model.
|
|
46
47
|
* Dynamic routing only applies in auto-mode where cost optimization is expected. (#3962) */
|
|
47
|
-
isAutoMode = true
|
|
48
|
-
|
|
48
|
+
isAutoMode = true,
|
|
49
|
+
/** Explicit /gsd model pin captured at bootstrap for long-running auto loops. */
|
|
50
|
+
sessionModelOverride) {
|
|
51
|
+
const effectiveSessionModelOverride = sessionModelOverride === undefined
|
|
52
|
+
? getSessionModelOverride(ctx.sessionManager.getSessionId())
|
|
53
|
+
: (sessionModelOverride ?? undefined);
|
|
54
|
+
const modelConfig = effectiveSessionModelOverride
|
|
55
|
+
? undefined
|
|
56
|
+
: resolvePreferredModelConfig(unitType, autoModeStartModel, isAutoMode);
|
|
49
57
|
let routing = null;
|
|
50
58
|
let appliedModel = null;
|
|
51
59
|
if (modelConfig) {
|
|
@@ -16,6 +16,7 @@ import { loadFile, parseSummary, resolveAllOverrides } from "./files.js";
|
|
|
16
16
|
import { loadPrompt } from "./prompt-loader.js";
|
|
17
17
|
import { resolveSliceFile, resolveSlicePath, resolveTaskFile, resolveMilestoneFile, resolveTasksDir, buildTaskFileName, } from "./paths.js";
|
|
18
18
|
import { invalidateAllCaches } from "./cache.js";
|
|
19
|
+
import { rebuildState } from "./doctor.js";
|
|
19
20
|
import { parseUnitId } from "./unit-id.js";
|
|
20
21
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
21
22
|
import { autoCommitCurrentBranch, } from "./worktree.js";
|
|
@@ -288,6 +289,11 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
288
289
|
debugLog("postUnit", { phase: "browser-teardown", status: "closed" });
|
|
289
290
|
}
|
|
290
291
|
});
|
|
292
|
+
// Keep the on-disk STATE.md aligned with the live derived state after
|
|
293
|
+
// ordinary unit completion, before any worktree state is synced back.
|
|
294
|
+
await runSafely("postUnit", "state-rebuild", async () => {
|
|
295
|
+
await rebuildState(s.basePath);
|
|
296
|
+
});
|
|
291
297
|
// Sync worktree state back to project root (skipped for lightweight sidecars)
|
|
292
298
|
if (!opts?.skipWorktreeSync && s.originalBasePath && s.originalBasePath !== s.basePath) {
|
|
293
299
|
await runSafely("postUnit", "worktree-sync", () => {
|