gsd-pi 2.71.0 → 2.72.0
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 +8 -8
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- 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.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- 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/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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 +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- 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/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/{nPky_WQC28aBD77eZsRAB → Y0I7CjXJl-tWoV__KidV4}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{nPky_WQC28aBD77eZsRAB → Y0I7CjXJl-tWoV__KidV4}/_ssgManifest.js +0 -0
|
@@ -24,7 +24,13 @@ import { getLoadedSkills, type Skill } from "@gsd/pi-coding-agent";
|
|
|
24
24
|
import { join, basename } from "node:path";
|
|
25
25
|
import { existsSync } from "node:fs";
|
|
26
26
|
import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary } from "./context-budget.js";
|
|
27
|
-
import { getPendingGates } from "./gsd-db.js";
|
|
27
|
+
import { getPendingGates, getPendingGatesForTurn } from "./gsd-db.js";
|
|
28
|
+
import {
|
|
29
|
+
GATE_REGISTRY,
|
|
30
|
+
assertGateCoverage,
|
|
31
|
+
getGatesForTurn,
|
|
32
|
+
type GateDefinition,
|
|
33
|
+
} from "./gate-registry.js";
|
|
28
34
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
29
35
|
import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
|
|
30
36
|
import { logWarning } from "./workflow-logger.js";
|
|
@@ -1395,6 +1401,17 @@ export async function buildExecuteTaskPrompt(
|
|
|
1395
1401
|
|
|
1396
1402
|
const phaseAnchorSection = planAnchor ? formatAnchorForPrompt(planAnchor) : "";
|
|
1397
1403
|
|
|
1404
|
+
// Task-scoped gates owned by execute-task (Q5/Q6/Q7). Pull only the
|
|
1405
|
+
// gates that plan-slice actually seeded for this task — tasks with no
|
|
1406
|
+
// external dependencies legitimately skip Q5, tasks with no runtime
|
|
1407
|
+
// load dimension skip Q6, etc.
|
|
1408
|
+
const etPending = getPendingGatesForTurn(mid, sid, "execute-task", tid);
|
|
1409
|
+
assertGateCoverage(etPending, "execute-task", { requireAll: false });
|
|
1410
|
+
const gatesToClose = renderGatesToCloseBlock(
|
|
1411
|
+
getGatesForTurn("execute-task"),
|
|
1412
|
+
{ pending: new Set(etPending.map((g) => g.gate_id)), allowOmit: true },
|
|
1413
|
+
);
|
|
1414
|
+
|
|
1398
1415
|
return loadPrompt("execute-task", {
|
|
1399
1416
|
overridesSection,
|
|
1400
1417
|
runtimeContext,
|
|
@@ -1412,6 +1429,7 @@ export async function buildExecuteTaskPrompt(
|
|
|
1412
1429
|
taskSummaryPath,
|
|
1413
1430
|
inlinedTemplates,
|
|
1414
1431
|
verificationBudget,
|
|
1432
|
+
gatesToClose,
|
|
1415
1433
|
skillActivation: buildSkillActivationBlock({
|
|
1416
1434
|
base,
|
|
1417
1435
|
milestoneId: mid,
|
|
@@ -1477,6 +1495,19 @@ export async function buildCompleteSlicePrompt(
|
|
|
1477
1495
|
const sliceSummaryPath = join(base, `${sliceRel}/${sid}-SUMMARY.md`);
|
|
1478
1496
|
const sliceUatPath = join(base, `${sliceRel}/${sid}-UAT.md`);
|
|
1479
1497
|
|
|
1498
|
+
// Gates owned by complete-slice (e.g. Q8). Pull from the DB so the
|
|
1499
|
+
// prompt only prompts for gates the plan actually seeded. The tool
|
|
1500
|
+
// handler closes each gate based on the SUMMARY.md section content
|
|
1501
|
+
// after the assistant calls gsd_complete_slice.
|
|
1502
|
+
const csPending = getPendingGatesForTurn(mid, sid, "complete-slice");
|
|
1503
|
+
// coverage check: every pending row must be owned by complete-slice.
|
|
1504
|
+
// requireAll:false because a slice may have already closed some gates.
|
|
1505
|
+
assertGateCoverage(csPending, "complete-slice", { requireAll: false });
|
|
1506
|
+
const gatesToClose = renderGatesToCloseBlock(
|
|
1507
|
+
getGatesForTurn("complete-slice"),
|
|
1508
|
+
{ pending: new Set(csPending.map((g) => g.gate_id)), allowOmit: true },
|
|
1509
|
+
);
|
|
1510
|
+
|
|
1480
1511
|
return loadPrompt("complete-slice", {
|
|
1481
1512
|
workingDirectory: base,
|
|
1482
1513
|
milestoneId: mid, sliceId: sid, sliceTitle: sTitle,
|
|
@@ -1485,6 +1516,7 @@ export async function buildCompleteSlicePrompt(
|
|
|
1485
1516
|
inlinedContext,
|
|
1486
1517
|
sliceSummaryPath,
|
|
1487
1518
|
sliceUatPath,
|
|
1519
|
+
gatesToClose,
|
|
1488
1520
|
});
|
|
1489
1521
|
}
|
|
1490
1522
|
|
|
@@ -1675,6 +1707,16 @@ export async function buildValidateMilestonePrompt(
|
|
|
1675
1707
|
const validationOutputPath = join(base, `${relMilestonePath(base, mid)}/${mid}-VALIDATION.md`);
|
|
1676
1708
|
const roadmapOutputPath = `${relMilestonePath(base, mid)}/${mid}-ROADMAP.md`;
|
|
1677
1709
|
|
|
1710
|
+
// Every milestone validation turn owns MV01–MV04 unconditionally: the
|
|
1711
|
+
// registry is the source of truth for which gates the validator must
|
|
1712
|
+
// address, and the block below is what the template renders so the
|
|
1713
|
+
// assistant can never accidentally skip one.
|
|
1714
|
+
const mvGates = getGatesForTurn("validate-milestone");
|
|
1715
|
+
const gatesToEvaluate = renderGatesToCloseBlock(mvGates, {
|
|
1716
|
+
pending: new Set(mvGates.map((g) => g.id)),
|
|
1717
|
+
allowOmit: false,
|
|
1718
|
+
});
|
|
1719
|
+
|
|
1678
1720
|
return loadPrompt("validate-milestone", {
|
|
1679
1721
|
workingDirectory: base,
|
|
1680
1722
|
milestoneId: mid,
|
|
@@ -1683,6 +1725,7 @@ export async function buildValidateMilestonePrompt(
|
|
|
1683
1725
|
inlinedContext,
|
|
1684
1726
|
validationPath: validationOutputPath,
|
|
1685
1727
|
remediationRound: String(remediationRound),
|
|
1728
|
+
gatesToEvaluate,
|
|
1686
1729
|
skillActivation: buildSkillActivationBlock({
|
|
1687
1730
|
base,
|
|
1688
1731
|
milestoneId: mid,
|
|
@@ -1955,27 +1998,51 @@ export async function buildReactiveExecutePrompt(
|
|
|
1955
1998
|
}
|
|
1956
1999
|
|
|
1957
2000
|
// ─── Gate Evaluation ──────────────────────────────────────────────────────
|
|
2001
|
+
//
|
|
2002
|
+
// Gate definitions (question, guidance, owner turn) now live in
|
|
2003
|
+
// gate-registry.ts so that prompt builders, dispatch rules, state
|
|
2004
|
+
// derivation, and tool handlers all consult the same source of truth.
|
|
2005
|
+
// See gate-registry.ts for the full ownership map.
|
|
1958
2006
|
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2007
|
+
/**
|
|
2008
|
+
* Render a "Gates to Close" block for turns like `complete-slice` and
|
|
2009
|
+
* `validate-milestone` that own gates which are closed as a side-effect
|
|
2010
|
+
* of writing artifact sections (not via a dedicated gate-evaluate
|
|
2011
|
+
* subagent loop).
|
|
2012
|
+
*
|
|
2013
|
+
* Returns a plain-text block or an empty string if there are no gates to
|
|
2014
|
+
* close, so callers can drop it straight into a template variable.
|
|
2015
|
+
*/
|
|
2016
|
+
function renderGatesToCloseBlock(
|
|
2017
|
+
gates: ReadonlyArray<GateDefinition>,
|
|
2018
|
+
opts: { pending: ReadonlySet<string>; allowOmit: boolean },
|
|
2019
|
+
): string {
|
|
2020
|
+
const applicable = gates.filter((g) => opts.pending.has(g.id));
|
|
2021
|
+
if (applicable.length === 0) return "";
|
|
2022
|
+
|
|
2023
|
+
const lines: string[] = [];
|
|
2024
|
+
lines.push("## Gates to Close");
|
|
2025
|
+
lines.push("");
|
|
2026
|
+
lines.push(
|
|
2027
|
+
"These quality gates are still pending for this unit. You MUST address every one before calling the closing tool — the handler closes the DB row based on whether the corresponding artifact section is present.",
|
|
2028
|
+
);
|
|
2029
|
+
lines.push("");
|
|
2030
|
+
for (const def of applicable) {
|
|
2031
|
+
lines.push(`### ${def.id} — ${def.promptSection}`);
|
|
2032
|
+
lines.push("");
|
|
2033
|
+
lines.push(`**Question:** ${def.question}`);
|
|
2034
|
+
lines.push("");
|
|
2035
|
+
lines.push(def.guidance);
|
|
2036
|
+
if (opts.allowOmit) {
|
|
2037
|
+
lines.push("");
|
|
2038
|
+
lines.push(
|
|
2039
|
+
`If this gate genuinely does not apply to this unit, leave the **${def.promptSection}** section empty and the handler will record it as \`omitted\`. Otherwise, fill the section with concrete evidence.`,
|
|
2040
|
+
);
|
|
2041
|
+
}
|
|
2042
|
+
lines.push("");
|
|
2043
|
+
}
|
|
2044
|
+
return lines.join("\n").trimEnd();
|
|
2045
|
+
}
|
|
1979
2046
|
|
|
1980
2047
|
export async function buildParallelResearchSlicesPrompt(
|
|
1981
2048
|
mid: string,
|
|
@@ -2011,28 +2078,39 @@ export async function buildGateEvaluatePrompt(
|
|
|
2011
2078
|
mid: string, midTitle: string, sid: string, sTitle: string,
|
|
2012
2079
|
base: string,
|
|
2013
2080
|
): Promise<string> {
|
|
2014
|
-
|
|
2081
|
+
// Pull only the gates this turn actually owns (Q3/Q4). Filter via the
|
|
2082
|
+
// registry so that scope:"slice" gates owned by other turns (Q8) can't
|
|
2083
|
+
// leak into this prompt and can't block dispatch via silent skip.
|
|
2084
|
+
const pending = getPendingGatesForTurn(mid, sid, "gate-evaluate");
|
|
2085
|
+
|
|
2086
|
+
// Fails loudly if the pending list contains a gate id the registry
|
|
2087
|
+
// doesn't own for this turn. Missing owned gates is allowed here —
|
|
2088
|
+
// `gate-evaluate` is dispatched whenever *any* of its owned gates are
|
|
2089
|
+
// pending, not only when all of them are.
|
|
2090
|
+
assertGateCoverage(pending, "gate-evaluate", { requireAll: false });
|
|
2015
2091
|
|
|
2016
2092
|
// Load the slice plan for context
|
|
2017
2093
|
const planFile = resolveSliceFile(base, mid, sid, "PLAN");
|
|
2018
2094
|
const planContent = planFile ? (await loadFile(planFile)) ?? "(plan file empty)" : "(plan file not found)";
|
|
2019
2095
|
|
|
2020
|
-
// Build per-gate subagent prompts
|
|
2096
|
+
// Build per-gate subagent prompts from the pending rows. Because the
|
|
2097
|
+
// registry has already validated every row, `getGateDefinition` cannot
|
|
2098
|
+
// return undefined here.
|
|
2099
|
+
const pendingIds = new Set(pending.map((g) => g.gate_id));
|
|
2100
|
+
const gateDefs = getGatesForTurn("gate-evaluate").filter((def) => pendingIds.has(def.id));
|
|
2101
|
+
|
|
2021
2102
|
const subagentSections: string[] = [];
|
|
2022
2103
|
const gateListLines: string[] = [];
|
|
2023
2104
|
|
|
2024
|
-
for (const
|
|
2025
|
-
|
|
2026
|
-
if (!meta) continue;
|
|
2027
|
-
|
|
2028
|
-
gateListLines.push(`- **${gate.gate_id}**: ${meta.question}`);
|
|
2105
|
+
for (const def of gateDefs) {
|
|
2106
|
+
gateListLines.push(`- **${def.id}**: ${def.question}`);
|
|
2029
2107
|
|
|
2030
2108
|
const subPrompt = [
|
|
2031
|
-
`You are evaluating quality gate **${
|
|
2109
|
+
`You are evaluating quality gate **${def.id}** for slice ${sid} (${sTitle}).`,
|
|
2032
2110
|
"",
|
|
2033
|
-
`## Question: ${
|
|
2111
|
+
`## Question: ${def.question}`,
|
|
2034
2112
|
"",
|
|
2035
|
-
|
|
2113
|
+
def.guidance,
|
|
2036
2114
|
"",
|
|
2037
2115
|
"## Slice Plan",
|
|
2038
2116
|
"",
|
|
@@ -2044,14 +2122,14 @@ export async function buildGateEvaluatePrompt(
|
|
|
2044
2122
|
`Call the \`gsd_save_gate_result\` tool with:`,
|
|
2045
2123
|
`- \`milestoneId\`: "${mid}"`,
|
|
2046
2124
|
`- \`sliceId\`: "${sid}"`,
|
|
2047
|
-
`- \`gateId\`: "${
|
|
2125
|
+
`- \`gateId\`: "${def.id}"`,
|
|
2048
2126
|
"- `verdict`: \"pass\" (no concerns), \"flag\" (concerns found), or \"omitted\" (not applicable)",
|
|
2049
2127
|
"- `rationale`: one-sentence justification",
|
|
2050
2128
|
"- `findings`: detailed markdown findings (or empty if omitted)",
|
|
2051
2129
|
].join("\n");
|
|
2052
2130
|
|
|
2053
2131
|
subagentSections.push([
|
|
2054
|
-
`### ${
|
|
2132
|
+
`### ${def.id}: ${def.question}`,
|
|
2055
2133
|
"",
|
|
2056
2134
|
"Use this as the prompt for a `subagent` call:",
|
|
2057
2135
|
"",
|
|
@@ -85,6 +85,7 @@ import { sep as pathSep } from "node:path";
|
|
|
85
85
|
import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
|
|
86
86
|
import { resolveDefaultSessionModel, resolveDynamicRoutingConfig } from "./preferences-models.js";
|
|
87
87
|
import type { WorktreeResolver } from "./worktree-resolver.js";
|
|
88
|
+
import { getSessionModelOverride } from "./session-model-override.js";
|
|
88
89
|
|
|
89
90
|
export interface BootstrapDeps {
|
|
90
91
|
shouldUseWorktreeIsolation: () => boolean;
|
|
@@ -266,13 +267,42 @@ export async function bootstrapAutoSession(
|
|
|
266
267
|
// Capture the user's session model before guided-flow dispatch can apply a
|
|
267
268
|
// phase-specific planning model for a discuss turn (#2829).
|
|
268
269
|
//
|
|
269
|
-
//
|
|
270
|
-
//
|
|
271
|
-
//
|
|
272
|
-
//
|
|
270
|
+
// Precedence:
|
|
271
|
+
// 1) Explicit session override via /gsd model (this session)
|
|
272
|
+
// 2) GSD model preferences from PREFERENCES.md (validated against live auth)
|
|
273
|
+
// 3) Current session model from settings/session restore (if provider ready)
|
|
274
|
+
//
|
|
275
|
+
// This preserves #3517 defaults while honoring explicit runtime model
|
|
276
|
+
// selection for subsequent /gsd runs in the same session.
|
|
277
|
+
const manualSessionOverride = getSessionModelOverride(ctx.sessionManager.getSessionId());
|
|
273
278
|
const preferredModel = resolveDefaultSessionModel(ctx.model?.provider);
|
|
274
|
-
|
|
275
|
-
|
|
279
|
+
// Validate the preferred model against the live registry + provider auth so
|
|
280
|
+
// an unconfigured PREFERENCES.md entry (no API key / OAuth) can't become the
|
|
281
|
+
// start-model snapshot. Without this, every subsequent unit would try to
|
|
282
|
+
// fall back to an unusable model.
|
|
283
|
+
let validatedPreferredModel: { provider: string; id: string } | undefined;
|
|
284
|
+
if (preferredModel) {
|
|
285
|
+
const { resolveModelId } = await import("./auto-model-selection.js");
|
|
286
|
+
const available = ctx.modelRegistry.getAvailable();
|
|
287
|
+
const match = resolveModelId(
|
|
288
|
+
`${preferredModel.provider}/${preferredModel.id}`,
|
|
289
|
+
available,
|
|
290
|
+
ctx.model?.provider,
|
|
291
|
+
);
|
|
292
|
+
if (match) {
|
|
293
|
+
validatedPreferredModel = { provider: match.provider, id: match.id };
|
|
294
|
+
} else {
|
|
295
|
+
ctx.ui.notify(
|
|
296
|
+
`Preferred model ${preferredModel.provider}/${preferredModel.id} from PREFERENCES.md is not configured; falling back to session default.`,
|
|
297
|
+
"warning",
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const sessionModelReady =
|
|
302
|
+
ctx.model && ctx.modelRegistry.isProviderRequestReady(ctx.model.provider);
|
|
303
|
+
const startModelSnapshot = manualSessionOverride
|
|
304
|
+
?? validatedPreferredModel
|
|
305
|
+
?? (sessionModelReady && ctx.model
|
|
276
306
|
? { provider: ctx.model.provider, id: ctx.model.id }
|
|
277
307
|
: null);
|
|
278
308
|
|
|
@@ -594,6 +624,9 @@ export async function bootstrapAutoSession(
|
|
|
594
624
|
s.consecutiveCompleteBootstraps = 0;
|
|
595
625
|
|
|
596
626
|
// ── Initialize session state ──
|
|
627
|
+
// Notify shared phase state so subagent conflict checks can fire
|
|
628
|
+
const { activateGSD: activateGSDPhaseState } = await import("../shared/gsd-phase-state.js");
|
|
629
|
+
activateGSDPhaseState();
|
|
597
630
|
s.active = true;
|
|
598
631
|
s.stepMode = requestedStepMode;
|
|
599
632
|
s.verbose = verboseMode;
|
|
@@ -678,7 +711,7 @@ export async function bootstrapAutoSession(
|
|
|
678
711
|
}
|
|
679
712
|
|
|
680
713
|
// ── DB lifecycle ──
|
|
681
|
-
const gsdDbPath =
|
|
714
|
+
const gsdDbPath = resolveProjectRootDbPath(s.basePath);
|
|
682
715
|
const gsdDirPath = join(s.basePath, ".gsd");
|
|
683
716
|
if (existsSync(gsdDirPath) && !existsSync(gsdDbPath)) {
|
|
684
717
|
const hasDecisions = existsSync(join(gsdDirPath, "DECISIONS.md"));
|
|
@@ -731,6 +764,7 @@ export async function bootstrapAutoSession(
|
|
|
731
764
|
id: startModelSnapshot.id,
|
|
732
765
|
};
|
|
733
766
|
}
|
|
767
|
+
s.manualSessionModelOverride = manualSessionOverride ?? null;
|
|
734
768
|
|
|
735
769
|
// Apply worker model override from parallel orchestrator (#worker-model).
|
|
736
770
|
// GSD_WORKER_MODEL is injected by the coordinator when parallel.worker_model
|
|
@@ -92,7 +92,7 @@ export function clearInFlightTools(): void {
|
|
|
92
92
|
* handler. When these errors occur, retrying the same unit will produce the same
|
|
93
93
|
* failure, so the retry loop must be broken.
|
|
94
94
|
*/
|
|
95
|
-
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Expected ',' or '\}' in JSON
|
|
95
|
+
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Expected ',' or '\}'(?: after property value)?(?: in JSON)?|Unexpected end of JSON|Unexpected token.*in JSON/i;
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
98
|
* Returns true if the error message indicates a tool invocation failure due to
|
|
@@ -2043,7 +2043,7 @@ export function mergeMilestoneToMain(
|
|
|
2043
2043
|
// 12. Remove worktree directory first (must happen before branch deletion)
|
|
2044
2044
|
try {
|
|
2045
2045
|
removeWorktree(originalBasePath_, milestoneId, {
|
|
2046
|
-
branch:
|
|
2046
|
+
branch: milestoneBranch,
|
|
2047
2047
|
deleteBranch: false,
|
|
2048
2048
|
});
|
|
2049
2049
|
} catch (err) {
|
|
@@ -115,6 +115,7 @@ import {
|
|
|
115
115
|
resetSkillTelemetry,
|
|
116
116
|
} from "./skill-telemetry.js";
|
|
117
117
|
import { getRtkSessionSavings } from "../shared/rtk-session-stats.js";
|
|
118
|
+
import { deactivateGSD } from "../shared/gsd-phase-state.js";
|
|
118
119
|
import {
|
|
119
120
|
initMetrics,
|
|
120
121
|
resetMetrics,
|
|
@@ -165,6 +166,7 @@ import {
|
|
|
165
166
|
reconcileMergeState,
|
|
166
167
|
} from "./auto-recovery.js";
|
|
167
168
|
import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
|
|
169
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
168
170
|
import { initRegistry, convertDispatchRules } from "./rule-registry.js";
|
|
169
171
|
import { emitJournalEvent as _emitJournalEvent, type JournalEntry } from "./journal.js";
|
|
170
172
|
import {
|
|
@@ -272,6 +274,53 @@ function restoreProjectRootEnv(): void {
|
|
|
272
274
|
s.projectRootEnvCaptured = false;
|
|
273
275
|
}
|
|
274
276
|
|
|
277
|
+
function captureMilestoneLockEnv(milestoneId: string | null): void {
|
|
278
|
+
if (!s.milestoneLockEnvCaptured) {
|
|
279
|
+
s.hadMilestoneLockEnv = Object.prototype.hasOwnProperty.call(process.env, "GSD_MILESTONE_LOCK");
|
|
280
|
+
s.previousMilestoneLockEnv = process.env.GSD_MILESTONE_LOCK ?? null;
|
|
281
|
+
s.milestoneLockEnvCaptured = true;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
if (milestoneId) {
|
|
285
|
+
process.env.GSD_MILESTONE_LOCK = milestoneId;
|
|
286
|
+
} else {
|
|
287
|
+
delete process.env.GSD_MILESTONE_LOCK;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function restoreMilestoneLockEnv(): void {
|
|
292
|
+
if (!s.milestoneLockEnvCaptured) return;
|
|
293
|
+
|
|
294
|
+
if (s.hadMilestoneLockEnv && s.previousMilestoneLockEnv !== null) {
|
|
295
|
+
process.env.GSD_MILESTONE_LOCK = s.previousMilestoneLockEnv;
|
|
296
|
+
} else {
|
|
297
|
+
delete process.env.GSD_MILESTONE_LOCK;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
s.previousMilestoneLockEnv = null;
|
|
301
|
+
s.hadMilestoneLockEnv = false;
|
|
302
|
+
s.milestoneLockEnvCaptured = false;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export function startAutoDetached(
|
|
306
|
+
ctx: ExtensionCommandContext,
|
|
307
|
+
pi: ExtensionAPI,
|
|
308
|
+
base: string,
|
|
309
|
+
verboseMode: boolean,
|
|
310
|
+
options?: {
|
|
311
|
+
step?: boolean;
|
|
312
|
+
interrupted?: InterruptedSessionAssessment;
|
|
313
|
+
milestoneLock?: string | null;
|
|
314
|
+
},
|
|
315
|
+
): void {
|
|
316
|
+
void startAuto(ctx, pi, base, verboseMode, options).catch((err) => {
|
|
317
|
+
const message = getErrorMessage(err);
|
|
318
|
+
ctx.ui.notify(`Auto-start failed: ${message}`, "error");
|
|
319
|
+
logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
|
|
320
|
+
debugLog("auto-start-failed", { error: message });
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
|
|
275
324
|
export function shouldUseWorktreeIsolation(): boolean {
|
|
276
325
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
277
326
|
if (prefs?.isolation === "worktree") return true;
|
|
@@ -549,11 +598,13 @@ function buildSnapshotOpts(
|
|
|
549
598
|
_unitType: string,
|
|
550
599
|
_unitId: string,
|
|
551
600
|
): {
|
|
601
|
+
autoSessionKey?: string;
|
|
552
602
|
continueHereFired?: boolean;
|
|
553
603
|
promptCharCount?: number;
|
|
554
604
|
baselineCharCount?: number;
|
|
555
605
|
} & Record<string, unknown> {
|
|
556
606
|
return {
|
|
607
|
+
...(s.autoStartTime > 0 ? { autoSessionKey: String(s.autoStartTime) } : {}),
|
|
557
608
|
promptCharCount: s.lastPromptCharCount,
|
|
558
609
|
baselineCharCount: s.lastBaselineCharCount,
|
|
559
610
|
...(s.currentUnitRouting ?? {}),
|
|
@@ -572,8 +623,10 @@ function handleLostSessionLock(
|
|
|
572
623
|
});
|
|
573
624
|
s.active = false;
|
|
574
625
|
s.paused = false;
|
|
626
|
+
deactivateGSD();
|
|
575
627
|
clearUnitTimeout();
|
|
576
628
|
restoreProjectRootEnv();
|
|
629
|
+
restoreMilestoneLockEnv();
|
|
577
630
|
deregisterSigtermHandler();
|
|
578
631
|
clearCmuxSidebar(loadEffectiveGSDPreferences()?.preferences);
|
|
579
632
|
const base = lockBase();
|
|
@@ -608,8 +661,10 @@ function handleLostSessionLock(
|
|
|
608
661
|
function cleanupAfterLoopExit(ctx: ExtensionContext): void {
|
|
609
662
|
s.currentUnit = null;
|
|
610
663
|
s.active = false;
|
|
664
|
+
deactivateGSD();
|
|
611
665
|
clearUnitTimeout();
|
|
612
666
|
restoreProjectRootEnv();
|
|
667
|
+
restoreMilestoneLockEnv();
|
|
613
668
|
|
|
614
669
|
// Clear crash lock and release session lock so the next `/gsd next` does
|
|
615
670
|
// not see a stale lock with the current PID and treat it as a "remote"
|
|
@@ -880,6 +935,7 @@ export async function stopAuto(
|
|
|
880
935
|
ctx?.ui.setWidget("gsd-progress", undefined);
|
|
881
936
|
ctx?.ui.setFooter(undefined);
|
|
882
937
|
restoreProjectRootEnv();
|
|
938
|
+
restoreMilestoneLockEnv();
|
|
883
939
|
|
|
884
940
|
// Reset all session state in one call
|
|
885
941
|
s.reset();
|
|
@@ -933,6 +989,7 @@ export async function pauseAuto(
|
|
|
933
989
|
activeEngineId: s.activeEngineId,
|
|
934
990
|
activeRunDir: s.activeRunDir,
|
|
935
991
|
autoStartTime: s.autoStartTime,
|
|
992
|
+
milestoneLock: s.sessionMilestoneLock ?? undefined,
|
|
936
993
|
};
|
|
937
994
|
const runtimeDir = join(gsdRoot(s.originalBasePath || s.basePath), "runtime");
|
|
938
995
|
mkdirSync(runtimeDir, { recursive: true });
|
|
@@ -970,7 +1027,9 @@ export async function pauseAuto(
|
|
|
970
1027
|
|
|
971
1028
|
s.active = false;
|
|
972
1029
|
s.paused = true;
|
|
1030
|
+
deactivateGSD();
|
|
973
1031
|
restoreProjectRootEnv();
|
|
1032
|
+
restoreMilestoneLockEnv();
|
|
974
1033
|
s.pendingVerificationRetry = null;
|
|
975
1034
|
s.verificationRetryCount.clear();
|
|
976
1035
|
ctx?.ui.setStatus("gsd-auto", "paused");
|
|
@@ -1154,6 +1213,7 @@ export async function startAuto(
|
|
|
1154
1213
|
options?: {
|
|
1155
1214
|
step?: boolean;
|
|
1156
1215
|
interrupted?: InterruptedSessionAssessment;
|
|
1216
|
+
milestoneLock?: string | null;
|
|
1157
1217
|
},
|
|
1158
1218
|
): Promise<void> {
|
|
1159
1219
|
if (s.active) {
|
|
@@ -1163,6 +1223,12 @@ export async function startAuto(
|
|
|
1163
1223
|
|
|
1164
1224
|
const requestedStepMode = options?.step ?? false;
|
|
1165
1225
|
const interruptedAssessment = options?.interrupted ?? null;
|
|
1226
|
+
if (options?.milestoneLock !== undefined) {
|
|
1227
|
+
s.sessionMilestoneLock = options.milestoneLock ?? null;
|
|
1228
|
+
}
|
|
1229
|
+
if (s.sessionMilestoneLock) {
|
|
1230
|
+
captureMilestoneLockEnv(s.sessionMilestoneLock);
|
|
1231
|
+
}
|
|
1166
1232
|
|
|
1167
1233
|
// Escape stale worktree cwd from a previous milestone (#608).
|
|
1168
1234
|
base = escapeStaleWorktree(base);
|
|
@@ -1194,6 +1260,7 @@ export async function startAuto(
|
|
|
1194
1260
|
s.originalBasePath = meta.originalBasePath || base;
|
|
1195
1261
|
s.stepMode = meta.stepMode ?? requestedStepMode;
|
|
1196
1262
|
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
1263
|
+
s.sessionMilestoneLock = meta.milestoneLock ?? null;
|
|
1197
1264
|
s.paused = true;
|
|
1198
1265
|
try { unlinkSync(pausedPath); } catch (e) { logWarning("session", `pause file cleanup failed: ${e instanceof Error ? e.message : String(e)}`, { file: "auto.ts" }); }
|
|
1199
1266
|
ctx.ui.notify(
|
|
@@ -1228,6 +1295,7 @@ export async function startAuto(
|
|
|
1228
1295
|
s.pausedUnitType = meta.unitType ?? null;
|
|
1229
1296
|
s.pausedUnitId = meta.unitId ?? null;
|
|
1230
1297
|
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
1298
|
+
s.sessionMilestoneLock = meta.milestoneLock ?? null;
|
|
1231
1299
|
s.paused = true;
|
|
1232
1300
|
try { unlinkSync(pausedPath); } catch (e) { logWarning("session", `pause file cleanup failed: ${e instanceof Error ? e.message : String(e)}`, { file: "auto.ts" }); }
|
|
1233
1301
|
ctx.ui.notify(
|
|
@@ -1247,6 +1315,10 @@ export async function startAuto(
|
|
|
1247
1315
|
if (!s.autoStartTime || s.autoStartTime <= 0) s.autoStartTime = Date.now();
|
|
1248
1316
|
}
|
|
1249
1317
|
|
|
1318
|
+
if (s.sessionMilestoneLock) {
|
|
1319
|
+
captureMilestoneLockEnv(s.sessionMilestoneLock);
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1250
1322
|
if (!s.paused) {
|
|
1251
1323
|
s.stepMode = requestedStepMode;
|
|
1252
1324
|
}
|
|
@@ -1026,12 +1026,12 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1026
1026
|
name: "gsd_save_gate_result",
|
|
1027
1027
|
label: "Save Gate Result",
|
|
1028
1028
|
description:
|
|
1029
|
-
"Save the result of a quality gate evaluation (Q3-Q8) to the GSD database. " +
|
|
1029
|
+
"Save the result of a quality gate evaluation (Q3-Q8 or MV01-MV04) to the GSD database. " +
|
|
1030
1030
|
"Called by gate evaluation sub-agents after analyzing a specific quality question.",
|
|
1031
1031
|
promptSnippet: "Save quality gate evaluation result (verdict, rationale, findings)",
|
|
1032
1032
|
promptGuidelines: [
|
|
1033
1033
|
"Use gsd_save_gate_result after evaluating a quality gate question.",
|
|
1034
|
-
"gateId must be one of: Q3, Q4, Q5, Q6, Q7, Q8.",
|
|
1034
|
+
"gateId must be one of: Q3, Q4, Q5, Q6, Q7, Q8, MV01, MV02, MV03, MV04.",
|
|
1035
1035
|
"verdict must be: pass (no concerns), flag (concerns found), or omitted (not applicable).",
|
|
1036
1036
|
"rationale should be a one-sentence justification for the verdict.",
|
|
1037
1037
|
"findings should contain detailed markdown analysis (or empty string if omitted).",
|
|
@@ -1039,7 +1039,7 @@ export function registerDbTools(pi: ExtensionAPI): void {
|
|
|
1039
1039
|
parameters: Type.Object({
|
|
1040
1040
|
milestoneId: Type.String({ description: "Milestone ID (e.g. M001)" }),
|
|
1041
1041
|
sliceId: Type.String({ description: "Slice ID (e.g. S01)" }),
|
|
1042
|
-
gateId: Type.String({ description: "Gate ID: Q3, Q4, Q5, Q6, Q7, or
|
|
1042
|
+
gateId: Type.String({ description: "Gate ID: Q3, Q4, Q5, Q6, Q7, Q8, MV01, MV02, MV03, or MV04" }),
|
|
1043
1043
|
taskId: Type.Optional(Type.String({ description: "Task ID for task-scoped gates (Q5/Q6/Q7)" })),
|
|
1044
1044
|
verdict: Type.String({ description: "pass, flag, or omitted" }),
|
|
1045
1045
|
rationale: Type.String({ description: "One-sentence justification" }),
|
|
@@ -121,6 +121,8 @@ export function registerHooks(pi: ExtensionAPI): void {
|
|
|
121
121
|
return { cancel: true };
|
|
122
122
|
}
|
|
123
123
|
const basePath = process.cwd();
|
|
124
|
+
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
125
|
+
await ensureDbOpen();
|
|
124
126
|
const state = await deriveState(basePath);
|
|
125
127
|
if (!state.activeMilestone || !state.activeSlice || !state.activeTask) return;
|
|
126
128
|
if (state.phase !== "executing") return;
|