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
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GSDNoProjectError — tests for friendly home-directory error handling.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that GSDNoProjectError is thrown for blocked directories and
|
|
5
|
+
* that the dispatcher catches it with a user-friendly message.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import test from "node:test";
|
|
9
|
+
import assert from "node:assert/strict";
|
|
10
|
+
import { readFileSync } from "node:fs";
|
|
11
|
+
import { join, dirname } from "node:path";
|
|
12
|
+
import { fileURLToPath } from "node:url";
|
|
13
|
+
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
|
|
16
|
+
const contextSrc = readFileSync(join(__dirname, "..", "commands", "context.ts"), "utf-8");
|
|
17
|
+
const dispatcherSrc = readFileSync(join(__dirname, "..", "commands", "dispatcher.ts"), "utf-8");
|
|
18
|
+
|
|
19
|
+
// ─── GSDNoProjectError class ──────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
test("GSDNoProjectError class is exported from context.ts", () => {
|
|
22
|
+
assert.ok(
|
|
23
|
+
contextSrc.includes("export class GSDNoProjectError extends Error"),
|
|
24
|
+
"GSDNoProjectError should be an exported Error subclass",
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("GSDNoProjectError sets name property", () => {
|
|
29
|
+
assert.ok(
|
|
30
|
+
contextSrc.includes('this.name = "GSDNoProjectError"'),
|
|
31
|
+
"GSDNoProjectError should set its name for instanceof checks",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// ─── projectRoot blocked directory handling ───────────────────────────────
|
|
36
|
+
|
|
37
|
+
test("projectRoot uses validateDirectory and checks for blocked severity", () => {
|
|
38
|
+
assert.ok(
|
|
39
|
+
contextSrc.includes("validateDirectory(pathToCheck)"),
|
|
40
|
+
"projectRoot should call validateDirectory",
|
|
41
|
+
);
|
|
42
|
+
assert.ok(
|
|
43
|
+
contextSrc.includes('result.severity === "blocked"'),
|
|
44
|
+
"projectRoot should check for blocked severity",
|
|
45
|
+
);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("projectRoot throws GSDNoProjectError on blocked directory", () => {
|
|
49
|
+
assert.ok(
|
|
50
|
+
contextSrc.includes("throw new GSDNoProjectError"),
|
|
51
|
+
"projectRoot should throw GSDNoProjectError when directory is blocked",
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// ─── Dispatcher catch ─────────────────────────────────────────────────────
|
|
56
|
+
|
|
57
|
+
test("dispatcher catches GSDNoProjectError with user-friendly message", () => {
|
|
58
|
+
assert.ok(
|
|
59
|
+
dispatcherSrc.includes("err instanceof GSDNoProjectError"),
|
|
60
|
+
"dispatcher should catch GSDNoProjectError specifically",
|
|
61
|
+
);
|
|
62
|
+
assert.ok(
|
|
63
|
+
dispatcherSrc.includes("cd"),
|
|
64
|
+
"error message should suggest cd-ing into a project directory",
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test("dispatcher re-throws non-GSDNoProjectError exceptions", () => {
|
|
69
|
+
assert.ok(
|
|
70
|
+
dispatcherSrc.includes("throw err"),
|
|
71
|
+
"dispatcher should re-throw unexpected errors",
|
|
72
|
+
);
|
|
73
|
+
});
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
// gsd / infra-errors cooldown detection tests
|
|
2
|
+
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
|
3
|
+
|
|
4
|
+
import test, { describe } from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
isTransientCooldownError,
|
|
9
|
+
getCooldownRetryAfterMs,
|
|
10
|
+
MAX_COOLDOWN_RETRIES,
|
|
11
|
+
COOLDOWN_FALLBACK_WAIT_MS,
|
|
12
|
+
} from "../auto/infra-errors.js";
|
|
13
|
+
|
|
14
|
+
// ─── Constants ────────────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
describe("infra-errors cooldown constants", () => {
|
|
17
|
+
test("COOLDOWN_FALLBACK_WAIT_MS is a positive number greater than the 30s rate-limit backoff", () => {
|
|
18
|
+
assert.ok(typeof COOLDOWN_FALLBACK_WAIT_MS === "number");
|
|
19
|
+
assert.ok(COOLDOWN_FALLBACK_WAIT_MS > 30_000, "should exceed the 30s rate-limit window");
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test("MAX_COOLDOWN_RETRIES is a positive integer", () => {
|
|
23
|
+
assert.ok(typeof MAX_COOLDOWN_RETRIES === "number");
|
|
24
|
+
assert.ok(Number.isInteger(MAX_COOLDOWN_RETRIES));
|
|
25
|
+
assert.ok(MAX_COOLDOWN_RETRIES > 0);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("COOLDOWN_FALLBACK_WAIT_MS is 35_000", () => {
|
|
29
|
+
assert.equal(COOLDOWN_FALLBACK_WAIT_MS, 35_000);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("MAX_COOLDOWN_RETRIES is 5", () => {
|
|
33
|
+
assert.equal(MAX_COOLDOWN_RETRIES, 5);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
// ─── isTransientCooldownError: structured detection ──────────────────────────
|
|
38
|
+
|
|
39
|
+
describe("isTransientCooldownError — structured code detection", () => {
|
|
40
|
+
test("returns true for an object with code === AUTH_COOLDOWN", () => {
|
|
41
|
+
const err = { code: "AUTH_COOLDOWN", message: "credentials in cooldown" };
|
|
42
|
+
assert.equal(isTransientCooldownError(err), true);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("returns true for a real CredentialCooldownError-shaped error", () => {
|
|
46
|
+
// Simulate CredentialCooldownError without importing sdk.ts (leaf-module rule)
|
|
47
|
+
const err = Object.assign(new Error('All credentials for "anthropic" are in a cooldown window.'), {
|
|
48
|
+
code: "AUTH_COOLDOWN",
|
|
49
|
+
retryAfterMs: 30_000,
|
|
50
|
+
name: "CredentialCooldownError",
|
|
51
|
+
});
|
|
52
|
+
assert.equal(isTransientCooldownError(err), true);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
test("returns false for an object with a different code", () => {
|
|
56
|
+
const err = { code: "ENOSPC", message: "disk full" };
|
|
57
|
+
assert.equal(isTransientCooldownError(err), false);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("returns false for an object with no code property", () => {
|
|
61
|
+
const err = { message: "some random error" };
|
|
62
|
+
assert.equal(isTransientCooldownError(err), false);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// ─── isTransientCooldownError: message fallback ───────────────────────────────
|
|
67
|
+
|
|
68
|
+
describe("isTransientCooldownError — message fallback (cross-process)", () => {
|
|
69
|
+
test("returns true when message contains 'in a cooldown window'", () => {
|
|
70
|
+
const err = new Error('All credentials for "openai" are in a cooldown window. Please wait.');
|
|
71
|
+
assert.equal(isTransientCooldownError(err), true);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test("returns true when message matches case-insensitively", () => {
|
|
75
|
+
const err = new Error("credentials IN A COOLDOWN WINDOW");
|
|
76
|
+
assert.equal(isTransientCooldownError(err), true);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
test("returns true for a plain string containing cooldown window phrase", () => {
|
|
80
|
+
assert.equal(isTransientCooldownError("all keys in a cooldown window"), true);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("returns false for a generic error message", () => {
|
|
84
|
+
const err = new Error("rate limit exceeded");
|
|
85
|
+
assert.equal(isTransientCooldownError(err), false);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("returns false for an error message about auth failure without cooldown phrase", () => {
|
|
89
|
+
const err = new Error("Authentication failed: invalid API key");
|
|
90
|
+
assert.equal(isTransientCooldownError(err), false);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// ─── isTransientCooldownError: edge cases ────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
describe("isTransientCooldownError — edge cases", () => {
|
|
97
|
+
test("returns false for null", () => {
|
|
98
|
+
assert.equal(isTransientCooldownError(null), false);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("returns false for undefined", () => {
|
|
102
|
+
assert.equal(isTransientCooldownError(undefined), false);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test("returns false for a number", () => {
|
|
106
|
+
assert.equal(isTransientCooldownError(42), false);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("returns false for an empty object", () => {
|
|
110
|
+
assert.equal(isTransientCooldownError({}), false);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test("returns false for an object with code === AUTH_COOLDOWN as a non-string", () => {
|
|
114
|
+
// code must be a string matching "AUTH_COOLDOWN" exactly
|
|
115
|
+
const err = { code: 42 };
|
|
116
|
+
assert.equal(isTransientCooldownError(err), false);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
// ─── getCooldownRetryAfterMs: structured extraction ──────────────────────────
|
|
121
|
+
|
|
122
|
+
describe("getCooldownRetryAfterMs — structured extraction", () => {
|
|
123
|
+
test("returns retryAfterMs when code is AUTH_COOLDOWN and retryAfterMs is set", () => {
|
|
124
|
+
const err = { code: "AUTH_COOLDOWN", retryAfterMs: 30_000 };
|
|
125
|
+
assert.equal(getCooldownRetryAfterMs(err), 30_000);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("returns undefined when code is AUTH_COOLDOWN but retryAfterMs is absent", () => {
|
|
129
|
+
const err = { code: "AUTH_COOLDOWN" };
|
|
130
|
+
assert.equal(getCooldownRetryAfterMs(err), undefined);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("returns 0 when retryAfterMs is explicitly 0", () => {
|
|
134
|
+
const err = { code: "AUTH_COOLDOWN", retryAfterMs: 0 };
|
|
135
|
+
assert.equal(getCooldownRetryAfterMs(err), 0);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("returns undefined for an error with a different code even if retryAfterMs is set", () => {
|
|
139
|
+
const err = { code: "ENOSPC", retryAfterMs: 5_000 };
|
|
140
|
+
assert.equal(getCooldownRetryAfterMs(err), undefined);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
test("returns undefined for a plain Error with no code property", () => {
|
|
144
|
+
const err = new Error("something went wrong");
|
|
145
|
+
assert.equal(getCooldownRetryAfterMs(err), undefined);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("returns retryAfterMs from a full CredentialCooldownError-shaped object", () => {
|
|
149
|
+
const err = Object.assign(new Error('All credentials for "anthropic" are in a cooldown window.'), {
|
|
150
|
+
code: "AUTH_COOLDOWN",
|
|
151
|
+
retryAfterMs: 15_000,
|
|
152
|
+
name: "CredentialCooldownError",
|
|
153
|
+
});
|
|
154
|
+
assert.equal(getCooldownRetryAfterMs(err), 15_000);
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// ─── getCooldownRetryAfterMs: edge cases ─────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
describe("getCooldownRetryAfterMs — edge cases", () => {
|
|
161
|
+
test("returns undefined for null", () => {
|
|
162
|
+
assert.equal(getCooldownRetryAfterMs(null), undefined);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test("returns undefined for undefined", () => {
|
|
166
|
+
assert.equal(getCooldownRetryAfterMs(undefined), undefined);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("returns undefined for a plain string", () => {
|
|
170
|
+
assert.equal(getCooldownRetryAfterMs("AUTH_COOLDOWN"), undefined);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
test("returns undefined for an empty object", () => {
|
|
174
|
+
assert.equal(getCooldownRetryAfterMs({}), undefined);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test("returns undefined for a number", () => {
|
|
178
|
+
assert.equal(getCooldownRetryAfterMs(42), undefined);
|
|
179
|
+
});
|
|
180
|
+
});
|
package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { describe, test, afterEach } from "node:test";
|
|
14
14
|
import assert from "node:assert/strict";
|
|
15
|
-
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync, readFileSync } from "node:fs";
|
|
15
|
+
import { mkdtempSync, mkdirSync, writeFileSync, rmSync, existsSync, realpathSync, readFileSync, symlinkSync, unlinkSync } from "node:fs";
|
|
16
16
|
import { join } from "node:path";
|
|
17
17
|
import { tmpdir } from "node:os";
|
|
18
18
|
import { execSync } from "node:child_process";
|
|
@@ -44,6 +44,27 @@ function createTempRepo(): string {
|
|
|
44
44
|
return dir;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function createTempRepoWithExternalGsd(): { repo: string; externalState: string } {
|
|
48
|
+
const realTmp = realpathSync(tmpdir());
|
|
49
|
+
const repo = realpathSync(mkdtempSync(join(realTmp, "wt-ms-merge-ext-test-")));
|
|
50
|
+
const externalState = realpathSync(mkdtempSync(join(realTmp, "wt-ms-merge-ext-state-")));
|
|
51
|
+
|
|
52
|
+
run("git init", repo);
|
|
53
|
+
run("git config user.email test@test.com", repo);
|
|
54
|
+
run("git config user.name Test", repo);
|
|
55
|
+
|
|
56
|
+
mkdirSync(join(externalState, "worktrees"), { recursive: true });
|
|
57
|
+
symlinkSync(externalState, join(repo, ".gsd"));
|
|
58
|
+
|
|
59
|
+
writeFileSync(join(repo, "README.md"), "# test\n");
|
|
60
|
+
writeFileSync(join(externalState, "STATE.md"), "# State\n");
|
|
61
|
+
run("git add .", repo);
|
|
62
|
+
run("git commit -m init", repo);
|
|
63
|
+
run("git branch -M main", repo);
|
|
64
|
+
|
|
65
|
+
return { repo, externalState };
|
|
66
|
+
}
|
|
67
|
+
|
|
47
68
|
/** Minimal roadmap content for mergeMilestoneToMain. */
|
|
48
69
|
function makeRoadmap(milestoneId: string, title: string, slices: Array<{ id: string; title: string }>): string {
|
|
49
70
|
const sliceLines = slices.map(s => `- [x] **${s.id}: ${s.title}**`).join("\n");
|
|
@@ -87,6 +108,12 @@ describe("auto-worktree-milestone-merge", { timeout: 300_000 }, () => {
|
|
|
87
108
|
return d;
|
|
88
109
|
}
|
|
89
110
|
|
|
111
|
+
function freshRepoWithExternalGsd(): { repo: string; externalState: string } {
|
|
112
|
+
const { repo, externalState } = createTempRepoWithExternalGsd();
|
|
113
|
+
tempDirs.push(repo, externalState);
|
|
114
|
+
return { repo, externalState };
|
|
115
|
+
}
|
|
116
|
+
|
|
90
117
|
afterEach(() => {
|
|
91
118
|
process.chdir(savedCwd);
|
|
92
119
|
for (const d of tempDirs) {
|
|
@@ -638,6 +665,44 @@ describe("auto-worktree-milestone-merge", { timeout: 300_000 }, () => {
|
|
|
638
665
|
"#1906: codeFilesChanged must be false when only .gsd/ files were merged");
|
|
639
666
|
});
|
|
640
667
|
|
|
668
|
+
test("#2156: mergeMilestoneToMain removes external-state worktrees using the milestone branch name", () => {
|
|
669
|
+
const { repo, externalState } = freshRepoWithExternalGsd();
|
|
670
|
+
const wtPath = createAutoWorktree(repo, "M215");
|
|
671
|
+
|
|
672
|
+
addSliceToMilestone(repo, wtPath, "M215", "S01", "External cleanup", [
|
|
673
|
+
{ file: "external-cleanup.ts", content: "export const externalCleanup = true;\n", message: "add external cleanup" },
|
|
674
|
+
]);
|
|
675
|
+
|
|
676
|
+
const realWtPath = realpathSync(wtPath);
|
|
677
|
+
assert.ok(
|
|
678
|
+
realWtPath.startsWith(externalState),
|
|
679
|
+
`worktree should be registered under external .gsd state, got ${realWtPath}`,
|
|
680
|
+
);
|
|
681
|
+
|
|
682
|
+
// Recreate the exact divergence from #1852: local .gsd/ is replaced with a
|
|
683
|
+
// stale real directory, so worktreePath() no longer matches git's record.
|
|
684
|
+
unlinkSync(join(repo, ".gsd"));
|
|
685
|
+
mkdirSync(join(repo, ".gsd", "worktrees", "M215"), { recursive: true });
|
|
686
|
+
writeFileSync(join(repo, ".gsd", "STATE.md"), "# Local stale state\n");
|
|
687
|
+
writeFileSync(join(repo, ".gsd", "worktrees", "M215", "stale.txt"), "stale local artifact\n");
|
|
688
|
+
|
|
689
|
+
const roadmap = makeRoadmap("M215", "External cleanup", [
|
|
690
|
+
{ id: "S01", title: "External cleanup" },
|
|
691
|
+
]);
|
|
692
|
+
|
|
693
|
+
mergeMilestoneToMain(repo, "M215", roadmap);
|
|
694
|
+
|
|
695
|
+
assert.ok(
|
|
696
|
+
!run("git worktree list", repo).includes("M215"),
|
|
697
|
+
"merged milestone worktree should be removed from git worktree list",
|
|
698
|
+
);
|
|
699
|
+
assert.ok(!existsSync(realWtPath), "real external worktree directory should be removed");
|
|
700
|
+
assert.ok(
|
|
701
|
+
!run("git branch", repo).includes("milestone/M215"),
|
|
702
|
+
"milestone branch should be deleted after merge cleanup",
|
|
703
|
+
);
|
|
704
|
+
});
|
|
705
|
+
|
|
641
706
|
test("#2912: MERGE_HEAD cleaned up after squash-merge conflict", () => {
|
|
642
707
|
const repo = freshRepo();
|
|
643
708
|
const wtPath = createAutoWorktree(repo, "M291");
|
|
@@ -248,23 +248,25 @@ describe('git-service', async () => {
|
|
|
248
248
|
|
|
249
249
|
assert.deepStrictEqual(
|
|
250
250
|
RUNTIME_EXCLUSION_PATHS.length,
|
|
251
|
-
|
|
252
|
-
"exactly
|
|
251
|
+
15,
|
|
252
|
+
"exactly 15 runtime exclusion paths"
|
|
253
253
|
);
|
|
254
254
|
|
|
255
255
|
const expectedPaths = [
|
|
256
256
|
".gsd/activity/",
|
|
257
|
+
".gsd/forensics/",
|
|
257
258
|
".gsd/runtime/",
|
|
258
259
|
".gsd/worktrees/",
|
|
260
|
+
".gsd/parallel/",
|
|
259
261
|
".gsd/auto.lock",
|
|
260
262
|
".gsd/metrics.json",
|
|
261
|
-
".gsd/completed-units
|
|
263
|
+
".gsd/completed-units*.json",
|
|
264
|
+
".gsd/state-manifest.json",
|
|
262
265
|
".gsd/STATE.md",
|
|
263
|
-
".gsd/gsd.db",
|
|
264
|
-
".gsd/gsd.db-shm",
|
|
265
|
-
".gsd/gsd.db-wal",
|
|
266
|
+
".gsd/gsd.db*",
|
|
266
267
|
".gsd/journal/",
|
|
267
268
|
".gsd/doctor-history.jsonl",
|
|
269
|
+
".gsd/event-log.jsonl",
|
|
268
270
|
".gsd/DISCUSSION-MANIFEST.json",
|
|
269
271
|
];
|
|
270
272
|
|
|
@@ -427,3 +427,66 @@ test("formatDoctorFindings shows findings with appropriate icons", () => {
|
|
|
427
427
|
assert.ok(output.includes("1 warning"));
|
|
428
428
|
assert.ok(output.includes("1 fixed"));
|
|
429
429
|
});
|
|
430
|
+
|
|
431
|
+
// ─── Regression #3891 — alibaba-coding-plan missing from PROVIDER_REGISTRY ───────
|
|
432
|
+
//
|
|
433
|
+
// Before this fix, `alibaba-coding-plan` was not in PROVIDER_REGISTRY, causing
|
|
434
|
+
// `/gsd keys add alibaba-coding-plan` to silently fail (provider not found).
|
|
435
|
+
// alibaba-dashscope is the new standalone provider added in the same PR.
|
|
436
|
+
|
|
437
|
+
test("regression #3891 — alibaba-coding-plan is in PROVIDER_REGISTRY", () => {
|
|
438
|
+
const provider = findProvider("alibaba-coding-plan");
|
|
439
|
+
assert.ok(provider, "alibaba-coding-plan must be in PROVIDER_REGISTRY for /gsd keys add to work");
|
|
440
|
+
assert.equal(provider.id, "alibaba-coding-plan");
|
|
441
|
+
assert.equal(provider.category, "llm");
|
|
442
|
+
assert.equal(provider.envVar, "ALIBABA_API_KEY");
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
test("alibaba-dashscope is in PROVIDER_REGISTRY", () => {
|
|
446
|
+
const provider = findProvider("alibaba-dashscope");
|
|
447
|
+
assert.ok(provider, "alibaba-dashscope must be in PROVIDER_REGISTRY for /gsd keys add to work");
|
|
448
|
+
assert.equal(provider.id, "alibaba-dashscope");
|
|
449
|
+
assert.equal(provider.category, "llm");
|
|
450
|
+
assert.equal(provider.envVar, "DASHSCOPE_API_KEY");
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
test("alibaba-coding-plan and alibaba-dashscope are separate providers (different env vars)", () => {
|
|
454
|
+
const codingPlan = findProvider("alibaba-coding-plan");
|
|
455
|
+
const dashscope = findProvider("alibaba-dashscope");
|
|
456
|
+
assert.ok(codingPlan, "alibaba-coding-plan must exist");
|
|
457
|
+
assert.ok(dashscope, "alibaba-dashscope must exist");
|
|
458
|
+
assert.notEqual(
|
|
459
|
+
codingPlan.envVar,
|
|
460
|
+
dashscope.envVar,
|
|
461
|
+
"alibaba-coding-plan and alibaba-dashscope must use different env vars",
|
|
462
|
+
);
|
|
463
|
+
});
|
|
464
|
+
|
|
465
|
+
test("getAllKeyStatuses includes alibaba-coding-plan", () => {
|
|
466
|
+
const auth = makeAuth();
|
|
467
|
+
const statuses = getAllKeyStatuses(auth);
|
|
468
|
+
const found = statuses.find((s) => s.provider.id === "alibaba-coding-plan");
|
|
469
|
+
assert.ok(found, "getAllKeyStatuses must include alibaba-coding-plan");
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
test("getAllKeyStatuses includes alibaba-dashscope", () => {
|
|
473
|
+
const auth = makeAuth();
|
|
474
|
+
const statuses = getAllKeyStatuses(auth);
|
|
475
|
+
const found = statuses.find((s) => s.provider.id === "alibaba-dashscope");
|
|
476
|
+
assert.ok(found, "getAllKeyStatuses must include alibaba-dashscope");
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
test("getAllKeyStatuses detects DASHSCOPE_API_KEY for alibaba-dashscope (failure path: missing key shows not configured)", () => {
|
|
480
|
+
const saved = process.env.DASHSCOPE_API_KEY;
|
|
481
|
+
delete process.env.DASHSCOPE_API_KEY;
|
|
482
|
+
try {
|
|
483
|
+
const auth = makeAuth();
|
|
484
|
+
const statuses = getAllKeyStatuses(auth);
|
|
485
|
+
const found = statuses.find((s) => s.provider.id === "alibaba-dashscope");
|
|
486
|
+
assert.ok(found);
|
|
487
|
+
assert.equal(found.configured, false);
|
|
488
|
+
assert.equal(found.source, "none");
|
|
489
|
+
} finally {
|
|
490
|
+
if (saved !== undefined) process.env.DASHSCOPE_API_KEY = saved;
|
|
491
|
+
}
|
|
492
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Regression tests for memory pressure monitoring (#3331) and
|
|
3
|
+
* stuck detection persistence (#3704) in auto/loop.ts.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, test } from "node:test";
|
|
7
|
+
import assert from "node:assert/strict";
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { join, dirname } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
|
|
12
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const loopSource = readFileSync(join(__dirname, "..", "auto", "loop.ts"), "utf-8");
|
|
14
|
+
|
|
15
|
+
describe("memory pressure monitoring (#3331)", () => {
|
|
16
|
+
test("checkMemoryPressure function exists", () => {
|
|
17
|
+
assert.match(loopSource, /function checkMemoryPressure/);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test("MEMORY_PRESSURE_THRESHOLD constant is defined", () => {
|
|
21
|
+
assert.match(loopSource, /MEMORY_PRESSURE_THRESHOLD\s*=\s*0\.\d+/);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test("memory check runs every MEMORY_CHECK_INTERVAL iterations", () => {
|
|
25
|
+
assert.match(loopSource, /iteration\s*%\s*MEMORY_CHECK_INTERVAL\s*===\s*0/);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("memory pressure triggers graceful stopAuto", () => {
|
|
29
|
+
assert.match(loopSource, /mem\.pressured/);
|
|
30
|
+
assert.match(loopSource, /Stopping gracefully to prevent OOM/);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
describe("stuck detection persistence (#3704)", () => {
|
|
35
|
+
test("loadStuckState function exists", () => {
|
|
36
|
+
assert.match(loopSource, /function loadStuckState/);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("saveStuckState function exists", () => {
|
|
40
|
+
assert.match(loopSource, /function saveStuckState/);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("loopState initialized from persisted state", () => {
|
|
44
|
+
assert.match(loopSource, /loadStuckState\(s\.basePath\)/);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test("stuck state saved after each iteration", () => {
|
|
48
|
+
assert.match(loopSource, /saveStuckState\(s\.basePath,\s*loopState\)/);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test("stuck state file path uses runtime directory", () => {
|
|
52
|
+
assert.match(loopSource, /stuck-state\.json/);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tests for model config isolation between concurrent instances (#650, #1065)
|
|
3
|
-
* and
|
|
3
|
+
* and session-scoped model precedence behavior.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { describe, it, beforeEach, afterEach } from "node:test";
|
|
@@ -157,75 +157,60 @@ describe("session model recovery on error (#1065)", () => {
|
|
|
157
157
|
});
|
|
158
158
|
});
|
|
159
159
|
|
|
160
|
-
// ───
|
|
160
|
+
// ─── Manual session model override precedence ───────────────────────────────
|
|
161
161
|
|
|
162
|
-
describe("
|
|
163
|
-
it("
|
|
164
|
-
|
|
165
|
-
const preferredModel = { provider: "
|
|
166
|
-
const ctxModel = { provider: "claude-code", id: "claude-
|
|
162
|
+
describe("manual session model override precedence", () => {
|
|
163
|
+
it("manual session override takes priority over preferences and ctx.model", () => {
|
|
164
|
+
const manualSessionOverride = { provider: "openai-codex", id: "gpt-5.4" };
|
|
165
|
+
const preferredModel = { provider: "anthropic", id: "claude-sonnet-4-6" };
|
|
166
|
+
const ctxModel = { provider: "claude-code", id: "claude-opus-4-6" };
|
|
167
167
|
|
|
168
|
-
const startModelSnapshot =
|
|
168
|
+
const startModelSnapshot = manualSessionOverride
|
|
169
|
+
?? preferredModel
|
|
169
170
|
?? { provider: ctxModel.provider, id: ctxModel.id };
|
|
170
171
|
|
|
171
|
-
assert.equal(startModelSnapshot.provider, "openai-codex"
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
assert.equal(startModelSnapshot.provider, "openai-codex");
|
|
173
|
+
assert.equal(startModelSnapshot.id, "gpt-5.4");
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it("falls back to preferences when no manual override is active", () => {
|
|
177
|
+
const manualSessionOverride: { provider: string; id: string } | undefined = undefined;
|
|
178
|
+
const preferredModel = { provider: "anthropic", id: "claude-sonnet-4-6" };
|
|
179
|
+
const ctxModel = { provider: "claude-code", id: "claude-opus-4-6" };
|
|
180
|
+
|
|
181
|
+
const startModelSnapshot = manualSessionOverride
|
|
182
|
+
?? preferredModel
|
|
183
|
+
?? { provider: ctxModel.provider, id: ctxModel.id };
|
|
184
|
+
|
|
185
|
+
assert.equal(startModelSnapshot.provider, "anthropic");
|
|
186
|
+
assert.equal(startModelSnapshot.id, "claude-sonnet-4-6");
|
|
175
187
|
});
|
|
176
188
|
|
|
177
|
-
it("falls back to ctx.model when no
|
|
189
|
+
it("falls back to ctx.model when no manual override or preferences are configured", () => {
|
|
190
|
+
const manualSessionOverride: { provider: string; id: string } | undefined = undefined;
|
|
178
191
|
const preferredModel: { provider: string; id: string } | undefined = undefined;
|
|
179
|
-
const ctxModel = { provider: "claude-code", id: "claude-
|
|
192
|
+
const ctxModel = { provider: "claude-code", id: "claude-opus-4-6" };
|
|
180
193
|
|
|
181
|
-
const startModelSnapshot =
|
|
194
|
+
const startModelSnapshot = manualSessionOverride
|
|
195
|
+
?? preferredModel
|
|
182
196
|
?? { provider: ctxModel.provider, id: ctxModel.id };
|
|
183
197
|
|
|
184
|
-
assert.equal(startModelSnapshot.provider, "claude-code"
|
|
185
|
-
|
|
186
|
-
assert.equal(startModelSnapshot.id, "claude-sonnet-4-6",
|
|
187
|
-
"should fall back to ctx.model id when no preferences");
|
|
198
|
+
assert.equal(startModelSnapshot.provider, "claude-code");
|
|
199
|
+
assert.equal(startModelSnapshot.id, "claude-opus-4-6");
|
|
188
200
|
});
|
|
189
201
|
|
|
190
|
-
it("handles null ctx.model with no preferences gracefully", () => {
|
|
202
|
+
it("handles null ctx.model with no override or preferences gracefully", () => {
|
|
203
|
+
const manualSessionOverride: { provider: string; id: string } | undefined = undefined;
|
|
191
204
|
const preferredModel: { provider: string; id: string } | undefined = undefined;
|
|
192
205
|
// Use a function to prevent TS from narrowing to `never` in the ternary
|
|
193
206
|
function getCtxModel(): { provider: string; id: string } | null { return null; }
|
|
194
207
|
const ctxModel = getCtxModel();
|
|
195
208
|
|
|
196
|
-
const startModelSnapshot =
|
|
209
|
+
const startModelSnapshot = manualSessionOverride
|
|
210
|
+
?? preferredModel
|
|
197
211
|
?? (ctxModel ? { provider: ctxModel.provider, id: ctxModel.id } : null);
|
|
198
212
|
|
|
199
213
|
assert.equal(startModelSnapshot, null,
|
|
200
|
-
"should be null when
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
it("bare model ID uses session provider when available", () => {
|
|
204
|
-
// Simulates: PREFERENCES.md has "gpt-5.4" (no provider), session is openai-codex
|
|
205
|
-
const preferredModel = { provider: "openai-codex", id: "gpt-5.4" }; // from resolveDefaultSessionModel("openai-codex")
|
|
206
|
-
const ctxModel = { provider: "openai-codex", id: "claude-sonnet-4-6" };
|
|
207
|
-
|
|
208
|
-
const startModelSnapshot = preferredModel
|
|
209
|
-
?? { provider: ctxModel.provider, id: ctxModel.id };
|
|
210
|
-
|
|
211
|
-
assert.equal(startModelSnapshot.provider, "openai-codex");
|
|
212
|
-
assert.equal(startModelSnapshot.id, "gpt-5.4",
|
|
213
|
-
"bare model ID from preferences should still override ctx.model");
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
it("stale settings.json does not leak when preferences are set", () => {
|
|
217
|
-
// Scenario: settings.json has claude-code, PREFERENCES.md has openai-codex
|
|
218
|
-
const settingsJsonDefault = { provider: "claude-code", id: "claude-sonnet-4-6" };
|
|
219
|
-
const preferencesModel = { provider: "openai-codex", id: "gpt-5.4" };
|
|
220
|
-
|
|
221
|
-
// auto-start.ts captures preferredModel first, which preempts settingsJsonDefault
|
|
222
|
-
const startModelSnapshot = preferencesModel ?? settingsJsonDefault;
|
|
223
|
-
|
|
224
|
-
assert.equal(startModelSnapshot.provider, "openai-codex",
|
|
225
|
-
"PREFERENCES.md must override stale settings.json provider");
|
|
226
|
-
assert.equal(startModelSnapshot.id, "gpt-5.4",
|
|
227
|
-
"PREFERENCES.md must override stale settings.json model");
|
|
228
|
-
assert.notEqual(startModelSnapshot.provider, settingsJsonDefault.provider,
|
|
229
|
-
"settings.json provider must NOT leak through");
|
|
214
|
+
"should be null when no model source is available");
|
|
230
215
|
});
|
|
231
216
|
});
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
getLineCount,
|
|
17
17
|
suppressPersistence,
|
|
18
18
|
unsuppressPersistence,
|
|
19
|
+
onNotificationStoreChange,
|
|
19
20
|
_resetNotificationStore,
|
|
20
21
|
} from "../notification-store.js";
|
|
21
22
|
|
|
@@ -187,6 +188,23 @@ describe("notification-store", () => {
|
|
|
187
188
|
assert.ok(!entries.some((e) => e.message === "suppressed"));
|
|
188
189
|
});
|
|
189
190
|
|
|
191
|
+
test("appendNotification suppresses identical messages within the dedup window", (t) => {
|
|
192
|
+
initNotificationStore(tmp);
|
|
193
|
+
let now = 1_000;
|
|
194
|
+
t.mock.method(Date, "now", () => now);
|
|
195
|
+
|
|
196
|
+
appendNotification("same", "warning");
|
|
197
|
+
now += 1_000;
|
|
198
|
+
appendNotification("same", "warning");
|
|
199
|
+
now += 31_000;
|
|
200
|
+
appendNotification("same", "warning");
|
|
201
|
+
|
|
202
|
+
const entries = readNotifications();
|
|
203
|
+
assert.equal(entries.length, 2);
|
|
204
|
+
assert.equal(entries[0].message, "same");
|
|
205
|
+
assert.equal(entries[1].message, "same");
|
|
206
|
+
});
|
|
207
|
+
|
|
190
208
|
test("suppressPersistence is ref-counted", () => {
|
|
191
209
|
initNotificationStore(tmp);
|
|
192
210
|
suppressPersistence();
|
|
@@ -279,4 +297,21 @@ describe("notification-store", () => {
|
|
|
279
297
|
|
|
280
298
|
rmSync(lockPath, { force: true });
|
|
281
299
|
});
|
|
300
|
+
|
|
301
|
+
test("listeners are notified on append, markAllRead, and clear", () => {
|
|
302
|
+
initNotificationStore(tmp);
|
|
303
|
+
let calls = 0;
|
|
304
|
+
const unsubscribe = onNotificationStoreChange(() => { calls++; });
|
|
305
|
+
|
|
306
|
+
appendNotification("msg1", "info");
|
|
307
|
+
assert.equal(calls, 1, "append should emit one change");
|
|
308
|
+
|
|
309
|
+
markAllRead();
|
|
310
|
+
assert.equal(calls, 2, "markAllRead should emit one change when state changes");
|
|
311
|
+
|
|
312
|
+
clearNotifications();
|
|
313
|
+
assert.equal(calls, 3, "clear should emit one change");
|
|
314
|
+
|
|
315
|
+
unsubscribe();
|
|
316
|
+
});
|
|
282
317
|
});
|