gsd-pi 2.71.0 → 2.72.0-dev.de4c4b3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -17
- package/dist/cli.js +29 -3
- package/dist/headless-events.d.ts +2 -0
- package/dist/headless-events.js +7 -0
- package/dist/headless.js +16 -3
- package/dist/mcp-server.js +40 -17
- package/dist/provider-migrations.d.ts +10 -0
- package/dist/provider-migrations.js +12 -0
- package/dist/resource-loader.js +139 -13
- package/dist/resources/GSD-WORKFLOW.md +1 -1
- package/dist/resources/agents/debugger.md +58 -0
- package/dist/resources/agents/doc-writer.md +43 -0
- package/dist/resources/agents/git-ops.md +56 -0
- package/dist/resources/agents/javascript-pro.md +46 -271
- package/dist/resources/agents/planner.md +55 -0
- package/dist/resources/agents/refactorer.md +47 -0
- package/dist/resources/agents/reviewer.md +48 -0
- package/dist/resources/agents/security.md +59 -0
- package/dist/resources/agents/tester.md +50 -0
- package/dist/resources/agents/typescript-pro.md +41 -235
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +113 -10
- package/dist/resources/extensions/gsd/auto/infra-errors.js +34 -0
- package/dist/resources/extensions/gsd/auto/loop.js +32 -1
- package/dist/resources/extensions/gsd/auto/phases.js +5 -1
- package/dist/resources/extensions/gsd/auto/session.js +11 -0
- package/dist/resources/extensions/gsd/auto-dashboard.js +22 -16
- package/dist/resources/extensions/gsd/auto-model-selection.js +10 -2
- package/dist/resources/extensions/gsd/auto-prompts.js +88 -33
- package/dist/resources/extensions/gsd/auto-start.js +34 -7
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
- package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +56 -0
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +2 -0
- package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +63 -51
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +6 -0
- package/dist/resources/extensions/gsd/commands/context.js +15 -6
- package/dist/resources/extensions/gsd/commands/dispatcher.js +12 -2
- package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -33
- package/dist/resources/extensions/gsd/commands/handlers/core.js +56 -11
- package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +15 -6
- package/dist/resources/extensions/gsd/commands/handlers/workflow.js +4 -10
- package/dist/resources/extensions/gsd/dashboard-overlay.js +8 -3
- package/dist/resources/extensions/gsd/dispatch-guard.js +18 -1
- package/dist/resources/extensions/gsd/doctor-providers.js +23 -0
- package/dist/resources/extensions/gsd/error-classifier.js +5 -2
- package/dist/resources/extensions/gsd/forensics.js +19 -6
- package/dist/resources/extensions/gsd/gate-registry.js +208 -0
- package/dist/resources/extensions/gsd/gsd-db.js +41 -0
- package/dist/resources/extensions/gsd/guided-flow.js +5 -10
- package/dist/resources/extensions/gsd/metrics.js +1 -0
- package/dist/resources/extensions/gsd/milestone-actions.js +10 -4
- package/dist/resources/extensions/gsd/milestone-validation-gates.js +11 -12
- package/dist/resources/extensions/gsd/notification-overlay.js +42 -13
- package/dist/resources/extensions/gsd/notification-store.js +56 -5
- package/dist/resources/extensions/gsd/notification-widget.js +5 -13
- package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +8 -3
- package/dist/resources/extensions/gsd/pre-execution-checks.js +35 -2
- package/dist/resources/extensions/gsd/prompt-validation.js +126 -0
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/dist/resources/extensions/gsd/prompts/queue.md +3 -2
- package/dist/resources/extensions/gsd/prompts/system.md +1 -0
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/dist/resources/extensions/gsd/session-model-override.js +25 -0
- package/dist/resources/extensions/gsd/shortcut-defs.js +40 -0
- package/dist/resources/extensions/gsd/state.js +9 -2
- package/dist/resources/extensions/gsd/tools/complete-slice.js +52 -1
- package/dist/resources/extensions/gsd/tools/complete-task.js +51 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +4 -1
- package/dist/resources/extensions/ollama/index.js +13 -5
- package/dist/resources/extensions/shared/gsd-phase-state.js +35 -0
- package/dist/resources/extensions/subagent/agents.js +8 -0
- package/dist/resources/extensions/subagent/index.js +17 -0
- package/dist/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/startup-model-validation.d.ts +0 -1
- package/dist/startup-model-validation.js +6 -2
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
- package/dist/web/standalone/.next/build-manifest.json +3 -3
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/required-server-files.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
- package/dist/web/standalone/.next/server/chunks/63.js +3 -3
- package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware.js +2 -2
- package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
- package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
- package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
- package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
- package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
- package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
- package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
- package/dist/web/standalone/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/dist/server.d.ts +12 -1
- package/packages/mcp-server/dist/server.d.ts.map +1 -1
- package/packages/mcp-server/dist/server.js +90 -42
- package/packages/mcp-server/dist/server.js.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +22 -12
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/server.ts +110 -38
- package/packages/mcp-server/src/workflow-tools.test.ts +110 -0
- package/packages/mcp-server/src/workflow-tools.ts +32 -12
- package/packages/pi-ai/dist/providers/amazon-bedrock.js +11 -2
- package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts +2 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js +20 -0
- package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -0
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +4 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.js +8 -3
- package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js +44 -1
- package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts +2 -1
- package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/anthropic.js +7 -4
- package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
- package/packages/pi-ai/dist/providers/openai-completions.js +11 -0
- package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
- package/packages/pi-ai/src/providers/amazon-bedrock.ts +13 -1
- package/packages/pi-ai/src/providers/anthropic-auth.test.ts +32 -0
- package/packages/pi-ai/src/providers/anthropic-shared.test.ts +55 -1
- package/packages/pi-ai/src/providers/anthropic-shared.ts +14 -3
- package/packages/pi-ai/src/providers/anthropic.ts +8 -4
- package/packages/pi-ai/src/providers/openai-completions.ts +14 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js +61 -0
- package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js +2 -1
- package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +10 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +27 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js +85 -0
- package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js +64 -0
- package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +22 -18
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts +8 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js +75 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +5 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js +55 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js +57 -0
- package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts +11 -0
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +38 -5
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js +71 -0
- package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/index.d.ts +1 -1
- package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/index.js +1 -1
- package/packages/pi-coding-agent/dist/index.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts +2 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js +13 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js.map +1 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +24 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
- package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +4 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +43 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +7 -2
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +6 -1
- package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +4 -3
- package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +4 -2
- package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/agent-session-renderable-tools.test.ts +70 -0
- package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
- package/packages/pi-coding-agent/src/core/auth-storage.test.ts +108 -0
- package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -0
- package/packages/pi-coding-agent/src/core/model-resolver-initial-model-auth.test.ts +78 -0
- package/packages/pi-coding-agent/src/core/model-resolver.test.ts +85 -0
- package/packages/pi-coding-agent/src/core/model-resolver.ts +22 -18
- package/packages/pi-coding-agent/src/core/retry-handler.test.ts +83 -0
- package/packages/pi-coding-agent/src/core/retry-handler.ts +60 -1
- package/packages/pi-coding-agent/src/core/sdk.test.ts +89 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +45 -9
- package/packages/pi-coding-agent/src/index.ts +1 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/login-dialog.test.ts +24 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +30 -2
- package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +15 -6
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +47 -0
- package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +7 -2
- package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +6 -1
- package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +4 -3
- package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +4 -2
- package/pkg/package.json +1 -1
- package/src/resources/GSD-WORKFLOW.md +1 -1
- package/src/resources/agents/debugger.md +58 -0
- package/src/resources/agents/doc-writer.md +43 -0
- package/src/resources/agents/git-ops.md +56 -0
- package/src/resources/agents/javascript-pro.md +46 -271
- package/src/resources/agents/planner.md +55 -0
- package/src/resources/agents/refactorer.md +47 -0
- package/src/resources/agents/reviewer.md +48 -0
- package/src/resources/agents/security.md +59 -0
- package/src/resources/agents/tester.md +50 -0
- package/src/resources/agents/typescript-pro.md +41 -235
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +122 -8
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +189 -6
- package/src/resources/extensions/gsd/auto/infra-errors.ts +38 -0
- package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
- package/src/resources/extensions/gsd/auto/loop.ts +45 -1
- package/src/resources/extensions/gsd/auto/phases.ts +6 -0
- package/src/resources/extensions/gsd/auto/session.ts +11 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +29 -18
- package/src/resources/extensions/gsd/auto-model-selection.ts +9 -1
- package/src/resources/extensions/gsd/auto-prompts.ts +111 -33
- package/src/resources/extensions/gsd/auto-start.ts +41 -7
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
- package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +72 -0
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +2 -0
- package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +79 -60
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +7 -0
- package/src/resources/extensions/gsd/commands/context.ts +16 -5
- package/src/resources/extensions/gsd/commands/dispatcher.ts +14 -2
- package/src/resources/extensions/gsd/commands/handlers/auto.ts +10 -36
- package/src/resources/extensions/gsd/commands/handlers/core.ts +58 -11
- package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +17 -7
- package/src/resources/extensions/gsd/commands/handlers/workflow.ts +4 -10
- package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -3
- package/src/resources/extensions/gsd/dispatch-guard.ts +18 -1
- package/src/resources/extensions/gsd/doctor-providers.ts +24 -0
- package/src/resources/extensions/gsd/error-classifier.ts +5 -2
- package/src/resources/extensions/gsd/forensics.ts +23 -7
- package/src/resources/extensions/gsd/gate-registry.ts +251 -0
- package/src/resources/extensions/gsd/gsd-db.ts +51 -0
- package/src/resources/extensions/gsd/guided-flow.ts +5 -10
- package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
- package/src/resources/extensions/gsd/metrics.ts +12 -1
- package/src/resources/extensions/gsd/milestone-actions.ts +10 -3
- package/src/resources/extensions/gsd/milestone-validation-gates.ts +11 -13
- package/src/resources/extensions/gsd/notification-overlay.ts +47 -14
- package/src/resources/extensions/gsd/notification-store.ts +54 -5
- package/src/resources/extensions/gsd/notification-widget.ts +5 -14
- package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -3
- package/src/resources/extensions/gsd/pre-execution-checks.ts +39 -2
- package/src/resources/extensions/gsd/prompt-validation.ts +157 -0
- package/src/resources/extensions/gsd/prompts/complete-slice.md +5 -3
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +22 -19
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
- package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
- package/src/resources/extensions/gsd/prompts/queue.md +3 -2
- package/src/resources/extensions/gsd/prompts/system.md +1 -0
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
- package/src/resources/extensions/gsd/session-model-override.ts +36 -0
- package/src/resources/extensions/gsd/shortcut-defs.ts +56 -0
- package/src/resources/extensions/gsd/state.ts +13 -2
- package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +25 -9
- package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +28 -0
- package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +39 -0
- package/src/resources/extensions/gsd/tests/complete-slice-gate-closure.test.ts +167 -0
- package/src/resources/extensions/gsd/tests/complete-slice-prompt-task-summary-layout.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/execute-task-prompt-existing-artifact-guard.test.ts +33 -0
- package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +31 -0
- package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/gate-registry.test.ts +140 -0
- package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +73 -0
- package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +180 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +66 -1
- package/src/resources/extensions/gsd/tests/model-isolation.test.ts +36 -51
- package/src/resources/extensions/gsd/tests/notification-store.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/notification-widget.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +49 -0
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/prompt-system-gate-coverage.test.ts +208 -0
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +63 -5
- package/src/resources/extensions/gsd/tests/session-model-override.test.ts +35 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +90 -0
- package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +7 -0
- package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +18 -0
- package/src/resources/extensions/gsd/tools/complete-slice.ts +63 -0
- package/src/resources/extensions/gsd/tools/complete-task.ts +63 -0
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +4 -1
- package/src/resources/extensions/gsd/types.ts +26 -0
- package/src/resources/extensions/ollama/index.ts +13 -3
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
- package/src/resources/extensions/shared/gsd-phase-state.ts +42 -0
- package/src/resources/extensions/shared/tests/gsd-phase-state.test.ts +48 -0
- package/src/resources/extensions/subagent/agents.ts +10 -0
- package/src/resources/extensions/subagent/index.ts +18 -0
- package/src/resources/extensions/subagent/tests/agents-conflicts.test.ts +33 -0
- package/src/resources/skills/create-skill/SKILL.md +2 -0
- package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
- package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
- package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → f-Gremw0nLxxFUySaHRPw}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → f-Gremw0nLxxFUySaHRPw}/_ssgManifest.js +0 -0
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");
|
|
@@ -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
|
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { mkdtempSync, mkdirSync, rmSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
|
|
7
|
+
import { initNotificationStore, appendNotification, _resetNotificationStore } from "../notification-store.js";
|
|
8
|
+
import { buildNotificationWidgetLines } from "../notification-widget.js";
|
|
9
|
+
|
|
10
|
+
test("buildNotificationWidgetLines shows unread count with shortcut pair", () => {
|
|
11
|
+
const tmp = mkdtempSync(join(tmpdir(), "gsd-notification-widget-"));
|
|
12
|
+
try {
|
|
13
|
+
mkdirSync(join(tmp, ".gsd"), { recursive: true });
|
|
14
|
+
_resetNotificationStore();
|
|
15
|
+
initNotificationStore(tmp);
|
|
16
|
+
appendNotification("Need attention", "warning");
|
|
17
|
+
|
|
18
|
+
const lines = buildNotificationWidgetLines();
|
|
19
|
+
assert.equal(lines.length, 1);
|
|
20
|
+
assert.match(lines[0]!, /Notifications:\s+1 unread/);
|
|
21
|
+
assert.match(lines[0]!, /\(.+\/.+\)/);
|
|
22
|
+
} finally {
|
|
23
|
+
_resetNotificationStore();
|
|
24
|
+
rmSync(tmp, { recursive: true, force: true });
|
|
25
|
+
}
|
|
26
|
+
});
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import test from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { mkdirSync, rmSync } from "node:fs";
|
|
6
|
+
|
|
7
|
+
import { handleNotificationsCommand } from "../commands/handlers/notifications-handler.ts";
|
|
8
|
+
import {
|
|
9
|
+
_resetNotificationStore,
|
|
10
|
+
appendNotification,
|
|
11
|
+
initNotificationStore,
|
|
12
|
+
} from "../notification-store.ts";
|
|
13
|
+
|
|
14
|
+
function makeTempDir(prefix: string): string {
|
|
15
|
+
const dir = join(
|
|
16
|
+
tmpdir(),
|
|
17
|
+
`gsd-notifications-handler-test-${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
|
|
18
|
+
);
|
|
19
|
+
mkdirSync(dir, { recursive: true });
|
|
20
|
+
mkdirSync(join(dir, ".gsd"), { recursive: true });
|
|
21
|
+
return dir;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function cleanup(dir: string): void {
|
|
25
|
+
try {
|
|
26
|
+
rmSync(dir, { recursive: true, force: true });
|
|
27
|
+
} catch {
|
|
28
|
+
// best-effort
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
test("notifications command falls back to text output when overlay returns undefined", async (t) => {
|
|
33
|
+
const base = makeTempDir("overlay-fallback");
|
|
34
|
+
initNotificationStore(base);
|
|
35
|
+
appendNotification("Build complete", "success");
|
|
36
|
+
|
|
37
|
+
t.after(() => {
|
|
38
|
+
_resetNotificationStore();
|
|
39
|
+
cleanup(base);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const notices: Array<{ message: string; level?: string }> = [];
|
|
43
|
+
await handleNotificationsCommand(
|
|
44
|
+
"",
|
|
45
|
+
{
|
|
46
|
+
hasUI: true,
|
|
47
|
+
ui: {
|
|
48
|
+
custom: async () => undefined,
|
|
49
|
+
notify: (message: string, level?: string) => {
|
|
50
|
+
notices.push({ message, level });
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
} as any,
|
|
54
|
+
{} as any,
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
assert.equal(notices.length, 1, "text fallback should be emitted when overlay cannot render");
|
|
58
|
+
assert.match(notices[0].message, /Recent notifications:/);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test("notifications tail caps inline output and hints to open overlay", async (t) => {
|
|
62
|
+
const base = makeTempDir("tail-cap");
|
|
63
|
+
initNotificationStore(base);
|
|
64
|
+
for (let i = 0; i < 55; i++) {
|
|
65
|
+
appendNotification(`notification-${i + 1}`, "info");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
t.after(() => {
|
|
69
|
+
_resetNotificationStore();
|
|
70
|
+
cleanup(base);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const notices: Array<{ message: string; level?: string }> = [];
|
|
74
|
+
await handleNotificationsCommand(
|
|
75
|
+
"tail 200",
|
|
76
|
+
{
|
|
77
|
+
hasUI: true,
|
|
78
|
+
ui: {
|
|
79
|
+
notify: (message: string, level?: string) => {
|
|
80
|
+
notices.push({ message, level });
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
} as any,
|
|
84
|
+
{} as any,
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
assert.equal(notices.length, 1);
|
|
88
|
+
assert.match(notices[0].message, /Last 40 notification\(s\):/);
|
|
89
|
+
assert.match(notices[0].message, /\.\.\. and \d+ more \(open \/gsd notifications to browse all\)/);
|
|
90
|
+
});
|
|
@@ -69,6 +69,24 @@ test("unparkMilestone updates DB status to 'active' (#2694)", () => {
|
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
71
|
|
|
72
|
+
test("unparkMilestone repairs parked DB state when PARKED.md is missing (#3707)", () => {
|
|
73
|
+
const base = createBase();
|
|
74
|
+
try {
|
|
75
|
+
openDatabase(":memory:");
|
|
76
|
+
insertMilestone({ id: "M001", title: "Test", status: "parked" });
|
|
77
|
+
|
|
78
|
+
const unparked = unparkMilestone(base, "M001");
|
|
79
|
+
|
|
80
|
+
assert.ok(unparked, "unparkMilestone should recover DB-only parked state");
|
|
81
|
+
assert.equal(getMilestone("M001")!.status, "active", "DB status should be repaired to active");
|
|
82
|
+
|
|
83
|
+
closeDatabase();
|
|
84
|
+
} finally {
|
|
85
|
+
closeDatabase();
|
|
86
|
+
rmSync(base, { recursive: true, force: true });
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
72
90
|
test("park/unpark are safe when DB is not available (#2694 guard)", () => {
|
|
73
91
|
const base = createBase();
|
|
74
92
|
try {
|
|
@@ -1107,6 +1107,38 @@ describe("checkTaskOrdering false positive regression (#3677)", () => {
|
|
|
1107
1107
|
assert.equal(results[0].target, "`later.ts` — needed first");
|
|
1108
1108
|
assert.ok(results[0].message.includes("sequence violation"));
|
|
1109
1109
|
});
|
|
1110
|
+
|
|
1111
|
+
test("existing on-disk files do not trigger ordering violations just because a later task modifies them", () => {
|
|
1112
|
+
const tempDir = join(tmpdir(), `pre-exec-ordering-existing-file-${Date.now()}`);
|
|
1113
|
+
const existingFile = "frontend/src/__tests__/ProcurementPage29.test.tsx";
|
|
1114
|
+
|
|
1115
|
+
mkdirSync(join(tempDir, "frontend", "src", "__tests__"), { recursive: true });
|
|
1116
|
+
writeFileSync(join(tempDir, existingFile), "// existing file");
|
|
1117
|
+
|
|
1118
|
+
try {
|
|
1119
|
+
const tasks = [
|
|
1120
|
+
createTask({
|
|
1121
|
+
id: "T01",
|
|
1122
|
+
sequence: 0,
|
|
1123
|
+
files: [],
|
|
1124
|
+
inputs: ["`frontend/src/__tests__/ProcurementPage29.test.tsx` — contains matchMedia stub to remove"],
|
|
1125
|
+
expected_output: [],
|
|
1126
|
+
}),
|
|
1127
|
+
createTask({
|
|
1128
|
+
id: "T03",
|
|
1129
|
+
sequence: 2,
|
|
1130
|
+
files: [],
|
|
1131
|
+
inputs: [],
|
|
1132
|
+
expected_output: ["frontend/src/__tests__/ProcurementPage29.test.tsx"],
|
|
1133
|
+
}),
|
|
1134
|
+
];
|
|
1135
|
+
|
|
1136
|
+
const results = checkTaskOrdering(tasks, tempDir);
|
|
1137
|
+
assert.equal(results.length, 0, "Pre-existing files should not be treated as created by later tasks");
|
|
1138
|
+
} finally {
|
|
1139
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1110
1142
|
});
|
|
1111
1143
|
|
|
1112
1144
|
// ─── checkFilePathConsistency additional edge cases ──────────────────────────
|
|
@@ -1175,6 +1207,23 @@ describe("checkFilePathConsistency additional edge cases", () => {
|
|
|
1175
1207
|
assert.equal(results![0].blocking, true);
|
|
1176
1208
|
});
|
|
1177
1209
|
|
|
1210
|
+
test("multi-word prose inputs are ignored by path consistency checks", () => {
|
|
1211
|
+
const tasks = [
|
|
1212
|
+
createTask({
|
|
1213
|
+
id: "T01",
|
|
1214
|
+
files: [],
|
|
1215
|
+
inputs: [
|
|
1216
|
+
"Current WIZARD_PRODUCTS enum",
|
|
1217
|
+
"Existing test patterns in wizard.test.ts",
|
|
1218
|
+
],
|
|
1219
|
+
expected_output: [],
|
|
1220
|
+
}),
|
|
1221
|
+
];
|
|
1222
|
+
|
|
1223
|
+
const results = checkFilePathConsistency(tasks, "/tmp");
|
|
1224
|
+
assert.equal(results.length, 0, "Prose planning hints should not be treated as missing file paths");
|
|
1225
|
+
});
|
|
1226
|
+
|
|
1178
1227
|
test("empty inputs array produces no results", () => {
|
|
1179
1228
|
// A task with no inputs and only files should produce zero results from
|
|
1180
1229
|
// consistency check — files are not checked (#3626).
|
|
@@ -42,9 +42,19 @@ test("system prompt references CODEBASE.md and /gsd codebase", () => {
|
|
|
42
42
|
assert.match(prompt, /auto-refreshes it when tracked files change/i);
|
|
43
43
|
});
|
|
44
44
|
|
|
45
|
+
test("system prompt hard rules forbid fabricating user responses", () => {
|
|
46
|
+
const prompt = readPrompt("system");
|
|
47
|
+
assert.match(prompt, /never fabricate, simulate, or role-play user responses/i);
|
|
48
|
+
assert.match(prompt, /never generate markers like `?\[User\]`?, `?\[Human\]`?, `?User:`?/i);
|
|
49
|
+
assert.match(prompt, /ask one question round \(1-3 questions\), then stop and wait for the user's actual response/i);
|
|
50
|
+
assert.match(prompt, /ask_user_questions.*only valid structured user input/i);
|
|
51
|
+
});
|
|
52
|
+
|
|
45
53
|
test("discuss prompt allows implementation questions when they materially matter", () => {
|
|
46
54
|
const prompt = readPrompt("discuss");
|
|
47
55
|
assert.match(prompt, /Lead with experience, but ask implementation when it materially matters/i);
|
|
56
|
+
assert.match(prompt, /Never fabricate, simulate, or role-play user responses/i);
|
|
57
|
+
assert.match(prompt, /Ask one question round \(1-3 questions\) per turn, then stop and wait for the user's actual response/i);
|
|
48
58
|
assert.match(prompt, /one gate, not two/i);
|
|
49
59
|
assert.doesNotMatch(prompt, /Questions must be about the experience, not the implementation/i);
|
|
50
60
|
});
|
|
@@ -56,6 +66,8 @@ test("guided discussion prompts avoid wrap-up prompts after every round", () =>
|
|
|
56
66
|
assert.match(slicePrompt, /Do \*\*not\*\* ask a meta "ready to wrap up\?" question after every round/i);
|
|
57
67
|
assert.doesNotMatch(milestonePrompt, /I think I have a solid picture of this milestone\. Ready to wrap up/i);
|
|
58
68
|
assert.doesNotMatch(slicePrompt, /I think I have a solid picture of this slice\. Ready to wrap up/i);
|
|
69
|
+
assert.match(milestonePrompt, /Never fabricate or simulate user input/i);
|
|
70
|
+
assert.match(slicePrompt, /Never fabricate or simulate user input/i);
|
|
59
71
|
});
|
|
60
72
|
|
|
61
73
|
test("guided milestone discussion scopes depth verification to the milestone id", () => {
|
|
@@ -64,6 +76,13 @@ test("guided milestone discussion scopes depth verification to the milestone id"
|
|
|
64
76
|
assert.doesNotMatch(prompt, /depth_verification_confirm" — this enables the write-gate downstream/i, "legacy global depth gate wording should be gone");
|
|
65
77
|
});
|
|
66
78
|
|
|
79
|
+
test("queue prompt requires waiting for user response between rounds", () => {
|
|
80
|
+
const prompt = readPrompt("queue");
|
|
81
|
+
assert.match(prompt, /Never fabricate or simulate user input during this discussion/i);
|
|
82
|
+
assert.match(prompt, /Ask 1-3 questions per round, then wait for the user's response before asking the next round\./i);
|
|
83
|
+
assert.doesNotMatch(prompt, /treat that as permission to continue/i);
|
|
84
|
+
});
|
|
85
|
+
|
|
67
86
|
test("guided-resume-task prompt preserves recovery state until work is superseded", () => {
|
|
68
87
|
const prompt = readPrompt("guided-resume-task");
|
|
69
88
|
assert.match(prompt, /Do \*\*not\*\* delete the continue file immediately/i);
|