@opengsd/gsd-pi 1.1.1-dev.b2556262 → 1.2.0-dev.844675c9
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/project-sessions.js +4 -2
- package/dist/resources/.managed-resources-content-hash +1 -1
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +17 -9
- package/dist/resources/extensions/gsd/auto/contracts.js +8 -1
- package/dist/resources/extensions/gsd/auto/orchestrator.js +659 -57
- package/dist/resources/extensions/gsd/auto-prompts.js +110 -1
- package/dist/resources/extensions/gsd/auto-runtime-state.js +3 -0
- package/dist/resources/extensions/gsd/auto-tool-tracking.js +5 -0
- package/dist/resources/extensions/gsd/auto-unit-tool-scope.js +29 -0
- package/dist/resources/extensions/gsd/auto-worktree.js +24 -17
- package/dist/resources/extensions/gsd/auto.js +62 -464
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +4 -1
- package/dist/resources/extensions/gsd/debug-logger.js +10 -0
- package/dist/resources/extensions/gsd/doctor-proactive.js +7 -2
- package/dist/resources/extensions/gsd/guided-flow.js +2 -2
- package/dist/resources/extensions/gsd/markdown-renderer.js +31 -32
- package/dist/resources/extensions/gsd/mcp-filter.js +6 -0
- package/dist/resources/extensions/gsd/native-git-bridge.js +45 -0
- package/dist/resources/extensions/gsd/prompts/discuss.md +6 -7
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
- package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -5
- package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/dist/resources/extensions/gsd/prompts/research-milestone.md +2 -2
- package/dist/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
- package/dist/resources/extensions/gsd/schemas/parsers.js +6 -1
- package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +21 -1
- package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +169 -20
- package/dist/resources/extensions/gsd/user-input-boundary.js +42 -4
- package/dist/tsconfig.extensions.tsbuildinfo +1 -0
- 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/api/boot/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/mcp-connections/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +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/chunks/5047.js +2 -0
- package/dist/web/standalone/.next/server/chunks/5124.js +1 -0
- package/dist/web/standalone/.next/server/chunks/8357.js +2 -2
- 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/node_modules/@gsd/native/package.json +1 -1
- package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/container.js +26 -18
- package/dist/web/standalone/node_modules/postcss/lib/css-syntax-error.js +47 -14
- package/dist/web/standalone/node_modules/postcss/lib/declaration.js +4 -4
- package/dist/web/standalone/node_modules/postcss/lib/fromJSON.js +3 -3
- package/dist/web/standalone/node_modules/postcss/lib/input.js +54 -29
- package/dist/web/standalone/node_modules/postcss/lib/lazy-result.js +47 -37
- package/dist/web/standalone/node_modules/postcss/lib/map-generator.js +26 -9
- package/dist/web/standalone/node_modules/postcss/lib/no-work-result.js +57 -55
- package/dist/web/standalone/node_modules/postcss/lib/node.js +99 -31
- package/dist/web/standalone/node_modules/postcss/lib/parse.js +1 -1
- package/dist/web/standalone/node_modules/postcss/lib/parser.js +10 -9
- package/dist/web/standalone/node_modules/postcss/lib/postcss.js +12 -12
- package/dist/web/standalone/node_modules/postcss/lib/previous-map.js +30 -11
- package/dist/web/standalone/node_modules/postcss/lib/processor.js +7 -7
- package/dist/web/standalone/node_modules/postcss/lib/result.js +5 -5
- package/dist/web/standalone/node_modules/postcss/lib/rule.js +6 -6
- package/dist/web/standalone/node_modules/postcss/lib/stringifier.js +69 -28
- package/dist/web/standalone/node_modules/postcss/lib/tokenize.js +6 -2
- package/dist/web/standalone/node_modules/postcss/package.json +48 -48
- package/package.json +16 -11
- 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/package.json +5 -5
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +1 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
- package/packages/gsd-agent-modes/package.json +7 -7
- package/packages/mcp-server/package.json +3 -3
- package/packages/native/package.json +1 -1
- package/packages/pi-agent-core/package.json +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +0 -34
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +12 -46
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/auth-storage.js +11 -3
- package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
- package/packages/pi-coding-agent/package.json +7 -7
- package/packages/pi-tui/package.json +2 -2
- package/packages/rpc-client/package.json +2 -2
- package/pkg/package.json +1 -1
- package/scripts/install/deps.js +10 -0
- package/scripts/link-workspace-packages.cjs +7 -40
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +18 -8
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +2 -2
- package/src/resources/extensions/gsd/auto/contracts.ts +8 -119
- package/src/resources/extensions/gsd/auto/orchestrator.ts +794 -58
- package/src/resources/extensions/gsd/auto-prompts.ts +114 -1
- package/src/resources/extensions/gsd/auto-runtime-state.ts +4 -0
- package/src/resources/extensions/gsd/auto-tool-tracking.ts +5 -0
- package/src/resources/extensions/gsd/auto-unit-tool-scope.ts +33 -0
- package/src/resources/extensions/gsd/auto-worktree.ts +24 -16
- package/src/resources/extensions/gsd/auto.ts +81 -500
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +4 -0
- package/src/resources/extensions/gsd/debug-logger.ts +11 -0
- package/src/resources/extensions/gsd/doctor-proactive.ts +8 -2
- package/src/resources/extensions/gsd/guided-flow.ts +2 -2
- package/src/resources/extensions/gsd/markdown-renderer.ts +38 -19
- package/src/resources/extensions/gsd/mcp-filter.ts +7 -0
- package/src/resources/extensions/gsd/native-git-bridge.ts +48 -0
- package/src/resources/extensions/gsd/prompts/discuss.md +6 -7
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -7
- package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +3 -5
- package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +1 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +5 -6
- package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
- package/src/resources/extensions/gsd/prompts/research-milestone.md +2 -2
- package/src/resources/extensions/gsd/prompts/validate-milestone.md +5 -3
- package/src/resources/extensions/gsd/schemas/parsers.ts +6 -1
- package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +31 -10
- package/src/resources/extensions/gsd/tests/artifact-db-drift-memo.test.ts +66 -0
- package/src/resources/extensions/gsd/tests/auto-dispatch-baseline-harness.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +590 -855
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +38 -10
- package/src/resources/extensions/gsd/tests/debug-logger.test.ts +15 -0
- package/src/resources/extensions/gsd/tests/execute-summary-save-empty-project.test.ts +64 -1
- package/src/resources/extensions/gsd/tests/integration/merge-strategy-regular.test.ts +157 -0
- package/src/resources/extensions/gsd/tests/markdown-renderer-parse-cache.test.ts +75 -0
- package/src/resources/extensions/gsd/tests/native-merge-regular.test.ts +139 -0
- package/src/resources/extensions/gsd/tests/orchestrator-legacy-parity.test.ts +127 -0
- package/src/resources/extensions/gsd/tests/parse-project-milestone-bridge.test.ts +77 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +4 -2
- package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +29 -2
- package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +65 -0
- package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +19 -5
- package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +38 -0
- package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +24 -0
- package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +15 -3
- package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +183 -21
- package/src/resources/extensions/gsd/user-input-boundary.ts +37 -5
- package/dist/web/standalone/.next/server/chunks/678.js +0 -2
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts +0 -21
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.d.ts.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js +0 -213
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/gsd-widget-prototype.js.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts +0 -28
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.d.ts.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js +0 -249
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-density-prototype.js.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts +0 -19
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.d.ts.map +0 -1
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js +0 -797
- package/packages/gsd-agent-modes/dist/modes/interactive/components/__prototype__/transcript-design-prototype.js.map +0 -1
- package/scripts/ensure-workspace-builds.cjs +0 -129
- /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → Qbr81pQ-pbQXP4bq2VXLv}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{tJOKQbQRO-9MiFDO8DIDS → Qbr81pQ-pbQXP4bq2VXLv}/_ssgManifest.js +0 -0
|
@@ -107,7 +107,7 @@ import {
|
|
|
107
107
|
} from "./auto-tool-tracking.js";
|
|
108
108
|
import { closeoutUnit } from "./auto-unit-closeout.js";
|
|
109
109
|
import { recoverTimedOutUnit } from "./auto-timeout-recovery.js";
|
|
110
|
-
import { selectAndApplyModel, resolveModelId, clearToolBaseline
|
|
110
|
+
import { selectAndApplyModel, resolveModelId, clearToolBaseline } from "./auto-model-selection.js";
|
|
111
111
|
import { resetRoutingHistory, recordOutcome } from "./routing-history.js";
|
|
112
112
|
import {
|
|
113
113
|
checkPostUnitHooks,
|
|
@@ -270,18 +270,11 @@ import { runAutoLoopWithUok } from "./uok/kernel.js";
|
|
|
270
270
|
import { resolveUokFlags } from "./uok/flags.js";
|
|
271
271
|
import { validateDirectory } from "./validate-directory.js";
|
|
272
272
|
import { createAutoOrchestrator } from "./auto/orchestrator.js";
|
|
273
|
-
import type { AutoAdvanceResult, AutoOrchestrationModule
|
|
274
|
-
import { reconcileBeforeDispatch } from "./state-reconciliation.js";
|
|
275
|
-
import { compileUnitToolContract } from "./tool-contract.js";
|
|
276
|
-
import { createWorktreeSafetyModule } from "./worktree-safety.js";
|
|
273
|
+
import type { AutoAdvanceResult, AutoOrchestrationModule } from "./auto/contracts.js";
|
|
277
274
|
import {
|
|
278
275
|
repairAutoWorktreeSafetyFailure,
|
|
279
276
|
resolvePausedAutoWorktreePath,
|
|
280
277
|
} from "./auto-worktree-repair.js";
|
|
281
|
-
import { resolveManifest } from "./unit-context-manifest.js";
|
|
282
|
-
import { classifyFailure } from "./recovery-classification.js";
|
|
283
|
-
import { supportsStructuredQuestions } from "./workflow-mcp.js";
|
|
284
|
-
import type { MinimalModelRegistry } from "./context-budget.js";
|
|
285
278
|
// Slice-level parallelism (#2340)
|
|
286
279
|
import { getEligibleSlices } from "./slice-parallel-eligibility.js";
|
|
287
280
|
import { startSliceParallel } from "./slice-parallel-orchestrator.js";
|
|
@@ -317,7 +310,6 @@ import type {
|
|
|
317
310
|
UnitRouting,
|
|
318
311
|
StartModel,
|
|
319
312
|
AutoSession,
|
|
320
|
-
PendingOrchestrationDispatch,
|
|
321
313
|
} from "./auto/session.js";
|
|
322
314
|
export {
|
|
323
315
|
STUB_RECOVERY_THRESHOLD,
|
|
@@ -639,6 +631,26 @@ export function shouldUseWorktreeIsolation(basePath?: string): boolean {
|
|
|
639
631
|
return getIsolationMode(basePath) === "worktree";
|
|
640
632
|
}
|
|
641
633
|
|
|
634
|
+
type AutoIsolationMode = ReturnType<typeof getIsolationMode>;
|
|
635
|
+
|
|
636
|
+
function resolveEffectiveUnitIsolationMode(
|
|
637
|
+
configuredMode: AutoIsolationMode,
|
|
638
|
+
isolationDegraded: boolean,
|
|
639
|
+
): AutoIsolationMode {
|
|
640
|
+
return configuredMode === "worktree" && isolationDegraded ? "branch" : configuredMode;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
export function _resolveEffectiveUnitIsolationModeForTest(
|
|
644
|
+
configuredMode: AutoIsolationMode,
|
|
645
|
+
isolationDegraded: boolean,
|
|
646
|
+
): AutoIsolationMode {
|
|
647
|
+
return resolveEffectiveUnitIsolationMode(configuredMode, isolationDegraded);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
function getEffectiveUnitIsolationMode(basePath: string): AutoIsolationMode {
|
|
651
|
+
return resolveEffectiveUnitIsolationMode(getIsolationMode(basePath), s.isolationDegraded);
|
|
652
|
+
}
|
|
653
|
+
|
|
642
654
|
/** Crash recovery prompt — set by startAuto, consumed by the main loop */
|
|
643
655
|
|
|
644
656
|
/** Pending verification retry — set when gate fails with retries remaining, consumed by autoLoop */
|
|
@@ -1126,6 +1138,48 @@ function setLifecycleOutcome(
|
|
|
1126
1138
|
});
|
|
1127
1139
|
}
|
|
1128
1140
|
|
|
1141
|
+
const TERMINAL_CLOSEOUT_COMMANDS = [
|
|
1142
|
+
"/gsd status for overview",
|
|
1143
|
+
"/gsd visualize to inspect",
|
|
1144
|
+
"/gsd notifications for history",
|
|
1145
|
+
"/gsd start for new work",
|
|
1146
|
+
];
|
|
1147
|
+
|
|
1148
|
+
function setTerminalCloseoutOutcome(
|
|
1149
|
+
ctx: ExtensionContext | undefined,
|
|
1150
|
+
input: {
|
|
1151
|
+
milestoneId?: string | null;
|
|
1152
|
+
milestoneTitle?: string | null;
|
|
1153
|
+
allMilestonesComplete?: boolean;
|
|
1154
|
+
reason?: string;
|
|
1155
|
+
},
|
|
1156
|
+
): void {
|
|
1157
|
+
if (!ctx?.hasUI) return;
|
|
1158
|
+
const milestoneLabel = input.milestoneId ? `Milestone ${input.milestoneId}` : "Milestone";
|
|
1159
|
+
const title = input.allMilestonesComplete ? "All milestones complete" : `${milestoneLabel} complete`;
|
|
1160
|
+
const titleLine = input.milestoneTitle && input.milestoneId
|
|
1161
|
+
? `${input.milestoneTitle}. `
|
|
1162
|
+
: "";
|
|
1163
|
+
const nextAction = input.allMilestonesComplete
|
|
1164
|
+
? "Review the closeout, then start new work when ready."
|
|
1165
|
+
: "Review the closeout, then start the next milestone when ready.";
|
|
1166
|
+
|
|
1167
|
+
ctx.ui.setHeader?.(() => ({
|
|
1168
|
+
render(): string[] { return []; },
|
|
1169
|
+
invalidate(): void {},
|
|
1170
|
+
}));
|
|
1171
|
+
ctx.ui.setStatus?.("gsd-step", undefined);
|
|
1172
|
+
ctx.ui.setWidget?.("gsd-progress", undefined);
|
|
1173
|
+
setLifecycleOutcome(ctx, {
|
|
1174
|
+
status: "complete",
|
|
1175
|
+
title,
|
|
1176
|
+
detail: `${titleLine}${input.reason ?? "Milestone closeout finished."}`,
|
|
1177
|
+
nextAction,
|
|
1178
|
+
commands: TERMINAL_CLOSEOUT_COMMANDS,
|
|
1179
|
+
unitLabel: input.milestoneId ? `complete-milestone ${input.milestoneId}` : null,
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1129
1183
|
function handleLostSessionLock(
|
|
1130
1184
|
ctx?: ExtensionContext,
|
|
1131
1185
|
lockStatus?: SessionLockStatus,
|
|
@@ -1271,7 +1325,6 @@ export async function cleanupAfterLoopExit(ctx: ExtensionContext): Promise<void>
|
|
|
1271
1325
|
if (!s.paused) {
|
|
1272
1326
|
if (preserveCompletionSurface) {
|
|
1273
1327
|
ctx.ui.setStatus("gsd-auto", undefined);
|
|
1274
|
-
s.completionStopInProgress = false;
|
|
1275
1328
|
if (preserveStepSurface) {
|
|
1276
1329
|
s.preserveStepSurfaceAfterLoopExit = false;
|
|
1277
1330
|
}
|
|
@@ -1414,6 +1467,7 @@ export async function stopAuto(
|
|
|
1414
1467
|
options.preserveCloseoutTranscript ?? completionStopRequested
|
|
1415
1468
|
);
|
|
1416
1469
|
const installCompletionWidget = completionStopRequested && !preserveCloseoutTranscript;
|
|
1470
|
+
const installTerminalCloseoutOutcome = completionStopRequested && preserveCloseoutTranscript;
|
|
1417
1471
|
const preserveCompletionSurface = completionStopRequested || preserveCloseoutTranscript;
|
|
1418
1472
|
s.completionStopInProgress = preserveCompletionSurface;
|
|
1419
1473
|
playNotificationBell("stop", loadedPreferences?.notifications);
|
|
@@ -1747,6 +1801,15 @@ export async function stopAuto(
|
|
|
1747
1801
|
}
|
|
1748
1802
|
}
|
|
1749
1803
|
|
|
1804
|
+
if (installTerminalCloseoutOutcome && ctx && options.completionWidget) {
|
|
1805
|
+
setTerminalCloseoutOutcome(ctx, {
|
|
1806
|
+
milestoneId: completionMilestoneId,
|
|
1807
|
+
milestoneTitle: options.completionWidget.milestoneTitle ?? null,
|
|
1808
|
+
allMilestonesComplete: options.completionWidget.allMilestonesComplete,
|
|
1809
|
+
reason: reason ?? "Milestone closeout finished.",
|
|
1810
|
+
});
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1750
1813
|
// ── Step 9: Cmux sidebar / event log ──
|
|
1751
1814
|
try {
|
|
1752
1815
|
pi?.events.emit(CMUX_CHANNELS.SIDEBAR, { action: "clear" as const, preferences: loadedPreferences });
|
|
@@ -2097,494 +2160,6 @@ function buildLifecycle(): WorktreeLifecycle {
|
|
|
2097
2160
|
return new WorktreeLifecycle(s, buildWorktreeLifecycleDeps());
|
|
2098
2161
|
}
|
|
2099
2162
|
|
|
2100
|
-
/**
|
|
2101
|
-
* Build the production `DispatchAdapter` used by `createWiredAutoOrchestrationModule`.
|
|
2102
|
-
*
|
|
2103
|
-
* Exported so tests can verify parity with `runDispatch`'s `resolveDispatch` call —
|
|
2104
|
-
* the wired adapter must derive `structuredQuestionsAvailable`, `sessionContextWindow`,
|
|
2105
|
-
* `sessionProvider`, and `modelRegistry` the same way phases.ts:runDispatch does.
|
|
2106
|
-
*/
|
|
2107
|
-
export function createWiredDispatchAdapter(
|
|
2108
|
-
ctx: ExtensionContext,
|
|
2109
|
-
pi: ExtensionAPI,
|
|
2110
|
-
dispatchBasePath: string,
|
|
2111
|
-
session?: AutoSession,
|
|
2112
|
-
): DispatchAdapter {
|
|
2113
|
-
function getAlreadyClosedDispatchReason(unitType: string, unitId: string): string | null {
|
|
2114
|
-
if (!isDbAvailable()) return null;
|
|
2115
|
-
refreshOpenDatabaseFromDisk();
|
|
2116
|
-
const { milestone, slice, task } = parseUnitId(unitId);
|
|
2117
|
-
if (unitType === "execute-task" && milestone && slice && task) {
|
|
2118
|
-
const row = getTask(milestone, slice, task);
|
|
2119
|
-
return row && isClosedStatus(row.status)
|
|
2120
|
-
? `execute-task ${unitId} is already ${row.status}`
|
|
2121
|
-
: null;
|
|
2122
|
-
}
|
|
2123
|
-
if (unitType === "complete-slice" && milestone && slice) {
|
|
2124
|
-
const row = getSlice(milestone, slice);
|
|
2125
|
-
return row && isClosedStatus(row.status)
|
|
2126
|
-
? `complete-slice ${unitId} is already ${row.status}`
|
|
2127
|
-
: null;
|
|
2128
|
-
}
|
|
2129
|
-
return null;
|
|
2130
|
-
}
|
|
2131
|
-
|
|
2132
|
-
function shouldAdoptActiveMilestone(
|
|
2133
|
-
state: GSDState,
|
|
2134
|
-
activeSession: AutoSession | undefined,
|
|
2135
|
-
activeDispatchBasePath: string,
|
|
2136
|
-
): boolean {
|
|
2137
|
-
const activeMilestoneId = state.activeMilestone?.id;
|
|
2138
|
-
const currentMilestoneId = activeSession?.currentMilestoneId;
|
|
2139
|
-
if (!activeSession || !activeMilestoneId || !currentMilestoneId || activeMilestoneId === currentMilestoneId) {
|
|
2140
|
-
return false;
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2143
|
-
const scopedWorktreeMilestone =
|
|
2144
|
-
(activeSession.basePath ? detectWorktreeName(activeSession.basePath) : null) ??
|
|
2145
|
-
detectWorktreeName(activeDispatchBasePath);
|
|
2146
|
-
if (scopedWorktreeMilestone && scopedWorktreeMilestone !== activeMilestoneId) {
|
|
2147
|
-
return false;
|
|
2148
|
-
}
|
|
2149
|
-
|
|
2150
|
-
const currentMilestone = state.registry.find((milestone) => milestone.id === currentMilestoneId);
|
|
2151
|
-
return !!currentMilestone && isClosedStatus(currentMilestone.status);
|
|
2152
|
-
}
|
|
2153
|
-
|
|
2154
|
-
return {
|
|
2155
|
-
async decideNextUnit(input) {
|
|
2156
|
-
const state = input.stateSnapshot;
|
|
2157
|
-
const active = state.activeMilestone;
|
|
2158
|
-
if (!active) return null;
|
|
2159
|
-
|
|
2160
|
-
const activeSession = input.session ?? session;
|
|
2161
|
-
const activeDispatchBasePath = activeSession?.basePath || dispatchBasePath;
|
|
2162
|
-
if (activeSession && shouldAdoptActiveMilestone(state, activeSession, activeDispatchBasePath)) {
|
|
2163
|
-
activeSession.currentMilestoneId = active.id;
|
|
2164
|
-
}
|
|
2165
|
-
const prefs = loadEffectiveGSDPreferences(activeDispatchBasePath)?.preferences;
|
|
2166
|
-
|
|
2167
|
-
// Derive session-derived dispatch inputs the same way phases.ts:runDispatch does
|
|
2168
|
-
// (#5789). Prefer caller-supplied values when present so test harnesses and
|
|
2169
|
-
// alternative wirings can inject deterministic snapshots; otherwise pull from
|
|
2170
|
-
// the captured pi/ctx references.
|
|
2171
|
-
const sessionProvider = input.sessionProvider ?? ctx.model?.provider;
|
|
2172
|
-
const sessionContextWindow = input.sessionContextWindow ?? ctx.model?.contextWindow;
|
|
2173
|
-
const modelRegistry = input.modelRegistry ?? (ctx.modelRegistry as MinimalModelRegistry | undefined);
|
|
2174
|
-
const authMode =
|
|
2175
|
-
sessionProvider && typeof ctx.modelRegistry?.getProviderAuthMode === "function"
|
|
2176
|
-
? ctx.modelRegistry.getProviderAuthMode(sessionProvider)
|
|
2177
|
-
: undefined;
|
|
2178
|
-
// Use baseline snapshot — same reason as phases.ts:runDispatch: the live
|
|
2179
|
-
// active set may be narrowed by the prior unit before selectAndApplyModel
|
|
2180
|
-
// restores it, causing false transport-preflight failures (#477 follow-up).
|
|
2181
|
-
const activeTools = getToolBaselineSnapshot(pi);
|
|
2182
|
-
// Mirrors runDispatch: deep-planning keeps approval gates in plain chat
|
|
2183
|
-
// because structured questions can be cancelled outside the chat turn on
|
|
2184
|
-
// some transports.
|
|
2185
|
-
const structuredQuestionsAvailable =
|
|
2186
|
-
input.structuredQuestionsAvailable ??
|
|
2187
|
-
(prefs?.planning_depth === "deep"
|
|
2188
|
-
? "false"
|
|
2189
|
-
: supportsStructuredQuestions(activeTools, {
|
|
2190
|
-
authMode,
|
|
2191
|
-
baseUrl: ctx.model?.baseUrl,
|
|
2192
|
-
})
|
|
2193
|
-
? "true"
|
|
2194
|
-
: "false");
|
|
2195
|
-
|
|
2196
|
-
const pendingRetry = session?.pendingVerificationRetryDispatch;
|
|
2197
|
-
if (session && pendingRetry) {
|
|
2198
|
-
session.pendingVerificationRetryDispatch = null;
|
|
2199
|
-
const alreadyClosedReason = getAlreadyClosedDispatchReason(
|
|
2200
|
-
pendingRetry.unitType,
|
|
2201
|
-
pendingRetry.unitId,
|
|
2202
|
-
);
|
|
2203
|
-
if (alreadyClosedReason) {
|
|
2204
|
-
session.pendingOrchestrationDispatch = null;
|
|
2205
|
-
session.pendingVerificationRetry = null;
|
|
2206
|
-
return { kind: "skipped", reason: alreadyClosedReason };
|
|
2207
|
-
}
|
|
2208
|
-
session.pendingOrchestrationDispatch = pendingRetry;
|
|
2209
|
-
return {
|
|
2210
|
-
unitType: pendingRetry.unitType,
|
|
2211
|
-
unitId: pendingRetry.unitId,
|
|
2212
|
-
reason: "verification-retry",
|
|
2213
|
-
preconditions: [],
|
|
2214
|
-
};
|
|
2215
|
-
}
|
|
2216
|
-
|
|
2217
|
-
const action = await resolveDispatch({
|
|
2218
|
-
basePath: activeDispatchBasePath,
|
|
2219
|
-
mid: active.id,
|
|
2220
|
-
midTitle: active.title,
|
|
2221
|
-
state,
|
|
2222
|
-
prefs,
|
|
2223
|
-
session: activeSession,
|
|
2224
|
-
structuredQuestionsAvailable,
|
|
2225
|
-
sessionContextWindow,
|
|
2226
|
-
sessionProvider,
|
|
2227
|
-
modelRegistry,
|
|
2228
|
-
activeTools,
|
|
2229
|
-
sessionAuthMode: authMode,
|
|
2230
|
-
sessionBaseUrl: ctx.model?.baseUrl,
|
|
2231
|
-
});
|
|
2232
|
-
|
|
2233
|
-
if (action.action === "stop") {
|
|
2234
|
-
if (session) session.pendingOrchestrationDispatch = null;
|
|
2235
|
-
return {
|
|
2236
|
-
kind: "blocked",
|
|
2237
|
-
reason: action.reason,
|
|
2238
|
-
action: action.level === "warning" ? "pause" : "stop",
|
|
2239
|
-
};
|
|
2240
|
-
}
|
|
2241
|
-
if (action.action !== "dispatch") {
|
|
2242
|
-
if (session) session.pendingOrchestrationDispatch = null;
|
|
2243
|
-
return {
|
|
2244
|
-
kind: "skipped",
|
|
2245
|
-
reason: action.matchedRule ?? "dispatch-skip",
|
|
2246
|
-
};
|
|
2247
|
-
}
|
|
2248
|
-
const alreadyClosedReason = getAlreadyClosedDispatchReason(action.unitType, action.unitId);
|
|
2249
|
-
if (alreadyClosedReason) {
|
|
2250
|
-
if (session) {
|
|
2251
|
-
session.pendingOrchestrationDispatch = null;
|
|
2252
|
-
session.pendingVerificationRetry = null;
|
|
2253
|
-
}
|
|
2254
|
-
return { kind: "skipped", reason: alreadyClosedReason };
|
|
2255
|
-
}
|
|
2256
|
-
if (session) {
|
|
2257
|
-
const pending: PendingOrchestrationDispatch = {
|
|
2258
|
-
unitType: action.unitType,
|
|
2259
|
-
unitId: action.unitId,
|
|
2260
|
-
prompt: action.prompt,
|
|
2261
|
-
pauseAfterUatDispatch: action.pauseAfterDispatch ?? false,
|
|
2262
|
-
state,
|
|
2263
|
-
mid: active.id,
|
|
2264
|
-
midTitle: active.title,
|
|
2265
|
-
};
|
|
2266
|
-
session.pendingOrchestrationDispatch = pending;
|
|
2267
|
-
}
|
|
2268
|
-
return {
|
|
2269
|
-
unitType: action.unitType,
|
|
2270
|
-
unitId: action.unitId,
|
|
2271
|
-
reason: action.matchedRule ?? "dispatch",
|
|
2272
|
-
preconditions: [],
|
|
2273
|
-
};
|
|
2274
|
-
},
|
|
2275
|
-
};
|
|
2276
|
-
}
|
|
2277
|
-
|
|
2278
|
-
function isUsableLiveOrchestratorBasePath(basePath: string): boolean {
|
|
2279
|
-
if (!basePath || !existsSync(basePath)) return false;
|
|
2280
|
-
if (!detectWorktreeName(basePath)) return true;
|
|
2281
|
-
|
|
2282
|
-
try {
|
|
2283
|
-
return readFileSync(join(basePath, ".git"), "utf8").trim().startsWith("gitdir: ");
|
|
2284
|
-
} catch {
|
|
2285
|
-
return false;
|
|
2286
|
-
}
|
|
2287
|
-
}
|
|
2288
|
-
|
|
2289
|
-
export function resolveLiveOrchestratorBasePath(input: {
|
|
2290
|
-
capturedBasePath: string;
|
|
2291
|
-
runtimeBasePath: string;
|
|
2292
|
-
sessionBasePath?: string | null;
|
|
2293
|
-
originalBasePath?: string | null;
|
|
2294
|
-
}): string {
|
|
2295
|
-
const primary = input.sessionBasePath || input.capturedBasePath;
|
|
2296
|
-
if (isUsableLiveOrchestratorBasePath(primary)) return primary;
|
|
2297
|
-
|
|
2298
|
-
const fallbacks = [
|
|
2299
|
-
input.originalBasePath,
|
|
2300
|
-
input.runtimeBasePath,
|
|
2301
|
-
resolveProjectRoot(input.capturedBasePath),
|
|
2302
|
-
];
|
|
2303
|
-
|
|
2304
|
-
for (const candidate of fallbacks) {
|
|
2305
|
-
if (candidate && isUsableLiveOrchestratorBasePath(candidate)) {
|
|
2306
|
-
return candidate;
|
|
2307
|
-
}
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
return input.runtimeBasePath || input.capturedBasePath;
|
|
2311
|
-
}
|
|
2312
|
-
|
|
2313
|
-
/**
|
|
2314
|
-
* Thin entry glue for the new Auto Orchestration module.
|
|
2315
|
-
*
|
|
2316
|
-
* This intentionally wires only dispatch + error notification today, with
|
|
2317
|
-
* no behavior changes to the existing auto loop. It provides a concrete seam
|
|
2318
|
-
* the next refactor steps can adopt incrementally.
|
|
2319
|
-
*/
|
|
2320
|
-
export function createWiredAutoOrchestrationModule(
|
|
2321
|
-
ctx: ExtensionContext,
|
|
2322
|
-
pi: ExtensionAPI,
|
|
2323
|
-
dispatchBasePath: string,
|
|
2324
|
-
runtimeBasePath = resolveProjectRoot(dispatchBasePath),
|
|
2325
|
-
): AutoOrchestrationModule {
|
|
2326
|
-
const flowId = `auto-orchestrator-${Date.now()}`;
|
|
2327
|
-
let seq = 0;
|
|
2328
|
-
const getLiveDispatchBasePath = () =>
|
|
2329
|
-
resolveLiveOrchestratorBasePath({
|
|
2330
|
-
capturedBasePath: dispatchBasePath,
|
|
2331
|
-
runtimeBasePath,
|
|
2332
|
-
sessionBasePath: s.basePath,
|
|
2333
|
-
originalBasePath: s.originalBasePath,
|
|
2334
|
-
});
|
|
2335
|
-
|
|
2336
|
-
const deps: AutoOrchestratorDeps = {
|
|
2337
|
-
stateReconciliation: {
|
|
2338
|
-
async reconcileBeforeDispatch() {
|
|
2339
|
-
const activeBasePath = getLiveDispatchBasePath();
|
|
2340
|
-
const result = await reconcileBeforeDispatch(activeBasePath);
|
|
2341
|
-
// Failure-path summaries written by gsd_summary_save create
|
|
2342
|
-
// artifact-db-status-divergence blockers for tasks that are still
|
|
2343
|
-
// pending (gsd_task_complete never ran). These tasks can still be
|
|
2344
|
-
// dispatched and the drift self-heals once they complete successfully.
|
|
2345
|
-
const hardBlockers = result.blockers.filter(
|
|
2346
|
-
(b) =>
|
|
2347
|
-
!b.includes("has SUMMARY artifact while DB status is") &&
|
|
2348
|
-
!b.includes("has SUMMARY on disk while DB status is") &&
|
|
2349
|
-
!b.includes("has task SUMMARY artifacts but no DB tasks"),
|
|
2350
|
-
);
|
|
2351
|
-
if (hardBlockers.length > 0) {
|
|
2352
|
-
return {
|
|
2353
|
-
ok: false,
|
|
2354
|
-
reason: hardBlockers[0],
|
|
2355
|
-
stateSnapshot: result.stateSnapshot,
|
|
2356
|
-
};
|
|
2357
|
-
}
|
|
2358
|
-
const repairedKinds = result.repaired.map((d) => d.kind);
|
|
2359
|
-
return {
|
|
2360
|
-
ok: true,
|
|
2361
|
-
reason:
|
|
2362
|
-
repairedKinds.length > 0
|
|
2363
|
-
? `repaired: ${repairedKinds.join(", ")}`
|
|
2364
|
-
: "clean",
|
|
2365
|
-
stateSnapshot: result.stateSnapshot,
|
|
2366
|
-
};
|
|
2367
|
-
},
|
|
2368
|
-
},
|
|
2369
|
-
dispatch: createWiredDispatchAdapter(ctx, pi, dispatchBasePath, s),
|
|
2370
|
-
recovery: {
|
|
2371
|
-
async classifyAndRecover(input) {
|
|
2372
|
-
const recovery = classifyFailure(input);
|
|
2373
|
-
return { action: recovery.action, reason: recovery.reason };
|
|
2374
|
-
},
|
|
2375
|
-
},
|
|
2376
|
-
toolContract: {
|
|
2377
|
-
async compileUnitToolContract(unitType) {
|
|
2378
|
-
const result = compileUnitToolContract(unitType);
|
|
2379
|
-
if (!result.ok) return { ok: false, reason: result.detail };
|
|
2380
|
-
return { ok: true, reason: result.contract.validationRules.join(", ") };
|
|
2381
|
-
},
|
|
2382
|
-
},
|
|
2383
|
-
worktree: {
|
|
2384
|
-
async prepareForUnit(unitType, unitId) {
|
|
2385
|
-
const manifest = resolveManifest(unitType);
|
|
2386
|
-
if (!manifest) {
|
|
2387
|
-
return {
|
|
2388
|
-
ok: false,
|
|
2389
|
-
reason: `No Unit manifest is registered for ${unitType}`,
|
|
2390
|
-
};
|
|
2391
|
-
}
|
|
2392
|
-
if (getIsolationMode(runtimeBasePath) !== "worktree") {
|
|
2393
|
-
return { ok: true, reason: "not-required" };
|
|
2394
|
-
}
|
|
2395
|
-
const writeScope =
|
|
2396
|
-
manifest.tools.mode === "all" || manifest.tools.mode === "docs"
|
|
2397
|
-
? "source-writing"
|
|
2398
|
-
: "planning-only";
|
|
2399
|
-
if (getIsolationMode(runtimeBasePath) !== "worktree") {
|
|
2400
|
-
return { ok: true, reason: "isolation-not-worktree" };
|
|
2401
|
-
}
|
|
2402
|
-
const safety = createWorktreeSafetyModule();
|
|
2403
|
-
const activeBasePath = getLiveDispatchBasePath();
|
|
2404
|
-
const snapshot = await deriveState(activeBasePath);
|
|
2405
|
-
const milestoneId = snapshot.activeMilestone?.id ?? null;
|
|
2406
|
-
const expectedBranch = milestoneId ? autoWorktreeBranch(milestoneId) : null;
|
|
2407
|
-
let result = safety.validateUnitRoot({
|
|
2408
|
-
unitType,
|
|
2409
|
-
unitId,
|
|
2410
|
-
writeScope,
|
|
2411
|
-
projectRoot: runtimeBasePath,
|
|
2412
|
-
unitRoot: activeBasePath,
|
|
2413
|
-
milestoneId,
|
|
2414
|
-
isolationMode: getIsolationMode(runtimeBasePath),
|
|
2415
|
-
expectedBranch,
|
|
2416
|
-
});
|
|
2417
|
-
if (!result.ok) {
|
|
2418
|
-
const repaired = await repairAutoWorktreeSafetyFailure({
|
|
2419
|
-
safetyResult: result,
|
|
2420
|
-
projectRoot: runtimeBasePath,
|
|
2421
|
-
activeRoot: activeBasePath,
|
|
2422
|
-
milestoneId,
|
|
2423
|
-
enterMilestone: async (id) => {
|
|
2424
|
-
buildLifecycle().adoptSessionRoot(runtimeBasePath, s.originalBasePath || runtimeBasePath);
|
|
2425
|
-
const enterResult = buildLifecycle().enterMilestone(id, {
|
|
2426
|
-
notify: ctx.ui.notify.bind(ctx.ui),
|
|
2427
|
-
});
|
|
2428
|
-
if (!enterResult.ok) return { ok: false, reason: enterResult.reason };
|
|
2429
|
-
rebuildScope(s.basePath, s.currentMilestoneId);
|
|
2430
|
-
return { ok: true };
|
|
2431
|
-
},
|
|
2432
|
-
revalidate: () => safety.validateUnitRoot({
|
|
2433
|
-
unitType,
|
|
2434
|
-
unitId,
|
|
2435
|
-
writeScope,
|
|
2436
|
-
projectRoot: runtimeBasePath,
|
|
2437
|
-
unitRoot: getLiveDispatchBasePath(),
|
|
2438
|
-
milestoneId,
|
|
2439
|
-
isolationMode: getIsolationMode(runtimeBasePath),
|
|
2440
|
-
expectedBranch,
|
|
2441
|
-
}),
|
|
2442
|
-
});
|
|
2443
|
-
result = repaired.result;
|
|
2444
|
-
if (result.ok) {
|
|
2445
|
-
return { ok: true, reason: repaired.repaired ? `repaired-${result.kind}` : result.kind };
|
|
2446
|
-
}
|
|
2447
|
-
const repairDetail = repaired.repairReason
|
|
2448
|
-
? ` (repair skipped: ${repaired.repairReason})`
|
|
2449
|
-
: "";
|
|
2450
|
-
return { ok: false, reason: `${result.kind}: ${result.reason}${repairDetail}` };
|
|
2451
|
-
}
|
|
2452
|
-
return { ok: true, reason: result.kind };
|
|
2453
|
-
},
|
|
2454
|
-
async syncAfterUnit() {},
|
|
2455
|
-
async cleanupOnStop() {},
|
|
2456
|
-
},
|
|
2457
|
-
health: {
|
|
2458
|
-
checkResourcesStale() {
|
|
2459
|
-
return checkResourcesStale(s.resourceVersionOnStart);
|
|
2460
|
-
},
|
|
2461
|
-
async preAdvanceGate() {
|
|
2462
|
-
try {
|
|
2463
|
-
const gate = await preDispatchHealthGate(getLiveDispatchBasePath());
|
|
2464
|
-
if (gate.proceed) {
|
|
2465
|
-
return {
|
|
2466
|
-
kind: "pass",
|
|
2467
|
-
fixesApplied: gate.fixesApplied,
|
|
2468
|
-
};
|
|
2469
|
-
}
|
|
2470
|
-
return {
|
|
2471
|
-
kind: "fail",
|
|
2472
|
-
reason: gate.reason ?? "Pre-dispatch health check failed — run /gsd doctor for details.",
|
|
2473
|
-
action: gate.severity ?? "pause",
|
|
2474
|
-
};
|
|
2475
|
-
} catch (error) {
|
|
2476
|
-
return { kind: "threw", error };
|
|
2477
|
-
}
|
|
2478
|
-
},
|
|
2479
|
-
async postAdvanceRecord(result) {
|
|
2480
|
-
if (result.kind === "error") {
|
|
2481
|
-
recordHealthSnapshot(1, 0, 0, [{
|
|
2482
|
-
code: "orchestration-error",
|
|
2483
|
-
message: result.reason ?? "orchestration error",
|
|
2484
|
-
severity: "error",
|
|
2485
|
-
unitId: "orchestration",
|
|
2486
|
-
}], [], "orchestration");
|
|
2487
|
-
} else if (result.kind === "blocked") {
|
|
2488
|
-
recordHealthSnapshot(0, 1, 0, [{
|
|
2489
|
-
code: "orchestration-blocked",
|
|
2490
|
-
message: result.reason ?? "orchestration blocked",
|
|
2491
|
-
severity: "warning",
|
|
2492
|
-
unitId: "orchestration",
|
|
2493
|
-
}], [], "orchestration");
|
|
2494
|
-
}
|
|
2495
|
-
},
|
|
2496
|
-
},
|
|
2497
|
-
runtime: {
|
|
2498
|
-
async ensureLockOwnership() {
|
|
2499
|
-
const status = getSessionLockStatus(runtimeBasePath);
|
|
2500
|
-
if (!status.valid || status.failureReason === "pid-mismatch") {
|
|
2501
|
-
throw new Error("session lock held by another process");
|
|
2502
|
-
}
|
|
2503
|
-
},
|
|
2504
|
-
async journalTransition(event) {
|
|
2505
|
-
const eventType = event.name === "start"
|
|
2506
|
-
? "orchestrator-iteration-start"
|
|
2507
|
-
: event.name === "resume"
|
|
2508
|
-
? "orchestrator-iteration-start"
|
|
2509
|
-
: event.name === "advance"
|
|
2510
|
-
? "orchestrator-dispatch-match"
|
|
2511
|
-
: event.name === "advance-blocked"
|
|
2512
|
-
? "orchestrator-guard-block"
|
|
2513
|
-
: event.name === "advance-stopped"
|
|
2514
|
-
? "orchestrator-dispatch-stop"
|
|
2515
|
-
: event.name === "advance-error"
|
|
2516
|
-
? "orchestrator-iteration-end"
|
|
2517
|
-
: event.name === "advance-paused" || event.name === "advance-retry"
|
|
2518
|
-
? "orchestrator-guard-block"
|
|
2519
|
-
: event.name === "stop"
|
|
2520
|
-
? "orchestrator-terminal"
|
|
2521
|
-
: "orchestrator-iteration-end";
|
|
2522
|
-
|
|
2523
|
-
_emitJournalEvent(runtimeBasePath, {
|
|
2524
|
-
ts: new Date().toISOString(),
|
|
2525
|
-
flowId,
|
|
2526
|
-
seq: ++seq,
|
|
2527
|
-
eventType,
|
|
2528
|
-
data: {
|
|
2529
|
-
source: "auto-orchestrator",
|
|
2530
|
-
name: event.name,
|
|
2531
|
-
reason: event.reason,
|
|
2532
|
-
unitType: event.unitType,
|
|
2533
|
-
unitId: event.unitId,
|
|
2534
|
-
},
|
|
2535
|
-
});
|
|
2536
|
-
},
|
|
2537
|
-
},
|
|
2538
|
-
notifications: {
|
|
2539
|
-
async notifyLifecycle(event) {
|
|
2540
|
-
if (event.name === "error") {
|
|
2541
|
-
ctx.ui.notify(event.detail ?? "auto orchestration error", "error");
|
|
2542
|
-
}
|
|
2543
|
-
},
|
|
2544
|
-
},
|
|
2545
|
-
uokGate: {
|
|
2546
|
-
async emit(input) {
|
|
2547
|
-
const activeBasePath = getLiveDispatchBasePath();
|
|
2548
|
-
const prefs = loadEffectiveGSDPreferences(activeBasePath)?.preferences;
|
|
2549
|
-
const uokFlags = resolveUokFlags(prefs);
|
|
2550
|
-
if (!uokFlags.gates) return;
|
|
2551
|
-
const milestoneId = input.milestoneId ?? s.currentMilestoneId ?? undefined;
|
|
2552
|
-
try {
|
|
2553
|
-
const { UokGateRunner } = await import("./uok/gate-runner.js");
|
|
2554
|
-
const runner = new UokGateRunner();
|
|
2555
|
-
runner.register({
|
|
2556
|
-
id: input.gateId,
|
|
2557
|
-
type: input.gateType,
|
|
2558
|
-
execute: async () => ({
|
|
2559
|
-
outcome: input.outcome,
|
|
2560
|
-
failureClass: input.failureClass,
|
|
2561
|
-
rationale: input.rationale,
|
|
2562
|
-
findings: input.findings ?? "",
|
|
2563
|
-
}),
|
|
2564
|
-
});
|
|
2565
|
-
await runner.run(input.gateId, {
|
|
2566
|
-
basePath: activeBasePath,
|
|
2567
|
-
traceId: `pre-dispatch:${flowId}`,
|
|
2568
|
-
turnId: `orch-${seq}`,
|
|
2569
|
-
milestoneId,
|
|
2570
|
-
unitType: "pre-dispatch",
|
|
2571
|
-
unitId: `orch-${seq}`,
|
|
2572
|
-
});
|
|
2573
|
-
} catch (err) {
|
|
2574
|
-
logWarning("engine", `uok gate emit failed: ${getErrorMessage(err)}`, {
|
|
2575
|
-
file: "auto.ts",
|
|
2576
|
-
gateId: input.gateId,
|
|
2577
|
-
gateType: input.gateType,
|
|
2578
|
-
...(milestoneId ? { milestoneId } : {}),
|
|
2579
|
-
});
|
|
2580
|
-
}
|
|
2581
|
-
},
|
|
2582
|
-
},
|
|
2583
|
-
};
|
|
2584
|
-
|
|
2585
|
-
return createAutoOrchestrator(deps);
|
|
2586
|
-
}
|
|
2587
|
-
|
|
2588
2163
|
function notifyResumeBlocked(ctx: ExtensionContext, result: Extract<AutoAdvanceResult, { kind: "blocked" }>): void {
|
|
2589
2164
|
const resumeCmd = s.stepMode ? "/gsd next" : "/gsd auto";
|
|
2590
2165
|
ctx.ui.notify(`Auto-mode blocked: ${result.reason}. Fix and run ${resumeCmd} to resume.`, "warning");
|
|
@@ -2598,7 +2173,13 @@ function notifyResumeBlocked(ctx: ExtensionContext, result: Extract<AutoAdvanceR
|
|
|
2598
2173
|
}
|
|
2599
2174
|
|
|
2600
2175
|
function ensureOrchestrationModule(ctx: ExtensionContext, pi: ExtensionAPI, basePath: string): void {
|
|
2601
|
-
s.orchestration =
|
|
2176
|
+
s.orchestration = createAutoOrchestrator({
|
|
2177
|
+
ctx,
|
|
2178
|
+
pi,
|
|
2179
|
+
dispatchBasePath: basePath,
|
|
2180
|
+
runtimeBasePath: lockBase(),
|
|
2181
|
+
session: s,
|
|
2182
|
+
});
|
|
2602
2183
|
}
|
|
2603
2184
|
|
|
2604
2185
|
/**
|
|
@@ -18,6 +18,7 @@ import { resolveManifest } from "../unit-context-manifest.js";
|
|
|
18
18
|
import { isBlockedStateFile, isBashWriteToStateFile, BLOCKED_WRITE_ERROR } from "../write-intercept.js";
|
|
19
19
|
import { loadFile, saveFile, formatContinue } from "../files.js";
|
|
20
20
|
import {
|
|
21
|
+
clearAutoCompletionStopInProgress,
|
|
21
22
|
clearToolInvocationError,
|
|
22
23
|
getAutoRuntimeSnapshot,
|
|
23
24
|
getSourceObservationStore,
|
|
@@ -138,7 +139,9 @@ export const MINIMAL_GSD_TOOL_NAMES = [
|
|
|
138
139
|
"gsd_checkpoint_db",
|
|
139
140
|
"gsd_plan_milestone",
|
|
140
141
|
"memory_query",
|
|
142
|
+
"gsd_memory_query",
|
|
141
143
|
"capture_thought",
|
|
144
|
+
"gsd_capture_thought",
|
|
142
145
|
] as const;
|
|
143
146
|
|
|
144
147
|
export const MINIMAL_AUTO_BASE_TOOL_NAMES = [
|
|
@@ -790,6 +793,7 @@ export function registerHooks(
|
|
|
790
793
|
});
|
|
791
794
|
|
|
792
795
|
pi.on("before_agent_start", async (event, ctx: ExtensionContext) => {
|
|
796
|
+
clearAutoCompletionStopInProgress();
|
|
793
797
|
resetPendingGatePauseGuard();
|
|
794
798
|
applyMinimalGsdToolSurface(pi);
|
|
795
799
|
|