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
|
@@ -574,6 +574,42 @@ test("runProviderChecks reports ok for OpenAI via openai-codex auth.json (#2922)
|
|
|
574
574
|
rmSync(tmpHome, { recursive: true, force: true });
|
|
575
575
|
});
|
|
576
576
|
|
|
577
|
+
test("runProviderChecks reports ok for claude-code without any API key", () => {
|
|
578
|
+
const repo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-providers-cc-repo-")));
|
|
579
|
+
mkdirSync(join(repo, ".gsd"), { recursive: true });
|
|
580
|
+
writeFileSync(
|
|
581
|
+
join(repo, ".gsd", "PREFERENCES.md"),
|
|
582
|
+
[
|
|
583
|
+
"---",
|
|
584
|
+
"models:",
|
|
585
|
+
" execution:",
|
|
586
|
+
" model: claude-sonnet-4-6",
|
|
587
|
+
" provider: claude-code",
|
|
588
|
+
"---",
|
|
589
|
+
"",
|
|
590
|
+
].join("\n"),
|
|
591
|
+
);
|
|
592
|
+
|
|
593
|
+
const tmpHome = realpathSync(mkdtempSync(join(tmpdir(), "gsd-providers-cc-home-")));
|
|
594
|
+
|
|
595
|
+
withEnv({
|
|
596
|
+
HOME: tmpHome,
|
|
597
|
+
ANTHROPIC_API_KEY: undefined,
|
|
598
|
+
ANTHROPIC_OAUTH_TOKEN: undefined,
|
|
599
|
+
}, () => {
|
|
600
|
+
withCwd(repo, () => {
|
|
601
|
+
const results = runProviderChecks();
|
|
602
|
+
const cc = results.find(r => r.name === "claude-code");
|
|
603
|
+
assert.ok(cc, "claude-code result should exist");
|
|
604
|
+
assert.equal(cc!.status, "ok", "claude-code uses CLI auth — must be ok without API keys");
|
|
605
|
+
assert.ok(cc!.message.includes("CLI auth"), "should indicate CLI auth");
|
|
606
|
+
});
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
rmSync(repo, { recursive: true, force: true });
|
|
610
|
+
rmSync(tmpHome, { recursive: true, force: true });
|
|
611
|
+
});
|
|
612
|
+
|
|
577
613
|
test("PROVIDER_ROUTES includes google-gemini-cli as route for google (#2922)", async () => {
|
|
578
614
|
const { readFileSync: readFS } = await import("node:fs");
|
|
579
615
|
const { dirname: dirn, join: joinPath } = await import("node:path");
|
package/src/resources/extensions/gsd/tests/execute-task-prompt-existing-artifact-guard.test.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
8
|
+
const promptsDir = join(__dirname, "..", "prompts");
|
|
9
|
+
|
|
10
|
+
test("execute-task prompt requires reading existing artifacts before write", () => {
|
|
11
|
+
const prompt = readFileSync(join(promptsDir, "execute-task.md"), "utf-8");
|
|
12
|
+
|
|
13
|
+
assert.match(
|
|
14
|
+
prompt,
|
|
15
|
+
/Before any `Write` that creates an artifact or output file, check whether that path already exists\./,
|
|
16
|
+
"execute-task prompt should require an existence check before creating artifacts",
|
|
17
|
+
);
|
|
18
|
+
assert.match(
|
|
19
|
+
prompt,
|
|
20
|
+
/If it does, read it first and decide whether the work is already done, should be extended, or truly needs replacement\./,
|
|
21
|
+
"execute-task prompt should require reading existing artifacts before replacement",
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test("guided resume prompt checks for pre-existing artifacts", () => {
|
|
26
|
+
const prompt = readFileSync(join(promptsDir, "guided-resume-task.md"), "utf-8");
|
|
27
|
+
|
|
28
|
+
assert.match(
|
|
29
|
+
prompt,
|
|
30
|
+
/Before you create any expected artifact or output file, check whether it already exists and read it first/i,
|
|
31
|
+
"guided resume prompt should guard pre-existing artifacts",
|
|
32
|
+
);
|
|
33
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* false-degraded-mode-warning.test.ts — Regression tests for #3922.
|
|
3
|
+
*
|
|
4
|
+
* Before this fix, deriveState() logged a "DB unavailable — degraded mode"
|
|
5
|
+
* warning even when the DB simply hadn't been opened yet (e.g. during
|
|
6
|
+
* before_agent_start context injection). The fix introduces wasDbOpenAttempted()
|
|
7
|
+
* to distinguish "not yet initialized" from "genuinely unavailable."
|
|
8
|
+
*
|
|
9
|
+
* Two aspects:
|
|
10
|
+
* 1. gsd-db: wasDbOpenAttempted() tracks whether openDatabase() was ever called.
|
|
11
|
+
* 2. state: the degraded-mode warning is gated behind wasDbOpenAttempted().
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { describe, test } from "node:test";
|
|
15
|
+
import assert from "node:assert/strict";
|
|
16
|
+
import { readFileSync } from "node:fs";
|
|
17
|
+
import { dirname, join } from "node:path";
|
|
18
|
+
import { fileURLToPath } from "node:url";
|
|
19
|
+
import {
|
|
20
|
+
openDatabase,
|
|
21
|
+
closeDatabase,
|
|
22
|
+
isDbAvailable,
|
|
23
|
+
wasDbOpenAttempted,
|
|
24
|
+
} from "../gsd-db.ts";
|
|
25
|
+
|
|
26
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
27
|
+
const stateSource = readFileSync(join(__dirname, "..", "state.ts"), "utf-8");
|
|
28
|
+
|
|
29
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
30
|
+
// 1. gsd-db: wasDbOpenAttempted flag
|
|
31
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
32
|
+
|
|
33
|
+
describe("wasDbOpenAttempted (#3922)", () => {
|
|
34
|
+
|
|
35
|
+
test("wasDbOpenAttempted returns true after openDatabase is called", () => {
|
|
36
|
+
// By this point in the test suite, openDatabase may or may not have been
|
|
37
|
+
// called by other tests. So we call it explicitly and verify it returns true.
|
|
38
|
+
openDatabase(":memory:");
|
|
39
|
+
assert.strictEqual(wasDbOpenAttempted(), true,
|
|
40
|
+
"wasDbOpenAttempted should be true after openDatabase call");
|
|
41
|
+
closeDatabase();
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("openDatabase sets the flag even if it fails on invalid path", () => {
|
|
45
|
+
// openDatabase with an unreachable path may fail, but the flag should
|
|
46
|
+
// still be set because the attempt was made.
|
|
47
|
+
try { openDatabase("/nonexistent/path/that/will/fail.db"); } catch { /* expected */ }
|
|
48
|
+
assert.strictEqual(wasDbOpenAttempted(), true,
|
|
49
|
+
"wasDbOpenAttempted should be true even after a failed open attempt");
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
54
|
+
// 2. state.ts: degraded-mode warning is gated behind wasDbOpenAttempted
|
|
55
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
56
|
+
|
|
57
|
+
describe("degraded-mode warning guard (#3922)", () => {
|
|
58
|
+
|
|
59
|
+
test("state.ts imports wasDbOpenAttempted from gsd-db", () => {
|
|
60
|
+
assert.ok(
|
|
61
|
+
stateSource.includes("wasDbOpenAttempted"),
|
|
62
|
+
"state.ts must import wasDbOpenAttempted to gate the degraded-mode warning",
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("degraded-mode warning is inside a wasDbOpenAttempted() guard", () => {
|
|
67
|
+
// Find the degraded-mode warning string
|
|
68
|
+
const warningStr = 'DB unavailable — using filesystem state derivation (degraded mode)';
|
|
69
|
+
const warningIdx = stateSource.indexOf(warningStr);
|
|
70
|
+
assert.ok(warningIdx > 0, "degraded-mode warning string must exist in state.ts");
|
|
71
|
+
|
|
72
|
+
// The wasDbOpenAttempted() check must appear BEFORE the warning,
|
|
73
|
+
// within the same else-branch (i.e. within a reasonable distance).
|
|
74
|
+
// Look backwards from the warning for the guard.
|
|
75
|
+
const searchWindow = stateSource.slice(Math.max(0, warningIdx - 300), warningIdx);
|
|
76
|
+
assert.ok(
|
|
77
|
+
searchWindow.includes("wasDbOpenAttempted()"),
|
|
78
|
+
"wasDbOpenAttempted() guard must appear shortly before the degraded-mode warning " +
|
|
79
|
+
"to prevent false warnings when DB has not been initialized yet",
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("warning is NOT emitted unconditionally in the else branch", () => {
|
|
84
|
+
// The old code had `logWarning(...)` directly in the else branch.
|
|
85
|
+
// The fix wraps it in `if (wasDbOpenAttempted())`.
|
|
86
|
+
// Verify the logWarning call is inside a conditional, not bare.
|
|
87
|
+
const lines = stateSource.split("\n");
|
|
88
|
+
for (let i = 0; i < lines.length; i++) {
|
|
89
|
+
if (lines[i]!.includes("DB unavailable") && lines[i]!.includes("degraded mode")) {
|
|
90
|
+
// This line has the warning. Check that the preceding non-empty line
|
|
91
|
+
// contains an if-condition (wasDbOpenAttempted), not a bare else.
|
|
92
|
+
let prev = i - 1;
|
|
93
|
+
while (prev >= 0 && lines[prev]!.trim() === "") prev--;
|
|
94
|
+
const prevLine = lines[prev]!.trim();
|
|
95
|
+
assert.ok(
|
|
96
|
+
prevLine.includes("wasDbOpenAttempted"),
|
|
97
|
+
`Line ${i + 1} emits degraded-mode warning — preceding line ${prev + 1} must ` +
|
|
98
|
+
`contain wasDbOpenAttempted guard, but found: "${prevLine}"`,
|
|
99
|
+
);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
@@ -101,3 +101,65 @@ test("#1943 detectStuckLoops ignores watchdog duplicates but flags real re-dispa
|
|
|
101
101
|
assert.equal(anomalies.length, 1, `expected 1 anomaly (for the 3x dispatched task), got ${anomalies.length}`);
|
|
102
102
|
assert.ok(anomalies[0].summary.includes("3 times"));
|
|
103
103
|
});
|
|
104
|
+
|
|
105
|
+
test("#3760 detectStuckLoops ignores cross-session recovery re-dispatches", () => {
|
|
106
|
+
const anomalies: ForensicAnomaly[] = [];
|
|
107
|
+
|
|
108
|
+
const units: UnitMetrics[] = [
|
|
109
|
+
makeUnit({
|
|
110
|
+
type: "plan-slice",
|
|
111
|
+
id: "M001/S02",
|
|
112
|
+
startedAt: 1000,
|
|
113
|
+
finishedAt: 2000,
|
|
114
|
+
autoSessionKey: "session-a",
|
|
115
|
+
}),
|
|
116
|
+
makeUnit({
|
|
117
|
+
type: "plan-slice",
|
|
118
|
+
id: "M001/S02",
|
|
119
|
+
startedAt: 5000,
|
|
120
|
+
finishedAt: 6000,
|
|
121
|
+
autoSessionKey: "session-b",
|
|
122
|
+
}),
|
|
123
|
+
];
|
|
124
|
+
|
|
125
|
+
detectStuckLoops(units, anomalies);
|
|
126
|
+
|
|
127
|
+
assert.equal(anomalies.length, 0, "cross-session recovery should not be flagged as a stuck loop");
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test("#3760 detectStuckLoops still flags repeated dispatches within one auto session", () => {
|
|
131
|
+
const anomalies: ForensicAnomaly[] = [];
|
|
132
|
+
|
|
133
|
+
const units: UnitMetrics[] = [
|
|
134
|
+
makeUnit({
|
|
135
|
+
type: "complete-slice",
|
|
136
|
+
id: "M011/S02",
|
|
137
|
+
startedAt: 1000,
|
|
138
|
+
finishedAt: 2000,
|
|
139
|
+
autoSessionKey: "session-a",
|
|
140
|
+
}),
|
|
141
|
+
makeUnit({
|
|
142
|
+
type: "complete-slice",
|
|
143
|
+
id: "M011/S02",
|
|
144
|
+
startedAt: 5000,
|
|
145
|
+
finishedAt: 6000,
|
|
146
|
+
autoSessionKey: "session-a",
|
|
147
|
+
}),
|
|
148
|
+
makeUnit({
|
|
149
|
+
type: "complete-slice",
|
|
150
|
+
id: "M011/S02",
|
|
151
|
+
startedAt: 9000,
|
|
152
|
+
finishedAt: 10000,
|
|
153
|
+
autoSessionKey: "session-b",
|
|
154
|
+
}),
|
|
155
|
+
];
|
|
156
|
+
|
|
157
|
+
detectStuckLoops(units, anomalies);
|
|
158
|
+
|
|
159
|
+
assert.equal(anomalies.length, 1, "within-session retries should still be flagged");
|
|
160
|
+
assert.ok(anomalies[0].summary.includes("2 times"), `summary should reflect the worst same-session loop: ${anomalies[0].summary}`);
|
|
161
|
+
assert.ok(
|
|
162
|
+
anomalies[0].details.includes("Cross-session recovery runs are ignored"),
|
|
163
|
+
`details should explain the session-aware rule: ${anomalies[0].details}`,
|
|
164
|
+
);
|
|
165
|
+
});
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import test from 'node:test';
|
|
5
5
|
import assert from 'node:assert/strict';
|
|
6
6
|
import { formatShortcut } from '../files.ts';
|
|
7
|
+
import { formattedShortcutPair, primaryShortcutCombo, fallbackShortcutCombo } from '../shortcut-defs.ts';
|
|
7
8
|
|
|
8
9
|
// ─── formatShortcut renders per-platform shortcuts ──────────────────────
|
|
9
10
|
|
|
@@ -67,3 +68,33 @@ test('formatShortcut: passes through plain key names', () => {
|
|
|
67
68
|
assert.strictEqual(formatShortcut('Escape'), 'Escape');
|
|
68
69
|
assert.strictEqual(formatShortcut('Enter'), 'Enter');
|
|
69
70
|
});
|
|
71
|
+
|
|
72
|
+
test("shortcut-defs: exposes canonical dashboard combos", () => {
|
|
73
|
+
assert.equal(primaryShortcutCombo("dashboard"), "Ctrl+Alt+G");
|
|
74
|
+
assert.equal(fallbackShortcutCombo("dashboard"), "Ctrl+Shift+G");
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
test("shortcut-defs: formats shortcut pair using platform symbols", () => {
|
|
78
|
+
const pair = formattedShortcutPair("notifications");
|
|
79
|
+
if (process.platform === "darwin") {
|
|
80
|
+
assert.equal(pair, "⌃⌥N / ⌃⇧N");
|
|
81
|
+
} else {
|
|
82
|
+
assert.equal(pair, "Ctrl+Alt+N / Ctrl+Shift+N");
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test("shortcut-defs: parallel shortcut omits fallback (hasFallback: false)", () => {
|
|
87
|
+
const pair = formattedShortcutPair("parallel");
|
|
88
|
+
if (process.platform === "darwin") {
|
|
89
|
+
assert.equal(pair, "⌃⌥P", "parallel should only show primary combo");
|
|
90
|
+
} else {
|
|
91
|
+
assert.equal(pair, "Ctrl+Alt+P", "parallel should only show primary combo");
|
|
92
|
+
}
|
|
93
|
+
// Verify it does NOT contain the fallback separator
|
|
94
|
+
assert.ok(!pair.includes("/"), "parallel pair should not contain fallback separator");
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test("shortcut-defs: dashboard shortcut includes fallback (hasFallback: true)", () => {
|
|
98
|
+
const pair = formattedShortcutPair("dashboard");
|
|
99
|
+
assert.ok(pair.includes("/"), "dashboard pair should contain fallback separator");
|
|
100
|
+
});
|
|
@@ -186,4 +186,31 @@ describe("evaluating-gates phase", () => {
|
|
|
186
186
|
insertGateRow({ milestoneId: "M001", sliceId: "S01", gateId: "Q5", scope: "task", taskId: "T01" });
|
|
187
187
|
assert.equal(getPendingSliceGateCount("M001", "S01"), 1);
|
|
188
188
|
});
|
|
189
|
+
|
|
190
|
+
test("Q8 (owned by complete-slice) does not block evaluating-gates phase", async () => {
|
|
191
|
+
// Regression: Q8 is stored with scope:"slice" but owned by the
|
|
192
|
+
// complete-slice turn. Before the gate registry landed, deriveState
|
|
193
|
+
// counted Q8 as a blocker for evaluating-gates while the gate-evaluate
|
|
194
|
+
// prompt silently dropped Q8 — an unrecoverable stall. After the
|
|
195
|
+
// registry change, deriveState filters by owner turn, so Q8 never
|
|
196
|
+
// blocks evaluating-gates.
|
|
197
|
+
planSlice(tmpDir);
|
|
198
|
+
await renderPlanFromDb(tmpDir, "M001", "S01");
|
|
199
|
+
|
|
200
|
+
insertGateRow({ milestoneId: "M001", sliceId: "S01", gateId: "Q3", scope: "slice" });
|
|
201
|
+
insertGateRow({ milestoneId: "M001", sliceId: "S01", gateId: "Q4", scope: "slice" });
|
|
202
|
+
insertGateRow({ milestoneId: "M001", sliceId: "S01", gateId: "Q8", scope: "slice" });
|
|
203
|
+
|
|
204
|
+
saveGateResult({ milestoneId: "M001", sliceId: "S01", gateId: "Q3", verdict: "pass", rationale: "OK", findings: "" });
|
|
205
|
+
saveGateResult({ milestoneId: "M001", sliceId: "S01", gateId: "Q4", verdict: "omitted", rationale: "N/A", findings: "" });
|
|
206
|
+
// Q8 deliberately left pending — it's complete-slice's problem.
|
|
207
|
+
|
|
208
|
+
invalidateStateCache();
|
|
209
|
+
const state = await deriveState(tmpDir);
|
|
210
|
+
assert.equal(
|
|
211
|
+
state.phase,
|
|
212
|
+
"executing",
|
|
213
|
+
`pending Q8 must not stall evaluating-gates — got phase=${state.phase}`,
|
|
214
|
+
);
|
|
215
|
+
});
|
|
189
216
|
});
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gate registry tests — enforce that every declared GateId has a registry
|
|
3
|
+
* entry, that every owner-turn bucket is non-empty, and that coverage
|
|
4
|
+
* assertions fail loudly instead of silently skipping unknown gates.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { describe, test } from "node:test";
|
|
8
|
+
import assert from "node:assert/strict";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
GATE_REGISTRY,
|
|
12
|
+
assertGateCoverage,
|
|
13
|
+
getGateDefinition,
|
|
14
|
+
getGateIdsForTurn,
|
|
15
|
+
getGatesForTurn,
|
|
16
|
+
getOwnerTurn,
|
|
17
|
+
type OwnerTurn,
|
|
18
|
+
} from "../gate-registry.ts";
|
|
19
|
+
import type { GateId } from "../types.ts";
|
|
20
|
+
|
|
21
|
+
/** Authoritative list of GateIds as declared in types.ts. */
|
|
22
|
+
const ALL_GATE_IDS: readonly GateId[] = [
|
|
23
|
+
"Q3", "Q4", "Q5", "Q6", "Q7", "Q8",
|
|
24
|
+
"MV01", "MV02", "MV03", "MV04",
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const ALL_OWNER_TURNS: readonly OwnerTurn[] = [
|
|
28
|
+
"gate-evaluate",
|
|
29
|
+
"execute-task",
|
|
30
|
+
"complete-slice",
|
|
31
|
+
"validate-milestone",
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
describe("gate-registry", () => {
|
|
35
|
+
test("every declared GateId has a registry entry", () => {
|
|
36
|
+
for (const id of ALL_GATE_IDS) {
|
|
37
|
+
const def = GATE_REGISTRY[id];
|
|
38
|
+
assert.ok(def, `missing registry entry for gate ${id}`);
|
|
39
|
+
assert.equal(def.id, id);
|
|
40
|
+
assert.ok(def.question.length > 0, `${id} missing question`);
|
|
41
|
+
assert.ok(def.guidance.length > 0, `${id} missing guidance`);
|
|
42
|
+
assert.ok(def.promptSection.length > 0, `${id} missing promptSection`);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test("registry contains no extra gate entries", () => {
|
|
47
|
+
const registryIds = new Set(Object.keys(GATE_REGISTRY));
|
|
48
|
+
const declaredIds = new Set<string>(ALL_GATE_IDS);
|
|
49
|
+
for (const id of registryIds) {
|
|
50
|
+
assert.ok(declaredIds.has(id), `registry has unknown gate ${id}`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("every owner turn owns at least one gate", () => {
|
|
55
|
+
for (const turn of ALL_OWNER_TURNS) {
|
|
56
|
+
const gates = getGatesForTurn(turn);
|
|
57
|
+
assert.ok(
|
|
58
|
+
gates.length > 0,
|
|
59
|
+
`owner turn "${turn}" has no gates — likely a registry mistake`,
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
test("owner turn buckets are disjoint", () => {
|
|
65
|
+
const seen = new Set<string>();
|
|
66
|
+
for (const turn of ALL_OWNER_TURNS) {
|
|
67
|
+
for (const def of getGatesForTurn(turn)) {
|
|
68
|
+
assert.ok(!seen.has(def.id), `gate ${def.id} claimed by two turns`);
|
|
69
|
+
seen.add(def.id);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// Every gate should appear in exactly one bucket.
|
|
73
|
+
assert.equal(seen.size, ALL_GATE_IDS.length);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("getOwnerTurn round-trips against GATE_REGISTRY", () => {
|
|
77
|
+
for (const id of ALL_GATE_IDS) {
|
|
78
|
+
const turn = getOwnerTurn(id);
|
|
79
|
+
const idsForTurn = getGateIdsForTurn(turn);
|
|
80
|
+
assert.ok(idsForTurn.has(id), `${id} not in ${turn} bucket`);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test("getGateDefinition returns undefined for unknown ids", () => {
|
|
85
|
+
assert.equal(getGateDefinition("Q99"), undefined);
|
|
86
|
+
assert.equal(getGateDefinition("not-a-gate"), undefined);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("assertGateCoverage", () => {
|
|
91
|
+
test("throws when a row is owned by a different turn", () => {
|
|
92
|
+
// Q8 is owned by complete-slice, not gate-evaluate — this used to be
|
|
93
|
+
// silently dropped by the old `if (!meta) continue;` filter, causing
|
|
94
|
+
// the evaluating-gates phase to stall.
|
|
95
|
+
assert.throws(
|
|
96
|
+
() => assertGateCoverage([{ gate_id: "Q8" }], "gate-evaluate"),
|
|
97
|
+
(err: Error) =>
|
|
98
|
+
err.message.includes("Q8") && err.message.includes("gate-evaluate"),
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test("throws when a row has an unknown gate id", () => {
|
|
103
|
+
assert.throws(
|
|
104
|
+
() => assertGateCoverage([{ gate_id: "Q999" as GateId }], "gate-evaluate", { requireAll: false }),
|
|
105
|
+
(err: Error) => err.message.includes("Q999"),
|
|
106
|
+
);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test("throws when requireAll is true and an owned gate is missing", () => {
|
|
110
|
+
// gate-evaluate owns Q3 and Q4. Passing only Q3 should fail.
|
|
111
|
+
assert.throws(
|
|
112
|
+
() => assertGateCoverage([{ gate_id: "Q3" }], "gate-evaluate", { requireAll: true }),
|
|
113
|
+
(err: Error) => err.message.includes("Q4"),
|
|
114
|
+
);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test("passes when requireAll is false and only a subset is pending", () => {
|
|
118
|
+
// execute-task owns Q5/Q6/Q7, but a task with no external dependencies
|
|
119
|
+
// may only have Q7 seeded. That's still valid coverage.
|
|
120
|
+
assert.doesNotThrow(() =>
|
|
121
|
+
assertGateCoverage([{ gate_id: "Q7" }], "execute-task", { requireAll: false }),
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test("passes when requireAll is true and every owned gate is pending", () => {
|
|
126
|
+
assert.doesNotThrow(() =>
|
|
127
|
+
assertGateCoverage(
|
|
128
|
+
[{ gate_id: "Q3" }, { gate_id: "Q4" }],
|
|
129
|
+
"gate-evaluate",
|
|
130
|
+
{ requireAll: true },
|
|
131
|
+
),
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
test("empty pending list passes when requireAll is false", () => {
|
|
136
|
+
assert.doesNotThrow(() =>
|
|
137
|
+
assertGateCoverage([], "complete-slice", { requireAll: false }),
|
|
138
|
+
);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
getRequirementById,
|
|
16
16
|
getActiveDecisions,
|
|
17
17
|
getActiveRequirements,
|
|
18
|
+
getTask,
|
|
18
19
|
transaction,
|
|
19
20
|
_getAdapter,
|
|
20
21
|
_resetProvider,
|
|
@@ -43,6 +44,16 @@ function cleanup(dbPath: string): void {
|
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
|
|
47
|
+
function withPlatform<T>(platform: NodeJS.Platform, fn: () => T): T {
|
|
48
|
+
const original = process.platform;
|
|
49
|
+
Object.defineProperty(process, 'platform', { value: platform });
|
|
50
|
+
try {
|
|
51
|
+
return fn();
|
|
52
|
+
} finally {
|
|
53
|
+
Object.defineProperty(process, 'platform', { value: original });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
46
57
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
47
58
|
// gsd-db tests
|
|
48
59
|
// ═══════════════════════════════════════════════════════════════════════════
|
|
@@ -279,6 +290,26 @@ describe('gsd-db', () => {
|
|
|
279
290
|
cleanup(dbPath);
|
|
280
291
|
});
|
|
281
292
|
|
|
293
|
+
test('gsd-db: mmap stays disabled on darwin file-backed DBs', () => {
|
|
294
|
+
const darwinDbPath = tempDbPath();
|
|
295
|
+
withPlatform('darwin', () => {
|
|
296
|
+
openDatabase(darwinDbPath);
|
|
297
|
+
const adapter = _getAdapter()!;
|
|
298
|
+
const mmap = adapter.prepare('PRAGMA mmap_size').get();
|
|
299
|
+
assert.deepStrictEqual(mmap?.['mmap_size'], 0, 'darwin should leave mmap_size disabled');
|
|
300
|
+
cleanup(darwinDbPath);
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
const linuxDbPath = tempDbPath();
|
|
304
|
+
withPlatform('linux', () => {
|
|
305
|
+
openDatabase(linuxDbPath);
|
|
306
|
+
const adapter = _getAdapter()!;
|
|
307
|
+
const mmap = adapter.prepare('PRAGMA mmap_size').get();
|
|
308
|
+
assert.deepStrictEqual(mmap?.['mmap_size'], 67108864, 'non-darwin should still enable mmap_size');
|
|
309
|
+
cleanup(linuxDbPath);
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
|
|
282
313
|
test('gsd-db: transaction rollback on error', () => {
|
|
283
314
|
openDatabase(':memory:');
|
|
284
315
|
|
|
@@ -329,6 +360,79 @@ describe('gsd-db', () => {
|
|
|
329
360
|
closeDatabase();
|
|
330
361
|
});
|
|
331
362
|
|
|
363
|
+
test('gsd-db: recreates missing verification evidence dedup index after removing duplicate rows', () => {
|
|
364
|
+
const dbPath = tempDbPath();
|
|
365
|
+
openDatabase(dbPath);
|
|
366
|
+
|
|
367
|
+
let adapter = _getAdapter()!;
|
|
368
|
+
adapter.prepare("INSERT INTO milestones (id, created_at) VALUES (?, '')").run('M001');
|
|
369
|
+
adapter.prepare("INSERT INTO slices (milestone_id, id, created_at) VALUES (?, ?, '')").run('M001', 'S01');
|
|
370
|
+
adapter.prepare("INSERT INTO tasks (milestone_id, slice_id, id) VALUES (?, ?, ?)").run('M001', 'S01', 'T01');
|
|
371
|
+
adapter.exec('DROP INDEX IF EXISTS idx_verification_evidence_dedup');
|
|
372
|
+
|
|
373
|
+
const insertEvidence = adapter.prepare(
|
|
374
|
+
`INSERT INTO verification_evidence (
|
|
375
|
+
task_id, slice_id, milestone_id, command, exit_code, verdict, duration_ms, created_at
|
|
376
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
377
|
+
);
|
|
378
|
+
insertEvidence.run('T01', 'S01', 'M001', 'npm test', 1, 'fail', 125, '2026-04-12T00:00:00.000Z');
|
|
379
|
+
insertEvidence.run('T01', 'S01', 'M001', 'npm test', 1, 'fail', 125, '2026-04-12T00:00:01.000Z');
|
|
380
|
+
insertEvidence.run('T01', 'S01', 'M001', 'npm run lint', 0, 'pass', 90, '2026-04-12T00:00:02.000Z');
|
|
381
|
+
|
|
382
|
+
closeDatabase();
|
|
383
|
+
|
|
384
|
+
assert.equal(openDatabase(dbPath), true, 'openDatabase should repair legacy duplicate evidence rows');
|
|
385
|
+
|
|
386
|
+
adapter = _getAdapter()!;
|
|
387
|
+
const countRow = adapter.prepare(
|
|
388
|
+
`SELECT count(*) as cnt
|
|
389
|
+
FROM verification_evidence
|
|
390
|
+
WHERE task_id = ? AND slice_id = ? AND milestone_id = ? AND command = ? AND verdict = ?`,
|
|
391
|
+
).get('T01', 'S01', 'M001', 'npm test', 'fail');
|
|
392
|
+
assert.equal(countRow?.['cnt'], 1, 'duplicate verification evidence rows should be deduplicated before index creation');
|
|
393
|
+
|
|
394
|
+
const indexRow = adapter.prepare(
|
|
395
|
+
"SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'idx_verification_evidence_dedup'",
|
|
396
|
+
).get();
|
|
397
|
+
assert.equal(indexRow?.['name'], 'idx_verification_evidence_dedup', 'dedup index should be recreated on reopen');
|
|
398
|
+
|
|
399
|
+
cleanup(dbPath);
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
test('gsd-db: rowToTask tolerates legacy comma-separated task arrays', () => {
|
|
403
|
+
openDatabase(':memory:');
|
|
404
|
+
|
|
405
|
+
const adapter = _getAdapter()!;
|
|
406
|
+
adapter.prepare("INSERT INTO milestones (id, created_at) VALUES (?, '')").run('M001');
|
|
407
|
+
adapter.prepare("INSERT INTO slices (milestone_id, id, created_at) VALUES (?, ?, '')").run('M001', 'S01');
|
|
408
|
+
adapter.prepare(
|
|
409
|
+
`INSERT INTO tasks (
|
|
410
|
+
milestone_id, slice_id, id, key_files, key_decisions, files, inputs, expected_output
|
|
411
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
412
|
+
).run(
|
|
413
|
+
'M001',
|
|
414
|
+
'S01',
|
|
415
|
+
'T01',
|
|
416
|
+
'[]',
|
|
417
|
+
'[]',
|
|
418
|
+
'tests/test_verify.py, config.yaml, configs/roster_2026-05-11.yaml',
|
|
419
|
+
'tests/test_verify.py',
|
|
420
|
+
'reports/summary.md, artifacts/output.json',
|
|
421
|
+
);
|
|
422
|
+
|
|
423
|
+
const task = getTask('M001', 'S01', 'T01');
|
|
424
|
+
assert.ok(task, 'task should load successfully from DB');
|
|
425
|
+
assert.deepEqual(task?.files, [
|
|
426
|
+
'tests/test_verify.py',
|
|
427
|
+
'config.yaml',
|
|
428
|
+
'configs/roster_2026-05-11.yaml',
|
|
429
|
+
]);
|
|
430
|
+
assert.deepEqual(task?.inputs, ['tests/test_verify.py']);
|
|
431
|
+
assert.deepEqual(task?.expected_output, ['reports/summary.md', 'artifacts/output.json']);
|
|
432
|
+
|
|
433
|
+
closeDatabase();
|
|
434
|
+
});
|
|
435
|
+
|
|
332
436
|
test('gsd-db: query wrappers return null/empty when DB unavailable', () => {
|
|
333
437
|
// Ensure DB is closed
|
|
334
438
|
closeDatabase();
|
|
@@ -347,15 +451,13 @@ describe('gsd-db', () => {
|
|
|
347
451
|
assert.deepStrictEqual(ar, [], 'getActiveRequirements returns [] when DB closed');
|
|
348
452
|
});
|
|
349
453
|
|
|
350
|
-
test('gsd-db: wasDbOpenAttempted
|
|
351
|
-
|
|
352
|
-
// (previous tests in this suite already called openDatabase, so the flag is set)
|
|
454
|
+
test('gsd-db: closeDatabase resets wasDbOpenAttempted after an intentional close', () => {
|
|
455
|
+
openDatabase(':memory:');
|
|
353
456
|
assert.ok(wasDbOpenAttempted(), 'wasDbOpenAttempted should be true after openDatabase was called');
|
|
354
457
|
|
|
355
|
-
// Verify the flag persists even after closeDatabase
|
|
356
458
|
closeDatabase();
|
|
357
459
|
assert.ok(!isDbAvailable(), 'DB should not be available after close');
|
|
358
|
-
assert.ok(wasDbOpenAttempted(), 'wasDbOpenAttempted should
|
|
460
|
+
assert.ok(!wasDbOpenAttempted(), 'wasDbOpenAttempted should reset after closeDatabase');
|
|
359
461
|
});
|
|
360
462
|
|
|
361
463
|
// ─── Final Report ──────────────────────────────────────────────────────────
|