gsd-pi 2.71.0-dev.977c553 → 2.71.0-dev.d4d916a
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/dist/cli.js +12 -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 +6 -6
- 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/extensions/claude-code-cli/stream-adapter.js +10 -4
- 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 +1 -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-start.js +31 -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 +52 -0
- 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/error-classifier.js +1 -1
- package/dist/resources/extensions/gsd/forensics.js +19 -6
- 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/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/prompts/complete-slice.md +2 -2
- package/dist/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/dist/resources/extensions/gsd/prompts/execute-task.md +20 -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 +2 -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/ollama/index.js +13 -5
- 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 +14 -14
- 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/required-server-files.json +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.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 +14 -14
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +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/server.js +1 -1
- package/package.json +1 -1
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +21 -11
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/src/workflow-tools.test.ts +110 -0
- package/packages/mcp-server/src/workflow-tools.ts +31 -11
- 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/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/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/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/src/resources/GSD-WORKFLOW.md +1 -1
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +13 -5
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +56 -4
- 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 +2 -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-start.ts +38 -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 +68 -0
- 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/error-classifier.ts +1 -1
- package/src/resources/extensions/gsd/forensics.ts +23 -7
- 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/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/prompts/complete-slice.md +2 -2
- package/src/resources/extensions/gsd/prompts/discuss.md +2 -0
- package/src/resources/extensions/gsd/prompts/execute-task.md +20 -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 +2 -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/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-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/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/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/provider-errors.test.ts +7 -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/ollama/index.ts +13 -3
- package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
- package/src/resources/skills/create-skill/SKILL.md +2 -0
- /package/dist/web/standalone/.next/static/{4xyaXTn7-shVHaGMcl75o → IRnpNeY-_eO7SxKBIkTbL}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{4xyaXTn7-shVHaGMcl75o → IRnpNeY-_eO7SxKBIkTbL}/_ssgManifest.js +0 -0
|
@@ -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) {
|
|
@@ -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 {
|
|
@@ -523,7 +546,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
523
546
|
}
|
|
524
547
|
}
|
|
525
548
|
// ── DB lifecycle ──
|
|
526
|
-
const gsdDbPath =
|
|
549
|
+
const gsdDbPath = resolveProjectRootDbPath(s.basePath);
|
|
527
550
|
const gsdDirPath = join(s.basePath, ".gsd");
|
|
528
551
|
if (existsSync(gsdDirPath) && !existsSync(gsdDbPath)) {
|
|
529
552
|
const hasDecisions = existsSync(join(gsdDirPath, "DECISIONS.md"));
|
|
@@ -571,6 +594,7 @@ export async function bootstrapAutoSession(s, ctx, pi, base, verboseMode, reques
|
|
|
571
594
|
id: startModelSnapshot.id,
|
|
572
595
|
};
|
|
573
596
|
}
|
|
597
|
+
s.manualSessionModelOverride = manualSessionOverride ?? null;
|
|
574
598
|
// Apply worker model override from parallel orchestrator (#worker-model).
|
|
575
599
|
// GSD_WORKER_MODEL is injected by the coordinator when parallel.worker_model
|
|
576
600
|
// 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
|
}
|
|
@@ -49,6 +49,7 @@ import { pruneQueueOrder } from "./queue-order.js";
|
|
|
49
49
|
import { debugLog, isDebugEnabled, writeDebugSummary } from "./debug-logger.js";
|
|
50
50
|
import { reconcileMergeState, } from "./auto-recovery.js";
|
|
51
51
|
import { resolveDispatch, DISPATCH_RULES } from "./auto-dispatch.js";
|
|
52
|
+
import { getErrorMessage } from "./error-utils.js";
|
|
52
53
|
import { initRegistry, convertDispatchRules } from "./rule-registry.js";
|
|
53
54
|
import { emitJournalEvent as _emitJournalEvent } from "./journal.js";
|
|
54
55
|
import { updateProgressWidget as _updateProgressWidget, updateSliceProgressCache, clearSliceProgressCache, hideFooter, } from "./auto-dashboard.js";
|
|
@@ -103,6 +104,40 @@ function restoreProjectRootEnv() {
|
|
|
103
104
|
s.hadProjectRootEnv = false;
|
|
104
105
|
s.projectRootEnvCaptured = false;
|
|
105
106
|
}
|
|
107
|
+
function captureMilestoneLockEnv(milestoneId) {
|
|
108
|
+
if (!s.milestoneLockEnvCaptured) {
|
|
109
|
+
s.hadMilestoneLockEnv = Object.prototype.hasOwnProperty.call(process.env, "GSD_MILESTONE_LOCK");
|
|
110
|
+
s.previousMilestoneLockEnv = process.env.GSD_MILESTONE_LOCK ?? null;
|
|
111
|
+
s.milestoneLockEnvCaptured = true;
|
|
112
|
+
}
|
|
113
|
+
if (milestoneId) {
|
|
114
|
+
process.env.GSD_MILESTONE_LOCK = milestoneId;
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
delete process.env.GSD_MILESTONE_LOCK;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function restoreMilestoneLockEnv() {
|
|
121
|
+
if (!s.milestoneLockEnvCaptured)
|
|
122
|
+
return;
|
|
123
|
+
if (s.hadMilestoneLockEnv && s.previousMilestoneLockEnv !== null) {
|
|
124
|
+
process.env.GSD_MILESTONE_LOCK = s.previousMilestoneLockEnv;
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
delete process.env.GSD_MILESTONE_LOCK;
|
|
128
|
+
}
|
|
129
|
+
s.previousMilestoneLockEnv = null;
|
|
130
|
+
s.hadMilestoneLockEnv = false;
|
|
131
|
+
s.milestoneLockEnvCaptured = false;
|
|
132
|
+
}
|
|
133
|
+
export function startAutoDetached(ctx, pi, base, verboseMode, options) {
|
|
134
|
+
void startAuto(ctx, pi, base, verboseMode, options).catch((err) => {
|
|
135
|
+
const message = getErrorMessage(err);
|
|
136
|
+
ctx.ui.notify(`Auto-start failed: ${message}`, "error");
|
|
137
|
+
logWarning("engine", `auto start error: ${message}`, { file: "auto.ts" });
|
|
138
|
+
debugLog("auto-start-failed", { error: message });
|
|
139
|
+
});
|
|
140
|
+
}
|
|
106
141
|
export function shouldUseWorktreeIsolation() {
|
|
107
142
|
const prefs = loadEffectiveGSDPreferences()?.preferences?.git;
|
|
108
143
|
if (prefs?.isolation === "worktree")
|
|
@@ -324,6 +359,7 @@ function clearUnitTimeout() {
|
|
|
324
359
|
/** Build snapshot metric opts. */
|
|
325
360
|
function buildSnapshotOpts(_unitType, _unitId) {
|
|
326
361
|
return {
|
|
362
|
+
...(s.autoStartTime > 0 ? { autoSessionKey: String(s.autoStartTime) } : {}),
|
|
327
363
|
promptCharCount: s.lastPromptCharCount,
|
|
328
364
|
baselineCharCount: s.lastBaselineCharCount,
|
|
329
365
|
...(s.currentUnitRouting ?? {}),
|
|
@@ -340,6 +376,7 @@ function handleLostSessionLock(ctx, lockStatus) {
|
|
|
340
376
|
s.paused = false;
|
|
341
377
|
clearUnitTimeout();
|
|
342
378
|
restoreProjectRootEnv();
|
|
379
|
+
restoreMilestoneLockEnv();
|
|
343
380
|
deregisterSigtermHandler();
|
|
344
381
|
clearCmuxSidebar(loadEffectiveGSDPreferences()?.preferences);
|
|
345
382
|
const base = lockBase();
|
|
@@ -371,6 +408,7 @@ function cleanupAfterLoopExit(ctx) {
|
|
|
371
408
|
s.active = false;
|
|
372
409
|
clearUnitTimeout();
|
|
373
410
|
restoreProjectRootEnv();
|
|
411
|
+
restoreMilestoneLockEnv();
|
|
374
412
|
// Clear crash lock and release session lock so the next `/gsd next` does
|
|
375
413
|
// not see a stale lock with the current PID and treat it as a "remote"
|
|
376
414
|
// session (which would cause it to SIGTERM itself). (#2730)
|
|
@@ -628,6 +666,7 @@ export async function stopAuto(ctx, pi, reason) {
|
|
|
628
666
|
ctx?.ui.setWidget("gsd-progress", undefined);
|
|
629
667
|
ctx?.ui.setFooter(undefined);
|
|
630
668
|
restoreProjectRootEnv();
|
|
669
|
+
restoreMilestoneLockEnv();
|
|
631
670
|
// Reset all session state in one call
|
|
632
671
|
s.reset();
|
|
633
672
|
}
|
|
@@ -673,6 +712,7 @@ export async function pauseAuto(ctx, _pi, _errorContext) {
|
|
|
673
712
|
activeEngineId: s.activeEngineId,
|
|
674
713
|
activeRunDir: s.activeRunDir,
|
|
675
714
|
autoStartTime: s.autoStartTime,
|
|
715
|
+
milestoneLock: s.sessionMilestoneLock ?? undefined,
|
|
676
716
|
};
|
|
677
717
|
const runtimeDir = join(gsdRoot(s.originalBasePath || s.basePath), "runtime");
|
|
678
718
|
mkdirSync(runtimeDir, { recursive: true });
|
|
@@ -704,6 +744,7 @@ export async function pauseAuto(ctx, _pi, _errorContext) {
|
|
|
704
744
|
s.active = false;
|
|
705
745
|
s.paused = true;
|
|
706
746
|
restoreProjectRootEnv();
|
|
747
|
+
restoreMilestoneLockEnv();
|
|
707
748
|
s.pendingVerificationRetry = null;
|
|
708
749
|
s.verificationRetryCount.clear();
|
|
709
750
|
ctx?.ui.setStatus("gsd-auto", "paused");
|
|
@@ -859,6 +900,12 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
859
900
|
}
|
|
860
901
|
const requestedStepMode = options?.step ?? false;
|
|
861
902
|
const interruptedAssessment = options?.interrupted ?? null;
|
|
903
|
+
if (options?.milestoneLock !== undefined) {
|
|
904
|
+
s.sessionMilestoneLock = options.milestoneLock ?? null;
|
|
905
|
+
}
|
|
906
|
+
if (s.sessionMilestoneLock) {
|
|
907
|
+
captureMilestoneLockEnv(s.sessionMilestoneLock);
|
|
908
|
+
}
|
|
862
909
|
// Escape stale worktree cwd from a previous milestone (#608).
|
|
863
910
|
base = escapeStaleWorktree(base);
|
|
864
911
|
const freshStartAssessment = interruptedAssessment
|
|
@@ -883,6 +930,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
883
930
|
s.originalBasePath = meta.originalBasePath || base;
|
|
884
931
|
s.stepMode = meta.stepMode ?? requestedStepMode;
|
|
885
932
|
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
933
|
+
s.sessionMilestoneLock = meta.milestoneLock ?? null;
|
|
886
934
|
s.paused = true;
|
|
887
935
|
try {
|
|
888
936
|
unlinkSync(pausedPath);
|
|
@@ -918,6 +966,7 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
918
966
|
s.pausedUnitType = meta.unitType ?? null;
|
|
919
967
|
s.pausedUnitId = meta.unitId ?? null;
|
|
920
968
|
s.autoStartTime = meta.autoStartTime || Date.now();
|
|
969
|
+
s.sessionMilestoneLock = meta.milestoneLock ?? null;
|
|
921
970
|
s.paused = true;
|
|
922
971
|
try {
|
|
923
972
|
unlinkSync(pausedPath);
|
|
@@ -946,6 +995,9 @@ export async function startAuto(ctx, pi, base, verboseMode, options) {
|
|
|
946
995
|
if (!s.autoStartTime || s.autoStartTime <= 0)
|
|
947
996
|
s.autoStartTime = Date.now();
|
|
948
997
|
}
|
|
998
|
+
if (s.sessionMilestoneLock) {
|
|
999
|
+
captureMilestoneLockEnv(s.sessionMilestoneLock);
|
|
1000
|
+
}
|
|
949
1001
|
if (!s.paused) {
|
|
950
1002
|
s.stepMode = requestedStepMode;
|
|
951
1003
|
}
|
|
@@ -111,6 +111,8 @@ export function registerHooks(pi) {
|
|
|
111
111
|
return { cancel: true };
|
|
112
112
|
}
|
|
113
113
|
const basePath = process.cwd();
|
|
114
|
+
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
115
|
+
await ensureDbOpen();
|
|
114
116
|
const state = await deriveState(basePath);
|
|
115
117
|
if (!state.activeMilestone || !state.activeSlice || !state.activeTask)
|
|
116
118
|
return;
|
|
@@ -4,61 +4,73 @@ import { Key } from "@gsd/pi-tui";
|
|
|
4
4
|
import { GSDDashboardOverlay } from "../dashboard-overlay.js";
|
|
5
5
|
import { GSDNotificationOverlay } from "../notification-overlay.js";
|
|
6
6
|
import { ParallelMonitorOverlay } from "../parallel-monitor-overlay.js";
|
|
7
|
+
import { GSD_SHORTCUTS } from "../shortcut-defs.js";
|
|
7
8
|
import { projectRoot } from "../commands/context.js";
|
|
8
9
|
import { shortcutDesc } from "../../shared/mod.js";
|
|
9
10
|
export function registerShortcuts(pi) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
11
|
+
const overlayOptions = {
|
|
12
|
+
width: "90%",
|
|
13
|
+
minWidth: 80,
|
|
14
|
+
maxHeight: "92%",
|
|
15
|
+
anchor: "center",
|
|
16
|
+
};
|
|
17
|
+
const openDashboardOverlay = async (ctx) => {
|
|
18
|
+
const basePath = projectRoot();
|
|
19
|
+
if (!existsSync(join(basePath, ".gsd"))) {
|
|
20
|
+
ctx.ui.notify("No .gsd/ directory found. Run /gsd to start.", "info");
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
await ctx.ui.custom((tui, theme, _kb, done) => new GSDDashboardOverlay(tui, theme, () => done(true)), {
|
|
24
|
+
overlay: true,
|
|
25
|
+
overlayOptions,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const openNotificationsOverlay = async (ctx) => {
|
|
29
|
+
await ctx.ui.custom((tui, theme, _kb, done) => new GSDNotificationOverlay(tui, theme, () => done(true)), {
|
|
30
|
+
overlay: true,
|
|
31
|
+
overlayOptions: {
|
|
32
|
+
width: "80%",
|
|
33
|
+
minWidth: 60,
|
|
34
|
+
maxHeight: "88%",
|
|
35
|
+
anchor: "center",
|
|
36
|
+
backdrop: true,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
const openParallelOverlay = async (ctx) => {
|
|
41
|
+
const basePath = projectRoot();
|
|
42
|
+
const parallelDir = join(basePath, ".gsd", "parallel");
|
|
43
|
+
if (!existsSync(parallelDir)) {
|
|
44
|
+
ctx.ui.notify("No parallel workers found. Run /gsd parallel start first.", "info");
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await ctx.ui.custom((tui, theme, _kb, done) => new ParallelMonitorOverlay(tui, theme, () => done(true), basePath), {
|
|
48
|
+
overlay: true,
|
|
49
|
+
overlayOptions,
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
pi.registerShortcut(Key.ctrlAlt(GSD_SHORTCUTS.dashboard.key), {
|
|
53
|
+
description: shortcutDesc(GSD_SHORTCUTS.dashboard.action, GSD_SHORTCUTS.dashboard.command),
|
|
54
|
+
handler: openDashboardOverlay,
|
|
28
55
|
});
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
overlay: true,
|
|
34
|
-
overlayOptions: {
|
|
35
|
-
width: "80%",
|
|
36
|
-
minWidth: 60,
|
|
37
|
-
maxHeight: "88%",
|
|
38
|
-
anchor: "center",
|
|
39
|
-
backdrop: true,
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
},
|
|
56
|
+
// Fallback for terminals where Ctrl+Alt letter chords are not forwarded reliably.
|
|
57
|
+
pi.registerShortcut(Key.ctrlShift(GSD_SHORTCUTS.dashboard.key), {
|
|
58
|
+
description: shortcutDesc(`${GSD_SHORTCUTS.dashboard.action} (fallback)`, GSD_SHORTCUTS.dashboard.command),
|
|
59
|
+
handler: openDashboardOverlay,
|
|
43
60
|
});
|
|
44
|
-
pi.registerShortcut(Key.ctrlAlt(
|
|
45
|
-
description: shortcutDesc(
|
|
46
|
-
handler:
|
|
47
|
-
const basePath = projectRoot();
|
|
48
|
-
const parallelDir = join(basePath, ".gsd", "parallel");
|
|
49
|
-
if (!existsSync(parallelDir)) {
|
|
50
|
-
ctx.ui.notify("No parallel workers found. Run /gsd parallel start first.", "info");
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
await ctx.ui.custom((tui, theme, _kb, done) => new ParallelMonitorOverlay(tui, theme, () => done(true)), {
|
|
54
|
-
overlay: true,
|
|
55
|
-
overlayOptions: {
|
|
56
|
-
width: "90%",
|
|
57
|
-
minWidth: 80,
|
|
58
|
-
maxHeight: "92%",
|
|
59
|
-
anchor: "center",
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
},
|
|
61
|
+
pi.registerShortcut(Key.ctrlAlt(GSD_SHORTCUTS.notifications.key), {
|
|
62
|
+
description: shortcutDesc(GSD_SHORTCUTS.notifications.action, GSD_SHORTCUTS.notifications.command),
|
|
63
|
+
handler: openNotificationsOverlay,
|
|
63
64
|
});
|
|
65
|
+
// Fallback for terminals where Ctrl+Alt letter chords are not forwarded reliably.
|
|
66
|
+
pi.registerShortcut(Key.ctrlShift(GSD_SHORTCUTS.notifications.key), {
|
|
67
|
+
description: shortcutDesc(`${GSD_SHORTCUTS.notifications.action} (fallback)`, GSD_SHORTCUTS.notifications.command),
|
|
68
|
+
handler: openNotificationsOverlay,
|
|
69
|
+
});
|
|
70
|
+
pi.registerShortcut(Key.ctrlAlt(GSD_SHORTCUTS.parallel.key), {
|
|
71
|
+
description: shortcutDesc(GSD_SHORTCUTS.parallel.action, GSD_SHORTCUTS.parallel.command),
|
|
72
|
+
handler: openParallelOverlay,
|
|
73
|
+
});
|
|
74
|
+
// No Ctrl+Shift+P fallback — conflicts with cycleModelBackward (shift+ctrl+p).
|
|
75
|
+
// Use Ctrl+Alt+P or /gsd parallel watch instead.
|
|
64
76
|
}
|
|
@@ -257,6 +257,10 @@ function buildWorktreeContextBlock() {
|
|
|
257
257
|
*/
|
|
258
258
|
const RESUME_INTENT_PATTERNS = /^(continue|resume|ok|go|go ahead|proceed|keep going|carry on|next|yes|yeah|yep|sure|do it|let's go|pick up where you left off)$/;
|
|
259
259
|
async function buildGuidedExecuteContextInjection(prompt, basePath) {
|
|
260
|
+
const ensureStateDbOpen = async () => {
|
|
261
|
+
const { ensureDbOpen } = await import("./dynamic-tools.js");
|
|
262
|
+
await ensureDbOpen();
|
|
263
|
+
};
|
|
260
264
|
const executeMatch = prompt.match(/Execute the next task:\s+(T\d+)\s+\("([^"]+)"\)\s+in slice\s+(S\d+)\s+of milestone\s+(M\d+(?:-[a-z0-9]{6})?)/i);
|
|
261
265
|
if (executeMatch) {
|
|
262
266
|
const [, taskId, taskTitle, sliceId, milestoneId] = executeMatch;
|
|
@@ -265,6 +269,7 @@ async function buildGuidedExecuteContextInjection(prompt, basePath) {
|
|
|
265
269
|
const resumeMatch = prompt.match(/Resume interrupted work\.[\s\S]*?slice\s+(S\d+)\s+of milestone\s+(M\d+(?:-[a-z0-9]{6})?)/i);
|
|
266
270
|
if (resumeMatch) {
|
|
267
271
|
const [, sliceId, milestoneId] = resumeMatch;
|
|
272
|
+
await ensureStateDbOpen();
|
|
268
273
|
const state = await deriveState(basePath);
|
|
269
274
|
if (state.activeMilestone?.id === milestoneId && state.activeSlice?.id === sliceId && state.activeTask) {
|
|
270
275
|
return buildTaskExecutionContextInjection(basePath, milestoneId, sliceId, state.activeTask.id, state.activeTask.title);
|
|
@@ -279,6 +284,7 @@ async function buildGuidedExecuteContextInjection(prompt, basePath) {
|
|
|
279
284
|
// replanning, gate evaluation, or other non-execution phases.
|
|
280
285
|
const trimmed = prompt.trim().toLowerCase().replace(/[.!?,]+$/g, "");
|
|
281
286
|
if (RESUME_INTENT_PATTERNS.test(trimmed)) {
|
|
287
|
+
await ensureStateDbOpen();
|
|
282
288
|
const state = await deriveState(basePath);
|
|
283
289
|
if (state.phase === "executing" && state.activeTask && state.activeMilestone && state.activeSlice) {
|
|
284
290
|
return buildTaskExecutionContextInjection(basePath, state.activeMilestone.id, state.activeSlice.id, state.activeTask.id, state.activeTask.title);
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { checkRemoteAutoSession, isAutoActive, isAutoPaused, stopAutoRemote } from "../auto.js";
|
|
2
|
-
import {
|
|
2
|
+
import { validateDirectory } from "../validate-directory.js";
|
|
3
3
|
import { resolveProjectRoot } from "../worktree.js";
|
|
4
4
|
import { showNextAction } from "../../shared/tui.js";
|
|
5
5
|
import { handleStatus } from "./handlers/core.js";
|
|
6
|
+
/**
|
|
7
|
+
* Typed error for when GSD is run outside a valid project directory.
|
|
8
|
+
* Command handlers catch this to show a friendly message instead of a raw exception.
|
|
9
|
+
*/
|
|
10
|
+
export class GSDNoProjectError extends Error {
|
|
11
|
+
constructor(reason) {
|
|
12
|
+
super(reason);
|
|
13
|
+
this.name = "GSDNoProjectError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
6
16
|
export function projectRoot() {
|
|
7
17
|
let cwd;
|
|
8
18
|
try {
|
|
@@ -13,11 +23,10 @@ export function projectRoot() {
|
|
|
13
23
|
cwd = process.env.HOME ?? "/";
|
|
14
24
|
}
|
|
15
25
|
const root = resolveProjectRoot(cwd);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
assertSafeDirectory(root);
|
|
26
|
+
const pathToCheck = root !== cwd ? cwd : root;
|
|
27
|
+
const result = validateDirectory(pathToCheck);
|
|
28
|
+
if (result.severity === "blocked") {
|
|
29
|
+
throw new GSDNoProjectError(result.reason ?? "GSD must be run inside a project directory.");
|
|
21
30
|
}
|
|
22
31
|
return root;
|
|
23
32
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GSDNoProjectError } from "./context.js";
|
|
1
2
|
import { handleAutoCommand } from "./handlers/auto.js";
|
|
2
3
|
import { handleCoreCommand } from "./handlers/core.js";
|
|
3
4
|
import { handleOpsCommand } from "./handlers/ops.js";
|
|
@@ -12,10 +13,19 @@ export async function handleGSDCommand(args, ctx, pi) {
|
|
|
12
13
|
() => handleWorkflowCommand(trimmed, ctx, pi),
|
|
13
14
|
() => handleOpsCommand(trimmed, ctx, pi),
|
|
14
15
|
];
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
try {
|
|
17
|
+
for (const handler of handlers) {
|
|
18
|
+
if (await handler()) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
if (err instanceof GSDNoProjectError) {
|
|
25
|
+
ctx.ui.notify(`${err.message} \`cd\` into a project directory first.`, "warning");
|
|
17
26
|
return;
|
|
18
27
|
}
|
|
28
|
+
throw err;
|
|
19
29
|
}
|
|
20
30
|
ctx.ui.notify(`Unknown: /gsd ${trimmed}. Run /gsd help for available commands.`, "warning");
|
|
21
31
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { resolve } from "node:path";
|
|
3
3
|
import { enableDebug } from "../../debug-logger.js";
|
|
4
|
-
import { isAutoActive, isAutoPaused, pauseAuto,
|
|
4
|
+
import { isAutoActive, isAutoPaused, pauseAuto, startAutoDetached, stopAuto, stopAutoRemote } from "../../auto.js";
|
|
5
5
|
import { handleRate } from "../../commands-rate.js";
|
|
6
6
|
import { guardRemoteSession, projectRoot } from "../context.js";
|
|
7
7
|
import { findMilestoneIds } from "../../milestone-id-utils.js";
|
|
@@ -36,27 +36,6 @@ export function parseMilestoneTarget(input) {
|
|
|
36
36
|
const rest = input.replace(match[0], "").replace(/\s+/g, " ").trim();
|
|
37
37
|
return { milestoneId: match[1], rest };
|
|
38
38
|
}
|
|
39
|
-
/**
|
|
40
|
-
* Set GSD_MILESTONE_LOCK to target a specific milestone, then run `fn`.
|
|
41
|
-
* Clears the env var when `fn` resolves or rejects, so the lock does not
|
|
42
|
-
* leak into subsequent commands in the same process.
|
|
43
|
-
*/
|
|
44
|
-
async function withMilestoneLock(milestoneId, fn) {
|
|
45
|
-
const previous = process.env.GSD_MILESTONE_LOCK;
|
|
46
|
-
process.env.GSD_MILESTONE_LOCK = milestoneId;
|
|
47
|
-
try {
|
|
48
|
-
await fn();
|
|
49
|
-
}
|
|
50
|
-
finally {
|
|
51
|
-
// Restore previous value (undefined → delete, else restore).
|
|
52
|
-
if (previous === undefined) {
|
|
53
|
-
delete process.env.GSD_MILESTONE_LOCK;
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
process.env.GSD_MILESTONE_LOCK = previous;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
39
|
export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
61
40
|
if (trimmed === "next" || trimmed.startsWith("next ")) {
|
|
62
41
|
if (trimmed.includes("--dry-run")) {
|
|
@@ -79,12 +58,10 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
|
79
58
|
return true;
|
|
80
59
|
}
|
|
81
60
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
await startAuto(ctx, pi, projectRoot(), verboseMode, { step: true });
|
|
87
|
-
}
|
|
61
|
+
startAutoDetached(ctx, pi, projectRoot(), verboseMode, {
|
|
62
|
+
step: true,
|
|
63
|
+
milestoneLock: milestoneId,
|
|
64
|
+
});
|
|
88
65
|
return true;
|
|
89
66
|
}
|
|
90
67
|
if (trimmed === "auto" || trimmed.startsWith("auto ")) {
|
|
@@ -122,12 +99,12 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
|
122
99
|
await showHeadlessMilestoneCreation(ctx, pi, projectRoot(), seedContent);
|
|
123
100
|
}
|
|
124
101
|
else if (milestoneId) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
102
|
+
startAutoDetached(ctx, pi, projectRoot(), verboseMode, {
|
|
103
|
+
milestoneLock: milestoneId,
|
|
104
|
+
});
|
|
128
105
|
}
|
|
129
106
|
else {
|
|
130
|
-
|
|
107
|
+
startAutoDetached(ctx, pi, projectRoot(), verboseMode);
|
|
131
108
|
}
|
|
132
109
|
return true;
|
|
133
110
|
}
|
|
@@ -168,7 +145,7 @@ export async function handleAutoCommand(trimmed, ctx, pi) {
|
|
|
168
145
|
if (trimmed === "") {
|
|
169
146
|
if (!(await guardRemoteSession(ctx, pi)))
|
|
170
147
|
return true;
|
|
171
|
-
|
|
148
|
+
startAutoDetached(ctx, pi, projectRoot(), false, { step: true });
|
|
172
149
|
return true;
|
|
173
150
|
}
|
|
174
151
|
return false;
|