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.
Files changed (196) hide show
  1. package/dist/resources/extensions/ask-user-questions.js +4 -7
  2. package/dist/resources/extensions/gsd/auto/phases.js +7 -15
  3. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -21
  4. package/dist/resources/extensions/gsd/auto-dispatch.js +3 -6
  5. package/dist/resources/extensions/gsd/auto-model-selection.js +9 -58
  6. package/dist/resources/extensions/gsd/auto-post-unit.js +2 -3
  7. package/dist/resources/extensions/gsd/auto-prompts.js +20 -36
  8. package/dist/resources/extensions/gsd/auto-recovery.js +18 -37
  9. package/dist/resources/extensions/gsd/auto-start.js +5 -9
  10. package/dist/resources/extensions/gsd/auto-timers.js +5 -11
  11. package/dist/resources/extensions/gsd/auto-unit-closeout.js +3 -5
  12. package/dist/resources/extensions/gsd/auto-verification.js +2 -3
  13. package/dist/resources/extensions/gsd/auto-worktree.js +55 -120
  14. package/dist/resources/extensions/gsd/auto.js +17 -39
  15. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +3 -6
  16. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +2 -2
  17. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +10 -4
  18. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +1 -2
  19. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +0 -7
  20. package/dist/resources/extensions/gsd/bootstrap/system-context.js +10 -11
  21. package/dist/resources/extensions/gsd/commands/catalog.js +0 -2
  22. package/dist/resources/extensions/gsd/commands-codebase.js +21 -48
  23. package/dist/resources/extensions/gsd/commands-inspect.js +1 -2
  24. package/dist/resources/extensions/gsd/commands-maintenance.js +19 -32
  25. package/dist/resources/extensions/gsd/complexity-classifier.js +4 -8
  26. package/dist/resources/extensions/gsd/custom-verification.js +2 -3
  27. package/dist/resources/extensions/gsd/gsd-db.js +13 -33
  28. package/dist/resources/extensions/gsd/guided-flow.js +9 -19
  29. package/dist/resources/extensions/gsd/init-wizard.js +0 -12
  30. package/dist/resources/extensions/gsd/markdown-renderer.js +9 -11
  31. package/dist/resources/extensions/gsd/md-importer.js +4 -5
  32. package/dist/resources/extensions/gsd/milestone-actions.js +2 -3
  33. package/dist/resources/extensions/gsd/milestone-ids.js +1 -2
  34. package/dist/resources/extensions/gsd/model-router.js +121 -156
  35. package/dist/resources/extensions/gsd/parallel-merge.js +3 -5
  36. package/dist/resources/extensions/gsd/parallel-orchestrator.js +14 -26
  37. package/dist/resources/extensions/gsd/preferences-types.js +0 -1
  38. package/dist/resources/extensions/gsd/preferences-validation.js +0 -45
  39. package/dist/resources/extensions/gsd/preferences.js +3 -15
  40. package/dist/resources/extensions/gsd/prompt-loader.js +2 -3
  41. package/dist/resources/extensions/gsd/prompts/rethink.md +1 -1
  42. package/dist/resources/extensions/gsd/rule-registry.js +6 -7
  43. package/dist/resources/extensions/gsd/safe-fs.js +8 -6
  44. package/dist/resources/extensions/gsd/tools/complete-milestone.js +2 -3
  45. package/dist/resources/extensions/gsd/tools/complete-slice.js +2 -3
  46. package/dist/resources/extensions/gsd/tools/complete-task.js +2 -3
  47. package/dist/resources/extensions/gsd/tools/plan-milestone.js +2 -3
  48. package/dist/resources/extensions/gsd/tools/plan-slice.js +2 -3
  49. package/dist/resources/extensions/gsd/tools/plan-task.js +1 -2
  50. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +4 -4
  51. package/dist/resources/extensions/gsd/tools/reopen-slice.js +1 -2
  52. package/dist/resources/extensions/gsd/tools/reopen-task.js +1 -2
  53. package/dist/resources/extensions/gsd/tools/replan-slice.js +1 -2
  54. package/dist/resources/extensions/gsd/tools/validate-milestone.js +1 -2
  55. package/dist/resources/extensions/gsd/triage-resolution.js +4 -11
  56. package/dist/resources/extensions/gsd/workflow-events.js +1 -2
  57. package/dist/resources/extensions/gsd/workflow-logger.js +4 -37
  58. package/dist/resources/extensions/gsd/workflow-migration.js +12 -14
  59. package/dist/resources/extensions/gsd/workflow-projections.js +2 -2
  60. package/dist/resources/extensions/gsd/workflow-reconcile.js +2 -2
  61. package/dist/resources/extensions/gsd/worktree-manager.js +14 -26
  62. package/dist/resources/extensions/shared/interview-ui.js +1 -3
  63. package/dist/web/standalone/.next/BUILD_ID +1 -1
  64. package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
  65. package/dist/web/standalone/.next/build-manifest.json +2 -2
  66. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  67. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  68. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  76. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/index.html +1 -1
  84. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app-paths-manifest.json +19 -19
  91. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  92. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  93. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  94. package/package.json +1 -1
  95. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  96. package/packages/pi-coding-agent/dist/core/extensions/loader.js +0 -5
  97. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  98. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -2
  99. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  100. package/packages/pi-coding-agent/dist/core/extensions/runner.js +0 -16
  101. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  102. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +0 -26
  103. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  104. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  105. package/packages/pi-coding-agent/dist/core/lsp/config.d.ts.map +1 -1
  106. package/packages/pi-coding-agent/dist/core/lsp/config.js +1 -6
  107. package/packages/pi-coding-agent/dist/core/lsp/config.js.map +1 -1
  108. package/packages/pi-coding-agent/dist/core/lsp/defaults.json +2 -2
  109. package/packages/pi-coding-agent/src/core/extensions/loader.ts +0 -6
  110. package/packages/pi-coding-agent/src/core/extensions/runner.ts +0 -19
  111. package/packages/pi-coding-agent/src/core/extensions/types.ts +0 -26
  112. package/packages/pi-coding-agent/src/core/lsp/config.ts +1 -7
  113. package/packages/pi-coding-agent/src/core/lsp/defaults.json +2 -2
  114. package/src/resources/extensions/ask-user-questions.ts +3 -7
  115. package/src/resources/extensions/gsd/auto/phases.ts +7 -17
  116. package/src/resources/extensions/gsd/auto-dashboard.ts +8 -22
  117. package/src/resources/extensions/gsd/auto-dispatch.ts +3 -7
  118. package/src/resources/extensions/gsd/auto-model-selection.ts +15 -77
  119. package/src/resources/extensions/gsd/auto-post-unit.ts +4 -4
  120. package/src/resources/extensions/gsd/auto-prompts.ts +20 -37
  121. package/src/resources/extensions/gsd/auto-recovery.ts +18 -38
  122. package/src/resources/extensions/gsd/auto-start.ts +9 -10
  123. package/src/resources/extensions/gsd/auto-timers.ts +5 -12
  124. package/src/resources/extensions/gsd/auto-unit-closeout.ts +2 -6
  125. package/src/resources/extensions/gsd/auto-verification.ts +6 -3
  126. package/src/resources/extensions/gsd/auto-worktree.ts +55 -121
  127. package/src/resources/extensions/gsd/auto.ts +17 -40
  128. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +3 -4
  129. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +2 -2
  130. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -4
  131. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +1 -2
  132. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +0 -8
  133. package/src/resources/extensions/gsd/bootstrap/system-context.ts +10 -11
  134. package/src/resources/extensions/gsd/commands/catalog.ts +0 -2
  135. package/src/resources/extensions/gsd/commands-codebase.ts +20 -52
  136. package/src/resources/extensions/gsd/commands-inspect.ts +1 -2
  137. package/src/resources/extensions/gsd/commands-maintenance.ts +19 -28
  138. package/src/resources/extensions/gsd/complexity-classifier.ts +4 -9
  139. package/src/resources/extensions/gsd/custom-verification.ts +2 -3
  140. package/src/resources/extensions/gsd/gsd-db.ts +14 -12
  141. package/src/resources/extensions/gsd/guided-flow.ts +8 -9
  142. package/src/resources/extensions/gsd/init-wizard.ts +0 -12
  143. package/src/resources/extensions/gsd/markdown-renderer.ts +17 -11
  144. package/src/resources/extensions/gsd/md-importer.ts +4 -5
  145. package/src/resources/extensions/gsd/milestone-actions.ts +2 -3
  146. package/src/resources/extensions/gsd/milestone-ids.ts +1 -2
  147. package/src/resources/extensions/gsd/model-router.ts +173 -199
  148. package/src/resources/extensions/gsd/parallel-merge.ts +3 -5
  149. package/src/resources/extensions/gsd/parallel-orchestrator.ts +14 -18
  150. package/src/resources/extensions/gsd/preferences-types.ts +0 -13
  151. package/src/resources/extensions/gsd/preferences-validation.ts +0 -45
  152. package/src/resources/extensions/gsd/preferences.ts +3 -16
  153. package/src/resources/extensions/gsd/prompt-loader.ts +2 -3
  154. package/src/resources/extensions/gsd/prompts/rethink.md +1 -1
  155. package/src/resources/extensions/gsd/rule-registry.ts +6 -7
  156. package/src/resources/extensions/gsd/safe-fs.ts +5 -6
  157. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +0 -63
  158. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +2 -27
  159. package/src/resources/extensions/gsd/tests/db-path-worktree-symlink.test.ts +4 -4
  160. package/src/resources/extensions/gsd/tests/model-router.test.ts +3 -403
  161. package/src/resources/extensions/gsd/tests/preferences.test.ts +0 -62
  162. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +0 -21
  163. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +6 -6
  164. package/src/resources/extensions/gsd/tools/complete-milestone.ts +6 -3
  165. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -3
  166. package/src/resources/extensions/gsd/tools/complete-task.ts +6 -3
  167. package/src/resources/extensions/gsd/tools/plan-milestone.ts +6 -3
  168. package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -3
  169. package/src/resources/extensions/gsd/tools/plan-task.ts +3 -2
  170. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +6 -4
  171. package/src/resources/extensions/gsd/tools/reopen-slice.ts +3 -2
  172. package/src/resources/extensions/gsd/tools/reopen-task.ts +3 -2
  173. package/src/resources/extensions/gsd/tools/replan-slice.ts +3 -2
  174. package/src/resources/extensions/gsd/tools/validate-milestone.ts +3 -2
  175. package/src/resources/extensions/gsd/triage-resolution.ts +4 -11
  176. package/src/resources/extensions/gsd/types.ts +0 -1
  177. package/src/resources/extensions/gsd/workflow-events.ts +1 -2
  178. package/src/resources/extensions/gsd/workflow-logger.ts +5 -52
  179. package/src/resources/extensions/gsd/workflow-migration.ts +12 -14
  180. package/src/resources/extensions/gsd/workflow-projections.ts +2 -2
  181. package/src/resources/extensions/gsd/workflow-reconcile.ts +2 -2
  182. package/src/resources/extensions/gsd/worktree-manager.ts +14 -16
  183. package/src/resources/extensions/shared/interview-ui.ts +1 -3
  184. package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts +0 -2
  185. package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.d.ts.map +0 -1
  186. package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js +0 -47
  187. package/packages/pi-coding-agent/dist/core/lsp/lsp-legacy-alias.test.js.map +0 -1
  188. package/packages/pi-coding-agent/src/core/lsp/lsp-legacy-alias.test.ts +0 -70
  189. package/src/resources/extensions/gsd/tests/capability-router.test.ts +0 -347
  190. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +0 -1188
  191. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +0 -841
  192. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +0 -284
  193. package/src/resources/extensions/gsd/tests/workflow-logger-audit.test.ts +0 -120
  194. package/src/resources/extensions/shared/tests/interview-notes-loop.test.ts +0 -144
  195. /package/dist/web/standalone/.next/static/{ogyMN7M-3bGGuRY08L5HR → JVkoVYumy0cDhOQISEYdG}/_buildManifest.js +0 -0
  196. /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
- // Pause first ensures auto-mode stops even if later steps fail
512
- await deps.pauseAuto(ctx, pi);
513
- // For backtrack captures, write the backtrack trigger after pausing
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
- // Mark captures as executed only after successful pause/transition
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 (err) { /* non-fatal — anchor is advisory */
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 (err) {
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 (err) {
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 (err) {
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 (err) { /* non-fatal — use default */
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 (err) { /* non-fatal — mode still set in memory */
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 (err) { /* not in git repo */
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 (err) {
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 (err) { /* non-fatal */
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 { logWarning, logError } from "./workflow-logger.js";
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 (err) { /* fall through — don't block on DB errors */
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 (err) {
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, getEligibleModels, loadCapabilityOverrides } from "./model-router.js";
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
- // Load user capability overrides from preferences (D-17: deep-merged with built-in profiles)
72
- const capabilityOverrides = loadCapabilityOverrides(prefs ?? {});
73
- // Fire before_model_select hook (ADR-004, D-03)
74
- // Hook can override model selection entirely by returning { modelId }
75
- let hookOverride;
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
- if (routingResult.selectionMethod === "capability-scored" && routingResult.capabilityScores) {
122
- // Verbose scoring breakdown for capability-scored decisions (D-20)
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 (err) {
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
- logError("engine", `retry state-reset failed (DB unavailable): ${dbErr.message}. Run 'gsd recover' to reconcile.`);
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 (e) {
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 (err) {
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 (err) {
241
- logWarning("prompt", `inlineDecisionsFromDb failed: ${err instanceof Error ? err.message : String(err)}`);
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 (err) {
266
- logWarning("prompt", `inlineRequirementsFromDb failed: ${err instanceof Error ? err.message : String(err)}`);
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 (err) {
286
- logWarning("prompt", `inlineProjectFromDb failed: ${err instanceof Error ? err.message : String(err)}`);
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 (err) {
407
- logWarning("prompt", `parseTaskPlanFile failed: ${err instanceof Error ? err.message : String(err)}`);
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 (err) {
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 (err) {
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 (err) {
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 (err) {
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 (err) {
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 (err) {
1396
- logWarning("prompt", `loadReplanCaptures failed: ${err instanceof Error ? err.message : String(err)}`);
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 (err) {
1486
- logWarning("prompt", `loadDeferredCaptures failed: ${err instanceof Error ? err.message : String(err)}`);
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 (err) {
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 (e) {
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 (e) {
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
- // Expected — main doesn't exist, try master next
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
- // Expected — master doesn't exist either
98
- void _;
92
+ catch {
93
+ // master doesn't exist either
99
94
  }
100
- // Neither main nor master found — warn and fall back
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 (err) {
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 (e) {
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 (err) {
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 (err) {
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 (e) {
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 (err) { /* non-fatal */
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 (err) {
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 (err) {
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 (err) {
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 (e) {
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 (e) {
482
- logError("recovery", `auto-commit .gsd/ conflict resolution failed: ${e.message}`);
463
+ catch {
483
464
  resolved = false;
484
465
  }
485
466
  }