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
|
@@ -13,6 +13,7 @@ import { runUnit } from "./run-unit.js";
|
|
|
13
13
|
import { debugLog } from "../debug-logger.js";
|
|
14
14
|
import { PROJECT_FILES } from "../detection.js";
|
|
15
15
|
import { MergeConflictError } from "../git-service.js";
|
|
16
|
+
import { setCurrentPhase, clearCurrentPhase } from "../../shared/gsd-phase-state.js";
|
|
16
17
|
import { join, basename, dirname, parse as parsePath } from "node:path";
|
|
17
18
|
import { existsSync, cpSync, readdirSync } from "node:fs";
|
|
18
19
|
import { logWarning, logError } from "../workflow-logger.js";
|
|
@@ -770,6 +771,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
770
771
|
s.currentUnit.id === unitId);
|
|
771
772
|
const previousTier = s.currentUnitRouting?.tier;
|
|
772
773
|
s.currentUnit = { type: unitType, id: unitId, startedAt: Date.now() };
|
|
774
|
+
setCurrentPhase(unitType);
|
|
773
775
|
s.lastToolInvocationError = null; // #2883: clear stale error from previous unit
|
|
774
776
|
const unitStartSeq = ic.nextSeq();
|
|
775
777
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: unitStartSeq, eventType: "unit-start", data: { unitType, unitId } });
|
|
@@ -857,7 +859,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
857
859
|
logWarning("engine", "Prompt reorder failed", { error: msg });
|
|
858
860
|
}
|
|
859
861
|
// Select and apply model (with tier escalation on retry — normal units only)
|
|
860
|
-
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier });
|
|
862
|
+
const modelResult = await deps.selectAndApplyModel(ctx, pi, unitType, unitId, s.basePath, prefs, s.verbose, s.autoModeStartModel, sidecarItem ? undefined : { isRetry, previousTier }, undefined, s.manualSessionModelOverride);
|
|
861
863
|
s.currentUnitRouting =
|
|
862
864
|
modelResult.routing;
|
|
863
865
|
s.currentUnitModel =
|
|
@@ -1115,6 +1117,7 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1115
1117
|
// Detach session from the timed-out unit so late async completions
|
|
1116
1118
|
// cannot mutate state for the next unit (#3757).
|
|
1117
1119
|
s.currentUnit = null;
|
|
1120
|
+
clearCurrentPhase();
|
|
1118
1121
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1119
1122
|
debugLog("autoLoop", {
|
|
1120
1123
|
phase: "pre-verification-timeout",
|
|
@@ -1189,6 +1192,7 @@ export async function runFinalize(ic, iterData, loopState, sidecarItem) {
|
|
|
1189
1192
|
// Detach session from the timed-out unit so late async completions
|
|
1190
1193
|
// cannot mutate state for the next unit (#3757).
|
|
1191
1194
|
s.currentUnit = null;
|
|
1195
|
+
clearCurrentPhase();
|
|
1192
1196
|
loopState.consecutiveFinalizeTimeouts++;
|
|
1193
1197
|
debugLog("autoLoop", {
|
|
1194
1198
|
phase: "post-verification-timeout",
|
|
@@ -36,6 +36,10 @@ export class AutoSession {
|
|
|
36
36
|
previousProjectRootEnv = null;
|
|
37
37
|
hadProjectRootEnv = false;
|
|
38
38
|
projectRootEnvCaptured = false;
|
|
39
|
+
previousMilestoneLockEnv = null;
|
|
40
|
+
hadMilestoneLockEnv = false;
|
|
41
|
+
milestoneLockEnvCaptured = false;
|
|
42
|
+
sessionMilestoneLock = null;
|
|
39
43
|
gitService = null;
|
|
40
44
|
// ── Dispatch counters ────────────────────────────────────────────────────
|
|
41
45
|
unitDispatchCount = new Map();
|
|
@@ -52,6 +56,8 @@ export class AutoSession {
|
|
|
52
56
|
currentMilestoneId = null;
|
|
53
57
|
// ── Model state ──────────────────────────────────────────────────────────
|
|
54
58
|
autoModeStartModel = null;
|
|
59
|
+
/** Explicit /gsd model pin captured at bootstrap (session-scoped policy override). */
|
|
60
|
+
manualSessionModelOverride = null;
|
|
55
61
|
currentUnitModel = null;
|
|
56
62
|
/** Fully-qualified model ID (provider/id) set after selectAndApplyModel + hook overrides (#2899). */
|
|
57
63
|
currentDispatchedModelId = null;
|
|
@@ -140,6 +146,10 @@ export class AutoSession {
|
|
|
140
146
|
this.previousProjectRootEnv = null;
|
|
141
147
|
this.hadProjectRootEnv = false;
|
|
142
148
|
this.projectRootEnvCaptured = false;
|
|
149
|
+
this.previousMilestoneLockEnv = null;
|
|
150
|
+
this.hadMilestoneLockEnv = false;
|
|
151
|
+
this.milestoneLockEnvCaptured = false;
|
|
152
|
+
this.sessionMilestoneLock = null;
|
|
143
153
|
this.gitService = null;
|
|
144
154
|
// Dispatch
|
|
145
155
|
this.unitDispatchCount.clear();
|
|
@@ -151,6 +161,7 @@ export class AutoSession {
|
|
|
151
161
|
this.currentMilestoneId = null;
|
|
152
162
|
// Model
|
|
153
163
|
this.autoModeStartModel = null;
|
|
164
|
+
this.manualSessionModelOverride = null;
|
|
154
165
|
this.currentUnitModel = null;
|
|
155
166
|
this.currentDispatchedModelId = null;
|
|
156
167
|
this.originalModelId = null;
|
|
@@ -10,7 +10,6 @@ import { getActiveHook } from "./post-unit-hooks.js";
|
|
|
10
10
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
11
11
|
import { getErrorMessage } from "./error-utils.js";
|
|
12
12
|
import { isDbAvailable, getMilestoneSlices, getSliceTasks } from "./gsd-db.js";
|
|
13
|
-
import { formatShortcut } from "./files.js";
|
|
14
13
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
15
14
|
import { execFileSync } from "node:child_process";
|
|
16
15
|
import { truncateToWidth, visibleWidth } from "@gsd/pi-tui";
|
|
@@ -23,6 +22,7 @@ import { resolveServiceTierIcon, getEffectiveServiceTier } from "./service-tier.
|
|
|
23
22
|
import { parseUnitId } from "./unit-id.js";
|
|
24
23
|
import { formatRtkSavingsLabel, getRtkSessionSavings, } from "../shared/rtk-session-stats.js";
|
|
25
24
|
import { logWarning } from "./workflow-logger.js";
|
|
25
|
+
import { formattedShortcutPair } from "./shortcut-defs.js";
|
|
26
26
|
// ─── UAT Slice Extraction ─────────────────────────────────────────────────────
|
|
27
27
|
/**
|
|
28
28
|
* Extract the target slice ID from a run-uat unit ID (e.g. "M001/S01" → "S01").
|
|
@@ -282,12 +282,23 @@ function getLastCommit(basePath) {
|
|
|
282
282
|
}
|
|
283
283
|
// ─── Footer Factory ───────────────────────────────────────────────────────────
|
|
284
284
|
/**
|
|
285
|
-
* Footer factory
|
|
286
|
-
*
|
|
287
|
-
* progress widget instead, so there's no gap or redundancy.
|
|
285
|
+
* Footer factory used by auto-mode.
|
|
286
|
+
* Keep footer minimal but preserve extension status context from setStatus().
|
|
288
287
|
*/
|
|
289
|
-
|
|
290
|
-
|
|
288
|
+
function sanitizeFooterStatus(text) {
|
|
289
|
+
return text.replace(/\s+/g, " ").trim();
|
|
290
|
+
}
|
|
291
|
+
export const hideFooter = (_tui, theme, footerData) => ({
|
|
292
|
+
render(width) {
|
|
293
|
+
const extensionStatuses = footerData.getExtensionStatuses();
|
|
294
|
+
if (extensionStatuses.size === 0)
|
|
295
|
+
return [];
|
|
296
|
+
const statusLine = Array.from(extensionStatuses.entries())
|
|
297
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
298
|
+
.map(([, text]) => sanitizeFooterStatus(text))
|
|
299
|
+
.join(" ");
|
|
300
|
+
return [truncateToWidth(theme.fg("dim", statusLine), width, theme.fg("dim", "..."))];
|
|
301
|
+
},
|
|
291
302
|
invalidate() { },
|
|
292
303
|
dispose() { },
|
|
293
304
|
});
|
|
@@ -522,13 +533,6 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
522
533
|
: theme.fg("dim", elapsed))
|
|
523
534
|
: "";
|
|
524
535
|
lines.push(rightAlign(headerLeft, headerRight, width));
|
|
525
|
-
// Worktree/branch right-aligned below header
|
|
526
|
-
const branchLabel = worktreeName && cachedBranch
|
|
527
|
-
? `${worktreeName} (${cachedBranch})`
|
|
528
|
-
: cachedBranch ?? "";
|
|
529
|
-
if (branchLabel) {
|
|
530
|
-
lines.push(rightAlign("", theme.fg("dim", branchLabel), width));
|
|
531
|
-
}
|
|
532
536
|
// Show health signal details when degraded (yellow/red)
|
|
533
537
|
if (score.level !== "green" && score.signals.length > 0 && widgetMode !== "min") {
|
|
534
538
|
// Show up to 3 most relevant signals in compact form
|
|
@@ -776,16 +780,18 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
776
780
|
// Hints line
|
|
777
781
|
const hintParts = [];
|
|
778
782
|
hintParts.push("esc pause");
|
|
779
|
-
hintParts.push(`${
|
|
783
|
+
hintParts.push(`${formattedShortcutPair("dashboard")} dashboard`);
|
|
784
|
+
hintParts.push(`${formattedShortcutPair("parallel")} parallel`);
|
|
780
785
|
const hintStr = theme.fg("dim", hintParts.join(" | "));
|
|
781
786
|
const commitStr = lastCommit
|
|
782
787
|
? theme.fg("dim", `${lastCommit.timeAgo} ago: ${commitMsg}`)
|
|
783
788
|
: "";
|
|
789
|
+
const locationStr = theme.fg("dim", widgetPwd);
|
|
784
790
|
if (commitStr) {
|
|
785
|
-
lines.push(rightAlign(`${pad}${commitStr}`, hintStr, width));
|
|
791
|
+
lines.push(rightAlign(`${pad}${locationStr} · ${commitStr}`, hintStr, width));
|
|
786
792
|
}
|
|
787
793
|
else {
|
|
788
|
-
lines.push(rightAlign(
|
|
794
|
+
lines.push(rightAlign(`${pad}${locationStr}`, hintStr, width));
|
|
789
795
|
}
|
|
790
796
|
lines.push(...ui.bar());
|
|
791
797
|
cachedLines = lines;
|
|
@@ -8,6 +8,7 @@ import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
|
|
|
8
8
|
import { resolveModelForComplexity, escalateTier, getEligibleModels, loadCapabilityOverrides, adjustToolSet } from "./model-router.js";
|
|
9
9
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
10
10
|
import { unitPhaseLabel } from "./auto-dashboard.js";
|
|
11
|
+
import { getSessionModelOverride } from "./session-model-override.js";
|
|
11
12
|
export function resolvePreferredModelConfig(unitType, autoModeStartModel,
|
|
12
13
|
/** When false, only return explicit per-phase model configs — do not
|
|
13
14
|
* synthesize a routing ceiling from dynamic_routing.tier_models (#3962). */
|
|
@@ -44,8 +45,15 @@ isAutoMode = true) {
|
|
|
44
45
|
export async function selectAndApplyModel(ctx, pi, unitType, unitId, basePath, prefs, verbose, autoModeStartModel, retryContext,
|
|
45
46
|
/** When false (interactive/guided-flow), skip dynamic routing and use the session model.
|
|
46
47
|
* Dynamic routing only applies in auto-mode where cost optimization is expected. (#3962) */
|
|
47
|
-
isAutoMode = true
|
|
48
|
-
|
|
48
|
+
isAutoMode = true,
|
|
49
|
+
/** Explicit /gsd model pin captured at bootstrap for long-running auto loops. */
|
|
50
|
+
sessionModelOverride) {
|
|
51
|
+
const effectiveSessionModelOverride = sessionModelOverride === undefined
|
|
52
|
+
? getSessionModelOverride(ctx.sessionManager.getSessionId())
|
|
53
|
+
: (sessionModelOverride ?? undefined);
|
|
54
|
+
const modelConfig = effectiveSessionModelOverride
|
|
55
|
+
? undefined
|
|
56
|
+
: resolvePreferredModelConfig(unitType, autoModeStartModel, isAutoMode);
|
|
49
57
|
let routing = null;
|
|
50
58
|
let appliedModel = null;
|
|
51
59
|
if (modelConfig) {
|
|
@@ -15,7 +15,8 @@ import { getLoadedSkills } from "@gsd/pi-coding-agent";
|
|
|
15
15
|
import { join, basename } from "node:path";
|
|
16
16
|
import { existsSync } from "node:fs";
|
|
17
17
|
import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary } from "./context-budget.js";
|
|
18
|
-
import {
|
|
18
|
+
import { getPendingGatesForTurn } from "./gsd-db.js";
|
|
19
|
+
import { assertGateCoverage, getGatesForTurn, } from "./gate-registry.js";
|
|
19
20
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
20
21
|
import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
|
|
21
22
|
import { logWarning } from "./workflow-logger.js";
|
|
@@ -1221,6 +1222,13 @@ export async function buildExecuteTaskPrompt(mid, sid, sTitle, tid, tTitle, base
|
|
|
1221
1222
|
? `### Runtime Context\nSource: \`.gsd/RUNTIME.md\`\n\n${runtimeContent.trim()}`
|
|
1222
1223
|
: "";
|
|
1223
1224
|
const phaseAnchorSection = planAnchor ? formatAnchorForPrompt(planAnchor) : "";
|
|
1225
|
+
// Task-scoped gates owned by execute-task (Q5/Q6/Q7). Pull only the
|
|
1226
|
+
// gates that plan-slice actually seeded for this task — tasks with no
|
|
1227
|
+
// external dependencies legitimately skip Q5, tasks with no runtime
|
|
1228
|
+
// load dimension skip Q6, etc.
|
|
1229
|
+
const etPending = getPendingGatesForTurn(mid, sid, "execute-task", tid);
|
|
1230
|
+
assertGateCoverage(etPending, "execute-task", { requireAll: false });
|
|
1231
|
+
const gatesToClose = renderGatesToCloseBlock(getGatesForTurn("execute-task"), { pending: new Set(etPending.map((g) => g.gate_id)), allowOmit: true });
|
|
1224
1232
|
return loadPrompt("execute-task", {
|
|
1225
1233
|
overridesSection,
|
|
1226
1234
|
runtimeContext,
|
|
@@ -1238,6 +1246,7 @@ export async function buildExecuteTaskPrompt(mid, sid, sTitle, tid, tTitle, base
|
|
|
1238
1246
|
taskSummaryPath,
|
|
1239
1247
|
inlinedTemplates,
|
|
1240
1248
|
verificationBudget,
|
|
1249
|
+
gatesToClose,
|
|
1241
1250
|
skillActivation: buildSkillActivationBlock({
|
|
1242
1251
|
base,
|
|
1243
1252
|
milestoneId: mid,
|
|
@@ -1298,6 +1307,15 @@ export async function buildCompleteSlicePrompt(mid, _midTitle, sid, sTitle, base
|
|
|
1298
1307
|
const sliceRel = relSlicePath(base, mid, sid);
|
|
1299
1308
|
const sliceSummaryPath = join(base, `${sliceRel}/${sid}-SUMMARY.md`);
|
|
1300
1309
|
const sliceUatPath = join(base, `${sliceRel}/${sid}-UAT.md`);
|
|
1310
|
+
// Gates owned by complete-slice (e.g. Q8). Pull from the DB so the
|
|
1311
|
+
// prompt only prompts for gates the plan actually seeded. The tool
|
|
1312
|
+
// handler closes each gate based on the SUMMARY.md section content
|
|
1313
|
+
// after the assistant calls gsd_complete_slice.
|
|
1314
|
+
const csPending = getPendingGatesForTurn(mid, sid, "complete-slice");
|
|
1315
|
+
// coverage check: every pending row must be owned by complete-slice.
|
|
1316
|
+
// requireAll:false because a slice may have already closed some gates.
|
|
1317
|
+
assertGateCoverage(csPending, "complete-slice", { requireAll: false });
|
|
1318
|
+
const gatesToClose = renderGatesToCloseBlock(getGatesForTurn("complete-slice"), { pending: new Set(csPending.map((g) => g.gate_id)), allowOmit: true });
|
|
1301
1319
|
return loadPrompt("complete-slice", {
|
|
1302
1320
|
workingDirectory: base,
|
|
1303
1321
|
milestoneId: mid, sliceId: sid, sliceTitle: sTitle,
|
|
@@ -1306,6 +1324,7 @@ export async function buildCompleteSlicePrompt(mid, _midTitle, sid, sTitle, base
|
|
|
1306
1324
|
inlinedContext,
|
|
1307
1325
|
sliceSummaryPath,
|
|
1308
1326
|
sliceUatPath,
|
|
1327
|
+
gatesToClose,
|
|
1309
1328
|
});
|
|
1310
1329
|
}
|
|
1311
1330
|
export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
|
|
@@ -1498,6 +1517,15 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1498
1517
|
const inlinedContext = capPreamble(`## Inlined Context (preloaded — do not re-read these files)\n\n${inlined.join("\n\n---\n\n")}`);
|
|
1499
1518
|
const validationOutputPath = join(base, `${relMilestonePath(base, mid)}/${mid}-VALIDATION.md`);
|
|
1500
1519
|
const roadmapOutputPath = `${relMilestonePath(base, mid)}/${mid}-ROADMAP.md`;
|
|
1520
|
+
// Every milestone validation turn owns MV01–MV04 unconditionally: the
|
|
1521
|
+
// registry is the source of truth for which gates the validator must
|
|
1522
|
+
// address, and the block below is what the template renders so the
|
|
1523
|
+
// assistant can never accidentally skip one.
|
|
1524
|
+
const mvGates = getGatesForTurn("validate-milestone");
|
|
1525
|
+
const gatesToEvaluate = renderGatesToCloseBlock(mvGates, {
|
|
1526
|
+
pending: new Set(mvGates.map((g) => g.id)),
|
|
1527
|
+
allowOmit: false,
|
|
1528
|
+
});
|
|
1501
1529
|
return loadPrompt("validate-milestone", {
|
|
1502
1530
|
workingDirectory: base,
|
|
1503
1531
|
milestoneId: mid,
|
|
@@ -1506,6 +1534,7 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1506
1534
|
inlinedContext,
|
|
1507
1535
|
validationPath: validationOutputPath,
|
|
1508
1536
|
remediationRound: String(remediationRound),
|
|
1537
|
+
gatesToEvaluate,
|
|
1509
1538
|
skillActivation: buildSkillActivationBlock({
|
|
1510
1539
|
base,
|
|
1511
1540
|
milestoneId: mid,
|
|
@@ -1740,26 +1769,43 @@ export async function buildReactiveExecutePrompt(mid, midTitle, sid, sTitle, rea
|
|
|
1740
1769
|
});
|
|
1741
1770
|
}
|
|
1742
1771
|
// ─── Gate Evaluation ──────────────────────────────────────────────────────
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1772
|
+
//
|
|
1773
|
+
// Gate definitions (question, guidance, owner turn) now live in
|
|
1774
|
+
// gate-registry.ts so that prompt builders, dispatch rules, state
|
|
1775
|
+
// derivation, and tool handlers all consult the same source of truth.
|
|
1776
|
+
// See gate-registry.ts for the full ownership map.
|
|
1777
|
+
/**
|
|
1778
|
+
* Render a "Gates to Close" block for turns like `complete-slice` and
|
|
1779
|
+
* `validate-milestone` that own gates which are closed as a side-effect
|
|
1780
|
+
* of writing artifact sections (not via a dedicated gate-evaluate
|
|
1781
|
+
* subagent loop).
|
|
1782
|
+
*
|
|
1783
|
+
* Returns a plain-text block or an empty string if there are no gates to
|
|
1784
|
+
* close, so callers can drop it straight into a template variable.
|
|
1785
|
+
*/
|
|
1786
|
+
function renderGatesToCloseBlock(gates, opts) {
|
|
1787
|
+
const applicable = gates.filter((g) => opts.pending.has(g.id));
|
|
1788
|
+
if (applicable.length === 0)
|
|
1789
|
+
return "";
|
|
1790
|
+
const lines = [];
|
|
1791
|
+
lines.push("## Gates to Close");
|
|
1792
|
+
lines.push("");
|
|
1793
|
+
lines.push("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.");
|
|
1794
|
+
lines.push("");
|
|
1795
|
+
for (const def of applicable) {
|
|
1796
|
+
lines.push(`### ${def.id} — ${def.promptSection}`);
|
|
1797
|
+
lines.push("");
|
|
1798
|
+
lines.push(`**Question:** ${def.question}`);
|
|
1799
|
+
lines.push("");
|
|
1800
|
+
lines.push(def.guidance);
|
|
1801
|
+
if (opts.allowOmit) {
|
|
1802
|
+
lines.push("");
|
|
1803
|
+
lines.push(`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.`);
|
|
1804
|
+
}
|
|
1805
|
+
lines.push("");
|
|
1806
|
+
}
|
|
1807
|
+
return lines.join("\n").trimEnd();
|
|
1808
|
+
}
|
|
1763
1809
|
export async function buildParallelResearchSlicesPrompt(mid, midTitle, slices, basePath) {
|
|
1764
1810
|
// Build individual research-slice prompts for each slice
|
|
1765
1811
|
const subagentSections = [];
|
|
@@ -1784,24 +1830,33 @@ export async function buildParallelResearchSlicesPrompt(mid, midTitle, slices, b
|
|
|
1784
1830
|
});
|
|
1785
1831
|
}
|
|
1786
1832
|
export async function buildGateEvaluatePrompt(mid, midTitle, sid, sTitle, base) {
|
|
1787
|
-
|
|
1833
|
+
// Pull only the gates this turn actually owns (Q3/Q4). Filter via the
|
|
1834
|
+
// registry so that scope:"slice" gates owned by other turns (Q8) can't
|
|
1835
|
+
// leak into this prompt and can't block dispatch via silent skip.
|
|
1836
|
+
const pending = getPendingGatesForTurn(mid, sid, "gate-evaluate");
|
|
1837
|
+
// Fails loudly if the pending list contains a gate id the registry
|
|
1838
|
+
// doesn't own for this turn. Missing owned gates is allowed here —
|
|
1839
|
+
// `gate-evaluate` is dispatched whenever *any* of its owned gates are
|
|
1840
|
+
// pending, not only when all of them are.
|
|
1841
|
+
assertGateCoverage(pending, "gate-evaluate", { requireAll: false });
|
|
1788
1842
|
// Load the slice plan for context
|
|
1789
1843
|
const planFile = resolveSliceFile(base, mid, sid, "PLAN");
|
|
1790
1844
|
const planContent = planFile ? (await loadFile(planFile)) ?? "(plan file empty)" : "(plan file not found)";
|
|
1791
|
-
// Build per-gate subagent prompts
|
|
1845
|
+
// Build per-gate subagent prompts from the pending rows. Because the
|
|
1846
|
+
// registry has already validated every row, `getGateDefinition` cannot
|
|
1847
|
+
// return undefined here.
|
|
1848
|
+
const pendingIds = new Set(pending.map((g) => g.gate_id));
|
|
1849
|
+
const gateDefs = getGatesForTurn("gate-evaluate").filter((def) => pendingIds.has(def.id));
|
|
1792
1850
|
const subagentSections = [];
|
|
1793
1851
|
const gateListLines = [];
|
|
1794
|
-
for (const
|
|
1795
|
-
|
|
1796
|
-
if (!meta)
|
|
1797
|
-
continue;
|
|
1798
|
-
gateListLines.push(`- **${gate.gate_id}**: ${meta.question}`);
|
|
1852
|
+
for (const def of gateDefs) {
|
|
1853
|
+
gateListLines.push(`- **${def.id}**: ${def.question}`);
|
|
1799
1854
|
const subPrompt = [
|
|
1800
|
-
`You are evaluating quality gate **${
|
|
1855
|
+
`You are evaluating quality gate **${def.id}** for slice ${sid} (${sTitle}).`,
|
|
1801
1856
|
"",
|
|
1802
|
-
`## Question: ${
|
|
1857
|
+
`## Question: ${def.question}`,
|
|
1803
1858
|
"",
|
|
1804
|
-
|
|
1859
|
+
def.guidance,
|
|
1805
1860
|
"",
|
|
1806
1861
|
"## Slice Plan",
|
|
1807
1862
|
"",
|
|
@@ -1813,13 +1868,13 @@ export async function buildGateEvaluatePrompt(mid, midTitle, sid, sTitle, base)
|
|
|
1813
1868
|
`Call the \`gsd_save_gate_result\` tool with:`,
|
|
1814
1869
|
`- \`milestoneId\`: "${mid}"`,
|
|
1815
1870
|
`- \`sliceId\`: "${sid}"`,
|
|
1816
|
-
`- \`gateId\`: "${
|
|
1871
|
+
`- \`gateId\`: "${def.id}"`,
|
|
1817
1872
|
"- `verdict`: \"pass\" (no concerns), \"flag\" (concerns found), or \"omitted\" (not applicable)",
|
|
1818
1873
|
"- `rationale`: one-sentence justification",
|
|
1819
1874
|
"- `findings`: detailed markdown findings (or empty if omitted)",
|
|
1820
1875
|
].join("\n");
|
|
1821
1876
|
subagentSections.push([
|
|
1822
|
-
`### ${
|
|
1877
|
+
`### ${def.id}: ${def.question}`,
|
|
1823
1878
|
"",
|
|
1824
1879
|
"Use this as the prompt for a `subagent` call:",
|
|
1825
1880
|
"",
|
|
@@ -39,6 +39,7 @@ import { join } from "node:path";
|
|
|
39
39
|
import { sep as pathSep } from "node:path";
|
|
40
40
|
import { resolveProjectRootDbPath } from "./bootstrap/dynamic-tools.js";
|
|
41
41
|
import { resolveDefaultSessionModel, resolveDynamicRoutingConfig } from "./preferences-models.js";
|
|
42
|
+
import { getSessionModelOverride } from "./session-model-override.js";
|
|
42
43
|
/**
|
|
43
44
|
* Bootstrap a fresh auto-mode session. Handles everything from git init
|
|
44
45
|
* through secrets collection, returning when ready for the first
|
|
@@ -187,13 +188,35 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
187
188
|
// Capture the user's session model before guided-flow dispatch can apply a
|
|
188
189
|
// phase-specific planning model for a discuss turn (#2829).
|
|
189
190
|
//
|
|
190
|
-
//
|
|
191
|
-
//
|
|
192
|
-
//
|
|
193
|
-
//
|
|
191
|
+
// Precedence:
|
|
192
|
+
// 1) Explicit session override via /gsd model (this session)
|
|
193
|
+
// 2) GSD model preferences from PREFERENCES.md (validated against live auth)
|
|
194
|
+
// 3) Current session model from settings/session restore (if provider ready)
|
|
195
|
+
//
|
|
196
|
+
// This preserves #3517 defaults while honoring explicit runtime model
|
|
197
|
+
// selection for subsequent /gsd runs in the same session.
|
|
198
|
+
const manualSessionOverride = getSessionModelOverride(ctx.sessionManager.getSessionId());
|
|
194
199
|
const preferredModel = resolveDefaultSessionModel(ctx.model?.provider);
|
|
195
|
-
|
|
196
|
-
|
|
200
|
+
// Validate the preferred model against the live registry + provider auth so
|
|
201
|
+
// an unconfigured PREFERENCES.md entry (no API key / OAuth) can't become the
|
|
202
|
+
// start-model snapshot. Without this, every subsequent unit would try to
|
|
203
|
+
// fall back to an unusable model.
|
|
204
|
+
let validatedPreferredModel;
|
|
205
|
+
if (preferredModel) {
|
|
206
|
+
const { resolveModelId } = await import("./auto-model-selection.js");
|
|
207
|
+
const available = ctx.modelRegistry.getAvailable();
|
|
208
|
+
const match = resolveModelId(`${preferredModel.provider}/${preferredModel.id}`, available, ctx.model?.provider);
|
|
209
|
+
if (match) {
|
|
210
|
+
validatedPreferredModel = { provider: match.provider, id: match.id };
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
ctx.ui.notify(`Preferred model ${preferredModel.provider}/${preferredModel.id} from PREFERENCES.md is not configured; falling back to session default.`, "warning");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const sessionModelReady = ctx.model && ctx.modelRegistry.isProviderRequestReady(ctx.model.provider);
|
|
217
|
+
const startModelSnapshot = manualSessionOverride
|
|
218
|
+
?? validatedPreferredModel
|
|
219
|
+
?? (sessionModelReady && ctx.model
|
|
197
220
|
? { provider: ctx.model.provider, id: ctx.model.id }
|
|
198
221
|
: null);
|
|
199
222
|
try {
|
|
@@ -447,6 +470,9 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
447
470
|
// Successfully resolved an active milestone — reset the re-entry guard
|
|
448
471
|
s.consecutiveCompleteBootstraps = 0;
|
|
449
472
|
// ── Initialize session state ──
|
|
473
|
+
// Notify shared phase state so subagent conflict checks can fire
|
|
474
|
+
const { activateGSD: activateGSDPhaseState } = await import("../shared/gsd-phase-state.js");
|
|
475
|
+
activateGSDPhaseState();
|
|
450
476
|
s.active = true;
|
|
451
477
|
s.stepMode = requestedStepMode;
|
|
452
478
|
s.verbose = verboseMode;
|
|
@@ -523,7 +549,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
523
549
|
}
|
|
524
550
|
}
|
|
525
551
|
// ── DB lifecycle ──
|
|
526
|
-
const gsdDbPath =
|
|
552
|
+
const gsdDbPath = resolveProjectRootDbPath(s.basePath);
|
|
527
553
|
const gsdDirPath = join(s.basePath, ".gsd");
|
|
528
554
|
if (existsSync(gsdDirPath) && !existsSync(gsdDbPath)) {
|
|
529
555
|
const hasDecisions = existsSync(join(gsdDirPath, "DECISIONS.md"));
|
|
@@ -571,6 +597,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
571
597
|
id: startModelSnapshot.id,
|
|
572
598
|
};
|
|
573
599
|
}
|
|
600
|
+
s.manualSessionModelOverride = manualSessionOverride ?? null;
|
|
574
601
|
// Apply worker model override from parallel orchestrator (#worker-model).
|
|
575
602
|
// GSD_WORKER_MODEL is injected by the coordinator when parallel.worker_model
|
|
576
603
|
// is configured, so parallel milestone workers use a cheaper model than the
|
|
@@ -82,7 +82,7 @@ export function clearInFlightTools() {
|
|
|
82
82
|
* handler. When these errors occur, retrying the same unit will produce the same
|
|
83
83
|
* failure, so the retry loop must be broken.
|
|
84
84
|
*/
|
|
85
|
-
const TOOL_INVOCATION_ERROR_RE = /Validation failed for tool|Expected ',' or '\}' in JSON
|
|
85
|
+
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;
|
|
86
86
|
/**
|
|
87
87
|
* Returns true if the error message indicates a tool invocation failure due to
|
|
88
88
|
* malformed/truncated arguments (as opposed to a normal tool execution error).
|
|
@@ -1795,7 +1795,7 @@ export function mergeMilestoneToMain(originalBasePath_, milestoneId, roadmapCont
|
|
|
1795
1795
|
// 12. Remove worktree directory first (must happen before branch deletion)
|
|
1796
1796
|
try {
|
|
1797
1797
|
removeWorktree(originalBasePath_, milestoneId, {
|
|
1798
|
-
branch:
|
|
1798
|
+
branch: milestoneBranch,
|
|
1799
1799
|
deleteBranch: false,
|
|
1800
1800
|
});
|
|
1801
1801
|
}
|
|
@@ -34,6 +34,7 @@ import { preDispatchHealthGate, resetProactiveHealing, setLevelChangeCallback, }
|
|
|
34
34
|
import { clearSkillSnapshot } from "./skill-discovery.js";
|
|
35
35
|
import { captureAvailableSkills, resetSkillTelemetry, } from "./skill-telemetry.js";
|
|
36
36
|
import { getRtkSessionSavings } from "../shared/rtk-session-stats.js";
|
|
37
|
+
import { deactivateGSD } from "../shared/gsd-phase-state.js";
|
|
37
38
|
import { initMetrics, resetMetrics, getLedger, getProjectTotals, formatCost, formatTokenCount, } from "./metrics.js";
|
|
38
39
|
import { logWarning } from "./workflow-logger.js";
|
|
39
40
|
import { homedir } from "node:os";
|
|
@@ -49,6 +50,7 @@ import { pruneQueueOrder } from "./queue-order.js";
|
|
|
49
50
|
import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
|
|
50
51
|
import { reconcileMergeState, } from "./auto-recovery.js";
|
|
51
52
|
import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
|
|
53
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
52
54
|
import { initRegistry, convertDispatchRules } from "./rule-registry.js";
|
|
53
55
|
import { emitJournalEvent as _emitJournalEvent } from "./journal.js";
|
|
54
56
|
import { updateProgressWidget as _updateProgressWidget, updateSliceProgressCache, clearSliceProgressCache, hideFooter, } from "./auto-dashboard.js";
|
|
@@ -103,6 +105,40 @@ function restoreProjectRootEnv() {
|
|
|
103
105
|
s.hadProjectRootEnv = false;
|
|
104
106
|
s.projectRootEnvCaptured = false;
|
|
105
107
|
}
|
|
108
|
+
function captureMilestoneLockEnv(milestoneId) {
|
|
109
|
+
if (!s.milestoneLockEnvCaptured) {
|
|
110
|
+
s.hadMilestoneLockEnv = Object.prototype.hasOwnProperty.call(process.env, "GSD_MILESTONE_LOCK");
|
|
111
|
+
s.previousMilestoneLockEnv = process.env.GSD_MILESTONE_LOCK ?? null;
|
|
112
|
+
s.milestoneLockEnvCaptured = true;
|
|
113
|
+
}
|
|
114
|
+
if (milestoneId) {
|
|
115
|
+
process.env.GSD_MILESTONE_LOCK = milestoneId;
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
delete process.env.GSD_MILESTONE_LOCK;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function restoreMilestoneLockEnv() {
|
|
122
|
+
if (!s.milestoneLockEnvCaptured)
|
|
123
|
+
return;
|
|
124
|
+
if (s.hadMilestoneLockEnv && s.previousMilestoneLockEnv !== null) {
|
|
125
|
+
process.env.GSD_MILESTONE_LOCK = s.previousMilestoneLockEnv;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
delete process.env.GSD_MILESTONE_LOCK;
|
|
129
|
+
}
|
|
130
|
+
s.previousMilestoneLockEnv = null;
|
|
131
|
+
s.hadMilestoneLockEnv = false;
|
|
132
|
+
s.milestoneLockEnvCaptured = false;
|
|
133
|
+
}
|
|
134
|
+
export function startAutoDetached(ctx, pi, base, verboseMode, options) {
|
|
135
|
+
void startAuto(ctx, pi, base, verboseMode, options).catch((err) => {
|
|
136
|
+
const message = getErrorMessage(err);
|
|
137
|
+
ctx.ui.notify(`Auto-start failed: ${message}`, "error");
|
|
138
|
+
logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
|
|
139
|
+
debugLog("auto-start-failed", { error: message });
|
|
140
|
+
});
|
|
141
|
+
}
|
|
106
142
|
export function shouldUseWorktreeIsolation() {
|
|
107
143
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
108
144
|
if (prefs?.isolation === "worktree")
|
|
@@ -324,6 +360,7 @@ function clearUnitTimeout() {
|
|
|
324
360
|
/** Build snapshot metric opts. */
|
|
325
361
|
function buildSnapshotOpts(_unitType, _unitId) {
|
|
326
362
|
return {
|
|
363
|
+
...(s.autoStartTime > 0 ? { autoSessionKey: String(s.autoStartTime) } : {}),
|
|
327
364
|
promptCharCount: s.lastPromptCharCount,
|
|
328
365
|
baselineCharCount: s.lastBaselineCharCount,
|
|
329
366
|
...(s.currentUnitRouting ?? {}),
|
|
@@ -338,8 +375,10 @@ function handleLostSessionLock(ctx, lockStatus) {
|
|
|
338
375
|
});
|
|
339
376
|
s.active = false;
|
|
340
377
|
s.paused = false;
|
|
378
|
+
deactivateGSD();
|
|
341
379
|
clearUnitTimeout();
|
|
342
380
|
restoreProjectRootEnv();
|
|
381
|
+
restoreMilestoneLockEnv();
|
|
343
382
|
deregisterSigtermHandler();
|
|
344
383
|
clearCmuxSidebar(loadEffectiveGSDPreferences()?.preferences);
|
|
345
384
|
const base = lockBase();
|
|
@@ -369,8 +408,10 @@ function handleLostSessionLock(ctx, lockStatus) {
|
|
|
369
408
|
function cleanupAfterLoopExit(ctx) {
|
|
370
409
|
s.currentUnit = null;
|
|
371
410
|
s.active = false;
|
|
411
|
+
deactivateGSD();
|
|
372
412
|
clearUnitTimeout();
|
|
373
413
|
restoreProjectRootEnv();
|
|
414
|
+
restoreMilestoneLockEnv();
|
|
374
415
|
// Clear crash lock and release session lock so the next `/gsd next` does
|
|
375
416
|
// not see a stale lock with the current PID and treat it as a "remote"
|
|
376
417
|
// session (which would cause it to SIGTERM itself). (#2730)
|
|
@@ -628,6 +669,7 @@ export async function stopAuto(ctx, pi, reason) {
|
|
|
628
669
|
ctx?.ui.setWidget("gsd-progress", undefined);
|
|
629
670
|
ctx?.ui.setFooter(undefined);
|
|
630
671
|
restoreProjectRootEnv();
|
|
672
|
+
restoreMilestoneLockEnv();
|
|
631
673
|
// Reset all session state in one call
|
|
632
674
|
s.reset();
|
|
633
675
|
}
|
|
@@ -673,6 +715,7 @@ export async function pauseAuto(ctx, _pi, _errorContext) {
|
|
|
673
715
|
activeEngineId: s.activeEngineId,
|
|
674
716
|
activeRunDir: s.activeRunDir,
|
|
675
717
|
autoStartTime: s.autoStartTime,
|
|
718
|
+
milestoneLock: s.sessionMilestoneLock ?? undefined,
|
|
676
719
|
};
|
|
677
720
|
const runtimeDir = join(gsdRoot(s.originalBasePath || s.basePath), "runtime");
|
|
678
721
|
mkdirSync(runtimeDir, { recursive: true });
|
|
@@ -703,7 +746,9 @@ export async function pauseAuto(ctx, _pi, _errorContext) {
|
|
|
703
746
|
_resetPendingResolve();
|
|
704
747
|
s.active = false;
|
|
705
748
|
s.paused = true;
|
|
749
|
+
deactivateGSD();
|
|
706
750
|
restoreProjectRootEnv();
|
|
751
|
+
restoreMilestoneLockEnv();
|
|
707
752
|
s.pendingVerificationRetry = null;
|
|
708
753
|
s.verificationRetryCount.clear();
|
|
709
754
|
ctx?.ui.setStatus("gsd-auto", "paused");
|
|
@@ -859,6 +904,12 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
859
904
|
}
|
|
860
905
|
const requestedStepMode = options?.step ?? false;
|
|
861
906
|
const interruptedAssessment = options?.interrupted ?? null;
|
|
907
|
+
if (options?.milestoneLock !== undefined) {
|
|
908
|
+
s.sessionMilestoneLock = options.milestoneLock ?? null;
|
|
909
|
+
}
|
|
910
|
+
if (s.sessionMilestoneLock) {
|
|
911
|
+
captureMilestoneLockEnv(s.sessionMilestoneLock);
|
|
912
|
+
}
|
|
862
913
|
// Escape stale worktree cwd from a previous milestone (#608).
|
|
863
914
|
base = escapeStaleWorktree(base);
|
|
864
915
|
const freshStartAssessment = interruptedAssessment
|
|
@@ -883,6 +934,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
883
934
|
s.originalBasePath = meta.originalBasePath || base;
|
|
884
935
|
s.stepMode = meta.stepMode ?? requestedStepMode;
|
|
885
936
|
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
937
|
+
s.sessionMilestoneLock = meta.milestoneLock ?? null;
|
|
886
938
|
s.paused = true;
|
|
887
939
|
try {
|
|
888
940
|
unlinkSync(pausedPath);
|
|
@@ -918,6 +970,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
918
970
|
s.pausedUnitType = meta.unitType ?? null;
|
|
919
971
|
s.pausedUnitId = meta.unitId ?? null;
|
|
920
972
|
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
973
|
+
s.sessionMilestoneLock = meta.milestoneLock ?? null;
|
|
921
974
|
s.paused = true;
|
|
922
975
|
try {
|
|
923
976
|
unlinkSync(pausedPath);
|
|
@@ -946,6 +999,9 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
946
999
|
if (!s.autoStartTime || s.autoStartTime <= 0)
|
|
947
1000
|
s.autoStartTime = Date.now();
|
|
948
1001
|
}
|
|
1002
|
+
if (s.sessionMilestoneLock) {
|
|
1003
|
+
captureMilestoneLockEnv(s.sessionMilestoneLock);
|
|
1004
|
+
}
|
|
949
1005
|
if (!s.paused) {
|
|
950
1006
|
s.stepMode = requestedStepMode;
|
|
951
1007
|
}
|