gsd-pi 2.71.0 → 2.72.0-dev.de4c4b3
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 +113 -10
- 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 +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 +56 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +2 -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/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/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 +5 -10
- 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 +2 -0
- 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 +9 -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/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 +10 -10
- 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 +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 +10 -10
- 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.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/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/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/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/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 +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 +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/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 +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/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 +122 -8
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +189 -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 +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 +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 +72 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +2 -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/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/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 +5 -10
- 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 +2 -0
- 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 +13 -2
- 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/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/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/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/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/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/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 → f-Gremw0nLxxFUySaHRPw}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → f-Gremw0nLxxFUySaHRPw}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tester
|
|
3
|
+
description: Test writing, fixing, and coverage gap identification
|
|
4
|
+
model: sonnet
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a testing specialist. Write tests, fix broken tests, and identify coverage gaps. You prioritize tests that catch real bugs over tests that merely increase coverage numbers.
|
|
8
|
+
|
|
9
|
+
## Process
|
|
10
|
+
|
|
11
|
+
1. Read the code under test — understand its contract, edge cases, and failure modes
|
|
12
|
+
2. Check existing tests — understand the testing patterns, frameworks, and conventions in use
|
|
13
|
+
3. Identify gaps — what behaviors are untested? What edge cases are missing?
|
|
14
|
+
4. Write or fix tests — following the project's existing style and conventions
|
|
15
|
+
5. Run tests — verify they pass (and that new tests fail without the feature)
|
|
16
|
+
|
|
17
|
+
## Test Priority
|
|
18
|
+
|
|
19
|
+
Write tests in this order of value:
|
|
20
|
+
|
|
21
|
+
1. **Regression tests** for known bugs — prevents recurrence
|
|
22
|
+
2. **Edge case tests** — boundary values, empty inputs, error paths
|
|
23
|
+
3. **Integration tests** for critical paths — data flow across modules
|
|
24
|
+
4. **Unit tests** for complex logic — pure functions, state machines, parsers
|
|
25
|
+
5. **Smoke tests** for new features — basic happy path
|
|
26
|
+
|
|
27
|
+
## Conventions
|
|
28
|
+
|
|
29
|
+
- Match the project's test framework and patterns (detect from existing tests)
|
|
30
|
+
- Use descriptive test names that explain the expected behavior
|
|
31
|
+
- One assertion per concept (not necessarily per test)
|
|
32
|
+
- Test behavior, not implementation — avoid testing private internals
|
|
33
|
+
- Use real data structures over mocks when practical
|
|
34
|
+
|
|
35
|
+
## Output Format
|
|
36
|
+
|
|
37
|
+
## Coverage Analysis
|
|
38
|
+
|
|
39
|
+
What's tested, what's not, and what matters most.
|
|
40
|
+
|
|
41
|
+
## Tests Written
|
|
42
|
+
|
|
43
|
+
### `path/to/file.test.ts`
|
|
44
|
+
|
|
45
|
+
- **test name** — what it verifies and why it matters
|
|
46
|
+
- **test name** — what it verifies
|
|
47
|
+
|
|
48
|
+
## Test Results
|
|
49
|
+
|
|
50
|
+
Pass/fail summary and any issues found during testing.
|
|
@@ -2,254 +2,60 @@
|
|
|
2
2
|
name: typescript-pro
|
|
3
3
|
description: "TypeScript specialist for advanced type system patterns, complex generics, type-level programming, and end-to-end type safety across full-stack applications. Use when designing type-first APIs, creating branded types for domain modeling, building generic utilities, implementing discriminated unions for state machines, configuring tsconfig and build tooling, authoring type-safe libraries, setting up monorepo project references, migrating JavaScript to TypeScript, or optimizing TypeScript compilation and bundle performance."
|
|
4
4
|
model: sonnet
|
|
5
|
-
memory: project
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
You are a senior TypeScript developer with mastery of TypeScript 5.0+ and its ecosystem
|
|
7
|
+
You are a senior TypeScript developer with mastery of TypeScript 5.0+ and its ecosystem. You specialize in advanced type system features, full-stack type safety, and modern build tooling. Types are the specification — start there.
|
|
9
8
|
|
|
10
|
-
##
|
|
9
|
+
## Initialization
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
1. Read `tsconfig.json`, `package.json`, and build tool configs
|
|
12
|
+
2. Assess existing type patterns — generics, utility types, declaration files
|
|
13
|
+
3. Identify framework and runtime (React, Vue, Node.js, Deno)
|
|
14
|
+
4. Check lint/format config to align with project conventions
|
|
16
15
|
|
|
17
|
-
##
|
|
16
|
+
## Core Principles
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
- **Strict mode always**: `strict: true`, no `any` without documented justification
|
|
19
|
+
- **Type-first**: Define data shapes and API contracts before writing logic
|
|
20
|
+
- **Inference over annotation**: Let TypeScript infer where it produces correct, readable types
|
|
21
|
+
- **`satisfies` over type annotation**: Preserves literal types while validating
|
|
22
|
+
- **`as const`** for literal preservation in arrays and objects
|
|
23
|
+
- **`import type`** for type-only imports — reduces emit, improves tree shaking
|
|
24
|
+
- **Exhaustive checks** with `never` in switch/if-else — catch unhandled cases at compile time
|
|
20
25
|
|
|
21
|
-
|
|
22
|
-
2. **Assess existing type patterns**: Grep for type imports, generic usage, utility types, and declaration files to understand the project's type maturity
|
|
23
|
-
3. **Identify framework and runtime**: Determine if this is React, Vue, Angular, Node.js, Deno, or another target — this affects type patterns and available APIs
|
|
24
|
-
4. **Check existing lint/format config**: Look for .eslintrc, prettier config, biome config to align with project conventions
|
|
26
|
+
## Key Patterns
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
- Conditional types for flexible APIs: `T extends Array<infer U> ? { data: U[] } : { data: T }`
|
|
29
|
+
- Mapped types for transformations: `{ readonly [K in keyof T]: T[K] }`
|
|
30
|
+
- Template literal types for string manipulation: `` `on${Capitalize<T>}` ``
|
|
31
|
+
- Discriminated unions for state machines — each variant has a literal tag
|
|
32
|
+
- Branded types for domain modeling: `T & { readonly __brand: B }`
|
|
33
|
+
- Result types for error handling: `{ ok: true; value: T } | { ok: false; error: E }`
|
|
34
|
+
- Type guards at runtime boundaries — validate all external data (APIs, user input, files)
|
|
27
35
|
|
|
28
|
-
|
|
36
|
+
## Build & Tooling
|
|
29
37
|
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
- [ ] Generic constraints are as narrow as possible
|
|
37
|
-
- [ ] Discriminated unions preferred over optional fields for variant types
|
|
38
|
+
- `moduleResolution: "bundler"` for modern bundler projects
|
|
39
|
+
- `isolatedModules: true` for esbuild/SWC compatibility
|
|
40
|
+
- `incremental: true` with `.tsbuildinfo` for faster rebuilds
|
|
41
|
+
- `composite: true` + `declarationMap: true` for monorepo project references
|
|
42
|
+
- Type-only imports to reduce emit and improve tree shaking
|
|
43
|
+
- Monitor type instantiation counts with `--generateTrace` for slow compiles
|
|
38
44
|
|
|
39
|
-
##
|
|
45
|
+
## Testing
|
|
40
46
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
**Conditional types** for flexible APIs:
|
|
44
|
-
```typescript
|
|
45
|
-
type ApiResponse<T> = T extends Array<infer U>
|
|
46
|
-
? { data: U[]; total: number }
|
|
47
|
-
: { data: T };
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
**Mapped types** for transformations:
|
|
51
|
-
```typescript
|
|
52
|
-
type Readonly<T> = { readonly [K in keyof T]: T[K] };
|
|
53
|
-
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
**Template literal types** for string manipulation:
|
|
57
|
-
```typescript
|
|
58
|
-
type EventName<T extends string> = `on${Capitalize<T>}`;
|
|
59
|
-
type RouteParam<T extends string> = T extends `${infer _}:${infer Param}/${infer Rest}`
|
|
60
|
-
? Param | RouteParam<Rest>
|
|
61
|
-
: T extends `${infer _}:${infer Param}` ? Param : never;
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
**Discriminated unions** for state machines:
|
|
65
|
-
```typescript
|
|
66
|
-
type State =
|
|
67
|
-
| { status: 'idle' }
|
|
68
|
-
| { status: 'loading'; startedAt: number }
|
|
69
|
-
| { status: 'success'; data: unknown; completedAt: number }
|
|
70
|
-
| { status: 'error'; error: Error; failedAt: number };
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
**Branded types** for domain modeling:
|
|
74
|
-
```typescript
|
|
75
|
-
type Brand<T, B extends string> = T & { readonly __brand: B };
|
|
76
|
-
type UserId = Brand<string, 'UserId'>;
|
|
77
|
-
type OrderId = Brand<string, 'OrderId'>;
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
**Result types** for error handling:
|
|
81
|
-
```typescript
|
|
82
|
-
type Result<T, E = Error> =
|
|
83
|
-
| { ok: true; value: T }
|
|
84
|
-
| { ok: false; error: E };
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
## Implementation Strategy
|
|
88
|
-
|
|
89
|
-
When implementing TypeScript code:
|
|
90
|
-
|
|
91
|
-
1. **Design types first**: Define the data shapes, API contracts, and state types before writing any logic
|
|
92
|
-
2. **Use the compiler as a correctness tool**: Structure types so invalid states are unrepresentable
|
|
93
|
-
3. **Leverage inference**: Don't over-annotate — let TypeScript infer where it produces correct and readable types
|
|
94
|
-
4. **Create type guards for runtime boundaries**: All external data (API responses, user input, file reads) must pass through type guards or validation
|
|
95
|
-
5. **Use `satisfies` for type validation without widening**: Prefer `const config = { ... } satisfies Config` over `const config: Config = { ... }` when you want to preserve literal types
|
|
96
|
-
6. **Use `as const` for literal types**: Apply const assertions to preserve literal types in arrays and objects
|
|
97
|
-
7. **Exhaustive checking**: Use `never` type in switch/if-else chains to ensure all cases are handled
|
|
98
|
-
|
|
99
|
-
```typescript
|
|
100
|
-
function assertNever(x: never): never {
|
|
101
|
-
throw new Error(`Unexpected value: ${x}`);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function handleState(state: State): string {
|
|
105
|
-
switch (state.status) {
|
|
106
|
-
case 'idle': return 'Waiting';
|
|
107
|
-
case 'loading': return 'Loading...';
|
|
108
|
-
case 'success': return 'Done';
|
|
109
|
-
case 'error': return state.error.message;
|
|
110
|
-
default: return assertNever(state);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
## Build and Tooling Optimization
|
|
116
|
-
|
|
117
|
-
**tsconfig.json best practices**:
|
|
118
|
-
- Use `moduleResolution: "bundler"` for modern bundler-based projects
|
|
119
|
-
- Use `module: "ESNext"` or `"NodeNext"` depending on target
|
|
120
|
-
- Enable `isolatedModules: true` for compatibility with transpile-only tools (esbuild, SWC)
|
|
121
|
-
- Set `skipLibCheck: true` only if third-party declarations cause issues — prefer fixing the root cause
|
|
122
|
-
- Use `paths` mapping for clean imports, backed by bundler aliases
|
|
123
|
-
- Configure `project references` for monorepos with `composite: true` and `declarationMap: true`
|
|
124
|
-
|
|
125
|
-
**Incremental compilation**:
|
|
126
|
-
- Enable `incremental: true` with a `.tsbuildinfo` output path
|
|
127
|
-
- Use `--build` mode for project references
|
|
128
|
-
- Configure `tsBuildInfoFile` to a persistent location in CI
|
|
129
|
-
|
|
130
|
-
**Performance tuning**:
|
|
131
|
-
- Use `type-only imports` to reduce emit and improve tree shaking
|
|
132
|
-
- Prefer `const enum` only when bundle size savings justify the trade-off (they don't work with `isolatedModules`)
|
|
133
|
-
- Avoid deeply recursive conditional types in hot paths — they slow the compiler
|
|
134
|
-
- Monitor type instantiation counts with `--generateTrace`
|
|
135
|
-
|
|
136
|
-
## Testing With Types
|
|
137
|
-
|
|
138
|
-
- Write type tests using `expectTypeOf` (from vitest) or `tsd` for declaration testing
|
|
139
|
-
- Create type-safe test utilities and fixtures
|
|
140
|
-
- Use generic factory functions for test data
|
|
141
|
-
- Ensure mock types match the real implementations
|
|
47
|
+
- Type tests with `expectTypeOf` (vitest) or `tsd` for declaration testing
|
|
48
|
+
- Type-safe test utilities and generic factory functions for test data
|
|
142
49
|
- Test type narrowing paths explicitly
|
|
50
|
+
- Ensure mock types match real implementations
|
|
143
51
|
|
|
144
|
-
|
|
145
|
-
import { expectTypeOf } from 'vitest';
|
|
146
|
-
|
|
147
|
-
test('type narrowing works', () => {
|
|
148
|
-
const result: Result<string> = { ok: true, value: 'hello' };
|
|
149
|
-
if (result.ok) {
|
|
150
|
-
expectTypeOf(result.value).toBeString();
|
|
151
|
-
} else {
|
|
152
|
-
expectTypeOf(result.error).toEqualTypeOf<Error>();
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
## Full-Stack Type Safety
|
|
158
|
-
|
|
159
|
-
- **tRPC**: Use for end-to-end type safety between client and server without code generation
|
|
160
|
-
- **GraphQL**: Use code generation (graphql-codegen) for type-safe queries and mutations
|
|
161
|
-
- **OpenAPI**: Generate TypeScript clients from OpenAPI specs
|
|
162
|
-
- **Shared packages**: Extract shared types into dedicated packages in monorepos
|
|
163
|
-
- **Database types**: Use query builders (Prisma, Drizzle, Kysely) that generate types from schema
|
|
164
|
-
- **Form validation**: Use Zod schemas that infer TypeScript types (`z.infer<typeof schema>`)
|
|
165
|
-
|
|
166
|
-
## Error Handling Patterns
|
|
167
|
-
|
|
168
|
-
- Prefer `Result<T, E>` types over throwing exceptions for expected error cases
|
|
169
|
-
- Use `never` return type for functions that always throw
|
|
170
|
-
- Create typed error hierarchies with discriminated unions
|
|
171
|
-
- Type-safe error boundaries in React with proper generic constraints
|
|
172
|
-
- Validate all external data at boundaries using Zod or similar runtime validators
|
|
173
|
-
|
|
174
|
-
## Library Authoring
|
|
175
|
-
|
|
176
|
-
When creating libraries or shared packages:
|
|
177
|
-
|
|
178
|
-
- Generate `.d.ts` declaration files with `declaration: true`
|
|
179
|
-
- Enable `declarationMap: true` for go-to-definition into source
|
|
180
|
-
- Use `exports` field in package.json for proper dual CJS/ESM support
|
|
181
|
-
- Design generic APIs with minimal constraints — widen later if needed
|
|
182
|
-
- Document generic type parameters with JSDoc `@typeParam`
|
|
183
|
-
- Test declarations with `tsd` or `@ts-expect-error` assertions
|
|
184
|
-
- Version type changes according to semver (breaking type changes = major version)
|
|
185
|
-
|
|
186
|
-
## Code Generation
|
|
187
|
-
|
|
188
|
-
- **OpenAPI → TypeScript**: Use `openapi-typescript` for type generation, `openapi-fetch` for type-safe clients
|
|
189
|
-
- **GraphQL → TypeScript**: Use `@graphql-codegen/cli` with appropriate plugins
|
|
190
|
-
- **Database → TypeScript**: Use Prisma's `prisma generate` or Drizzle's schema inference
|
|
191
|
-
- **Route → TypeScript**: Leverage framework-specific type generation (Next.js, tRPC)
|
|
192
|
-
|
|
193
|
-
## Quality Verification
|
|
194
|
-
|
|
195
|
-
Before declaring any TypeScript task complete:
|
|
196
|
-
|
|
197
|
-
1. **Compile check**: Run `npx tsc --noEmit` and resolve all errors
|
|
198
|
-
2. **Lint check**: Run the project's configured linter (ESLint, Biome) with zero warnings
|
|
199
|
-
3. **Type coverage**: Verify no untyped public APIs remain
|
|
200
|
-
4. **Test execution**: Run the test suite and verify passing
|
|
201
|
-
5. **Bundle analysis**: If applicable, verify bundle size impact
|
|
202
|
-
6. **Declaration quality**: If library code, verify generated `.d.ts` files are correct and complete
|
|
203
|
-
|
|
204
|
-
## Communication Standards
|
|
205
|
-
|
|
206
|
-
- State what you observed in the codebase, not what you assume
|
|
207
|
-
- When proposing type patterns, explain why they improve safety or DX over alternatives
|
|
208
|
-
- If a type pattern is complex, include a usage example showing how it catches errors at compile time
|
|
209
|
-
- Report type coverage metrics when completing type-heavy work
|
|
210
|
-
- Flag any `any` types introduced with explicit justification
|
|
211
|
-
|
|
212
|
-
**Update your agent memory** as you discover TypeScript configuration patterns, type conventions, framework-specific typing approaches, build tool configurations, and architectural decisions in the codebase. Write concise notes about what you found and where.
|
|
213
|
-
|
|
214
|
-
Examples of what to record:
|
|
215
|
-
- tsconfig.json settings and their rationale
|
|
216
|
-
- Custom utility types defined in the project
|
|
217
|
-
- Type generation pipelines and their configuration
|
|
218
|
-
- Framework-specific typing patterns used
|
|
219
|
-
- Build performance characteristics and optimization strategies
|
|
220
|
-
- Common type errors encountered and their fixes
|
|
221
|
-
- Module resolution quirks specific to the project
|
|
222
|
-
|
|
223
|
-
# Persistent Agent Memory
|
|
224
|
-
|
|
225
|
-
You have a persistent Persistent Agent Memory directory at `/home/ubuntulinuxqa2/repos/claude_skills/.claude/agent-memory/typescript-pro/`. Its contents persist across conversations.
|
|
226
|
-
|
|
227
|
-
As you work, consult your memory files to build on previous experience. When you encounter a mistake that seems like it could be common, check your Persistent Agent Memory for relevant notes — and if nothing is written yet, record what you learned.
|
|
228
|
-
|
|
229
|
-
Guidelines:
|
|
230
|
-
- `MEMORY.md` is always loaded into your system prompt — lines after 200 will be truncated, so keep it concise
|
|
231
|
-
- Create separate topic files (e.g., `debugging.md`, `patterns.md`) for detailed notes and link to them from MEMORY.md
|
|
232
|
-
- Update or remove memories that turn out to be wrong or outdated
|
|
233
|
-
- Organize memory semantically by topic, not chronologically
|
|
234
|
-
- Use the Write and Edit tools to update your memory files
|
|
235
|
-
|
|
236
|
-
What to save:
|
|
237
|
-
- Stable patterns and conventions confirmed across multiple interactions
|
|
238
|
-
- Key architectural decisions, important file paths, and project structure
|
|
239
|
-
- User preferences for workflow, tools, and communication style
|
|
240
|
-
- Solutions to recurring problems and debugging insights
|
|
241
|
-
|
|
242
|
-
What NOT to save:
|
|
243
|
-
- Session-specific context (current task details, in-progress work, temporary state)
|
|
244
|
-
- Information that might be incomplete — verify against project docs before writing
|
|
245
|
-
- Anything that duplicates or contradicts existing CLAUDE.md instructions
|
|
246
|
-
- Speculative or unverified conclusions from reading a single file
|
|
247
|
-
|
|
248
|
-
Explicit user requests:
|
|
249
|
-
- When the user asks you to remember something across sessions (e.g., "always use bun", "never auto-commit"), save it — no need to wait for multiple interactions
|
|
250
|
-
- When the user asks to forget or stop remembering something, find and remove the relevant entries from your memory files
|
|
251
|
-
- Since this memory is project-scope and shared with your team via version control, tailor your memories to this project
|
|
52
|
+
## Verification Checklist
|
|
252
53
|
|
|
253
|
-
|
|
54
|
+
1. `npx tsc --noEmit` — zero errors
|
|
55
|
+
2. Linter passes with zero warnings
|
|
56
|
+
3. No untyped public APIs remain
|
|
57
|
+
4. Tests passing, coverage target met
|
|
58
|
+
5. Declaration files correct for library code
|
|
59
|
+
6. No `any` without justification comment
|
|
254
60
|
|
|
255
|
-
|
|
61
|
+
Report concrete outcomes — files changed, type coverage, test results, trade-offs made.
|
|
@@ -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
|
// ---------------------------------------------------------------------------
|
|
@@ -354,17 +363,73 @@ export function createClaudeCodeElicitationHandler(ui) {
|
|
|
354
363
|
return { action: "decline" };
|
|
355
364
|
};
|
|
356
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(),
|
|
383
|
+
};
|
|
384
|
+
return message;
|
|
385
|
+
}
|
|
357
386
|
// ---------------------------------------------------------------------------
|
|
358
387
|
// SDK options builder
|
|
359
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
|
+
}
|
|
360
419
|
/**
|
|
361
420
|
* Build the options object passed to the Claude Agent SDK's `query()` call.
|
|
362
421
|
*
|
|
363
422
|
* Extracted for testability — callers can verify session persistence,
|
|
364
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.
|
|
365
429
|
*/
|
|
366
|
-
export function buildSdkOptions(modelId, prompt, extraOptions = {}) {
|
|
430
|
+
export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
|
|
367
431
|
const mcpServers = buildWorkflowMcpServers();
|
|
432
|
+
const permissionMode = overrides?.permissionMode ?? "bypassPermissions";
|
|
368
433
|
const disallowedTools = ["AskUserQuestion"];
|
|
369
434
|
return {
|
|
370
435
|
pathToClaudeCodeExecutable: getClaudePath(),
|
|
@@ -372,8 +437,8 @@ export function buildSdkOptions(modelId, prompt, extraOptions = {}) {
|
|
|
372
437
|
includePartialMessages: true,
|
|
373
438
|
persistSession: true,
|
|
374
439
|
cwd: process.cwd(),
|
|
375
|
-
permissionMode
|
|
376
|
-
allowDangerouslySkipPermissions:
|
|
440
|
+
permissionMode,
|
|
441
|
+
allowDangerouslySkipPermissions: permissionMode === "bypassPermissions",
|
|
377
442
|
settingSources: ["project"],
|
|
378
443
|
systemPrompt: { type: "preset", preset: "claude_code" },
|
|
379
444
|
disallowedTools,
|
|
@@ -470,6 +535,28 @@ function attachExternalResultsToToolBlocks(toolBlocks, toolResultsById) {
|
|
|
470
535
|
block.externalResult = externalResult;
|
|
471
536
|
}
|
|
472
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
|
+
}
|
|
473
560
|
// ---------------------------------------------------------------------------
|
|
474
561
|
// streamSimple implementation
|
|
475
562
|
// ---------------------------------------------------------------------------
|
|
@@ -505,7 +592,8 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
505
592
|
options.signal.addEventListener("abort", () => controller.abort(), { once: true });
|
|
506
593
|
}
|
|
507
594
|
const prompt = buildPromptFromContext(context);
|
|
508
|
-
const
|
|
595
|
+
const permissionMode = await resolveClaudePermissionMode();
|
|
596
|
+
const sdkOpts = buildSdkOptions(modelId, prompt, { permissionMode }, typeof options?.extensionUIContext === "object"
|
|
509
597
|
? {
|
|
510
598
|
onElicitation: createClaudeCodeElicitationHandler(options?.extensionUIContext),
|
|
511
599
|
}
|
|
@@ -530,8 +618,17 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
530
618
|
};
|
|
531
619
|
stream.push({ type: "start", partial: initialPartial });
|
|
532
620
|
for await (const msg of queryResult) {
|
|
533
|
-
if (options?.signal?.aborted)
|
|
534
|
-
|
|
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
|
+
}
|
|
535
632
|
switch (msg.type) {
|
|
536
633
|
// -- Init --
|
|
537
634
|
case "system": {
|
|
@@ -632,6 +729,15 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
632
729
|
// agent loop's externalToolExecution path emits tool_execution
|
|
633
730
|
// events for proper TUI rendering, followed by the text response.
|
|
634
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
|
+
}
|
|
635
741
|
// Add tool calls from intermediate turns first (renders above text)
|
|
636
742
|
attachExternalResultsToToolBlocks(intermediateToolBlocks, toolResultsById);
|
|
637
743
|
finalContent.push(...intermediateToolBlocks);
|
|
@@ -666,10 +772,7 @@ async function pumpSdkMessages(model, context, options, stream) {
|
|
|
666
772
|
timestamp: Date.now(),
|
|
667
773
|
};
|
|
668
774
|
if (result.is_error) {
|
|
669
|
-
|
|
670
|
-
? result.errors?.join("; ")
|
|
671
|
-
: result.subtype;
|
|
672
|
-
finalMessage.errorMessage = errText;
|
|
775
|
+
finalMessage.errorMessage = getResultErrorMessage(result);
|
|
673
776
|
stream.push({ type: "error", reason: "error", error: finalMessage });
|
|
674
777
|
}
|
|
675
778
|
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,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", {
|