@opengsd/gsd-pi 1.2.0-dev.9ad8ae33 → 1.2.0-dev.a6376d75
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-model-override.d.ts +15 -0
- package/dist/cli-model-override.js +21 -0
- package/dist/cli.js +1 -18
- package/dist/loader.js +6 -4
- package/dist/register-agent-bundles.d.ts +11 -2
- package/dist/register-agent-bundles.js +18 -4
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/ask-user-questions.js +3 -2
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +447 -215
- package/dist/resources/extensions/claude-code-cli/turn-assembler.js +33 -1
- package/dist/resources/extensions/gsd/auto/closeout.js +215 -0
- package/dist/resources/extensions/gsd/auto/dispatch-history.js +21 -6
- package/dist/resources/extensions/gsd/auto/dispatch.js +365 -0
- package/dist/resources/extensions/gsd/auto/finalize.js +347 -0
- package/dist/resources/extensions/gsd/auto/loop.js +4 -1
- package/dist/resources/extensions/gsd/auto/milestone-lease-reclaim.js +56 -0
- package/dist/resources/extensions/gsd/auto/orchestrator.js +85 -15
- package/dist/resources/extensions/gsd/auto/phase-helpers.js +146 -0
- package/dist/resources/extensions/gsd/auto/phases.js +17 -2372
- package/dist/resources/extensions/gsd/auto/pre-dispatch.js +534 -0
- package/dist/resources/extensions/gsd/auto/unit-phase.js +694 -0
- package/dist/resources/extensions/gsd/auto/workflow-unit-dispatch.js +1 -1
- package/dist/resources/extensions/gsd/auto/worktree-safety-phase.js +125 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
- package/dist/resources/extensions/gsd/auto.js +15 -1
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +37 -7
- package/dist/resources/extensions/gsd/commands-mcp-status.js +2 -2
- package/dist/resources/extensions/gsd/commands-workflow-templates.js +9 -2
- package/dist/resources/extensions/gsd/db/queries.js +30 -0
- package/dist/resources/extensions/gsd/doctor-environment.js +256 -125
- package/dist/resources/extensions/gsd/guided-flow.js +88 -2
- package/dist/resources/extensions/gsd/health-widget.js +87 -28
- package/dist/resources/extensions/gsd/mcp-bridge.js +10 -0
- package/dist/resources/extensions/gsd/milestone-settlement.js +2 -2
- package/dist/resources/extensions/gsd/notifications.js +12 -7
- package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/execute-task.md +2 -1
- package/dist/resources/extensions/gsd/prompts/run-uat.md +2 -0
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +2 -1
- package/dist/resources/extensions/gsd/skill-activation.js +3 -6
- package/dist/resources/extensions/gsd/state.js +6 -2
- package/dist/resources/extensions/gsd/tool-surface-readiness.js +83 -31
- package/dist/resources/extensions/gsd/tools/complete-task.js +62 -0
- package/dist/resources/extensions/gsd/unit-context-composer.js +1 -1
- package/dist/resources/extensions/gsd/unit-registry.js +34 -4
- package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +2 -0
- package/dist/resources/extensions/gsd/workflow-mcp-readiness-cache.js +105 -0
- package/dist/resources/extensions/gsd/worktree-safety.js +28 -26
- package/dist/resources/extensions/mcp-client/manager.js +6 -1
- package/dist/runtime-checks.d.ts +10 -0
- package/dist/runtime-checks.js +27 -0
- package/dist/tsconfig.extensions.tsbuildinfo +1 -1
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/prerender-manifest.json +3 -3
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +2 -2
- package/packages/cloud-mcp-gateway/package.json +2 -2
- package/packages/contracts/package.json +1 -1
- package/packages/daemon/package.json +4 -4
- package/packages/gsd-agent-core/dist/sdk.d.ts.map +1 -1
- package/packages/gsd-agent-core/dist/sdk.js +6 -4
- package/packages/gsd-agent-core/dist/sdk.js.map +1 -1
- package/packages/gsd-agent-core/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js +10 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +8 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +50 -6
- package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts +2 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +34 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +1 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +12 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.d.ts.map +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js +4 -0
- package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-settings.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/README.md +12 -3
- package/packages/mcp-server/dist/cli-runner.d.ts +40 -0
- package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -0
- package/packages/mcp-server/dist/cli-runner.js +137 -0
- package/packages/mcp-server/dist/cli-runner.js.map +1 -0
- package/packages/mcp-server/dist/cli.js +2 -58
- package/packages/mcp-server/dist/cli.js.map +1 -1
- package/packages/mcp-server/dist/pid-registry.d.ts +46 -0
- package/packages/mcp-server/dist/pid-registry.d.ts.map +1 -0
- package/packages/mcp-server/dist/pid-registry.js +452 -0
- package/packages/mcp-server/dist/pid-registry.js.map +1 -0
- package/packages/mcp-server/dist/probe-mode.d.ts +4 -0
- package/packages/mcp-server/dist/probe-mode.d.ts.map +1 -0
- package/packages/mcp-server/dist/probe-mode.js +10 -0
- package/packages/mcp-server/dist/probe-mode.js.map +1 -0
- package/packages/mcp-server/dist/stdio-watchdog.d.ts +8 -0
- package/packages/mcp-server/dist/stdio-watchdog.d.ts.map +1 -0
- package/packages/mcp-server/dist/stdio-watchdog.js +40 -0
- package/packages/mcp-server/dist/stdio-watchdog.js.map +1 -0
- package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
- package/packages/mcp-server/dist/workflow-tools.js +62 -43
- package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
- package/packages/mcp-server/package.json +5 -5
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/dist/agent-loop.js +43 -2
- package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +3 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/settings-manager.js +11 -0
- package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/theme/theme.js +45 -17
- package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/dist/index.d.ts +1 -1
- package/packages/pi-tui/dist/index.d.ts.map +1 -1
- package/packages/pi-tui/dist/index.js +1 -1
- package/packages/pi-tui/dist/index.js.map +1 -1
- package/packages/pi-tui/dist/terminal-image.d.ts +33 -0
- package/packages/pi-tui/dist/terminal-image.d.ts.map +1 -1
- package/packages/pi-tui/dist/terminal-image.js +54 -2
- package/packages/pi-tui/dist/terminal-image.js.map +1 -1
- package/packages/pi-tui/dist/tui.d.ts +8 -0
- package/packages/pi-tui/dist/tui.d.ts.map +1 -1
- package/packages/pi-tui/dist/tui.js +63 -18
- package/packages/pi-tui/dist/tui.js.map +1 -1
- package/packages/pi-tui/dist/utils.d.ts.map +1 -1
- package/packages/pi-tui/dist/utils.js +110 -36
- package/packages/pi-tui/dist/utils.js.map +1 -1
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/dist/theme/theme.d.ts.map +1 -1
- package/pkg/dist/theme/theme.js +45 -17
- package/pkg/dist/theme/theme.js.map +1 -1
- package/pkg/package.json +1 -1
- package/src/resources/extensions/ask-user-questions.ts +7 -2
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +531 -226
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +672 -7
- package/src/resources/extensions/claude-code-cli/turn-assembler.ts +38 -1
- package/src/resources/extensions/gsd/auto/closeout.ts +309 -0
- package/src/resources/extensions/gsd/auto/dispatch-history.ts +22 -6
- package/src/resources/extensions/gsd/auto/dispatch.ts +449 -0
- package/src/resources/extensions/gsd/auto/finalize.ts +445 -0
- package/src/resources/extensions/gsd/auto/loop.ts +4 -1
- package/src/resources/extensions/gsd/auto/milestone-lease-reclaim.ts +74 -0
- package/src/resources/extensions/gsd/auto/orchestrator.ts +95 -15
- package/src/resources/extensions/gsd/auto/phase-helpers.ts +199 -0
- package/src/resources/extensions/gsd/auto/phases.ts +58 -3061
- package/src/resources/extensions/gsd/auto/pre-dispatch.ts +704 -0
- package/src/resources/extensions/gsd/auto/unit-phase.ts +910 -0
- package/src/resources/extensions/gsd/auto/workflow-unit-dispatch.ts +1 -1
- package/src/resources/extensions/gsd/auto/worktree-safety-phase.ts +149 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
- package/src/resources/extensions/gsd/auto.ts +20 -1
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +56 -6
- package/src/resources/extensions/gsd/commands-mcp-status.ts +2 -2
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +11 -4
- package/src/resources/extensions/gsd/db/queries.ts +29 -0
- package/src/resources/extensions/gsd/doctor-environment.ts +267 -142
- package/src/resources/extensions/gsd/guided-flow.ts +128 -2
- package/src/resources/extensions/gsd/health-widget.ts +91 -27
- package/src/resources/extensions/gsd/mcp-bridge.ts +39 -0
- package/src/resources/extensions/gsd/milestone-settlement.ts +2 -2
- package/src/resources/extensions/gsd/notifications.ts +13 -6
- package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/execute-task.md +2 -1
- package/src/resources/extensions/gsd/prompts/run-uat.md +2 -0
- package/src/resources/extensions/gsd/prompts/workflow-start.md +2 -1
- package/src/resources/extensions/gsd/skill-activation.ts +3 -6
- package/src/resources/extensions/gsd/state.ts +7 -1
- package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-blocked-remediation-message.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-loop.test.ts +206 -22
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +76 -12
- package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +77 -1
- package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/auto-unit-closeout.test.ts +169 -1
- package/src/resources/extensions/gsd/tests/complete-task.test.ts +141 -5
- package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +2 -1
- package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +36 -0
- package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +55 -0
- package/src/resources/extensions/gsd/tests/dist-redirect.mjs +8 -0
- package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +117 -91
- package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +113 -0
- package/src/resources/extensions/gsd/tests/guided-dispatch-root.test.ts +16 -0
- package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/integration/doctor-environment-async.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/integration/run-uat.test.ts +18 -0
- package/src/resources/extensions/gsd/tests/journal-integration.test.ts +47 -16
- package/src/resources/extensions/gsd/tests/mcp-readiness-preflight.test.ts +205 -0
- package/src/resources/extensions/gsd/tests/mcp-status.test.ts +6 -5
- package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-report-path.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/notifications.test.ts +64 -9
- package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +5 -0
- package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/phases-terminal-complete-idempotent.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +10 -2
- package/src/resources/extensions/gsd/tests/provider-errors.test.ts +2 -4
- package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +31 -81
- package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +7 -1
- package/src/resources/extensions/gsd/tests/skill-activation.test.ts +20 -17
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +7 -3
- package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +184 -10
- package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/workflow-mcp-readiness-cache.test.ts +119 -0
- package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +65 -2
- package/src/resources/extensions/gsd/tests/workflow-phase-contract-matrix.test.ts +332 -0
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +92 -0
- package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +1 -1
- package/src/resources/extensions/gsd/tests/worktree-safety-phase.test.ts +100 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +72 -0
- package/src/resources/extensions/gsd/tool-surface-readiness.ts +126 -19
- package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
- package/src/resources/extensions/gsd/unit-context-composer.ts +1 -1
- package/src/resources/extensions/gsd/unit-registry.ts +34 -4
- package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +2 -0
- package/src/resources/extensions/gsd/workflow-mcp-readiness-cache.ts +150 -0
- package/src/resources/extensions/gsd/worktree-safety.ts +41 -39
- package/src/resources/extensions/mcp-client/manager.ts +7 -1
- /package/dist/web/standalone/.next/static/{FBNo5cT_chy7YNoAQsU3o → xyMkEaICFHJoa98VgJyzY}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{FBNo5cT_chy7YNoAQsU3o → xyMkEaICFHJoa98VgJyzY}/_ssgManifest.js +0 -0
|
@@ -10,7 +10,7 @@ import type {
|
|
|
10
10
|
} from "./types.js";
|
|
11
11
|
import { ExecutionGraphScheduler } from "../uok/execution-graph.js";
|
|
12
12
|
import type { UokGraphNode } from "../uok/contracts.js";
|
|
13
|
-
import { runUnitPhase } from "./
|
|
13
|
+
import { runUnitPhase } from "./unit-phase.js";
|
|
14
14
|
import { decideDispatchNodeKind } from "./workflow-kernel.js";
|
|
15
15
|
|
|
16
16
|
export type DispatchContract = "legacy-direct" | "uok-scheduler";
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Worktree-safety helpers shared across auto-loop phase modules.
|
|
3
|
+
|
|
4
|
+
import { classifyProject } from "../detection.js";
|
|
5
|
+
import { resolveEffectiveUnitIsolationMode, getIsolationMode } from "../preferences.js";
|
|
6
|
+
import { createWorktreeSafetyModule, type WorktreeSafetyResult } from "../worktree-safety.js";
|
|
7
|
+
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
8
|
+
import { resolveManifest } from "../unit-context-manifest.js";
|
|
9
|
+
import { debugLog } from "../debug-logger.js";
|
|
10
|
+
import { isSamePathLocal } from "./phase-helpers.js";
|
|
11
|
+
import { hasHeldMilestoneLease, reclaimMissingMilestoneLease } from "./milestone-lease-reclaim.js";
|
|
12
|
+
import type { IterationContext } from "./types.js";
|
|
13
|
+
|
|
14
|
+
export function shouldDegradeEmptyWorktreeToProjectRoot(
|
|
15
|
+
worktreeClassification: ReturnType<typeof classifyProject>,
|
|
16
|
+
projectRootClassification: ReturnType<typeof classifyProject>,
|
|
17
|
+
): boolean {
|
|
18
|
+
return (
|
|
19
|
+
worktreeClassification.kind === "greenfield" &&
|
|
20
|
+
projectRootClassification.kind !== "greenfield" &&
|
|
21
|
+
projectRootClassification.kind !== "invalid-repo"
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function unitWritesSource(unitType: string): boolean | null {
|
|
26
|
+
if (unitType.startsWith("hook/")) return false;
|
|
27
|
+
// Backward compatibility: sidecar queues from older builds may persist
|
|
28
|
+
// prefixed unit types (e.g. "sidecar/quick-task").
|
|
29
|
+
const normalizedUnitType = unitType.startsWith("sidecar/")
|
|
30
|
+
? unitType.slice("sidecar/".length)
|
|
31
|
+
: unitType;
|
|
32
|
+
const manifest = resolveManifest(normalizedUnitType);
|
|
33
|
+
if (!manifest) return null;
|
|
34
|
+
return manifest.tools.mode === "all" || manifest.tools.mode === "docs";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function formatWorktreeSafetyFailure(result: Extract<WorktreeSafetyResult, { ok: false }>): string {
|
|
38
|
+
return `Worktree Safety failed (${result.kind}): ${result.reason} ${result.remediation}`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export function formatWorktreeSafetyStopReason(result: Extract<WorktreeSafetyResult, { ok: false }>): string {
|
|
42
|
+
if (result.kind === "empty-worktree-with-project-content") {
|
|
43
|
+
return `Worktree Safety failed (${result.kind}). Run /gsd doctor fix, then /gsd auto.`;
|
|
44
|
+
}
|
|
45
|
+
return `Worktree Safety failed (${result.kind}).`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function resolveEmptyWorktreeWithProjectContent(
|
|
49
|
+
unitRoot: string,
|
|
50
|
+
projectRoot: string,
|
|
51
|
+
): boolean {
|
|
52
|
+
if (isSamePathLocal(unitRoot, projectRoot)) return false;
|
|
53
|
+
const worktreeClassification = classifyProject(unitRoot);
|
|
54
|
+
if (worktreeClassification.kind !== "greenfield") return false;
|
|
55
|
+
const projectRootClassification = classifyProject(projectRoot);
|
|
56
|
+
return shouldDegradeEmptyWorktreeToProjectRoot(worktreeClassification, projectRootClassification);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function validateSourceWriteWorktreeSafety(
|
|
60
|
+
ic: IterationContext,
|
|
61
|
+
unitType: string,
|
|
62
|
+
unitId: string,
|
|
63
|
+
milestoneId: string | undefined,
|
|
64
|
+
phase: string,
|
|
65
|
+
): Promise<{ action: "break"; reason: string } | null> {
|
|
66
|
+
const { ctx, pi, s, deps } = ic;
|
|
67
|
+
if (!s.basePath) return null;
|
|
68
|
+
|
|
69
|
+
// Custom engine workflows (graph-driven, registered via run dirs) define
|
|
70
|
+
// their own step ids that are not in the GSD UnitContextManifest. Don't
|
|
71
|
+
// fail closed for those — the custom engine owns its own dispatch
|
|
72
|
+
// contract. The fail-closed safety check applies only to built-in GSD
|
|
73
|
+
// units whose Tool Contract is registered in the manifest. Use a truthy
|
|
74
|
+
// check so undefined (test sessions that never set the field) routes
|
|
75
|
+
// through the safety check, matching the regression test contract.
|
|
76
|
+
if (s.activeEngineId) return null;
|
|
77
|
+
|
|
78
|
+
const writesSource = unitWritesSource(unitType);
|
|
79
|
+
if (writesSource === null) {
|
|
80
|
+
const msg = `Worktree Safety failed (missing-tool-contract): missing Tool Contract for ${unitType}. Add a UnitContextManifest entry before dispatching this Unit.`;
|
|
81
|
+
debugLog("worktreeSafety", {
|
|
82
|
+
phase,
|
|
83
|
+
unitType,
|
|
84
|
+
unitId,
|
|
85
|
+
milestoneId,
|
|
86
|
+
result: { ok: false, kind: "missing-tool-contract", reason: msg },
|
|
87
|
+
basePath: s.basePath,
|
|
88
|
+
});
|
|
89
|
+
ctx.ui.notify(msg, "error");
|
|
90
|
+
await deps.stopAuto(ctx, pi, msg);
|
|
91
|
+
return { action: "break", reason: "missing-tool-contract" };
|
|
92
|
+
}
|
|
93
|
+
if (!writesSource) return null;
|
|
94
|
+
|
|
95
|
+
const projectRoot = s.canonicalProjectRoot ?? resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
96
|
+
// A degraded session already fell back to the milestone branch in the
|
|
97
|
+
// project root — validating against the canonical worktree root there
|
|
98
|
+
// would fail every dispatch with a false invalid-root. The same applies
|
|
99
|
+
// to a stranded-recovery session that adopted the milestone branch.
|
|
100
|
+
const isolationMode = resolveEffectiveUnitIsolationMode(
|
|
101
|
+
deps.getIsolationMode(projectRoot),
|
|
102
|
+
s.isolationDegraded,
|
|
103
|
+
s.strandedRecoveryIsolationMode,
|
|
104
|
+
);
|
|
105
|
+
reclaimMissingMilestoneLease(s, milestoneId, isolationMode, phase);
|
|
106
|
+
const safety = createWorktreeSafetyModule();
|
|
107
|
+
const result = safety.validateUnitRoot({
|
|
108
|
+
unitType,
|
|
109
|
+
unitId,
|
|
110
|
+
writeScope: "source-writing",
|
|
111
|
+
projectRoot,
|
|
112
|
+
unitRoot: s.basePath,
|
|
113
|
+
milestoneId,
|
|
114
|
+
isolationMode,
|
|
115
|
+
expectedBranch:
|
|
116
|
+
isolationMode !== "none" && milestoneId ? deps.autoWorktreeBranch(milestoneId) : null,
|
|
117
|
+
emptyWorktreeWithProjectContent: resolveEmptyWorktreeWithProjectContent(s.basePath, projectRoot),
|
|
118
|
+
// The milestone lease coordinates concurrent workers on an isolated
|
|
119
|
+
// milestone worktree/branch, which is established by enterMilestone in
|
|
120
|
+
// worktree/branch modes. `none` mode has no per-milestone isolation and
|
|
121
|
+
// does not reliably claim a lease (e.g. a fresh headless resume of an
|
|
122
|
+
// already-active milestone never re-enters it), so requiring a held lease
|
|
123
|
+
// there would falsely fail dispatch. Enforce the lease only in isolated
|
|
124
|
+
// modes; none-mode safety still validates the unit root.
|
|
125
|
+
lease: s.workerId
|
|
126
|
+
? {
|
|
127
|
+
required: isolationMode !== "none",
|
|
128
|
+
held: hasHeldMilestoneLease(s, milestoneId),
|
|
129
|
+
owner: s.workerId,
|
|
130
|
+
}
|
|
131
|
+
: undefined,
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
if (result.ok) return null;
|
|
135
|
+
|
|
136
|
+
const msg = formatWorktreeSafetyFailure(result);
|
|
137
|
+
debugLog("worktreeSafety", {
|
|
138
|
+
phase,
|
|
139
|
+
unitType,
|
|
140
|
+
unitId,
|
|
141
|
+
milestoneId,
|
|
142
|
+
result,
|
|
143
|
+
basePath: s.basePath,
|
|
144
|
+
projectRoot,
|
|
145
|
+
});
|
|
146
|
+
ctx.ui.notify(msg, "error");
|
|
147
|
+
await deps.stopAuto(ctx, pi, formatWorktreeSafetyStopReason(result));
|
|
148
|
+
return { action: "break", reason: result.kind };
|
|
149
|
+
}
|
|
@@ -1258,7 +1258,7 @@ export function teardownAutoWorktree(
|
|
|
1258
1258
|
* still works after process restart when module state has been reset.
|
|
1259
1259
|
*/
|
|
1260
1260
|
export function isInAutoWorktree(basePath: string): boolean {
|
|
1261
|
-
const targetPath = isGsdWorktreePath(basePath) ? basePath :
|
|
1261
|
+
const targetPath = isGsdWorktreePath(basePath) ? basePath : safeCwd("");
|
|
1262
1262
|
if (!isGsdWorktreePath(targetPath)) return false;
|
|
1263
1263
|
|
|
1264
1264
|
const storedBase = getAutoWorktreeOriginalBase();
|
|
@@ -859,6 +859,20 @@ export function _warnIfWorktreeMissingForTest(
|
|
|
859
859
|
return false;
|
|
860
860
|
}
|
|
861
861
|
|
|
862
|
+
export function anchorProcessCwdForAutoResume(basePath: string): boolean {
|
|
863
|
+
try {
|
|
864
|
+
process.chdir(basePath);
|
|
865
|
+
return true;
|
|
866
|
+
} catch (err) {
|
|
867
|
+
logWarning(
|
|
868
|
+
"session",
|
|
869
|
+
`resume cwd anchor failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
870
|
+
{ file: "auto.ts", basePath },
|
|
871
|
+
);
|
|
872
|
+
return false;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
|
|
862
876
|
export function isAutoPaused(): boolean {
|
|
863
877
|
return s.paused;
|
|
864
878
|
}
|
|
@@ -1160,6 +1174,10 @@ function pauseAutoUnitIdentityMatches(expected: PauseAutoUnitIdentity | null): b
|
|
|
1160
1174
|
s.currentUnit.startedAt === expected.startedAt;
|
|
1161
1175
|
}
|
|
1162
1176
|
|
|
1177
|
+
function shouldPreserveCoordinationForPause(errorContext?: ErrorContext): boolean {
|
|
1178
|
+
return errorContext?.category === "provider" && errorContext.isTransient === true;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1163
1181
|
function setLifecycleOutcome(
|
|
1164
1182
|
ctx: ExtensionContext | undefined,
|
|
1165
1183
|
input: {
|
|
@@ -2120,7 +2138,7 @@ export async function pauseAuto(
|
|
|
2120
2138
|
clearLock(lockBase());
|
|
2121
2139
|
}
|
|
2122
2140
|
|
|
2123
|
-
if (s.workerId) {
|
|
2141
|
+
if (s.workerId && !shouldPreserveCoordinationForPause(_errorContext)) {
|
|
2124
2142
|
try {
|
|
2125
2143
|
if (s.currentMilestoneId && s.milestoneLeaseToken) {
|
|
2126
2144
|
releaseMilestoneLease(s.workerId, s.currentMilestoneId, s.milestoneLeaseToken);
|
|
@@ -2638,6 +2656,7 @@ export async function startAuto(
|
|
|
2638
2656
|
}
|
|
2639
2657
|
// ADR-016 phase 2 / B3 (#5621): paused-resume worktree-path adoption.
|
|
2640
2658
|
buildLifecycle().resumeFromPausedSession(base, resumeWorktreePath);
|
|
2659
|
+
anchorProcessCwdForAutoResume(s.basePath || base);
|
|
2641
2660
|
// Rebuild scope now that s.basePath reflects the actual worktree (or project root).
|
|
2642
2661
|
rebuildScope(s.basePath, s.currentMilestoneId);
|
|
2643
2662
|
// Ensure the workflow-logger audit log is pinned to the project root
|
|
@@ -8,7 +8,12 @@ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
|
|
|
8
8
|
import { createBashTool, createEditTool, createReadTool, createWriteTool } from "@gsd/pi-coding-agent";
|
|
9
9
|
|
|
10
10
|
import { logWarning } from "../workflow-logger.js";
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
getWorkflowDatabaseStatus,
|
|
13
|
+
openWorkflowDatabase,
|
|
14
|
+
type WorkflowDatabaseOpenResult,
|
|
15
|
+
type WorkflowDatabaseStatus,
|
|
16
|
+
} from "../db-workspace.js";
|
|
12
17
|
import { getAutoWorktreePath } from "../auto-worktree.js";
|
|
13
18
|
import { resolveWorktreeProjectRoot } from "../worktree-root.js";
|
|
14
19
|
import { worktreesDirs } from "../worktree-placement.js";
|
|
@@ -69,15 +74,60 @@ export function resolveWorkflowToolBasePath(
|
|
|
69
74
|
|
|
70
75
|
export { resolveProjectRootDbPath } from "../db-workspace.js";
|
|
71
76
|
|
|
77
|
+
type WorkflowDatabaseOpenFailure = Extract<WorkflowDatabaseOpenResult, { ok: false }>;
|
|
78
|
+
|
|
79
|
+
function sqliteProviderHint(status: WorkflowDatabaseStatus, nodeVersion: string): string {
|
|
80
|
+
if (status.provider) return `Provider: ${status.provider}.`;
|
|
81
|
+
|
|
82
|
+
const major = Number.parseInt(nodeVersion.split(".")[0] ?? "", 10);
|
|
83
|
+
if (Number.isFinite(major) && major < 22) {
|
|
84
|
+
return (
|
|
85
|
+
`No SQLite provider available. Upgrade Node to >= 22.0.0 (current: v${nodeVersion}), ` +
|
|
86
|
+
"use the packaged GSD runtime, or install/restore better-sqlite3 in this runtime."
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
"No SQLite provider available. Use a Node build with node:sqlite enabled, " +
|
|
92
|
+
"run the packaged GSD runtime, or install/restore better-sqlite3 in this runtime."
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function dbOpenPhaseHint(status: WorkflowDatabaseStatus): string {
|
|
97
|
+
if (status.lastPhase === "open") return "The database file could not be opened";
|
|
98
|
+
if (status.lastPhase === "initSchema") return "The database schema could not be initialized";
|
|
99
|
+
if (status.lastPhase === "vacuum-recovery") return "Corruption recovery (VACUUM) failed";
|
|
100
|
+
if (status.attempted) return "The database could not be opened";
|
|
101
|
+
return "The database provider could not be loaded";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function formatWorkflowDatabaseOpenFailure(
|
|
105
|
+
result: WorkflowDatabaseOpenFailure,
|
|
106
|
+
status?: WorkflowDatabaseStatus,
|
|
107
|
+
nodeVersion: string = process.versions.node,
|
|
108
|
+
): string {
|
|
109
|
+
if (result.reason === "missing-gsd-dir") {
|
|
110
|
+
return `ensureDbOpen failed — no .gsd directory found at ${result.location.projectGsd}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (result.reason === "missing-database") {
|
|
114
|
+
return `ensureDbOpen failed — no GSD database found at ${result.location.projectDb}`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const resolvedStatus = status ?? getWorkflowDatabaseStatus();
|
|
118
|
+
const detail = result.error?.message ?? resolvedStatus.lastError?.message ?? "";
|
|
119
|
+
const detailSuffix = detail ? ` (${detail})` : "";
|
|
120
|
+
return (
|
|
121
|
+
`ensureDbOpen failed for ${result.location.projectDb}: ` +
|
|
122
|
+
`${dbOpenPhaseHint(resolvedStatus)}${detailSuffix}. ${sqliteProviderHint(resolvedStatus, nodeVersion)}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
72
126
|
export async function ensureDbOpen(basePath: string = safeWorkspaceCwd()): Promise<boolean> {
|
|
73
127
|
const result = openWorkflowDatabase(basePath);
|
|
74
128
|
if (result.ok) return true;
|
|
75
129
|
|
|
76
|
-
|
|
77
|
-
logWarning("bootstrap", "ensureDbOpen failed — no .gsd directory found");
|
|
78
|
-
} else {
|
|
79
|
-
logWarning("bootstrap", `ensureDbOpen failed: ${result.error?.message ?? "open failed"}`);
|
|
80
|
-
}
|
|
130
|
+
logWarning("bootstrap", formatWorkflowDatabaseOpenFailure(result));
|
|
81
131
|
return false;
|
|
82
132
|
}
|
|
83
133
|
|
|
@@ -102,7 +102,7 @@ export function formatMcpStatusReport(servers: McpServerStatus[]): string {
|
|
|
102
102
|
: s.connected
|
|
103
103
|
? `connected — ${s.toolCount} tools`
|
|
104
104
|
: s.available
|
|
105
|
-
? `available — ${s.toolCount} tools`
|
|
105
|
+
? `probe available — ${s.toolCount} tools`
|
|
106
106
|
: "disconnected";
|
|
107
107
|
const warningText = s.envWarnings?.length ? ` — ${s.envWarnings.length} warning(s)` : "";
|
|
108
108
|
lines.push(` ${icon} ${s.name} (${s.transport}) — ${status}${warningText}`);
|
|
@@ -128,7 +128,7 @@ export function formatMcpServerDetail(server: McpServerDetail): string {
|
|
|
128
128
|
lines.push(` Status: error`);
|
|
129
129
|
lines.push(` Error: ${server.error}`);
|
|
130
130
|
} else if (server.connected || server.available) {
|
|
131
|
-
lines.push(` Status: ${server.connected ? "connected" : "available"}`);
|
|
131
|
+
lines.push(` Status: ${server.connected ? "connected" : "probe available"}`);
|
|
132
132
|
lines.push(` Tools: ${server.toolCount}`);
|
|
133
133
|
if (server.tools.length > 0) {
|
|
134
134
|
lines.push("");
|
|
@@ -80,13 +80,13 @@ function datePrefix(): string {
|
|
|
80
80
|
|
|
81
81
|
// ─── State Types ─────────────────────────────────────────────────────────────
|
|
82
82
|
|
|
83
|
-
interface WorkflowPhaseState {
|
|
83
|
+
export interface WorkflowPhaseState {
|
|
84
84
|
name: string;
|
|
85
85
|
index: number;
|
|
86
86
|
status: "pending" | "active" | "completed";
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
interface WorkflowState {
|
|
89
|
+
export interface WorkflowState {
|
|
90
90
|
template: string;
|
|
91
91
|
templateName: string;
|
|
92
92
|
description: string;
|
|
@@ -99,6 +99,13 @@ interface WorkflowState {
|
|
|
99
99
|
artifactDir: string;
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
export function isWorkflowStateComplete(state: WorkflowState): boolean {
|
|
103
|
+
if (state.completedAt) return true;
|
|
104
|
+
return Array.isArray(state.phases) &&
|
|
105
|
+
state.phases.length > 0 &&
|
|
106
|
+
state.phases.every((phase) => phase.status === "completed");
|
|
107
|
+
}
|
|
108
|
+
|
|
102
109
|
/**
|
|
103
110
|
* Write a STATE.json file to track workflow execution state.
|
|
104
111
|
*/
|
|
@@ -133,7 +140,7 @@ function writeWorkflowState(
|
|
|
133
140
|
* Scan all workflow artifact directories for in-progress STATE.json files.
|
|
134
141
|
* Returns workflows that were started but not completed.
|
|
135
142
|
*/
|
|
136
|
-
function findInProgressWorkflows(basePath: string): WorkflowState[] {
|
|
143
|
+
export function findInProgressWorkflows(basePath: string): WorkflowState[] {
|
|
137
144
|
const workflowsRoot = join(gsdRoot(basePath), "workflows");
|
|
138
145
|
if (!existsSync(workflowsRoot)) return [];
|
|
139
146
|
|
|
@@ -152,7 +159,7 @@ function findInProgressWorkflows(basePath: string): WorkflowState[] {
|
|
|
152
159
|
try {
|
|
153
160
|
const raw = readFileSync(statePath, "utf-8");
|
|
154
161
|
const state = JSON.parse(raw) as WorkflowState;
|
|
155
|
-
if (!state
|
|
162
|
+
if (!isWorkflowStateComplete(state)) {
|
|
156
163
|
results.push(state);
|
|
157
164
|
}
|
|
158
165
|
} catch { /* corrupted state file — skip */ }
|
|
@@ -270,6 +270,35 @@ export function getMilestoneSlices(milestoneId: string): SliceRow[] {
|
|
|
270
270
|
return rows.map(rowToSlice);
|
|
271
271
|
}
|
|
272
272
|
|
|
273
|
+
/**
|
|
274
|
+
* Load slices for many milestones in a single query. Returns a Map keyed by
|
|
275
|
+
* milestone_id, preserving `ORDER BY sequence, id` within each bucket.
|
|
276
|
+
*/
|
|
277
|
+
export function getSlicesByMilestoneIds(milestoneIds: readonly string[]): Map<string, SliceRow[]> {
|
|
278
|
+
const db = getDbOrNull();
|
|
279
|
+
if (!db || milestoneIds.length === 0) return new Map();
|
|
280
|
+
const idList = [...milestoneIds];
|
|
281
|
+
const placeholders = idList.map((_, i) => `:mid${i}`).join(",");
|
|
282
|
+
const params: Record<string, unknown> = {};
|
|
283
|
+
idList.forEach((id, i) => {
|
|
284
|
+
params[`:mid${i}`] = id;
|
|
285
|
+
});
|
|
286
|
+
const rows = db
|
|
287
|
+
.prepare(`SELECT * FROM slices WHERE milestone_id IN (${placeholders}) ORDER BY milestone_id, sequence, id`)
|
|
288
|
+
.all(params) as Record<string, unknown>[];
|
|
289
|
+
const byMilestone = new Map<string, SliceRow[]>();
|
|
290
|
+
for (const row of rows) {
|
|
291
|
+
const slice = rowToSlice(row);
|
|
292
|
+
const bucket = byMilestone.get(slice.milestone_id);
|
|
293
|
+
if (bucket) {
|
|
294
|
+
bucket.push(slice);
|
|
295
|
+
} else {
|
|
296
|
+
byMilestone.set(slice.milestone_id, [slice]);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return byMilestone;
|
|
300
|
+
}
|
|
301
|
+
|
|
273
302
|
/** Dispatch-eligibility shape consumed by decision-path callers (ADR-017). */
|
|
274
303
|
export interface MilestoneSliceSummary {
|
|
275
304
|
id: string;
|