gsd-pi 2.60.0-dev.2580e65 → 2.60.0-dev.d9052f5
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/resources/extensions/ask-user-questions.js +4 -7
- package/dist/resources/extensions/gsd/auto/phases.js +7 -15
- package/dist/resources/extensions/gsd/auto-dashboard.js +8 -21
- package/dist/resources/extensions/gsd/auto-dispatch.js +3 -6
- package/dist/resources/extensions/gsd/auto-model-selection.js +9 -58
- package/dist/resources/extensions/gsd/auto-post-unit.js +2 -3
- package/dist/resources/extensions/gsd/auto-prompts.js +20 -36
- package/dist/resources/extensions/gsd/auto-recovery.js +18 -37
- package/dist/resources/extensions/gsd/auto-start.js +5 -9
- package/dist/resources/extensions/gsd/auto-timers.js +5 -11
- package/dist/resources/extensions/gsd/auto-unit-closeout.js +3 -5
- package/dist/resources/extensions/gsd/auto-verification.js +2 -3
- package/dist/resources/extensions/gsd/auto-worktree.js +55 -120
- package/dist/resources/extensions/gsd/auto.js +17 -39
- package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -6
- package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -2
- package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +10 -4
- package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +1 -2
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +0 -7
- package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -11
- package/dist/resources/extensions/gsd/commands/catalog.js +0 -2
- package/dist/resources/extensions/gsd/commands-codebase.js +21 -48
- package/dist/resources/extensions/gsd/commands-inspect.js +1 -2
- package/dist/resources/extensions/gsd/commands-maintenance.js +19 -32
- package/dist/resources/extensions/gsd/complexity-classifier.js +4 -8
- package/dist/resources/extensions/gsd/custom-verification.js +2 -3
- package/dist/resources/extensions/gsd/gsd-db.js +13 -33
- package/dist/resources/extensions/gsd/guided-flow.js +9 -19
- package/dist/resources/extensions/gsd/init-wizard.js +0 -12
- package/dist/resources/extensions/gsd/markdown-renderer.js +9 -11
- package/dist/resources/extensions/gsd/md-importer.js +4 -5
- package/dist/resources/extensions/gsd/milestone-actions.js +2 -3
- package/dist/resources/extensions/gsd/milestone-ids.js +1 -2
- package/dist/resources/extensions/gsd/model-router.js +121 -156
- package/dist/resources/extensions/gsd/parallel-merge.js +3 -5
- package/dist/resources/extensions/gsd/parallel-orchestrator.js +14 -26
- package/dist/resources/extensions/gsd/preferences-types.js +0 -1
- package/dist/resources/extensions/gsd/preferences-validation.js +0 -45
- package/dist/resources/extensions/gsd/preferences.js +3 -15
- package/dist/resources/extensions/gsd/prompt-loader.js +2 -3
- package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/dist/resources/extensions/gsd/rule-registry.js +6 -7
- package/dist/resources/extensions/gsd/safe-fs.js +8 -6
- package/dist/resources/extensions/gsd/tools/complete-milestone.js +2 -3
- package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -3
- package/dist/resources/extensions/gsd/tools/complete-task.js +2 -3
- package/dist/resources/extensions/gsd/tools/plan-milestone.js +2 -3
- package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -3
- package/dist/resources/extensions/gsd/tools/plan-task.js +1 -2
- package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +4 -4
- package/dist/resources/extensions/gsd/tools/reopen-slice.js +1 -2
- package/dist/resources/extensions/gsd/tools/reopen-task.js +1 -2
- package/dist/resources/extensions/gsd/tools/replan-slice.js +1 -2
- package/dist/resources/extensions/gsd/tools/validate-milestone.js +1 -2
- package/dist/resources/extensions/gsd/triage-resolution.js +4 -11
- package/dist/resources/extensions/gsd/workflow-events.js +1 -2
- package/dist/resources/extensions/gsd/workflow-logger.js +4 -37
- package/dist/resources/extensions/gsd/workflow-migration.js +12 -14
- package/dist/resources/extensions/gsd/workflow-projections.js +2 -2
- package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -2
- package/dist/resources/extensions/gsd/worktree-manager.js +14 -26
- package/dist/resources/extensions/shared/interview-ui.js +1 -3
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
- 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 +2 -2
- 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 +19 -19
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +2 -2
- package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
- package/package.json +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +0 -5
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -2
- package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/runner.js +0 -16
- package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +0 -26
- package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/config.js +1 -6
- package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/defaults.json +2 -2
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +0 -6
- package/packages/pi-coding-agent/src/core/extensions/runner.ts +0 -19
- package/packages/pi-coding-agent/src/core/extensions/types.ts +0 -26
- package/packages/pi-coding-agent/src/core/lsp/config.ts +1 -7
- package/packages/pi-coding-agent/src/core/lsp/defaults.json +2 -2
- package/src/resources/extensions/ask-user-questions.ts +3 -7
- package/src/resources/extensions/gsd/auto/phases.ts +7 -17
- package/src/resources/extensions/gsd/auto-dashboard.ts +8 -22
- package/src/resources/extensions/gsd/auto-dispatch.ts +3 -7
- package/src/resources/extensions/gsd/auto-model-selection.ts +15 -77
- package/src/resources/extensions/gsd/auto-post-unit.ts +4 -4
- package/src/resources/extensions/gsd/auto-prompts.ts +20 -37
- package/src/resources/extensions/gsd/auto-recovery.ts +18 -38
- package/src/resources/extensions/gsd/auto-start.ts +9 -10
- package/src/resources/extensions/gsd/auto-timers.ts +5 -12
- package/src/resources/extensions/gsd/auto-unit-closeout.ts +2 -6
- package/src/resources/extensions/gsd/auto-verification.ts +6 -3
- package/src/resources/extensions/gsd/auto-worktree.ts +55 -121
- package/src/resources/extensions/gsd/auto.ts +17 -40
- package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -4
- package/src/resources/extensions/gsd/bootstrap/db-tools.ts +2 -2
- package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -4
- package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +1 -2
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +0 -8
- package/src/resources/extensions/gsd/bootstrap/system-context.ts +10 -11
- package/src/resources/extensions/gsd/commands/catalog.ts +0 -2
- package/src/resources/extensions/gsd/commands-codebase.ts +20 -52
- package/src/resources/extensions/gsd/commands-inspect.ts +1 -2
- package/src/resources/extensions/gsd/commands-maintenance.ts +19 -28
- package/src/resources/extensions/gsd/complexity-classifier.ts +4 -9
- package/src/resources/extensions/gsd/custom-verification.ts +2 -3
- package/src/resources/extensions/gsd/gsd-db.ts +14 -12
- package/src/resources/extensions/gsd/guided-flow.ts +8 -9
- package/src/resources/extensions/gsd/init-wizard.ts +0 -12
- package/src/resources/extensions/gsd/markdown-renderer.ts +17 -11
- package/src/resources/extensions/gsd/md-importer.ts +4 -5
- package/src/resources/extensions/gsd/milestone-actions.ts +2 -3
- package/src/resources/extensions/gsd/milestone-ids.ts +1 -2
- package/src/resources/extensions/gsd/model-router.ts +173 -199
- package/src/resources/extensions/gsd/parallel-merge.ts +3 -5
- package/src/resources/extensions/gsd/parallel-orchestrator.ts +14 -18
- package/src/resources/extensions/gsd/preferences-types.ts +0 -13
- package/src/resources/extensions/gsd/preferences-validation.ts +0 -45
- package/src/resources/extensions/gsd/preferences.ts +3 -16
- package/src/resources/extensions/gsd/prompt-loader.ts +2 -3
- package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
- package/src/resources/extensions/gsd/rule-registry.ts +6 -7
- package/src/resources/extensions/gsd/safe-fs.ts +5 -6
- package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +0 -63
- package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +2 -27
- package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/model-router.test.ts +3 -403
- package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -62
- package/src/resources/extensions/gsd/tests/remote-questions.test.ts +0 -21
- package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +6 -6
- package/src/resources/extensions/gsd/tools/complete-milestone.ts +6 -3
- package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -3
- package/src/resources/extensions/gsd/tools/complete-task.ts +6 -3
- package/src/resources/extensions/gsd/tools/plan-milestone.ts +6 -3
- package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -3
- package/src/resources/extensions/gsd/tools/plan-task.ts +3 -2
- package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +6 -4
- package/src/resources/extensions/gsd/tools/reopen-slice.ts +3 -2
- package/src/resources/extensions/gsd/tools/reopen-task.ts +3 -2
- package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -2
- package/src/resources/extensions/gsd/tools/validate-milestone.ts +3 -2
- package/src/resources/extensions/gsd/triage-resolution.ts +4 -11
- package/src/resources/extensions/gsd/types.ts +0 -1
- package/src/resources/extensions/gsd/workflow-events.ts +1 -2
- package/src/resources/extensions/gsd/workflow-logger.ts +5 -52
- package/src/resources/extensions/gsd/workflow-migration.ts +12 -14
- package/src/resources/extensions/gsd/workflow-projections.ts +2 -2
- package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -2
- package/src/resources/extensions/gsd/worktree-manager.ts +14 -16
- package/src/resources/extensions/shared/interview-ui.ts +1 -3
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts +0 -2
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts.map +0 -1
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js +0 -47
- package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js.map +0 -1
- package/packages/pi-coding-agent/src/core/lsp/lsp-legacy-alias.test.ts +0 -70
- package/src/resources/extensions/gsd/tests/capability-router.test.ts +0 -347
- package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +0 -1188
- package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +0 -841
- package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +0 -284
- package/src/resources/extensions/gsd/tests/workflow-logger-audit.test.ts +0 -120
- package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +0 -144
- /package/dist/web/standalone/.next/static/{ogyMN7M-3bGGuRY08L5HR → JVkoVYumy0cDhOQISEYdG}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{ogyMN7M-3bGGuRY08L5HR → JVkoVYumy0cDhOQISEYdG}/_ssgManifest.js +0 -0
|
@@ -82,14 +82,11 @@ export default function AskUserQuestions(pi) {
|
|
|
82
82
|
return errorResult(`Error: ask_user_questions requires non-empty options for every question (question "${q.id}" has none)`, params.questions);
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
-
// Try remote first if configured (works in both interactive and headless modes).
|
|
86
|
-
// tryRemoteQuestions returns null when no remote channel is configured, so
|
|
87
|
-
// this is a no-op when the user has not set up Slack/Discord/Telegram.
|
|
88
|
-
const { tryRemoteQuestions } = await import("./remote-questions/manager.js");
|
|
89
|
-
const remoteResult = await tryRemoteQuestions(params.questions, signal);
|
|
90
|
-
if (remoteResult)
|
|
91
|
-
return { ...remoteResult, details: remoteResult.details };
|
|
92
85
|
if (!ctx.hasUI) {
|
|
86
|
+
const { tryRemoteQuestions } = await import("./remote-questions/manager.js");
|
|
87
|
+
const remoteResult = await tryRemoteQuestions(params.questions, signal);
|
|
88
|
+
if (remoteResult)
|
|
89
|
+
return { ...remoteResult, details: remoteResult.details };
|
|
93
90
|
return errorResult("Error: UI not available (non-interactive mode)", params.questions);
|
|
94
91
|
}
|
|
95
92
|
// Delegate to shared interview UI
|
|
@@ -495,8 +495,6 @@ export async function runGuards(ic, mid) {
|
|
|
495
495
|
// ── Stop/Backtrack directive guard (#3487) ──
|
|
496
496
|
// Check for unexecuted stop or backtrack captures BEFORE dispatching any unit.
|
|
497
497
|
// This ensures user "halt" directives are honored immediately.
|
|
498
|
-
// IMPORTANT: Fail-closed — any exception during stop handling still breaks the loop
|
|
499
|
-
// to ensure user halt intent is never silently dropped.
|
|
500
498
|
try {
|
|
501
499
|
const { loadStopCaptures, markCaptureExecuted } = await import("../captures.js");
|
|
502
500
|
const stopCaptures = loadStopCaptures(s.basePath);
|
|
@@ -508,9 +506,11 @@ export async function runGuards(ic, mid) {
|
|
|
508
506
|
: `Stop directive: ${first.text}`;
|
|
509
507
|
ctx.ui.notify(label, "warning");
|
|
510
508
|
deps.sendDesktopNotification("GSD", label, "warning", "stop-directive", basename(s.originalBasePath || s.basePath));
|
|
511
|
-
//
|
|
512
|
-
|
|
513
|
-
|
|
509
|
+
// Mark all stop/backtrack captures as executed so they don't re-fire
|
|
510
|
+
for (const cap of stopCaptures) {
|
|
511
|
+
markCaptureExecuted(s.basePath, cap.id);
|
|
512
|
+
}
|
|
513
|
+
// For backtrack captures, write the backtrack trigger before pausing
|
|
514
514
|
if (isBacktrack) {
|
|
515
515
|
try {
|
|
516
516
|
const { executeBacktrack } = await import("../triage-resolution.js");
|
|
@@ -520,19 +520,13 @@ export async function runGuards(ic, mid) {
|
|
|
520
520
|
debugLog("guards", { phase: "backtrack-execution-error", error: String(e) });
|
|
521
521
|
}
|
|
522
522
|
}
|
|
523
|
-
|
|
524
|
-
for (const cap of stopCaptures) {
|
|
525
|
-
markCaptureExecuted(s.basePath, cap.id);
|
|
526
|
-
}
|
|
523
|
+
await deps.pauseAuto(ctx, pi);
|
|
527
524
|
debugLog("autoLoop", { phase: "exit", reason: isBacktrack ? "user-backtrack" : "user-stop" });
|
|
528
525
|
return { action: "break", reason: isBacktrack ? "user-backtrack" : "user-stop" };
|
|
529
526
|
}
|
|
530
527
|
}
|
|
531
528
|
catch (e) {
|
|
532
|
-
// Fail-closed: if anything in the stop guard throws, break the loop
|
|
533
|
-
// rather than silently continuing and dropping user halt intent
|
|
534
529
|
debugLog("guards", { phase: "stop-guard-error", error: String(e) });
|
|
535
|
-
return { action: "break", reason: "stop-guard-error" };
|
|
536
530
|
}
|
|
537
531
|
// Budget ceiling guard
|
|
538
532
|
const budgetCeiling = prefs?.budget_ceiling;
|
|
@@ -900,9 +894,7 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
|
|
|
900
894
|
nextSteps: [],
|
|
901
895
|
});
|
|
902
896
|
}
|
|
903
|
-
catch
|
|
904
|
-
logWarning("engine", `phase anchor failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
905
|
-
}
|
|
897
|
+
catch { /* non-fatal — anchor is advisory */ }
|
|
906
898
|
}
|
|
907
899
|
deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "unit-end", data: { unitType, unitId, status: unitResult.status, artifactVerified, ...(unitResult.errorContext ? { errorContext: unitResult.errorContext } : {}) }, causedBy: { flowId: ic.flowId, seq: unitStartSeq } });
|
|
908
900
|
return { action: "next", data: { unitStartedAt: s.currentUnit?.startedAt } };
|
|
@@ -20,7 +20,6 @@ import { loadEffectiveGSDPreferences, getGlobalGSDPreferencesPath } from "./pref
|
|
|
20
20
|
import { resolveServiceTierIcon, getEffectiveServiceTier } from "./service-tier.js";
|
|
21
21
|
import { parseUnitId } from "./unit-id.js";
|
|
22
22
|
import { formatRtkSavingsLabel, getRtkSessionSavings, } from "../shared/rtk-session-stats.js";
|
|
23
|
-
import { logWarning } from "./workflow-logger.js";
|
|
24
23
|
// ─── UAT Slice Extraction ─────────────────────────────────────────────────────
|
|
25
24
|
/**
|
|
26
25
|
* Extract the target slice ID from a run-uat unit ID (e.g. "M001/S01" → "S01").
|
|
@@ -221,9 +220,8 @@ export function updateSliceProgressCache(base, mid, activeSid) {
|
|
|
221
220
|
}
|
|
222
221
|
}
|
|
223
222
|
}
|
|
224
|
-
catch
|
|
223
|
+
catch {
|
|
225
224
|
// Non-fatal — just omit task count
|
|
226
|
-
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
227
225
|
}
|
|
228
226
|
}
|
|
229
227
|
cachedSliceProgress = {
|
|
@@ -234,9 +232,8 @@ export function updateSliceProgressCache(base, mid, activeSid) {
|
|
|
234
232
|
taskDetails,
|
|
235
233
|
};
|
|
236
234
|
}
|
|
237
|
-
catch
|
|
235
|
+
catch {
|
|
238
236
|
// Non-fatal — widget just won't show progress bar
|
|
239
|
-
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
240
237
|
}
|
|
241
238
|
}
|
|
242
239
|
export function getRoadmapSlicesSync() {
|
|
@@ -266,9 +263,8 @@ function refreshLastCommit(basePath) {
|
|
|
266
263
|
}
|
|
267
264
|
lastCommitFetchedAt = Date.now();
|
|
268
265
|
}
|
|
269
|
-
catch
|
|
266
|
+
catch {
|
|
270
267
|
// Non-fatal — just skip last commit display
|
|
271
|
-
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
272
268
|
}
|
|
273
269
|
}
|
|
274
270
|
function getLastCommit(basePath) {
|
|
@@ -304,9 +300,7 @@ function ensureWidgetModeLoaded() {
|
|
|
304
300
|
widgetMode = saved;
|
|
305
301
|
}
|
|
306
302
|
}
|
|
307
|
-
catch
|
|
308
|
-
logWarning("dashboard", `operation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
309
|
-
}
|
|
303
|
+
catch { /* non-fatal — use default */ }
|
|
310
304
|
}
|
|
311
305
|
/** Persist widget mode to global preferences YAML. */
|
|
312
306
|
function persistWidgetMode(mode) {
|
|
@@ -326,9 +320,7 @@ function persistWidgetMode(mode) {
|
|
|
326
320
|
}
|
|
327
321
|
writeFileSync(prefsPath, content, "utf-8");
|
|
328
322
|
}
|
|
329
|
-
catch
|
|
330
|
-
logWarning("dashboard", `file write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
331
|
-
}
|
|
323
|
+
catch { /* non-fatal — mode still set in memory */ }
|
|
332
324
|
}
|
|
333
325
|
/** Cycle to the next widget mode. Returns the new mode. */
|
|
334
326
|
export function cycleWidgetMode() {
|
|
@@ -368,9 +360,7 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
368
360
|
try {
|
|
369
361
|
cachedBranch = getCurrentBranch(accessors.getBasePath());
|
|
370
362
|
}
|
|
371
|
-
catch
|
|
372
|
-
logWarning("dashboard", `git branch detection failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
373
|
-
}
|
|
363
|
+
catch { /* not in git repo */ }
|
|
374
364
|
// Cache short pwd (last 2 path segments only) + worktree/branch info
|
|
375
365
|
let widgetPwd;
|
|
376
366
|
{
|
|
@@ -404,8 +394,7 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
404
394
|
const savings = sessionId ? getRtkSessionSavings(accessors.getBasePath(), sessionId) : null;
|
|
405
395
|
cachedRtkLabel = formatRtkSavingsLabel(savings);
|
|
406
396
|
}
|
|
407
|
-
catch
|
|
408
|
-
logWarning("dashboard", `RTK savings lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
397
|
+
catch {
|
|
409
398
|
cachedRtkLabel = null;
|
|
410
399
|
}
|
|
411
400
|
};
|
|
@@ -427,9 +416,7 @@ export function updateProgressWidget(ctx, unitType, unitId, state, accessors, ti
|
|
|
427
416
|
refreshRtkLabel();
|
|
428
417
|
cachedLines = undefined;
|
|
429
418
|
}
|
|
430
|
-
catch
|
|
431
|
-
logWarning("dashboard", `DB status update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
432
|
-
}
|
|
419
|
+
catch { /* non-fatal */ }
|
|
433
420
|
}, 15_000);
|
|
434
421
|
return {
|
|
435
422
|
render(width) {
|
|
@@ -13,7 +13,7 @@ import { isDbAvailable, getMilestoneSlices, getPendingGates, markAllGatesOmitted
|
|
|
13
13
|
import { extractVerdict, isAcceptableUatVerdict } from "./verdict-parser.js";
|
|
14
14
|
import { gsdRoot, resolveMilestoneFile, resolveMilestonePath, resolveSliceFile, resolveTaskFile, relSliceFile, buildMilestoneFileName, } from "./paths.js";
|
|
15
15
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
-
import {
|
|
16
|
+
import { logError } from "./workflow-logger.js";
|
|
17
17
|
import { join } from "node:path";
|
|
18
18
|
import { hasImplementationArtifacts } from "./auto-recovery.js";
|
|
19
19
|
import { buildDiscussMilestonePrompt, buildResearchMilestonePrompt, buildPlanMilestonePrompt, buildResearchSlicePrompt, buildPlanSlicePrompt, buildExecuteTaskPrompt, buildCompleteSlicePrompt, buildCompleteMilestonePrompt, buildValidateMilestonePrompt, buildReplanSlicePrompt, buildRunUatPrompt, buildReassessRoadmapPrompt, buildRewriteDocsPrompt, buildReactiveExecutePrompt, buildGateEvaluatePrompt, checkNeedsReassessment, checkNeedsRunUat, } from "./auto-prompts.js";
|
|
@@ -564,9 +564,7 @@ export const DISPATCH_RULES = [
|
|
|
564
564
|
}
|
|
565
565
|
}
|
|
566
566
|
}
|
|
567
|
-
catch
|
|
568
|
-
logWarning("dispatch", `verification class check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
569
|
-
}
|
|
567
|
+
catch { /* fall through — don't block on DB errors */ }
|
|
570
568
|
return {
|
|
571
569
|
action: "dispatch",
|
|
572
570
|
unitType: "complete-milestone",
|
|
@@ -604,9 +602,8 @@ export async function resolveDispatch(ctx) {
|
|
|
604
602
|
const registry = getRegistry();
|
|
605
603
|
return await registry.evaluateDispatch(ctx);
|
|
606
604
|
}
|
|
607
|
-
catch
|
|
605
|
+
catch {
|
|
608
606
|
// Registry not initialized — fall back to inline loop
|
|
609
|
-
logWarning("dispatch", `registry dispatch failed, falling back to inline rules: ${err instanceof Error ? err.message : String(err)}`);
|
|
610
607
|
}
|
|
611
608
|
for (const rule of DISPATCH_RULES) {
|
|
612
609
|
const result = await rule.match(ctx);
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* and fallback chains.
|
|
5
5
|
*/
|
|
6
6
|
import { resolveModelWithFallbacksForUnit, resolveDynamicRoutingConfig } from "./preferences.js";
|
|
7
|
-
import { classifyUnitComplexity, tierLabel } from "./complexity-classifier.js";
|
|
8
|
-
import { resolveModelForComplexity, escalateTier
|
|
7
|
+
import { classifyUnitComplexity, tierLabel, extractTaskMetadata } from "./complexity-classifier.js";
|
|
8
|
+
import { resolveModelForComplexity, escalateTier } from "./model-router.js";
|
|
9
9
|
import { getLedger, getProjectTotals } from "./metrics.js";
|
|
10
10
|
import { unitPhaseLabel } from "./auto-dashboard.js";
|
|
11
11
|
export function resolvePreferredModelConfig(unitType, autoModeStartModel) {
|
|
@@ -68,68 +68,19 @@ export async function selectAndApplyModel(ctx, pi, unitType, unitId, basePath, p
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
|
-
//
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (routingConfig.hooks !== false) {
|
|
77
|
-
const eligible = getEligibleModels(classification.tier, availableModelIds, routingConfig);
|
|
78
|
-
const hookResult = await pi.emitBeforeModelSelect({
|
|
79
|
-
unitType,
|
|
80
|
-
unitId,
|
|
81
|
-
classification: {
|
|
82
|
-
tier: classification.tier,
|
|
83
|
-
reason: classification.reason,
|
|
84
|
-
downgraded: classification.downgraded,
|
|
85
|
-
},
|
|
86
|
-
taskMetadata: classification.taskMetadata,
|
|
87
|
-
eligibleModels: eligible,
|
|
88
|
-
phaseConfig: modelConfig ? {
|
|
89
|
-
primary: modelConfig.primary,
|
|
90
|
-
fallbacks: modelConfig.fallbacks ?? [],
|
|
91
|
-
} : undefined,
|
|
92
|
-
});
|
|
93
|
-
if (hookResult?.modelId) {
|
|
94
|
-
hookOverride = hookResult.modelId;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
let routingResult;
|
|
98
|
-
if (hookOverride) {
|
|
99
|
-
// Hook override bypasses capability scoring entirely
|
|
100
|
-
routingResult = {
|
|
101
|
-
modelId: hookOverride,
|
|
102
|
-
fallbacks: [
|
|
103
|
-
...(modelConfig?.fallbacks ?? []).filter(f => f !== hookOverride),
|
|
104
|
-
...(modelConfig?.primary && modelConfig.primary !== hookOverride ? [modelConfig.primary] : []),
|
|
105
|
-
],
|
|
106
|
-
tier: classification.tier,
|
|
107
|
-
wasDowngraded: hookOverride !== modelConfig?.primary,
|
|
108
|
-
reason: `hook override: ${hookOverride}`,
|
|
109
|
-
selectionMethod: "tier-only",
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
routingResult = resolveModelForComplexity(classification, modelConfig, routingConfig, availableModelIds, unitType, classification.taskMetadata, capabilityOverrides);
|
|
114
|
-
}
|
|
71
|
+
// Extract task metadata for capability scoring
|
|
72
|
+
const taskMeta = unitType === "execute-task"
|
|
73
|
+
? extractTaskMetadata(unitId, basePath)
|
|
74
|
+
: undefined;
|
|
75
|
+
const routingResult = resolveModelForComplexity(classification, modelConfig, routingConfig, availableModelIds, unitType, taskMeta);
|
|
115
76
|
if (routingResult.wasDowngraded) {
|
|
116
77
|
effectiveModelConfig = {
|
|
117
78
|
primary: routingResult.modelId,
|
|
118
79
|
fallbacks: routingResult.fallbacks,
|
|
119
80
|
};
|
|
120
81
|
if (verbose) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
const tierLbl = tierLabel(classification.tier);
|
|
124
|
-
const scores = Object.entries(routingResult.capabilityScores)
|
|
125
|
-
.sort(([, a], [, b]) => b - a)
|
|
126
|
-
.map(([id, score]) => `${id}: ${score.toFixed(1)}`)
|
|
127
|
-
.join(", ");
|
|
128
|
-
ctx.ui.notify(`Dynamic routing [${tierLbl}]: ${routingResult.modelId} (capability-scored) — ${scores}`, "info");
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
ctx.ui.notify(`Dynamic routing [${tierLabel(classification.tier)}]: ${routingResult.modelId} (${classification.reason})`, "info");
|
|
132
|
-
}
|
|
82
|
+
const method = routingResult.selectionMethod === "capability-scored" ? "capability-scored" : "tier-only";
|
|
83
|
+
ctx.ui.notify(`Dynamic routing [${tierLabel(classification.tier)}]: ${routingResult.modelId} (${method} — ${classification.reason})`, "info");
|
|
133
84
|
}
|
|
134
85
|
}
|
|
135
86
|
routingTierLabel = ` [${tierLabel(classification.tier)}]`;
|
|
@@ -208,9 +208,8 @@ export async function postUnitPreVerification(pctx, opts) {
|
|
|
208
208
|
const { getTaskIssueNumberForCommit } = await import("../github-sync/sync.js");
|
|
209
209
|
ghIssueNumber = getTaskIssueNumberForCommit(s.basePath, mid, sid, tid) ?? undefined;
|
|
210
210
|
}
|
|
211
|
-
catch
|
|
211
|
+
catch {
|
|
212
212
|
// GitHub sync not available — skip
|
|
213
|
-
logWarning("engine", `GitHub issue lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
214
213
|
}
|
|
215
214
|
taskContext = {
|
|
216
215
|
taskId: `${sid}/${tid}`,
|
|
@@ -449,7 +448,7 @@ export async function postUnitPostVerification(pctx) {
|
|
|
449
448
|
catch (dbErr) {
|
|
450
449
|
// DB unavailable — fail explicitly rather than silently reverting to markdown mutation.
|
|
451
450
|
// Use 'gsd recover' to rebuild DB state from disk if needed.
|
|
452
|
-
|
|
451
|
+
process.stderr.write(`gsd: retry state-reset failed (DB unavailable): ${dbErr.message}. Run 'gsd recover' to reconcile.\n`);
|
|
453
452
|
}
|
|
454
453
|
}
|
|
455
454
|
// 2. Delete SUMMARY.md for the task
|
|
@@ -18,7 +18,6 @@ import { computeBudgets, resolveExecutorContextWindow, truncateAtSectionBoundary
|
|
|
18
18
|
import { getPendingGates } from "./gsd-db.js";
|
|
19
19
|
import { formatDecisionsCompact, formatRequirementsCompact } from "./structured-data-formatter.js";
|
|
20
20
|
import { readPhaseAnchor, formatAnchorForPrompt } from "./phase-anchor.js";
|
|
21
|
-
import { logWarning } from "./workflow-logger.js";
|
|
22
21
|
// ─── Preamble Cap ─────────────────────────────────────────────────────────────
|
|
23
22
|
const MAX_PREAMBLE_CHARS = 30_000;
|
|
24
23
|
function capPreamble(preamble) {
|
|
@@ -38,8 +37,7 @@ function formatExecutorConstraints() {
|
|
|
38
37
|
const prefs = loadEffectiveGSDPreferences();
|
|
39
38
|
windowTokens = resolveExecutorContextWindow(undefined, prefs?.preferences);
|
|
40
39
|
}
|
|
41
|
-
catch
|
|
42
|
-
logWarning("prompt", `resolveExecutorContextWindow failed: ${e.message}`);
|
|
40
|
+
catch {
|
|
43
41
|
windowTokens = 200_000; // safe default
|
|
44
42
|
}
|
|
45
43
|
const budgets = computeBudgets(windowTokens);
|
|
@@ -163,9 +161,7 @@ export async function inlineDependencySummaries(mid, sid, base, budgetChars) {
|
|
|
163
161
|
// If slice not found in DB, fall through to file-based parsing
|
|
164
162
|
}
|
|
165
163
|
}
|
|
166
|
-
catch
|
|
167
|
-
logWarning("prompt", `inlineDependencySummaries DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
168
|
-
}
|
|
164
|
+
catch { /* fall through */ }
|
|
169
165
|
// If DB didn't provide depends, fall back to roadmap parsing
|
|
170
166
|
if (!depends) {
|
|
171
167
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
@@ -237,8 +233,8 @@ export async function inlineDecisionsFromDb(base, milestoneId, scope, level) {
|
|
|
237
233
|
}
|
|
238
234
|
}
|
|
239
235
|
}
|
|
240
|
-
catch
|
|
241
|
-
|
|
236
|
+
catch {
|
|
237
|
+
// DB not available — fall through to filesystem
|
|
242
238
|
}
|
|
243
239
|
return inlineGsdRootFile(base, "decisions.md", "Decisions");
|
|
244
240
|
}
|
|
@@ -262,8 +258,8 @@ export async function inlineRequirementsFromDb(base, sliceId, level) {
|
|
|
262
258
|
}
|
|
263
259
|
}
|
|
264
260
|
}
|
|
265
|
-
catch
|
|
266
|
-
|
|
261
|
+
catch {
|
|
262
|
+
// DB not available — fall through to filesystem
|
|
267
263
|
}
|
|
268
264
|
return inlineGsdRootFile(base, "requirements.md", "Requirements");
|
|
269
265
|
}
|
|
@@ -282,8 +278,8 @@ export async function inlineProjectFromDb(base) {
|
|
|
282
278
|
}
|
|
283
279
|
}
|
|
284
280
|
}
|
|
285
|
-
catch
|
|
286
|
-
|
|
281
|
+
catch {
|
|
282
|
+
// DB not available — fall through to filesystem
|
|
287
283
|
}
|
|
288
284
|
return inlineGsdRootFile(base, "project.md", "Project");
|
|
289
285
|
}
|
|
@@ -403,8 +399,8 @@ export function buildSkillActivationBlock(params) {
|
|
|
403
399
|
matched.add(normalizeSkillReference(skillName));
|
|
404
400
|
}
|
|
405
401
|
}
|
|
406
|
-
catch
|
|
407
|
-
|
|
402
|
+
catch {
|
|
403
|
+
// Non-fatal — malformed task plan should not break prompt construction
|
|
408
404
|
}
|
|
409
405
|
}
|
|
410
406
|
const ordered = [...matched]
|
|
@@ -623,9 +619,7 @@ export async function checkNeedsReassessment(base, mid, state) {
|
|
|
623
619
|
}
|
|
624
620
|
}
|
|
625
621
|
}
|
|
626
|
-
catch
|
|
627
|
-
logWarning("prompt", `checkNeedsReassessment DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
628
|
-
}
|
|
622
|
+
catch { /* fall through */ }
|
|
629
623
|
// File-based fallback using roadmap checkboxes
|
|
630
624
|
const roadmapPath = resolveMilestoneFile(base, mid, "ROADMAP");
|
|
631
625
|
if (!roadmapPath)
|
|
@@ -700,9 +694,7 @@ export async function checkNeedsRunUat(base, mid, state, prefs) {
|
|
|
700
694
|
}
|
|
701
695
|
}
|
|
702
696
|
}
|
|
703
|
-
catch
|
|
704
|
-
logWarning("prompt", `checkNeedsRunUat DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
705
|
-
}
|
|
697
|
+
catch { /* fall through */ }
|
|
706
698
|
// File-based fallback using roadmap checkboxes
|
|
707
699
|
if (!prefs?.uat_dispatch)
|
|
708
700
|
return null;
|
|
@@ -1158,9 +1150,7 @@ export async function buildCompleteMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1158
1150
|
sliceIds = getMilestoneSlices(mid).map(s => s.id);
|
|
1159
1151
|
}
|
|
1160
1152
|
}
|
|
1161
|
-
catch
|
|
1162
|
-
logWarning("prompt", `buildCompleteMilestonePrompt DB lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1163
|
-
}
|
|
1153
|
+
catch { /* fall through */ }
|
|
1164
1154
|
// File-based fallback: parse roadmap for slice IDs when DB has no data
|
|
1165
1155
|
if (sliceIds.length === 0 && roadmapPath) {
|
|
1166
1156
|
const roadmapContent = await loadFile(roadmapPath);
|
|
@@ -1243,9 +1233,7 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1243
1233
|
}
|
|
1244
1234
|
}
|
|
1245
1235
|
}
|
|
1246
|
-
catch
|
|
1247
|
-
logWarning("prompt", `buildValidateMilestonePrompt verification classes lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1248
|
-
}
|
|
1236
|
+
catch { /* fall through */ }
|
|
1249
1237
|
// Inline all slice summaries and UAT results
|
|
1250
1238
|
let valSliceIds = [];
|
|
1251
1239
|
try {
|
|
@@ -1254,9 +1242,7 @@ export async function buildValidateMilestonePrompt(mid, midTitle, base, level) {
|
|
|
1254
1242
|
valSliceIds = getMilestoneSlices(mid).map(s => s.id);
|
|
1255
1243
|
}
|
|
1256
1244
|
}
|
|
1257
|
-
catch
|
|
1258
|
-
logWarning("prompt", `buildValidateMilestonePrompt slice IDs lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1259
|
-
}
|
|
1245
|
+
catch { /* fall through */ }
|
|
1260
1246
|
// File-based fallback: parse roadmap for slice IDs when DB has no data
|
|
1261
1247
|
if (valSliceIds.length === 0 && roadmapPath) {
|
|
1262
1248
|
const roadmapContent = await loadFile(roadmapPath);
|
|
@@ -1392,8 +1378,8 @@ export async function buildReplanSlicePrompt(mid, midTitle, sid, sTitle, base) {
|
|
|
1392
1378
|
captureContext = replanCaptures.map(c => `- **${c.id}**: "${c.text}" — ${c.rationale ?? "no rationale"}`).join("\n");
|
|
1393
1379
|
}
|
|
1394
1380
|
}
|
|
1395
|
-
catch
|
|
1396
|
-
|
|
1381
|
+
catch {
|
|
1382
|
+
// Non-fatal — captures module may not be available
|
|
1397
1383
|
}
|
|
1398
1384
|
return loadPrompt("replan-slice", {
|
|
1399
1385
|
workingDirectory: base,
|
|
@@ -1482,8 +1468,8 @@ export async function buildReassessRoadmapPrompt(mid, midTitle, completedSliceId
|
|
|
1482
1468
|
deferredCaptures = deferred.map(c => `- **${c.id}**: "${c.text}" — ${c.rationale ?? "deferred during triage"}`).join("\n");
|
|
1483
1469
|
}
|
|
1484
1470
|
}
|
|
1485
|
-
catch
|
|
1486
|
-
|
|
1471
|
+
catch {
|
|
1472
|
+
// Non-fatal — captures module may not be available
|
|
1487
1473
|
}
|
|
1488
1474
|
const reassessCommitInstruction = "Do not commit — .gsd/ planning docs are managed externally and not tracked in git.";
|
|
1489
1475
|
return loadPrompt("reassess-roadmap", {
|
|
@@ -1660,9 +1646,7 @@ export async function buildRewriteDocsPrompt(mid, midTitle, activeSlice, base, o
|
|
|
1660
1646
|
.map(t => ({ id: t.id }));
|
|
1661
1647
|
}
|
|
1662
1648
|
}
|
|
1663
|
-
catch
|
|
1664
|
-
logWarning("prompt", `buildRewriteDocsPrompt DB task lookup failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
1665
|
-
}
|
|
1649
|
+
catch { /* fall through */ }
|
|
1666
1650
|
if (!incompleteTasks) {
|
|
1667
1651
|
// DB unavailable — no task data to inline
|
|
1668
1652
|
incompleteTasks = [];
|
|
@@ -12,7 +12,6 @@ import { parseRoadmap as parseLegacyRoadmap, parsePlan as parseLegacyPlan } from
|
|
|
12
12
|
import { isDbAvailable, getTask, getSlice, getSliceTasks, updateTaskStatus } from "./gsd-db.js";
|
|
13
13
|
import { isValidationTerminal } from "./state.js";
|
|
14
14
|
import { getErrorMessage } from "./error-utils.js";
|
|
15
|
-
import { logWarning, logError } from "./workflow-logger.js";
|
|
16
15
|
import { nativeConflictFiles, nativeCommit, nativeCheckoutTheirs, nativeAddPaths, nativeMergeAbort, nativeResetHard, } from "./native-git-bridge.js";
|
|
17
16
|
import { resolveSlicePath, resolveSliceFile, resolveTasksDir, resolveTaskFiles, relMilestoneFile, relSliceFile, buildSliceFileName, resolveMilestoneFile, clearPathCache, resolveGsdRootFile, } from "./paths.js";
|
|
18
17
|
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync, } from "node:fs";
|
|
@@ -41,8 +40,7 @@ export function hasImplementationArtifacts(basePath) {
|
|
|
41
40
|
encoding: "utf-8",
|
|
42
41
|
});
|
|
43
42
|
}
|
|
44
|
-
catch
|
|
45
|
-
logWarning("recovery", `git rev-parse check failed: ${e.message}`);
|
|
43
|
+
catch {
|
|
46
44
|
return true;
|
|
47
45
|
}
|
|
48
46
|
// Strategy: check `git diff --name-only` against the merge-base with the
|
|
@@ -61,9 +59,8 @@ export function hasImplementationArtifacts(basePath) {
|
|
|
61
59
|
const implFiles = changedFiles.filter(f => !f.startsWith(".gsd/") && !f.startsWith(".gsd\\"));
|
|
62
60
|
return implFiles.length > 0;
|
|
63
61
|
}
|
|
64
|
-
catch
|
|
62
|
+
catch {
|
|
65
63
|
// Non-fatal — if git operations fail, don't block the pipeline
|
|
66
|
-
logWarning("recovery", `implementation artifact check failed: ${e.message}`);
|
|
67
64
|
return true;
|
|
68
65
|
}
|
|
69
66
|
}
|
|
@@ -80,9 +77,8 @@ function detectMainBranch(basePath) {
|
|
|
80
77
|
if (result.trim())
|
|
81
78
|
return "main";
|
|
82
79
|
}
|
|
83
|
-
catch
|
|
84
|
-
//
|
|
85
|
-
void _;
|
|
80
|
+
catch {
|
|
81
|
+
// main doesn't exist
|
|
86
82
|
}
|
|
87
83
|
try {
|
|
88
84
|
const result = execFileSync("git", ["rev-parse", "--verify", "master"], {
|
|
@@ -93,13 +89,10 @@ function detectMainBranch(basePath) {
|
|
|
93
89
|
if (result.trim())
|
|
94
90
|
return "master";
|
|
95
91
|
}
|
|
96
|
-
catch
|
|
97
|
-
//
|
|
98
|
-
void _;
|
|
92
|
+
catch {
|
|
93
|
+
// master doesn't exist either
|
|
99
94
|
}
|
|
100
|
-
|
|
101
|
-
logWarning("recovery", "neither main nor master branch found, defaulting to main");
|
|
102
|
-
return "main";
|
|
95
|
+
return "main"; // default fallback
|
|
103
96
|
}
|
|
104
97
|
/**
|
|
105
98
|
* Get files changed since the branch diverged from the target branch.
|
|
@@ -114,17 +107,15 @@ function getChangedFilesSinceBranch(basePath, targetBranch) {
|
|
|
114
107
|
return result ? result.split("\n").filter(Boolean) : [];
|
|
115
108
|
}
|
|
116
109
|
}
|
|
117
|
-
catch
|
|
110
|
+
catch {
|
|
118
111
|
// merge-base failed — fall back
|
|
119
|
-
logWarning("recovery", `merge-base detection failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
120
112
|
}
|
|
121
113
|
// Fallback: check last 20 commits
|
|
122
114
|
try {
|
|
123
115
|
const result = execFileSync("git", ["log", "--name-only", "--pretty=format:", "-20", "HEAD"], { cwd: basePath, stdio: ["ignore", "pipe", "pipe"], encoding: "utf-8" }).trim();
|
|
124
116
|
return result ? [...new Set(result.split("\n").filter(Boolean))] : [];
|
|
125
117
|
}
|
|
126
|
-
catch
|
|
127
|
-
logWarning("recovery", `git log fallback failed: ${e.message}`);
|
|
118
|
+
catch {
|
|
128
119
|
return [];
|
|
129
120
|
}
|
|
130
121
|
}
|
|
@@ -207,9 +198,8 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
207
198
|
return false;
|
|
208
199
|
}
|
|
209
200
|
}
|
|
210
|
-
catch
|
|
201
|
+
catch {
|
|
211
202
|
// DB unavailable — treat as verified to avoid blocking
|
|
212
|
-
logWarning("recovery", `gate-evaluate DB check failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
213
203
|
}
|
|
214
204
|
return true;
|
|
215
205
|
}
|
|
@@ -301,9 +291,8 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
301
291
|
}
|
|
302
292
|
}
|
|
303
293
|
}
|
|
304
|
-
catch
|
|
294
|
+
catch {
|
|
305
295
|
// Parse failure — don't block; slice plan may have non-standard format
|
|
306
|
-
logWarning("recovery", `plan-slice task plan verification failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
307
296
|
}
|
|
308
297
|
}
|
|
309
298
|
}
|
|
@@ -336,8 +325,7 @@ export function verifyExpectedArtifact(unitType, unitId, base) {
|
|
|
336
325
|
if (slice && !slice.done)
|
|
337
326
|
return false;
|
|
338
327
|
}
|
|
339
|
-
catch
|
|
340
|
-
logWarning("recovery", `roadmap parse failed: ${e.message}`);
|
|
328
|
+
catch {
|
|
341
329
|
return false;
|
|
342
330
|
}
|
|
343
331
|
}
|
|
@@ -386,9 +374,7 @@ export function writeBlockerPlaceholder(unitType, unitId, base, reason) {
|
|
|
386
374
|
try {
|
|
387
375
|
updateTaskStatus(mid, sid, tid, "complete", new Date().toISOString());
|
|
388
376
|
}
|
|
389
|
-
catch
|
|
390
|
-
logError("recovery", `DB status update failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
391
|
-
}
|
|
377
|
+
catch { /* non-fatal */ }
|
|
392
378
|
}
|
|
393
379
|
}
|
|
394
380
|
return diagnoseExpectedArtifact(unitType, unitId, base);
|
|
@@ -403,26 +389,23 @@ function abortAndResetMerge(basePath, hasMergeHead, squashMsgPath) {
|
|
|
403
389
|
try {
|
|
404
390
|
nativeMergeAbort(basePath);
|
|
405
391
|
}
|
|
406
|
-
catch
|
|
392
|
+
catch {
|
|
407
393
|
/* best-effort */
|
|
408
|
-
logWarning("recovery", `git merge-abort failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
409
394
|
}
|
|
410
395
|
}
|
|
411
396
|
else if (squashMsgPath) {
|
|
412
397
|
try {
|
|
413
398
|
unlinkSync(squashMsgPath);
|
|
414
399
|
}
|
|
415
|
-
catch
|
|
400
|
+
catch {
|
|
416
401
|
/* best-effort */
|
|
417
|
-
logWarning("recovery", `file unlink failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
418
402
|
}
|
|
419
403
|
}
|
|
420
404
|
try {
|
|
421
405
|
nativeResetHard(basePath);
|
|
422
406
|
}
|
|
423
|
-
catch
|
|
407
|
+
catch {
|
|
424
408
|
/* best-effort */
|
|
425
|
-
logError("recovery", `git reset failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
426
409
|
}
|
|
427
410
|
}
|
|
428
411
|
/**
|
|
@@ -469,8 +452,7 @@ export function reconcileMergeState(basePath, ctx) {
|
|
|
469
452
|
nativeCheckoutTheirs(basePath, gsdConflicts);
|
|
470
453
|
nativeAddPaths(basePath, gsdConflicts);
|
|
471
454
|
}
|
|
472
|
-
catch
|
|
473
|
-
logError("recovery", `auto-resolve .gsd/ conflicts failed: ${e.message}`);
|
|
455
|
+
catch {
|
|
474
456
|
resolved = false;
|
|
475
457
|
}
|
|
476
458
|
if (resolved) {
|
|
@@ -478,8 +460,7 @@ export function reconcileMergeState(basePath, ctx) {
|
|
|
478
460
|
nativeCommit(basePath, "chore: auto-resolve .gsd/ state file conflicts");
|
|
479
461
|
ctx.ui.notify(`Auto-resolved ${gsdConflicts.length} .gsd/ state file conflict(s) from prior merge.`, "info");
|
|
480
462
|
}
|
|
481
|
-
catch
|
|
482
|
-
logError("recovery", `auto-commit .gsd/ conflict resolution failed: ${e.message}`);
|
|
463
|
+
catch {
|
|
483
464
|
resolved = false;
|
|
484
465
|
}
|
|
485
466
|
}
|