@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
|
@@ -74,6 +74,7 @@ import {
|
|
|
74
74
|
import { existsSync, readFileSync } from "node:fs";
|
|
75
75
|
import { join } from "node:path";
|
|
76
76
|
import { evaluateAllCompleteSettlement } from "../milestone-settlement.js";
|
|
77
|
+
import { hasHeldMilestoneLease, reclaimMissingMilestoneLease } from "./milestone-lease-reclaim.js";
|
|
77
78
|
|
|
78
79
|
function now(): number {
|
|
79
80
|
return Date.now();
|
|
@@ -209,6 +210,7 @@ export async function decideOrchestratorDispatch(
|
|
|
209
210
|
|
|
210
211
|
if (active && activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
|
|
211
212
|
activeSession.currentMilestoneId = active.id;
|
|
213
|
+
activeSession.milestoneLeaseToken = null;
|
|
212
214
|
}
|
|
213
215
|
const dispatchMid = active?.id ?? activeSession?.currentMilestoneId ?? "";
|
|
214
216
|
const dispatchMidTitle = active?.title ?? "";
|
|
@@ -609,6 +611,37 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
609
611
|
};
|
|
610
612
|
}
|
|
611
613
|
|
|
614
|
+
private async mergePendingCompleteMilestone(milestoneId: string): Promise<{ ok: true } | { ok: false; reason: string }> {
|
|
615
|
+
const result = this.buildLifecycle().exitMilestone(
|
|
616
|
+
milestoneId,
|
|
617
|
+
{ merge: true },
|
|
618
|
+
this.ctx.ui,
|
|
619
|
+
);
|
|
620
|
+
if (!result.ok) {
|
|
621
|
+
const detail = result.cause instanceof Error
|
|
622
|
+
? result.cause.message
|
|
623
|
+
: result.reason;
|
|
624
|
+
return {
|
|
625
|
+
ok: false,
|
|
626
|
+
reason: `Milestone ${milestoneId} is complete, but the system-owned merge failed: ${detail}`,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
this.s.milestoneMergedInPhases = true;
|
|
631
|
+
this.s.milestoneSettlement = { ok: true, reason: "settled" };
|
|
632
|
+
try {
|
|
633
|
+
const projectRoot = this.s.originalBasePath || this.s.canonicalProjectRoot || this.runtimeBasePath;
|
|
634
|
+
const { rebuildMarkdownProjectionsFromDb } = await import("../commands-maintenance.js");
|
|
635
|
+
await rebuildMarkdownProjectionsFromDb(projectRoot);
|
|
636
|
+
} catch (err) {
|
|
637
|
+
logWarning(
|
|
638
|
+
"engine",
|
|
639
|
+
`markdown projection rebuild after settlement merge failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
return { ok: true };
|
|
643
|
+
}
|
|
644
|
+
|
|
612
645
|
private clearPendingDispatch(): void {
|
|
613
646
|
this.s.pendingOrchestrationDispatch = null;
|
|
614
647
|
}
|
|
@@ -688,9 +721,6 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
688
721
|
reason: `No Unit manifest is registered for ${unitType}`,
|
|
689
722
|
};
|
|
690
723
|
}
|
|
691
|
-
if (isolationMode !== "worktree") {
|
|
692
|
-
return { ok: true, reason: "not-required" };
|
|
693
|
-
}
|
|
694
724
|
const writeScope =
|
|
695
725
|
manifest.tools.mode === "all" || manifest.tools.mode === "docs"
|
|
696
726
|
? "source-writing"
|
|
@@ -699,7 +729,23 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
699
729
|
const activeBasePath = this.getLiveDispatchBasePath();
|
|
700
730
|
const snapshot = await deriveState(activeBasePath);
|
|
701
731
|
const milestoneId = snapshot.activeMilestone?.id ?? null;
|
|
702
|
-
const
|
|
732
|
+
const buildExpectedBranch = (mode: ReturnType<typeof getIsolationMode>) =>
|
|
733
|
+
mode !== "none" && milestoneId ? autoWorktreeBranch(milestoneId) : null;
|
|
734
|
+
// The milestone lease coordinates concurrent workers on an isolated
|
|
735
|
+
// milestone worktree/branch. `none` mode has no per-milestone isolation
|
|
736
|
+
// and does not reliably claim a lease, so requiring one there would
|
|
737
|
+
// falsely fail dispatch; enforce it only in isolated modes.
|
|
738
|
+
const buildLease = (mode: ReturnType<typeof getIsolationMode>) =>
|
|
739
|
+
milestoneId && this.s.workerId
|
|
740
|
+
? {
|
|
741
|
+
required: writeScope === "source-writing" && mode !== "none",
|
|
742
|
+
held: hasHeldMilestoneLease(this.s, milestoneId),
|
|
743
|
+
owner: this.s.workerId,
|
|
744
|
+
}
|
|
745
|
+
: undefined;
|
|
746
|
+
if (writeScope === "source-writing") {
|
|
747
|
+
reclaimMissingMilestoneLease(this.s, milestoneId, isolationMode, "orchestrator");
|
|
748
|
+
}
|
|
703
749
|
let result = safety.validateUnitRoot({
|
|
704
750
|
unitType,
|
|
705
751
|
unitId,
|
|
@@ -708,7 +754,8 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
708
754
|
unitRoot: activeBasePath,
|
|
709
755
|
milestoneId,
|
|
710
756
|
isolationMode,
|
|
711
|
-
expectedBranch,
|
|
757
|
+
expectedBranch: buildExpectedBranch(isolationMode),
|
|
758
|
+
lease: buildLease(isolationMode),
|
|
712
759
|
});
|
|
713
760
|
if (!result.ok) {
|
|
714
761
|
const repaired = await repairAutoWorktreeSafetyFailure({
|
|
@@ -725,16 +772,20 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
725
772
|
this.rebuildScope(this.s.basePath, this.s.currentMilestoneId);
|
|
726
773
|
return { ok: true };
|
|
727
774
|
},
|
|
728
|
-
revalidate: () =>
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
775
|
+
revalidate: () => {
|
|
776
|
+
const revalidatedMode = this.getEffectiveUnitIsolationMode(this.runtimeBasePath);
|
|
777
|
+
return safety.validateUnitRoot({
|
|
778
|
+
unitType,
|
|
779
|
+
unitId,
|
|
780
|
+
writeScope,
|
|
781
|
+
projectRoot: this.runtimeBasePath,
|
|
782
|
+
unitRoot: this.getLiveDispatchBasePath(),
|
|
783
|
+
milestoneId,
|
|
784
|
+
isolationMode: revalidatedMode,
|
|
785
|
+
expectedBranch: buildExpectedBranch(revalidatedMode),
|
|
786
|
+
lease: buildLease(revalidatedMode),
|
|
787
|
+
});
|
|
788
|
+
},
|
|
738
789
|
});
|
|
739
790
|
result = repaired.result;
|
|
740
791
|
if (result.ok) {
|
|
@@ -942,6 +993,35 @@ export class AutoOrchestrator implements AutoOrchestrationModule {
|
|
|
942
993
|
if (!decision) {
|
|
943
994
|
const settlementBlock = this.evaluateNoRemainingUnitsSettlement(reconciliation.stateSnapshot);
|
|
944
995
|
if (settlementBlock) {
|
|
996
|
+
const settlement = this.s.milestoneSettlement;
|
|
997
|
+
if (settlement && !settlement.ok && settlement.reason === "merge-pending") {
|
|
998
|
+
const merged = await this.mergePendingCompleteMilestone(settlement.milestoneId);
|
|
999
|
+
if (merged.ok) {
|
|
1000
|
+
const terminalOutcome = noRemainingUnitsOutcome(reconciliation.stateSnapshot);
|
|
1001
|
+
const stopped: AutoAdvanceResult = {
|
|
1002
|
+
kind: "stopped",
|
|
1003
|
+
reason: terminalOutcome.displayReason,
|
|
1004
|
+
stateSnapshot: reconciliation.stateSnapshot,
|
|
1005
|
+
terminalOutcome,
|
|
1006
|
+
};
|
|
1007
|
+
this.status.phase = "stopped";
|
|
1008
|
+
this.status.activeUnit = undefined;
|
|
1009
|
+
this.lastAdvanceKey = null;
|
|
1010
|
+
this.dispatchHistory.clearOnRecovery();
|
|
1011
|
+
this.bumpTransition();
|
|
1012
|
+
this.journalTransition({ name: "advance-stopped", reason: stopped.reason });
|
|
1013
|
+
this.postAdvanceRecord(stopped);
|
|
1014
|
+
return stopped;
|
|
1015
|
+
}
|
|
1016
|
+
settlementBlock.reason = merged.reason;
|
|
1017
|
+
settlementBlock.terminalOutcome = {
|
|
1018
|
+
code: "settlement-blocked",
|
|
1019
|
+
displayReason: merged.reason,
|
|
1020
|
+
nextAction: `Fix the merge failure, then retry \`/gsd dispatch complete-milestone ${settlement.milestoneId}\`.`,
|
|
1021
|
+
milestoneId: settlement.milestoneId,
|
|
1022
|
+
allMilestonesComplete: false,
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
945
1025
|
this.status.phase = "paused";
|
|
946
1026
|
this.status.activeUnit = undefined;
|
|
947
1027
|
this.lastAdvanceKey = null;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
// Project/App: gsd-pi
|
|
2
|
+
// File Purpose: Shared helpers used across auto-loop phase modules.
|
|
3
|
+
|
|
4
|
+
import { setRuntimeKv } from "../db/runtime-kv.js";
|
|
5
|
+
import { debugLog } from "../debug-logger.js";
|
|
6
|
+
import { normalizeRealPath } from "../paths.js";
|
|
7
|
+
import { resolveWorktreeProjectRoot, normalizeWorktreePathForCompare } from "../worktree-root.js";
|
|
8
|
+
import { decideVerificationRetry, verificationRetryKey } from "./verification-retry-policy.js";
|
|
9
|
+
import type { AutoSession } from "./session.js";
|
|
10
|
+
import type { IterationContext, IterationData, LoopState, PhaseResult } from "./types.js";
|
|
11
|
+
import type { Phase } from "../types.js";
|
|
12
|
+
|
|
13
|
+
const STUCK_RECOVERY_ATTEMPTS_KEY = "stuck_recovery_attempts";
|
|
14
|
+
|
|
15
|
+
/** Compare two paths for physical identity, tolerating trailing slashes and symlinks. */
|
|
16
|
+
export function isSamePathLocal(a: string, b: string): boolean {
|
|
17
|
+
return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function isIsolatedWorktreeSession(s: AutoSession): boolean {
|
|
21
|
+
return Boolean(s.originalBasePath)
|
|
22
|
+
&& Boolean(s.basePath)
|
|
23
|
+
&& !isSamePathLocal(s.originalBasePath, s.basePath);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function persistStuckRecoveryAttempts(s: AutoSession, loopState: LoopState): void {
|
|
27
|
+
const scopeId = normalizeRealPath(
|
|
28
|
+
s.scope?.workspace.projectRoot ?? (s.originalBasePath || s.basePath),
|
|
29
|
+
);
|
|
30
|
+
if (!scopeId) return;
|
|
31
|
+
try {
|
|
32
|
+
setRuntimeKv("global", scopeId, STUCK_RECOVERY_ATTEMPTS_KEY, loopState.stuckRecoveryAttempts);
|
|
33
|
+
} catch (err) {
|
|
34
|
+
debugLog("autoLoop", {
|
|
35
|
+
phase: "save-stuck-state-failed",
|
|
36
|
+
error: err instanceof Error ? err.message : String(err),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function applyVerificationRetryPolicy(
|
|
42
|
+
ic: IterationContext,
|
|
43
|
+
unitType: string | undefined,
|
|
44
|
+
phase: "artifact-verification-retry" | "verification-retry" | "pre-execution-retry",
|
|
45
|
+
): Promise<PhaseResult | null> {
|
|
46
|
+
const { ctx, pi, s, deps } = ic;
|
|
47
|
+
const retryInfo = s.pendingVerificationRetry;
|
|
48
|
+
const key = unitType && retryInfo
|
|
49
|
+
? verificationRetryKey(unitType, retryInfo.unitId)
|
|
50
|
+
: undefined;
|
|
51
|
+
const decision = decideVerificationRetry({
|
|
52
|
+
unitType,
|
|
53
|
+
retryInfo,
|
|
54
|
+
previousFailureHash: key ? s.verificationRetryFailureHashes.get(key) : undefined,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (decision.action === "pause") {
|
|
58
|
+
s.pendingVerificationRetry = null;
|
|
59
|
+
debugLog("autoLoop", {
|
|
60
|
+
phase: `${phase}-paused`,
|
|
61
|
+
reason: decision.reason,
|
|
62
|
+
unitType,
|
|
63
|
+
unitId: retryInfo?.unitId,
|
|
64
|
+
failureHash: decision.failureHash,
|
|
65
|
+
});
|
|
66
|
+
ctx.ui.notify(
|
|
67
|
+
decision.reason === "duplicate-failure-context"
|
|
68
|
+
? `Verification retry for ${unitType ?? "unit"} ${retryInfo?.unitId ?? "unknown"} produced the same failure context. Pausing auto-mode instead of re-dispatching.`
|
|
69
|
+
: "Verification retry requested without retry context. Pausing auto-mode instead of re-dispatching.",
|
|
70
|
+
"warning",
|
|
71
|
+
);
|
|
72
|
+
await deps.pauseAuto(ctx, pi);
|
|
73
|
+
return { action: "break", reason: decision.reason };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
s.verificationRetryFailureHashes.set(decision.key, decision.failureHash);
|
|
77
|
+
debugLog("autoLoop", {
|
|
78
|
+
phase: `${phase}-backoff`,
|
|
79
|
+
iteration: ic.iteration,
|
|
80
|
+
unitType,
|
|
81
|
+
unitId: retryInfo?.unitId,
|
|
82
|
+
attempt: retryInfo?.attempt,
|
|
83
|
+
delayMs: decision.delayMs,
|
|
84
|
+
baseDelayMs: decision.baseDelayMs,
|
|
85
|
+
failureHash: decision.failureHash,
|
|
86
|
+
});
|
|
87
|
+
await new Promise<void>((resolve) => setTimeout(resolve, decision.delayMs));
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function rememberRetryDispatch(
|
|
92
|
+
s: AutoSession,
|
|
93
|
+
unit: { type: string; id: string } | null,
|
|
94
|
+
iterData: IterationData,
|
|
95
|
+
): void {
|
|
96
|
+
if (!unit) return;
|
|
97
|
+
s.pendingVerificationRetryDispatch = {
|
|
98
|
+
unitType: unit.type,
|
|
99
|
+
unitId: unit.id,
|
|
100
|
+
prompt: iterData.prompt,
|
|
101
|
+
pauseAfterUatDispatch: iterData.pauseAfterUatDispatch,
|
|
102
|
+
state: iterData.state,
|
|
103
|
+
mid: iterData.mid,
|
|
104
|
+
midTitle: iterData.midTitle,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Resolve the base path for milestone reports.
|
|
110
|
+
* Prefers originalBasePath (project root) over basePath (which may be a worktree).
|
|
111
|
+
*/
|
|
112
|
+
export function _resolveReportBasePath(s: Pick<AutoSession, "originalBasePath" | "basePath">): string {
|
|
113
|
+
return resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Resolve the authoritative project base for dispatch guards.
|
|
118
|
+
* Prior-milestone completion lives at the project root, even when the active
|
|
119
|
+
* unit is running inside an auto worktree.
|
|
120
|
+
*/
|
|
121
|
+
export function _resolveDispatchGuardBasePath(
|
|
122
|
+
s: Pick<AutoSession, "originalBasePath" | "basePath">,
|
|
123
|
+
): string {
|
|
124
|
+
return resolveWorktreeProjectRoot(s.basePath, s.originalBasePath);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const PLAN_V2_GATE_PHASES: ReadonlySet<Phase> = new Set([
|
|
128
|
+
"executing",
|
|
129
|
+
"summarizing",
|
|
130
|
+
"validating-milestone",
|
|
131
|
+
"completing-milestone",
|
|
132
|
+
]);
|
|
133
|
+
|
|
134
|
+
export function shouldRunPlanV2Gate(phase: Phase): boolean {
|
|
135
|
+
return PLAN_V2_GATE_PHASES.has(phase);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export function _resolveCurrentUnitStartedAtForTest(
|
|
139
|
+
currentUnit: { startedAt: number } | null | undefined,
|
|
140
|
+
): number | undefined {
|
|
141
|
+
return currentUnit?.startedAt;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export async function emitCancelledUnitEnd(
|
|
145
|
+
ic: IterationContext,
|
|
146
|
+
unitType: string,
|
|
147
|
+
unitId: string,
|
|
148
|
+
unitStartSeq: number,
|
|
149
|
+
errorContext?: { message: string; category: string; stopReason?: string; isTransient?: boolean; retryAfterMs?: number },
|
|
150
|
+
): Promise<void> {
|
|
151
|
+
ic.deps.emitJournalEvent({
|
|
152
|
+
ts: new Date().toISOString(),
|
|
153
|
+
flowId: ic.flowId,
|
|
154
|
+
seq: ic.nextSeq(),
|
|
155
|
+
eventType: "unit-end",
|
|
156
|
+
data: {
|
|
157
|
+
unitType,
|
|
158
|
+
unitId,
|
|
159
|
+
status: "cancelled",
|
|
160
|
+
artifactVerified: false,
|
|
161
|
+
...(errorContext ? { errorContext } : {}),
|
|
162
|
+
},
|
|
163
|
+
causedBy: { flowId: ic.flowId, seq: unitStartSeq },
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export function _buildCancelledUnitStopReason(
|
|
168
|
+
unitType: string,
|
|
169
|
+
unitId: string,
|
|
170
|
+
errorContext?: { message: string; category: string },
|
|
171
|
+
): {
|
|
172
|
+
notifyMessage: string;
|
|
173
|
+
stopReason: string;
|
|
174
|
+
loopReason: "session-failed" | "unit-aborted";
|
|
175
|
+
} {
|
|
176
|
+
const cancellationMessage = errorContext?.message ?? "unknown";
|
|
177
|
+
const isSessionCreationFailure = errorContext?.category === "session-failed";
|
|
178
|
+
|
|
179
|
+
if (isSessionCreationFailure) {
|
|
180
|
+
return {
|
|
181
|
+
notifyMessage: `Session creation failed for ${unitType} ${unitId}: ${cancellationMessage}. Stopping auto-mode.`,
|
|
182
|
+
stopReason: `Session creation failed: ${cancellationMessage}`,
|
|
183
|
+
loopReason: "session-failed",
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return {
|
|
188
|
+
notifyMessage: `Unit ${unitType} ${unitId} aborted after dispatch: ${cancellationMessage}. Stopping auto-mode.`,
|
|
189
|
+
stopReason: `Unit aborted: ${cancellationMessage}`,
|
|
190
|
+
loopReason: "unit-aborted",
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export function _isPauseOriginCancelledResult(
|
|
195
|
+
isPaused: boolean,
|
|
196
|
+
errorContext?: { message: string; category: string },
|
|
197
|
+
): boolean {
|
|
198
|
+
return isPaused && !errorContext;
|
|
199
|
+
}
|