@runfusion/fusion 0.74.0-beta.7 → 0.74.0-beta.9

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 (100) hide show
  1. package/dist/bin.js +367 -485
  2. package/dist/child-process-worker.js +172 -290
  3. package/dist/client/.vite/manifest.json +266 -266
  4. package/dist/client/assets/{AgentDetailView-CTdyQL11.js → AgentDetailView-DC3B06sE.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-DBa7nIQV.js → AgentPermissionPolicyEditor-BtKWfG2h.js} +1 -1
  6. package/dist/client/assets/{AgentsView-B5tss2oK.js → AgentsView-4DiJ2Htx.js} +3 -3
  7. package/dist/client/assets/{ChatView-DAKt1a2L.js → ChatView-1nqZiDRk.js} +1 -1
  8. package/dist/client/assets/{CommandCenter-yPvRo9F6.js → CommandCenter-BHZN2tf0.js} +1 -1
  9. package/dist/client/assets/{DevServerView-BTyS2owH.js → DevServerView-BwPjQxR_.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-BjGIupNU.js → DirectoryPicker-40vH29Sy.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-CuxfbpSZ.js → DocumentsView-DI2mQkGF.js} +1 -1
  12. package/dist/client/assets/{EvalsView-DGuy8SHR.js → EvalsView-CTSt1-CF.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-lK407ZAq.js → ExperimentalAgentOnboardingModal-Z1DJ2xFw.js} +1 -1
  14. package/dist/client/assets/{GoalsView-DAVN0ObR.js → GoalsView-BNyoKq27.js} +1 -1
  15. package/dist/client/assets/{InsightsView-BXQKcNof.js → InsightsView-zSwsbTfk.js} +1 -1
  16. package/dist/client/assets/{MemoryView-D7RKEtV7.js → MemoryView-e7R4rcQY.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-CrOJ57R2.js → PiExtensionsManager-DuZzMGuy.js} +1 -1
  18. package/dist/client/assets/{PluginManager-D7_evt4j.js → PluginManager--lgPTCei.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-C0lRUbth.js → PullRequestView-C9KOlfV-.js} +1 -1
  20. package/dist/client/assets/ReportModal-BiXAfHbg.js +21 -0
  21. package/dist/client/assets/ReportModal-M3uh98sc.css +1 -0
  22. package/dist/client/assets/{ResearchView-e8st2Sxu.js → ResearchView-N4N7-_7C.js} +1 -1
  23. package/dist/client/assets/{SecretsView-BLzckrzb.js → SecretsView-GPt8Mw9d.js} +1 -1
  24. package/dist/client/assets/{SessionTerminal-F_GIj4gh.js → SessionTerminal-D2bnTrLK.js} +1 -1
  25. package/dist/client/assets/SettingsModal-B30rPfYC.css +1 -0
  26. package/dist/client/assets/{SettingsModal-eQbxbkLU.js → SettingsModal-D42Cph4Z.js} +4 -4
  27. package/dist/client/assets/{SettingsModal-XAddgWkF.js → SettingsModal-DLKu3CYU.js} +1 -1
  28. package/dist/client/assets/{SettingsTextareaRow-DVjUHNQp.js → SettingsTextareaRow-terwvp1e.js} +1 -1
  29. package/dist/client/assets/{SetupWizardModal-xID9yIff.js → SetupWizardModal-C-ApHZiL.js} +2 -2
  30. package/dist/client/assets/{SkillsView-BNdMGu6E.js → SkillsView-GYBeq0B-.js} +1 -1
  31. package/dist/client/assets/{TodoView-xcOjHZm1.js → TodoView-_1AmNwaZ.js} +1 -1
  32. package/dist/client/assets/{WorkflowNodeEditor-DZ2WZ-ve.js → WorkflowNodeEditor-CYf2R0ap.js} +1 -1
  33. package/dist/client/assets/{agent-import-generation-0tkW9WMt.js → agent-import-generation-BZPb1nmV.js} +1 -1
  34. package/dist/client/assets/{architectureDiagram-3BPJPVTR-DP9_UvPn.js → architectureDiagram-3BPJPVTR-C_wwNBnV.js} +1 -1
  35. package/dist/client/assets/{blockDiagram-GPEHLZMM-EgKwYMgQ.js → blockDiagram-GPEHLZMM-C7URdbgi.js} +1 -1
  36. package/dist/client/assets/{c4Diagram-AAUBKEIU-Dzv0-_xt.js → c4Diagram-AAUBKEIU-BBc8CXBz.js} +1 -1
  37. package/dist/client/assets/channel-M95yBImf.js +1 -0
  38. package/dist/client/assets/{chunk-2J33WTMH-CNmFmJlQ.js → chunk-2J33WTMH-KfVf5U4u.js} +1 -1
  39. package/dist/client/assets/{chunk-4BX2VUAB-DwtF2sl5.js → chunk-4BX2VUAB-BYzFvVsE.js} +1 -1
  40. package/dist/client/assets/{chunk-55IACEB6-DoDurT6F.js → chunk-55IACEB6-B-sxSeny.js} +1 -1
  41. package/dist/client/assets/{chunk-727SXJPM-DB87A9uH.js → chunk-727SXJPM-B0xJsLsd.js} +1 -1
  42. package/dist/client/assets/{chunk-AQP2D5EJ-ClTDkMp1.js → chunk-AQP2D5EJ-BQ9rJQCA.js} +1 -1
  43. package/dist/client/assets/{chunk-FMBD7UC4-BhY2wlYr.js → chunk-FMBD7UC4-DR-KABew.js} +1 -1
  44. package/dist/client/assets/{chunk-ND2GUHAM-BB8mzlmk.js → chunk-ND2GUHAM-C6ZnAzm4.js} +1 -1
  45. package/dist/client/assets/{chunk-QZHKN3VN-D81qQMGf.js → chunk-QZHKN3VN-zs4tZGnv.js} +1 -1
  46. package/dist/client/assets/classDiagram-4FO5ZUOK-DU8poSst.js +1 -0
  47. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-DU8poSst.js +1 -0
  48. package/dist/client/assets/{cose-bilkent-S5V4N54A-CCFUHBJX.js → cose-bilkent-S5V4N54A-DnljjIm-.js} +1 -1
  49. package/dist/client/assets/{dagre-BM42HDAG-xr9MLhRA.js → dagre-BM42HDAG-CEX8DHCo.js} +1 -1
  50. package/dist/client/assets/{dashboard-view-RXKFv3QV.js → dashboard-view-Chxgvuq4.js} +1 -1
  51. package/dist/client/assets/{dashboard-view-lqwQ-pMo.js → dashboard-view-DPCI6MD3.js} +1 -1
  52. package/dist/client/assets/{dashboard-view-oTFt91I3.js → dashboard-view-D_xtIayp.js} +1 -1
  53. package/dist/client/assets/{diagram-2AECGRRQ-mN_tYnBs.js → diagram-2AECGRRQ-Dl9VFNxu.js} +1 -1
  54. package/dist/client/assets/{diagram-5GNKFQAL-xznlq-5C.js → diagram-5GNKFQAL-BPvDRIKP.js} +1 -1
  55. package/dist/client/assets/{diagram-KO2AKTUF-ClRlj1ZA.js → diagram-KO2AKTUF-c1v9YI9G.js} +1 -1
  56. package/dist/client/assets/{diagram-LMA3HP47-CNiPIQqT.js → diagram-LMA3HP47-ChVDgN1K.js} +1 -1
  57. package/dist/client/assets/{diagram-OG6HWLK6-DwQD-W0P.js → diagram-OG6HWLK6-Cns2RBoA.js} +1 -1
  58. package/dist/client/assets/{erDiagram-TEJ5UH35-ZXkiCm8S.js → erDiagram-TEJ5UH35-D33nn5Lx.js} +1 -1
  59. package/dist/client/assets/{flowDiagram-I6XJVG4X-DI5haEH9.js → flowDiagram-I6XJVG4X-BluS50at.js} +1 -1
  60. package/dist/client/assets/{folder-open-NenyCkrb.js → folder-open-oeYf8Ijc.js} +1 -1
  61. package/dist/client/assets/{ganttDiagram-6RSMTGT7-BRHJpfOZ.js → ganttDiagram-6RSMTGT7-D78LznXX.js} +1 -1
  62. package/dist/client/assets/{gitGraphDiagram-PVQCEYII-iXT_YBAZ.js → gitGraphDiagram-PVQCEYII-Cz-VVeuo.js} +1 -1
  63. package/dist/client/assets/index-Clr90mLV.js +2675 -0
  64. package/dist/client/assets/index-DRZtPb3i.css +1 -0
  65. package/dist/client/assets/{infoDiagram-5YYISTIA-BzkuQtqZ.js → infoDiagram-5YYISTIA-DW64QGM7.js} +1 -1
  66. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-5hnPG_98.js → ishikawaDiagram-YF4QCWOH-zB3QANvt.js} +1 -1
  67. package/dist/client/assets/{journeyDiagram-JHISSGLW-Co3fnxbr.js → journeyDiagram-JHISSGLW-nVRvkAiF.js} +1 -1
  68. package/dist/client/assets/{kanban-definition-UN3LZRKU-PZFl_y-h.js → kanban-definition-UN3LZRKU-DIsRSNcB.js} +1 -1
  69. package/dist/client/assets/{mermaid.core-CJRKeU9s.js → mermaid.core-ByWbtMdM.js} +4 -4
  70. package/dist/client/assets/{mindmap-definition-RKZ34NQL-B15e2rkx.js → mindmap-definition-RKZ34NQL-BbZZGyk5.js} +1 -1
  71. package/dist/client/assets/{pieDiagram-4H26LBE5-kGF592D_.js → pieDiagram-4H26LBE5-xEuGzir-.js} +1 -1
  72. package/dist/client/assets/{puzzle-Dgc4yzjO.js → puzzle-DfKZ6p_i.js} +1 -1
  73. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-CUShcj70.js → quadrantDiagram-W4KKPZXB-CXU0exeD.js} +1 -1
  74. package/dist/client/assets/{requirementDiagram-4Y6WPE33-D2k4nLqQ.js → requirementDiagram-4Y6WPE33-xrqjvySl.js} +1 -1
  75. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-CA03BxhT.js → sankeyDiagram-5OEKKPKP-B_XL-dlB.js} +1 -1
  76. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-DDuFN2Pi.js → sequenceDiagram-3UESZ5HK-yPNpJSyq.js} +1 -1
  77. package/dist/client/assets/{shield-alert-BlYWqolM.js → shield-alert-C0mvrTVY.js} +1 -1
  78. package/dist/client/assets/{standing-instructions-template-ujl7UARV.js → standing-instructions-template-BA-Y897i.js} +1 -1
  79. package/dist/client/assets/{stateDiagram-AJRCARHV-yJOkHK4Q.js → stateDiagram-AJRCARHV-B3WacriB.js} +1 -1
  80. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-BgErHdAN.js → stateDiagram-v2-BHNVJYJU-C2J3lqDw.js} +1 -1
  81. package/dist/client/assets/{timeline-definition-PNZ67QCA-BUiDQw21.js → timeline-definition-PNZ67QCA-BMDzGW-H.js} +1 -1
  82. package/dist/client/assets/{upload-DmlZvpMp.js → upload-BcE2JLKs.js} +1 -1
  83. package/dist/client/assets/{users-Cx6ACt-W.js → users-CG9A3bIX.js} +1 -1
  84. package/dist/client/assets/{vennDiagram-CIIHVFJN-DqyIjBY8.js → vennDiagram-CIIHVFJN-C7ZUUi6G.js} +1 -1
  85. package/dist/client/assets/{wardley-L42UT6IY-C93tXAKH.js → wardley-L42UT6IY-zpz98dmH.js} +1 -1
  86. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-DmH6-GJV.js → wardleyDiagram-YWT4CUSO-D4TOrUW4.js} +1 -1
  87. package/dist/client/assets/{xychartDiagram-2RQKCTM6-BPwjE4Su.js → xychartDiagram-2RQKCTM6-CDfiiyNj.js} +1 -1
  88. package/dist/client/index.html +4 -3
  89. package/dist/client/theme-data.css +85 -1
  90. package/dist/client/version.json +1 -1
  91. package/dist/extension.js +244 -362
  92. package/package.json +1 -1
  93. package/dist/client/assets/ReportModal-Bg-XvWay.css +0 -1
  94. package/dist/client/assets/ReportModal-Cy5fRNDK.js +0 -21
  95. package/dist/client/assets/SettingsModal-KnUd0942.css +0 -1
  96. package/dist/client/assets/channel-BdTAZBkX.js +0 -1
  97. package/dist/client/assets/classDiagram-4FO5ZUOK-CuoGzmwo.js +0 -1
  98. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-CuoGzmwo.js +0 -1
  99. package/dist/client/assets/index-CITV-wDq.css +0 -1
  100. package/dist/client/assets/index-CrAJA2v0.js +0 -2675
package/dist/bin.js CHANGED
@@ -867,6 +867,11 @@ var init_execution_and_ui = __esm({
867
867
  "dawn",
868
868
  // FNXC:DashboardTheming 2026-07-31-21:28: Sage must stay order-synchronized across core, selector metadata, and both first-paint validators so saved preferences survive pre-hydration validation.
869
869
  "sage",
870
+ /*
871
+ FNXC:MidnightTheme 2026-08-03-02:05:
872
+ Midnight is a persisted selectable dashboard theme. Keep its id and order synchronized with selector metadata and both web/Electron first-paint validators so saved choices survive before hydration, while shadcn-ember remains the unset default.
873
+ */
874
+ "midnight",
870
875
  // FNXC:DashboardTheming 2026-07-31-20:39: Factory Dark must stay order-synchronized across core, selector metadata, and both first-paint validators so saved preferences survive pre-hydration validation.
871
876
  "factory-dark",
872
877
  // FNXC:DashboardTheming 2026-07-31-23:51: Factory Light must stay order-synchronized across core, selector metadata, and both first-paint validators so saved preferences survive pre-hydration validation.
@@ -96698,15 +96703,20 @@ async function updateTaskUnlockedImpl(store, id, updates, runContext) {
96698
96703
  task.workspaceWorktrees = updates.workspaceWorktrees;
96699
96704
  }
96700
96705
  let movedToTriage = false;
96706
+ let respecifyFromColumn;
96707
+ let respecifyMoveLanes;
96701
96708
  if (updates.dependencies !== void 0) {
96702
96709
  const oldDeps = new Set((task.dependencies ?? []).map((dependency) => dependency.trim()).filter(Boolean));
96703
96710
  const normalizedDependencies = updates.dependencies.map((dependency) => dependency.trim()).filter(Boolean);
96704
96711
  const hasNewDeps = normalizedDependencies.some((d) => !oldDeps.has(d));
96705
96712
  task.dependencies = normalizedDependencies;
96706
- const depLanes = hasNewDeps ? await resolveTaskLifecycleColumns(store, id).catch(() => void 0) : void 0;
96713
+ const respecifyIr = hasNewDeps ? await resolveWorkflowIrForTask(store, id).catch(() => void 0) : void 0;
96714
+ respecifyMoveLanes = toTaskMoveLanes(respecifyIr);
96715
+ const depLanes = respecifyIr ? resolveLifecycleColumns(respecifyIr) : void 0;
96707
96716
  const holdLane = depLanes === void 0 ? "todo" : depLanes.hold;
96708
96717
  if (hasNewDeps && holdLane !== void 0 && task.column === holdLane) {
96709
96718
  const intakeLane = depLanes?.intake;
96719
+ respecifyFromColumn = task.column;
96710
96720
  const relocating = intakeLane !== void 0 && intakeLane !== task.column;
96711
96721
  if (relocating) {
96712
96722
  task.column = intakeLane;
@@ -97384,10 +97394,15 @@ async function updateTaskUnlockedImpl(store, id, updates, runContext) {
97384
97394
  storeLog.warn(`[task-detail] failed to sync PROMPT.md heading for ${task.id}: ${err instanceof Error ? err.message : String(err)}`);
97385
97395
  }
97386
97396
  }
97387
- if (movedToTriage) {
97388
- const lanes = toTaskMoveLanes(await resolveWorkflowIrForTask(store, id).catch(() => void 0));
97389
- store.laneCache.set(task.id, lanes);
97390
- store.emit("task:moved", { task, from: "todo", to: "triage", source: "engine", lanes });
97397
+ if (movedToTriage && respecifyFromColumn !== void 0 && respecifyFromColumn !== task.column && respecifyMoveLanes) {
97398
+ store.laneCache.set(task.id, respecifyMoveLanes);
97399
+ store.emit("task:moved", {
97400
+ task,
97401
+ from: respecifyFromColumn,
97402
+ to: task.column,
97403
+ source: "engine",
97404
+ lanes: respecifyMoveLanes
97405
+ });
97391
97406
  }
97392
97407
  store.emitTaskLifecycleEventSafely("task:updated", [task]);
97393
97408
  return task;
@@ -97399,7 +97414,6 @@ var init_task_update = __esm({
97399
97414
  init_store();
97400
97415
  init_workflow_lifecycle_traits();
97401
97416
  init_workflow_ir_resolver();
97402
- init_workflow_lifecycle_traits();
97403
97417
  init_errors3();
97404
97418
  init_task_fields();
97405
97419
  init_builtin_traits();
@@ -136278,7 +136292,8 @@ function wrapPluginRuntime(instance, runtimeId, runtimeName) {
136278
136292
  const result2 = await adapter.createSession(options);
136279
136293
  return {
136280
136294
  session: result2.session ?? result2,
136281
- sessionFile: result2.sessionFile
136295
+ sessionFile: result2.sessionFile,
136296
+ settleFallbackDispatch: result2.settleFallbackDispatch
136282
136297
  };
136283
136298
  }
136284
136299
  throw new Error(`Plugin runtime "${runtimeId}" does not implement createSession`);
@@ -136387,11 +136402,15 @@ var init_runtime_resolution = __esm({
136387
136402
  name = "Default PI Runtime";
136388
136403
  async createSession(options) {
136389
136404
  const { toolOutputMaxChars, mcpServers, ...agentOptions } = options;
136390
- return createFnAgent2({
136405
+ const result2 = await createFnAgent2({
136391
136406
  ...agentOptions,
136392
136407
  toolOutputMaxChars,
136393
136408
  mcpServers: normalizeAgentRuntimeMcpServers(mcpServers)
136394
136409
  });
136410
+ return {
136411
+ ...result2,
136412
+ settleFallbackDispatch: result2.settleFallbackDispatch ?? (async () => void 0)
136413
+ };
136395
136414
  }
136396
136415
  async promptWithFallback(session, prompt, options) {
136397
136416
  return promptWithFallback(session, prompt, options);
@@ -137273,6 +137292,7 @@ async function createResolvedAgentSession(options) {
137273
137292
  return {
137274
137293
  session: result2.session,
137275
137294
  sessionFile: result2.sessionFile,
137295
+ settleFallbackDispatch: result2.settleFallbackDispatch,
137276
137296
  runtimeId: resolved.runtimeId,
137277
137297
  wasConfigured: resolved.wasConfigured
137278
137298
  };
@@ -159268,7 +159288,11 @@ async function createFnAgent2(options) {
159268
159288
  }
159269
159289
  });
159270
159290
  attachSessionIdentity(promptableSession);
159271
- return { session: promptableSession, sessionFile: promptableSession.sessionFile };
159291
+ return {
159292
+ session: promptableSession,
159293
+ sessionFile: promptableSession.sessionFile,
159294
+ settleFallbackDispatch: async () => void 0
159295
+ };
159272
159296
  }
159273
159297
  var execAsync, RTK_ACCEPTED_REWRITE_EXIT_CODES, RTK_EXPECTED_PASSTHROUGH_EXIT_CODES, RTK_EXPECTED_FAIL_OPEN_ERROR_CODES, RTK_REWRITE_MAX_BUFFER_BYTES, hostExtensionPaths, FN_MEMORY_APPEND_TOOL_NAME, FUSION_SHUTDOWN_WRAP_FLAG, promptWithFallbackInFlight, COMPACTION_FALLBACK_INSTRUCTIONS, MAX_COMPACTED_PROMPT_MEMORY_CHARS, MAX_COMPACTED_SUBTASK_GUIDANCE_CHARS, MAX_COMPACTED_ATTACHMENTS_CHARS, MAX_COMPACTED_EXISTING_SPEC_CHARS, MAX_COMPACTED_TASK_PROMPT_CHARS, MAX_COMPACTED_USER_COMMENTS_CHARS, ModelFallbackExhaustedError, GATE_BYPASS_TOOL_NAMES, TOOL_OUTPUT_BUDGET_OVERRIDES;
159274
159298
  var init_pi = __esm({
@@ -185757,6 +185781,25 @@ var init_scheduler = __esm({
185757
185781
  });
185758
185782
  }
185759
185783
  }
185784
+ if (from === parked.wip && to2 === parked.hold) {
185785
+ if (source === "engine") {
185786
+ this.recentEngineTodoRequeues.set(task.id, task.columnMovedAt ?? (/* @__PURE__ */ new Date()).toISOString());
185787
+ } else {
185788
+ this.recentEngineTodoRequeues.delete(task.id);
185789
+ }
185790
+ } else if (to2 === parked.review || parked.terminal.has(to2)) {
185791
+ this.recentEngineTodoRequeues.delete(task.id);
185792
+ if (task.dispatchStormCount != null || task.lastDispatchAt != null || task.executeRequeueLoopCount != null || task.executeRequeueLoopSignature != null) {
185793
+ void this.store.updateTask(task.id, {
185794
+ dispatchStormCount: null,
185795
+ lastDispatchAt: null,
185796
+ executeRequeueLoopCount: null,
185797
+ executeRequeueLoopSignature: null
185798
+ }).catch((error3) => {
185799
+ schedulerLog.warn(`Failed to reset dispatch oscillation state for ${task.id} on move to ${to2}: ${error3 instanceof Error ? error3.message : String(error3)}`);
185800
+ });
185801
+ }
185802
+ }
185760
185803
  const resolvedParked = mergeParkedColumns(await resolveTaskParkedColumns(this.store, task.id), lanes);
185761
185804
  if (resolvedParked.terminal.has(to2)) {
185762
185805
  try {
@@ -185817,25 +185860,6 @@ var init_scheduler = __esm({
185817
185860
  schedulerLog.error(`Failed event-driven blocker reconciliation for ${task.id}`, error3);
185818
185861
  }
185819
185862
  }
185820
- if (from === resolvedParked.wip && to2 === resolvedParked.hold) {
185821
- if (source === "engine") {
185822
- this.recentEngineTodoRequeues.set(task.id, task.columnMovedAt ?? (/* @__PURE__ */ new Date()).toISOString());
185823
- } else {
185824
- this.recentEngineTodoRequeues.delete(task.id);
185825
- }
185826
- } else if (to2 === resolvedParked.review || resolvedParked.terminal.has(to2)) {
185827
- this.recentEngineTodoRequeues.delete(task.id);
185828
- if (task.dispatchStormCount != null || task.lastDispatchAt != null || task.executeRequeueLoopCount != null || task.executeRequeueLoopSignature != null) {
185829
- void this.store.updateTask(task.id, {
185830
- dispatchStormCount: null,
185831
- lastDispatchAt: null,
185832
- executeRequeueLoopCount: null,
185833
- executeRequeueLoopSignature: null
185834
- }).catch((error3) => {
185835
- schedulerLog.warn(`Failed to reset dispatch oscillation state for ${task.id} on move to ${to2}: ${error3 instanceof Error ? error3.message : String(error3)}`);
185836
- });
185837
- }
185838
- }
185839
185863
  if (resolvedParked.terminal.has(to2) || to2 === resolvedParked.hold) {
185840
185864
  schedulerLog.log(`Task moved to ${to2} \u2014 triggering scheduling`);
185841
185865
  this.schedule();
@@ -204093,7 +204117,6 @@ var init_self_healing = __esm({
204093
204117
  { name: "reconcile-done-task-integrity", fn: () => this.reconcileDoneTaskIntegrity() },
204094
204118
  { name: "reconcile-stale-merger-status", fn: () => this.reconcileStaleMergerStatus() },
204095
204119
  { name: "reconcile-stale-duplicate-decision", fn: () => this.reconcileStaleDuplicateDecisionPause() },
204096
- { name: "reconcile-external-pr-blockers", fn: () => this.reconcileExternalPrBlockers() },
204097
204120
  // FNXC:OrphanedPendingSteps 2026-07-22-16:35 (FN-8492 review follow-up): also
204098
204121
  // steady-state — a step session can die without an engine restart, and startup-only
204099
204122
  // cadence left that case riding the 3×30-min stall escalator to a deadlock park.
@@ -205597,6 +205620,7 @@ var init_self_healing = __esm({
205597
205620
  }
205598
205621
  async reclaimStaleActiveBranches() {
205599
205622
  const reclaimArchivedColumns = await resolveProjectColumnsForRoles(this.store, ["archived"]);
205623
+ const reclaimCompleteColumns = await resolveProjectColumnsForRoles(this.store, ["complete"]);
205600
205624
  try {
205601
205625
  const settings = await this.store.getSettings();
205602
205626
  if (settings.globalPause || settings.enginePaused) return 0;
@@ -205694,10 +205718,12 @@ var init_self_healing = __esm({
205694
205718
  if (task.worktree && await isUsableTaskWorktree(this.options.rootDir, task.worktree)) continue;
205695
205719
  const inspection = await this.inspectOrphanedBranch(branch);
205696
205720
  if (!inspection) continue;
205697
- if (inspection.uniqueCommitCount > 0) {
205721
+ const isCompleteColumn2 = reclaimCompleteColumns.has(task.column);
205722
+ if (inspection.uniqueCommitCount > 0 && !isCompleteColumn2) {
205698
205723
  log33.warn(`[recovery] stale-active-branch-rescue-needed ${task.id} branch=${branch} unique=${inspection.uniqueCommitCount} tip=${inspection.tipSha.slice(0, 12)}`);
205699
205724
  continue;
205700
205725
  }
205726
+ const reclaimReason = inspection.uniqueCommitCount > 0 ? "complete-column-unique-commits-force" : "zero-unique-commits-no-worktree";
205701
205727
  await execAsync18(`git branch -D ${JSON.stringify(branch)}`, {
205702
205728
  cwd: this.options.rootDir,
205703
205729
  timeout: 12e4,
@@ -205715,7 +205741,7 @@ var init_self_healing = __esm({
205715
205741
  });
205716
205742
  await this.store.logEntry(
205717
205743
  task.id,
205718
- `[recovery] stale-active-branch-reclaim ${task.id} branch=${branch} reason=zero-unique-commits-no-worktree`
205744
+ `[recovery] stale-active-branch-reclaim ${task.id} branch=${branch} reason=${reclaimReason}`
205719
205745
  );
205720
205746
  try {
205721
205747
  const auditor = createRunAuditor(this.store, {
@@ -205733,7 +205759,7 @@ var init_self_healing = __esm({
205733
205759
  branch,
205734
205760
  tipSha: inspection.tipSha,
205735
205761
  uniqueCommitCount: inspection.uniqueCommitCount,
205736
- reason: "zero-unique-commits-no-worktree"
205762
+ reason: reclaimReason
205737
205763
  }
205738
205764
  });
205739
205765
  } catch (auditErr) {
@@ -205780,10 +205806,9 @@ var init_self_healing = __esm({
205780
205806
  const baseBranch = task.baseBranch || await resolveIntegrationBranch(this.options.rootDir, void 0);
205781
205807
  const comparison = await listUniqueBranchCommits(this.options.rootDir, baseBranch, branchName);
205782
205808
  if (comparison.commits.length > 0) {
205783
- log33.warn(
205784
- `[self-healing] reconcileCompletedTask ${task.id}: branch ${branchName} has ${comparison.commits.length} unique commit(s) vs ${comparison.mainRef}; skip deletion`
205809
+ log33.log(
205810
+ `[self-healing] reconcileCompletedTask ${task.id}: branch ${branchName} has ${comparison.commits.length} unique commit(s) vs ${comparison.mainRef}; force-deleting post-completion (squash-safe)`
205785
205811
  );
205786
- return false;
205787
205812
  }
205788
205813
  try {
205789
205814
  await execAsync18(`git branch -D ${shellQuote2(branchName)}`, {
@@ -212990,71 +213015,12 @@ var init_self_healing = __esm({
212990
213015
  }
212991
213016
  }
212992
213017
  /*
212993
- FNXC:HonestBlockedExit 2026-08-02-01:30:
212994
- Durable parks store github-pr externalBlockers (FN-8700 file-claim). When every blocking
212995
- PR is MERGED or CLOSED, clear the failed park so the scheduler can re-dispatch. Fail-soft
212996
- when gh is unavailable leave the park for the operator.
213018
+ FNXC:HonestBlockedExit 2026-08-02-23:59 (operator decision — FN-8728 vs PR #2398):
213019
+ The FN-8700 `reconcile-external-pr-blockers` sweep (gh-backed clearing of PR-claim parks)
213020
+ is REMOVED with the whole PR/file-claim blocking mechanism. Open PRs are never blockers;
213021
+ file-scope conflicts are arbitrated only by Fusion's own board. Legacy PR-claim parks are
213022
+ no longer honored by isDurableBlockedTask, so normal recovery paths reclaim them.
212997
213023
  */
212998
- async reconcileExternalPrBlockers() {
212999
- try {
213000
- if (!await isGhAvailable()) {
213001
- log33.debug("reconcile-external-pr-blockers skipped \u2014 gh unavailable");
213002
- return 0;
213003
- }
213004
- const tasks2 = await this.store.listTasks({ slim: true, includeArchived: false, limit: 500 });
213005
- let cleared = 0;
213006
- for (const task of tasks2.slice(0, 80)) {
213007
- if (task.status !== "failed" || !task.error?.startsWith("BLOCKED:")) continue;
213008
- const meta2 = task.sourceMetadata;
213009
- const blockers = meta2?.externalBlockers;
213010
- if (!Array.isArray(blockers) || blockers.length === 0) continue;
213011
- const prNumbers = blockers.map((b3) => b3 && typeof b3 === "object" && b3.kind === "github-pr" ? Number(b3.number) : NaN).filter((n) => Number.isFinite(n) && n > 0);
213012
- if (prNumbers.length === 0) continue;
213013
- let allResolved = true;
213014
- for (const n of prNumbers) {
213015
- try {
213016
- const pr2 = await runGhJsonAsync(
213017
- ["pr", "view", String(n), "--json", "state,mergedAt"],
213018
- { timeoutMs: 15e3 }
213019
- );
213020
- const state = String(pr2?.state ?? "").toUpperCase();
213021
- const merged = Boolean(pr2?.mergedAt) || state === "MERGED";
213022
- const closed = state === "CLOSED" || state === "MERGED";
213023
- if (!merged && !closed) {
213024
- allResolved = false;
213025
- break;
213026
- }
213027
- } catch {
213028
- allResolved = false;
213029
- break;
213030
- }
213031
- }
213032
- if (!allResolved) continue;
213033
- await this.store.updateTask(task.id, {
213034
- status: null,
213035
- error: null,
213036
- sourceMetadataPatch: {
213037
- externalBlockers: [],
213038
- blockedClass: null,
213039
- blockedThrashSignature: null,
213040
- blockedThrashCount: null,
213041
- externalPrBlockersClearedAt: (/* @__PURE__ */ new Date()).toISOString(),
213042
- externalPrBlockersCleared: prNumbers
213043
- }
213044
- });
213045
- await this.store.logEntry(
213046
- task.id,
213047
- `Auto-recovered: external PR blocker(s) ${prNumbers.map((n) => `#${n}`).join(", ")} merged/closed \u2014 cleared durable BLOCKED park for re-dispatch`
213048
- );
213049
- log33.log(`Cleared durable PR block for ${task.id} (prs=${prNumbers.join(",")})`);
213050
- cleared += 1;
213051
- }
213052
- return cleared;
213053
- } catch (error3) {
213054
- log33.warn(`reconcile-external-pr-blockers failed: ${error3 instanceof Error ? error3.message : String(error3)}`);
213055
- return 0;
213056
- }
213057
- }
213058
213024
  async resolveExplicitDuplicateMarkerTasks() {
213059
213025
  try {
213060
213026
  const settings = await this.store.getSettings();
@@ -213808,6 +213774,7 @@ var init_self_healing = __esm({
213808
213774
  // ../engine/src/triage.ts
213809
213775
  import { Type as Type5 } from "@earendil-works/pi-ai";
213810
213776
  import { exec as exec34 } from "node:child_process";
213777
+ import { existsSync as existsSync60 } from "node:fs";
213811
213778
  import { readFile as readFile38, writeFile as writeFile27, rm as rm8 } from "node:fs/promises";
213812
213779
  import { join as join72 } from "node:path";
213813
213780
  import { promisify as promisify48 } from "node:util";
@@ -214314,6 +214281,8 @@ var init_triage = __esm({
214314
214281
  unregisterAdmissionProvider = null;
214315
214282
  /** Timestamps when tasks entered the `processing` set, for staleness detection. */
214316
214283
  processingSince = /* @__PURE__ */ new Map();
214284
+ /** Monotonic provenance token for attempt-local planner fallback observation. */
214285
+ planningAttemptSequence = 0;
214317
214286
  wasGlobalPaused = false;
214318
214287
  wasEnginePaused = false;
214319
214288
  idleSemaphoreLeakCandidateSince = null;
@@ -215609,7 +215578,28 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
215609
215578
  }
215610
215579
  await this.store.logEntry(task.id, `Planning session running in task worktree ${planningCwd}`).catch(() => void 0);
215611
215580
  }
215612
- const { session } = await createResolvedAgentSession({
215581
+ const authoritativePromptPath = join72(this.rootDir, promptPath);
215582
+ const planningAttemptBaseline = existsSync60(authoritativePromptPath) ? await readFile38(authoritativePromptPath, "utf-8").catch(() => void 0) : void 0;
215583
+ const planningAttempt = {
215584
+ id: `${task.id}:${++this.planningAttemptSequence}`,
215585
+ baseline: planningAttemptBaseline,
215586
+ fallbackEngaged: false,
215587
+ fallbackSettlements: []
215588
+ };
215589
+ const fallbackObserver = createFallbackModelObserver({
215590
+ agent: "triage",
215591
+ label: "triage",
215592
+ store: this.store,
215593
+ taskId: task.id,
215594
+ taskTitle: task.title
215595
+ });
215596
+ const onFallbackModelUsed = (payload) => {
215597
+ planningAttempt.fallbackEngaged = true;
215598
+ const settlement = Promise.resolve(fallbackObserver(payload));
215599
+ planningAttempt.fallbackSettlements.push(settlement);
215600
+ return settlement;
215601
+ };
215602
+ const { session, settleFallbackDispatch, runtimeId } = await createResolvedAgentSession({
215613
215603
  sessionPurpose: "triage",
215614
215604
  runtimeHint: triageRuntimeHint,
215615
215605
  pluginRunner: this.options.pluginRunner,
@@ -215648,13 +215638,7 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
215648
215638
  taskTitle: task.title,
215649
215639
  actionGateContext: this.buildActionGateContext(task.id, triageRunContext.runId, assignedAgent, settings.defaultAgentPermissionPolicy),
215650
215640
  permanentAgentGating: this.buildPermanentAgentGatingContext(task.id, triageRunContext.runId, assignedAgent, settings.defaultAgentPermissionPolicy),
215651
- onFallbackModelUsed: createFallbackModelObserver({
215652
- agent: "triage",
215653
- label: "triage",
215654
- store: this.store,
215655
- taskId: task.id,
215656
- taskTitle: task.title
215657
- })
215641
+ onFallbackModelUsed
215658
215642
  });
215659
215643
  const modelDesc = formatModelMarkerDetails(describeModel(session), resolvePlanningThinkingLevel(settings, task.planningThinkingLevel ?? task.thinkingLevel));
215660
215644
  planLog.debug(`${task.id}: using model ${modelDesc}`);
@@ -215724,6 +215708,10 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
215724
215708
  agentPrompt,
215725
215709
  imageContents.length > 0 ? { images: imageContents } : void 0
215726
215710
  );
215711
+ const fallbackDispatchBoundaryMissing = typeof settleFallbackDispatch !== "function";
215712
+ if (!fallbackDispatchBoundaryMissing) {
215713
+ await settleFallbackDispatch();
215714
+ }
215727
215715
  checkSessionError(session);
215728
215716
  if (this.pauseAborted.has(task.id)) {
215729
215717
  this.pauseAborted.delete(task.id);
@@ -215816,12 +215804,42 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
215816
215804
  }
215817
215805
  }
215818
215806
  }
215819
- const duplicateReport = { outcome: "parked" };
215820
- if (await this.tryFinalizeExplicitDuplicateMarker(task, written, settings, {
215821
- isReplan,
215822
- feedback
215823
- }, duplicateReport)) {
215824
- this.options.onSpecifyComplete?.(task, duplicateReport);
215807
+ let settledFallbackCount = 0;
215808
+ while (settledFallbackCount < planningAttempt.fallbackSettlements.length) {
215809
+ const pendingSettlements = planningAttempt.fallbackSettlements.slice(settledFallbackCount);
215810
+ settledFallbackCount = planningAttempt.fallbackSettlements.length;
215811
+ await Promise.all(pendingSettlements);
215812
+ }
215813
+ const artifactChangedByAttempt = planningAttempt.baseline !== written;
215814
+ if (fallbackDispatchBoundaryMissing || planningAttempt.fallbackEngaged || !artifactChangedByAttempt) {
215815
+ const failure = fallbackDispatchBoundaryMissing ? `Planner runtime ${runtimeId} did not provide a fallback-dispatch settlement boundary for attempt ${planningAttempt.id}` : planningAttempt.fallbackEngaged ? `Planner fallback engaged during attempt ${planningAttempt.id}` : `Planner did not update the authoritative PROMPT.md during attempt ${planningAttempt.id}`;
215816
+ const decision = computeRecoveryDecision({
215817
+ recoveryRetryCount: task.recoveryRetryCount,
215818
+ nextRecoveryAt: task.nextRecoveryAt
215819
+ });
215820
+ if (decision.shouldRetry) {
215821
+ const retryMessage = `${failure} \u2014 retry ${decision.nextState.recoveryRetryCount}/${MAX_RECOVERY_RETRIES} in ${formatDelay(decision.delayMs)}.`;
215822
+ planLog.warn(`${task.id} ${retryMessage}`);
215823
+ await this.store.logEntry(task.id, retryMessage);
215824
+ await this.updatePlanningStateIfStillCurrent(task, {
215825
+ status: this.restoreStatusAfterInterruptedTriageWork(task),
215826
+ error: null,
215827
+ recoveryRetryCount: decision.nextState.recoveryRetryCount,
215828
+ nextRecoveryAt: decision.nextState.nextRecoveryAt
215829
+ });
215830
+ return;
215831
+ }
215832
+ const failureMessage = `${failure} after ${MAX_RECOVERY_RETRIES} retries. Retry after adjusting the task prompt or model.`;
215833
+ planLog.error(`${task.id} clean planning attempt retry budget exhausted`);
215834
+ await this.store.logEntry(task.id, failureMessage);
215835
+ if (await this.updatePlanningStateIfStillCurrent(task, {
215836
+ status: "failed",
215837
+ error: failureMessage,
215838
+ recoveryRetryCount: null,
215839
+ nextRecoveryAt: null
215840
+ })) {
215841
+ await this.backfillBlankTitleAfterTerminalTriageFailure(task);
215842
+ }
215825
215843
  return;
215826
215844
  }
215827
215845
  const deterministicSpecFailure = await this.validateGeneratedPrompt(task.id, written);
@@ -215863,6 +215881,21 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
215863
215881
  }
215864
215882
  return;
215865
215883
  }
215884
+ const duplicateReport = { outcome: "parked" };
215885
+ if (await this.tryFinalizeExplicitDuplicateMarker(task, written, settings, {
215886
+ isReplan,
215887
+ feedback
215888
+ }, duplicateReport)) {
215889
+ this.options.onSpecifyComplete?.(task, duplicateReport);
215890
+ return;
215891
+ }
215892
+ if (task.recoveryRetryCount != null || task.nextRecoveryAt != null) {
215893
+ await this.updatePlanningStateIfStillCurrent(task, {
215894
+ error: null,
215895
+ recoveryRetryCount: null,
215896
+ nextRecoveryAt: null
215897
+ });
215898
+ }
215866
215899
  const finalizeReport = await this.finalizeApprovedTask(task, written, settings, {
215867
215900
  isReplan,
215868
215901
  feedback
@@ -216899,103 +216932,35 @@ Remove or replace these ids and call fn_task_create again.`
216899
216932
  // ../engine/src/execution-block-classifier.ts
216900
216933
  function partitionBlockedByRefs(blockedBy) {
216901
216934
  const taskIds = [];
216902
- const prNumbers = [];
216903
216935
  for (const raw of blockedBy) {
216904
216936
  const id = raw.trim();
216905
216937
  if (!id) continue;
216906
- const prMatch = id.match(PR_REF_RE);
216907
- if (prMatch) {
216908
- prNumbers.push(Number(prMatch[1]));
216909
- continue;
216910
- }
216938
+ if (LEGACY_PR_REF_RE.test(id)) continue;
216911
216939
  if (TASK_ID_RE.test(id)) {
216912
216940
  const m2 = id.toUpperCase().match(/^([A-Z][A-Z0-9]*)-(\d+)$/);
216913
216941
  taskIds.push(m2 ? `${m2[1]}-${m2[2]}` : id.toUpperCase());
216914
- continue;
216915
216942
  }
216916
216943
  }
216917
- return {
216918
- taskIds: [...new Set(taskIds)],
216919
- prNumbers: [...new Set(prNumbers.filter((n) => Number.isFinite(n) && n > 0))]
216920
- };
216944
+ return { taskIds: [...new Set(taskIds)] };
216921
216945
  }
216922
- function extractPrNumbersFromText(text3) {
216923
- const found = [];
216924
- for (const match of text3.matchAll(PR_IN_TEXT_RE)) {
216925
- const n = Number(match[1]);
216926
- if (Number.isFinite(n) && n > 0) found.push(n);
216927
- }
216928
- return [...new Set(found)];
216929
- }
216930
- function isFileClaimBlockedReason(reason) {
216931
- return CLAIM_REASON_RE.test(reason);
216932
- }
216933
- function classifyBlockedExit(reason, blockedBy = []) {
216934
- const trimmed = reason.trim();
216935
- const partitioned = partitionBlockedByRefs(blockedBy);
216936
- const prFromText = extractPrNumbersFromText(trimmed);
216937
- const prNumbers = [.../* @__PURE__ */ new Set([...partitioned.prNumbers, ...prFromText])];
216938
- const isClaim = isFileClaimBlockedReason(trimmed) || prNumbers.length > 0 && /claim/i.test(trimmed);
216939
- if (isClaim || prNumbers.length > 0 && isFileClaimBlockedReason(trimmed)) {
216940
- const externalBlockers = [
216941
- ...prNumbers.map((number4) => ({ kind: "github-pr", number: number4 }))
216942
- ];
216943
- if (externalBlockers.length === 0 && isClaim) {
216944
- externalBlockers.push({
216945
- kind: "file-claim",
216946
- prNumber: prNumbers[0]
216947
- });
216948
- } else if (isClaim) {
216949
- for (const n of prNumbers) {
216950
- if (!externalBlockers.some((b3) => b3.kind === "github-pr" && b3.number === n)) {
216951
- externalBlockers.push({ kind: "github-pr", number: n });
216952
- }
216953
- }
216954
- if (prNumbers.length === 0) {
216955
- externalBlockers.push({ kind: "file-claim" });
216956
- }
216957
- }
216958
- const thrashSignature = [
216959
- "file-claim",
216960
- ...prNumbers.map((n) => `pr:${n}`).sort(),
216961
- ...partitioned.taskIds.slice().sort()
216962
- ].join("|");
216963
- return {
216964
- allowAutoReplan: false,
216965
- class: "file-claim",
216966
- externalBlockers,
216967
- thrashSignature: thrashSignature || "file-claim",
216968
- prNumbers
216969
- };
216970
- }
216971
- if (partitioned.taskIds.length > 0) {
216946
+ function classifyBlockedExit(_reason, blockedBy = []) {
216947
+ const { taskIds } = partitionBlockedByRefs(blockedBy);
216948
+ if (taskIds.length > 0) {
216972
216949
  return {
216973
216950
  allowAutoReplan: false,
216974
216951
  class: "external",
216975
- externalBlockers: [],
216976
- thrashSignature: `tasks:${partitioned.taskIds.slice().sort().join(",")}`,
216977
- prNumbers
216978
- };
216979
- }
216980
- if (prNumbers.length > 0) {
216981
- return {
216982
- allowAutoReplan: false,
216983
- class: "external",
216984
- externalBlockers: prNumbers.map((number4) => ({ kind: "github-pr", number: number4 })),
216985
- thrashSignature: prNumbers.map((n) => `pr:${n}`).sort().join("|"),
216986
- prNumbers
216952
+ thrashSignature: `tasks:${taskIds.slice().sort().join(",")}`
216987
216953
  };
216988
216954
  }
216989
216955
  return {
216990
216956
  allowAutoReplan: true,
216991
216957
  class: "plan-defect",
216992
- externalBlockers: [],
216993
- thrashSignature: "plan-defect",
216994
- prNumbers: []
216958
+ thrashSignature: "plan-defect"
216995
216959
  };
216996
216960
  }
216997
216961
  function countBlockedThrashHits(log43, signature, nowMs = Date.now(), windowMs = BLOCKED_THRASH_WINDOW_MS) {
216998
216962
  if (!log43?.length) return 0;
216963
+ if (signature === "plan-defect") return 0;
216999
216964
  const cutoff = nowMs - windowMs;
217000
216965
  let count2 = 0;
217001
216966
  for (const entry of log43) {
@@ -217007,18 +216972,7 @@ function countBlockedThrashHits(log43, signature, nowMs = Date.now(), windowMs =
217007
216972
  continue;
217008
216973
  }
217009
216974
  }
217010
- if (signature === "plan-defect") continue;
217011
- if (signature.includes("file-claim") || signature.startsWith("pr:") || signature.includes("|pr:")) {
217012
- if (isFileClaimBlockedReason(action) || /PR\s*#?\s*\d+/i.test(action) || action.includes("durable external block")) {
217013
- count2 += 1;
217014
- continue;
217015
- }
217016
- }
217017
216975
  for (const part of signature.split("|")) {
217018
- if (part.startsWith("pr:") && action.includes(`PR #${part.slice(3)}`)) {
217019
- count2 += 1;
217020
- break;
217021
- }
217022
216976
  if (part.startsWith("tasks:") && part.slice(6).split(",").some((id) => id && action.includes(id))) {
217023
216977
  count2 += 1;
217024
216978
  break;
@@ -217027,38 +216981,26 @@ function countBlockedThrashHits(log43, signature, nowMs = Date.now(), windowMs =
217027
216981
  }
217028
216982
  return count2;
217029
216983
  }
217030
- function isDurableBlockedError(error3) {
217031
- if (!error3?.startsWith("BLOCKED:")) return false;
217032
- const reason = error3.slice("BLOCKED:".length).trim();
217033
- const classification = classifyBlockedExit(reason, []);
217034
- return !classification.allowAutoReplan;
217035
- }
217036
216984
  function isDurableBlockedTask(task) {
217037
- if (task.status === "failed" && isDurableBlockedError(task.error)) return true;
217038
216985
  const meta2 = task.sourceMetadata;
217039
216986
  if (!meta2 || typeof meta2 !== "object") return false;
217040
- if (meta2.blockedClass === "file-claim" || meta2.blockedClass === "external") {
217041
- if (task.status === "failed" || task.status === "needs-replan") return true;
217042
- }
217043
- const blockers = meta2.externalBlockers;
217044
- return Array.isArray(blockers) && blockers.length > 0 && task.status === "failed";
216987
+ if (meta2.blockedClass !== "external") return false;
216988
+ return task.status === "failed" || task.status === "needs-replan";
217045
216989
  }
217046
216990
  function buildExternalBlockMetadataPatch(classification, thrashCount) {
217047
216991
  return {
217048
216992
  blockedClass: classification.class,
217049
216993
  blockedThrashSignature: classification.thrashSignature,
217050
216994
  blockedThrashCount: thrashCount,
217051
- externalBlockers: classification.externalBlockers
216995
+ externalBlockers: []
217052
216996
  };
217053
216997
  }
217054
- var TASK_ID_RE, PR_REF_RE, PR_IN_TEXT_RE, CLAIM_REASON_RE, BLOCKED_THRASH_LIMIT, BLOCKED_THRASH_WINDOW_MS;
216998
+ var TASK_ID_RE, LEGACY_PR_REF_RE, BLOCKED_THRASH_LIMIT, BLOCKED_THRASH_WINDOW_MS;
217055
216999
  var init_execution_block_classifier = __esm({
217056
217000
  "../engine/src/execution-block-classifier.ts"() {
217057
217001
  "use strict";
217058
217002
  TASK_ID_RE = /^[A-Z][A-Z0-9]*-\d+$/i;
217059
- PR_REF_RE = /^(?:pr[:#-]|#|PR-)(\d+)$/i;
217060
- PR_IN_TEXT_RE = /\bPR\s*#?\s*(\d+)\b/gi;
217061
- CLAIM_REASON_RE = /check-file-claimed|actively claimed|file[- ]claim|claimed by (?:open )?pr|open pr\s*#?\s*\d+|collision policy|claimed paths?|file claims?/i;
217003
+ LEGACY_PR_REF_RE = /^(?:pr[:#-]|#|PR-)(\d+)$/i;
217062
217004
  BLOCKED_THRASH_LIMIT = 3;
217063
217005
  BLOCKED_THRASH_WINDOW_MS = 60 * 60 * 1e3;
217064
217006
  }
@@ -219876,7 +219818,7 @@ var init_workflow_completion_summary = __esm({
219876
219818
 
219877
219819
  // ../engine/src/review-checkout.ts
219878
219820
  import { execFileSync as execFileSync3 } from "node:child_process";
219879
- import { existsSync as existsSync60, realpathSync as realpathSync9, statSync as statSync11 } from "node:fs";
219821
+ import { existsSync as existsSync61, realpathSync as realpathSync9, statSync as statSync11 } from "node:fs";
219880
219822
  import { isAbsolute as isAbsolute15 } from "node:path";
219881
219823
  function readMetadataPath(value) {
219882
219824
  if (!value || typeof value !== "object") return void 0;
@@ -219900,7 +219842,7 @@ function resolveReviewCheckoutCwd(task, fallbackCwd) {
219900
219842
  const candidate = getTaskReviewCheckoutPath(task);
219901
219843
  if (!candidate || !isAbsolute15(candidate)) return fallbackCwd;
219902
219844
  try {
219903
- if (!existsSync60(candidate) || !statSync11(candidate).isDirectory()) return fallbackCwd;
219845
+ if (!existsSync61(candidate) || !statSync11(candidate).isDirectory()) return fallbackCwd;
219904
219846
  const realCandidate = realpathSync9(candidate);
219905
219847
  const topLevel = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
219906
219848
  cwd: realCandidate,
@@ -222506,7 +222448,7 @@ var init_external_integration_evidence = __esm({
222506
222448
 
222507
222449
  // ../engine/src/step-runner.ts
222508
222450
  import { exec as exec35 } from "node:child_process";
222509
- import { existsSync as existsSync62, statSync as statSync12 } from "node:fs";
222451
+ import { existsSync as existsSync63, statSync as statSync12 } from "node:fs";
222510
222452
  import { promisify as promisify50 } from "node:util";
222511
222453
  async function runTaskStep(deps, task, stepIndex, opts = {}) {
222512
222454
  const { store, worktreePath } = deps;
@@ -222660,7 +222602,7 @@ function makeAncestryBlastRadiusGuard(opts) {
222660
222602
  function isUsableWorktreeDirectory(candidate) {
222661
222603
  if (!candidate) return false;
222662
222604
  try {
222663
- return existsSync62(candidate) && statSync12(candidate).isDirectory();
222605
+ return existsSync63(candidate) && statSync12(candidate).isDirectory();
222664
222606
  } catch {
222665
222607
  return false;
222666
222608
  }
@@ -222697,7 +222639,7 @@ var init_step_runner = __esm({
222697
222639
 
222698
222640
  // ../engine/src/auto-recovery-handlers/branch-worktree.ts
222699
222641
  import { exec as exec36 } from "node:child_process";
222700
- import { existsSync as existsSync63 } from "node:fs";
222642
+ import { existsSync as existsSync64 } from "node:fs";
222701
222643
  import { promisify as promisify51 } from "node:util";
222702
222644
  var execAsync33, baseLog2, GIT_TIMEOUT_MS8, GIT_MAX_BUFFER6, BranchWorktreeAutoRecoveryHandler;
222703
222645
  var init_branch_worktree = __esm({
@@ -222888,7 +222830,7 @@ var init_branch_worktree = __esm({
222888
222830
  if (inspection.kind === "stale-resolved" || inspection.kind === "fully-subsumed" || inspection.kind === "tip-already-merged") {
222889
222831
  await this.requeueAfterRecovery(ctx.task, failure, inspection.kind, {
222890
222832
  branchExists: await this.hasBranchRef(repoDir, branchName),
222891
- worktreePresent: existsSync63(conflictingWorktreePath),
222833
+ worktreePresent: existsSync64(conflictingWorktreePath),
222892
222834
  tipSha: "tipSha" in inspection ? inspection.tipSha : void 0,
222893
222835
  inspectionKind: inspection.kind
222894
222836
  });
@@ -222958,7 +222900,7 @@ var init_branch_worktree = __esm({
222958
222900
  let branchDeleted = false;
222959
222901
  let worktreeRemoved = false;
222960
222902
  if (!isLiveOwned) {
222961
- if (existsSync63(conflictingWorktreePath)) {
222903
+ if (existsSync64(conflictingWorktreePath)) {
222962
222904
  try {
222963
222905
  await execAsync33(`git worktree remove --force ${this.quote(conflictingWorktreePath)}`, {
222964
222906
  cwd: repoDir,
@@ -223006,7 +222948,7 @@ var init_branch_worktree = __esm({
223006
222948
  });
223007
222949
  await this.requeueAfterRecovery(ctx.task, failure, "live-foreign-discard-and-recreate", {
223008
222950
  branchExists: !branchDeleted,
223009
- worktreePresent: !worktreeRemoved && existsSync63(conflictingWorktreePath),
222951
+ worktreePresent: !worktreeRemoved && existsSync64(conflictingWorktreePath),
223010
222952
  tipSha: tipSha2,
223011
222953
  inspectionKind: inspection.kind
223012
222954
  });
@@ -223019,7 +222961,7 @@ var init_branch_worktree = __esm({
223019
222961
  conflictingWorktreePath,
223020
222962
  inspectionKind: inspection.kind,
223021
222963
  branchExists,
223022
- worktreePresent: existsSync63(conflictingWorktreePath),
222964
+ worktreePresent: existsSync64(conflictingWorktreePath),
223023
222965
  tipSha
223024
222966
  });
223025
222967
  }
@@ -223180,7 +223122,7 @@ var init_file_scope2 = __esm({
223180
223122
  });
223181
223123
 
223182
223124
  // ../engine/src/run-verification-tool.ts
223183
- import { existsSync as existsSync64, readdirSync as readdirSync11, readFileSync as readFileSync23 } from "node:fs";
223125
+ import { existsSync as existsSync65, readdirSync as readdirSync11, readFileSync as readFileSync23 } from "node:fs";
223184
223126
  import { isAbsolute as isAbsolute16, join as join77, relative as relative14 } from "node:path";
223185
223127
  import { Type as Type6 } from "@earendil-works/pi-ai";
223186
223128
  function shellSplit(input) {
@@ -223740,7 +223682,7 @@ function createRunVerificationTool(opts) {
223740
223682
  }
223741
223683
  if (effectiveCommand.trimStart().startsWith("pnpm --filter")) {
223742
223684
  const modulesYaml = join77(rootDir, "node_modules", ".modules.yaml");
223743
- if (!existsSync64(modulesYaml)) {
223685
+ if (!existsSync65(modulesYaml)) {
223744
223686
  const installCmd = "pnpm install --prefer-offline";
223745
223687
  const msg = `node_modules/.modules.yaml not found in workspace root \u2014 auto-prepending \`${installCmd}\` before running the command.`;
223746
223688
  warnings.push(msg);
@@ -224101,7 +224043,7 @@ import { exec as exec39, execFile as execFile26, execSync as execSync7 } from "n
224101
224043
  import { promisify as promisify54 } from "node:util";
224102
224044
  import { setImmediate as setImmediateCb3 } from "node:timers";
224103
224045
  import { basename as basename19, delimiter as delimiter2, isAbsolute as isAbsolute18, join as join78, relative as relative16, resolve as resolvePath3 } from "node:path";
224104
- import { existsSync as existsSync65, lstatSync as lstatSync3, realpathSync as realpathSync10 } from "node:fs";
224046
+ import { existsSync as existsSync66, lstatSync as lstatSync3, realpathSync as realpathSync10 } from "node:fs";
224105
224047
  import { readFile as readFile40, rm as rm12, writeFile as writeFile29 } from "node:fs/promises";
224106
224048
  import { Type as Type7 } from "@earendil-works/pi-ai";
224107
224049
  import { SessionManager as SessionManager2 } from "@earendil-works/pi-coding-agent";
@@ -224119,7 +224061,7 @@ function isWorkflowStepSkillDiscoverable(skillName, additionalSkillPaths, ceSkil
224119
224061
  return false;
224120
224062
  }
224121
224063
  return (additionalSkillPaths ?? []).some(
224122
- (skillPath) => basename19(skillPath) === bareSkillName2 && existsSync65(join78(skillPath, "SKILL.md")) || existsSync65(join78(skillPath, bareSkillName2, "SKILL.md"))
224064
+ (skillPath) => basename19(skillPath) === bareSkillName2 && existsSync66(join78(skillPath, "SKILL.md")) || existsSync66(join78(skillPath, bareSkillName2, "SKILL.md"))
224123
224065
  );
224124
224066
  }
224125
224067
  function getPromptSection(prompt, heading) {
@@ -225092,7 +225034,7 @@ If you have just finished a step's work, immediately call \`fn_task_update\` to
225092
225034
 
225093
225035
  The user is not watching this conversation in real-time. They will read the final result. Asking permission wastes a full retry cycle and may orphan committed work.
225094
225036
 
225095
- **Cannot proceed \u2014 the honest blocked exit.** If the work genuinely cannot be finished (an upstream API break, a missing prerequisite task, an unresolvable external error, or a **file claim / open PR collision**), call \`fn_task_done(outcome="blocked", reason="<concrete blocker + what would unblock it>", blockedBy=["FN-XXXX"] or ["pr:2398"])\`. File-claim reasons must name the PR (e.g. "actively claimed by PR #2398" + \`blockedBy:["pr:2398"]\`). That parks durable failed WITHOUT auto-replan so the engine does not thrash; task IDs requeue when those tasks complete; PR refs clear when the PR merges/closes. Do NOT skip remaining steps to fake completion.
225037
+ **Cannot proceed \u2014 the honest blocked exit.** If the work genuinely cannot be finished (an upstream API break, a missing prerequisite task, or an unresolvable external error), call \`fn_task_done(outcome="blocked", reason="<concrete blocker + what would unblock it>", blockedBy=["FN-XXXX"])\`. That parks durable failed WITHOUT auto-replan so the engine does not thrash; task IDs requeue when those tasks complete. Blockers must be Fusion board tasks \u2014 do NOT treat open GitHub PRs touching the same files as blockers; other PRs are not claims on your file scope. Do NOT skip remaining steps to fake completion.
225096
225038
  This is THE correct action when you are stuck \u2014 do NOT instead mark the remaining steps \`skipped\` and call \`fn_task_done\` to make the task look finished. Skipping steps to escape a blocker launders a failure into \`done\` and is never the right move. (\`skipped\` remains valid only for the stale-premise path below, when the requested work is already present on HEAD.) Never write the blocker as plain prose.
225097
225039
 
225098
225040
  ## How to work
@@ -227681,7 +227623,7 @@ The tool prevents your session from being killed by the inactivity watchdog duri
227681
227623
  );
227682
227624
  return false;
227683
227625
  }
227684
- if (task.worktree && existsSync65(task.worktree)) {
227626
+ if (task.worktree && existsSync66(task.worktree)) {
227685
227627
  const modifiedFiles = await this.captureModifiedFiles(task.worktree, task.baseCommitSha, task.id, void 0, "recovery");
227686
227628
  if (modifiedFiles.length > 0) {
227687
227629
  await this.store.updateTask(task.id, { modifiedFiles });
@@ -230643,7 +230585,7 @@ ${info.feedback}`, revisionKey),
230643
230585
  if (live.firstExecutionAt || live.executionStartedAt) return false;
230644
230586
  if (activeSessionRegistry.isPathActive(live.worktree) || activeSessionRegistry.isPathActive(resolvePath3(live.worktree))) return false;
230645
230587
  if (this.hasLiveTaskSessionSurface(taskId) || executingTaskLock.has(taskId)) return false;
230646
- if (existsSync65(live.worktree)) {
230588
+ if (existsSync66(live.worktree)) {
230647
230589
  if (await this.preExecutionWorktreeHasWork(live.worktree)) {
230648
230590
  executorLog.log(`${taskId}: keeping pre-execution worktree ${live.worktree} \u2014 it carries commits or uncommitted changes`);
230649
230591
  return false;
@@ -230685,7 +230627,7 @@ ${info.feedback}`, revisionKey),
230685
230627
  }
230686
230628
  if (this.workspaceConfig && (this.workspaceConfig.repos.length ?? 0) > 0) return null;
230687
230629
  const live = await this.store.getTask(taskId);
230688
- if (live.worktree && existsSync65(live.worktree)) return live.worktree;
230630
+ if (live.worktree && existsSync66(live.worktree)) return live.worktree;
230689
230631
  const settings = await this.store.getSettings();
230690
230632
  const acquisitionTask = live.worktree ? { ...live, worktree: void 0, sessionFile: void 0 } : live;
230691
230633
  const acquired = await this.ensureGraphCustomNodeWorktree(acquisitionTask, settings, "planning");
@@ -230699,8 +230641,8 @@ ${info.feedback}`, revisionKey),
230699
230641
  if (!requirement.requiresWorktree) return;
230700
230642
  const live = await this.store.getTask(nodeTask.id);
230701
230643
  const executionCodeNode = node.kind === "code";
230702
- if (live.worktree && existsSync65(live.worktree) && !executionCodeNode) return;
230703
- const taskForAcquisition = live.worktree && !existsSync65(live.worktree) ? { ...live, worktree: void 0, sessionFile: void 0 } : live;
230644
+ if (live.worktree && existsSync66(live.worktree) && !executionCodeNode) return;
230645
+ const taskForAcquisition = live.worktree && !existsSync66(live.worktree) ? { ...live, worktree: void 0, sessionFile: void 0 } : live;
230704
230646
  if (live.worktree) {
230705
230647
  await this.store.logEntry(
230706
230648
  live.id,
@@ -230826,7 +230768,7 @@ ${info.feedback}`, revisionKey),
230826
230768
  const nodeDisplayName = typeof cfg.name === "string" && cfg.name.trim() ? cfg.name.trim() : node.id;
230827
230769
  const isPlanReviewNode = node.id === "plan-review-step" || nodeDisplayName === "Plan Review" || optionalGroupId === "plan-review";
230828
230770
  if (!this.workspaceConfig) {
230829
- const recordedWorktreeMissing = Boolean(executionTarget.worktree) && !existsSync65(executionTarget.worktree);
230771
+ const recordedWorktreeMissing = Boolean(executionTarget.worktree) && !existsSync66(executionTarget.worktree);
230830
230772
  const shouldAcquire = !executionTarget.worktree || recordedWorktreeMissing && isPlanReviewNode;
230831
230773
  if (shouldAcquire) {
230832
230774
  if (recordedWorktreeMissing) {
@@ -232500,75 +232442,16 @@ Graph value: ${failureValue}` : ""}`, budget.key),
232500
232442
  );
232501
232443
  }
232502
232444
  }
232503
- /*
232504
- FNXC:HonestBlockedExit 2026-08-02-01:30:
232505
- Agents often log `BLOCKED: … actively claimed by PR #N` without calling fn_task_done.
232506
- Without promotion, incomplete-step graph resume requeues the card and thrash restarts
232507
- (FN-8700). Promote claim/external blocks to a durable failed park here.
232508
- */
232509
- async parkDurableBlockedFromRecentLog(live) {
232510
- const recent = [...live.log ?? []].reverse().find((entry) => {
232511
- const action = entry.action ?? "";
232512
- return action.startsWith("BLOCKED:") || action.includes("durable external block");
232513
- });
232514
- if (!recent?.action) return false;
232515
- const reason = recent.action.startsWith("BLOCKED:") ? recent.action.slice("BLOCKED:".length).trim() : recent.action;
232516
- const classification = classifyBlockedExit(reason, []);
232517
- if (classification.allowAutoReplan) return false;
232518
- const thrashCount = countBlockedThrashHits(live.log, classification.thrashSignature) + 1;
232519
- const thrashExhausted = thrashCount >= BLOCKED_THRASH_LIMIT;
232520
- const parkError = thrashExhausted ? `BLOCKED: ${reason} [thrash-exhausted after ${thrashCount} identical durable blocks]` : `BLOCKED: ${reason}`;
232521
- const metaPatch = buildExternalBlockMetadataPatch(classification, thrashCount);
232522
- await this.store.updateTask(live.id, {
232523
- status: "failed",
232524
- error: parkError,
232525
- paused: false,
232526
- pausedByAgentId: null,
232527
- sourceMetadataPatch: metaPatch
232528
- }, this.getRunContextFor(live.id));
232529
- await this.store.logEntry(
232530
- live.id,
232531
- thrashExhausted ? `${parkError} \u2014 promoted from session log; thrash-exhausted, no auto-requeue` : `${parkError} \u2014 promoted from session log to durable external block park (class=${classification.class})`,
232532
- void 0,
232533
- this.getRunContextFor(live.id)
232534
- );
232535
- await this.store.recordRunAuditEvent?.({
232536
- taskId: live.id,
232537
- agentId: "executor",
232538
- runId: generateSyntheticRunId("execution-blocked-log-promote", live.id),
232539
- domain: "database",
232540
- mutationType: "task:execution-blocked-parked",
232541
- target: live.id,
232542
- metadata: {
232543
- taskId: live.id,
232544
- blockedBy: [],
232545
- hasReason: true,
232546
- parkedAs: "failed",
232547
- blockedClass: classification.class,
232548
- thrashCount,
232549
- thrashExhausted,
232550
- prNumbers: classification.prNumbers,
232551
- source: "session-log-promote"
232552
- }
232553
- });
232554
- executorLog.warn(
232555
- `${live.id}: promoted durable BLOCKED from session log (class=${classification.class}; thrash=${thrashCount})`
232556
- );
232557
- return true;
232558
- }
232559
232445
  async routeGraphFailureToExecutionResume(live, failedNode, failureValue, resumeLanesMemo) {
232560
232446
  if (live.deletedAt) return false;
232561
232447
  if (live.paused || live.userPaused === true) return false;
232562
232448
  if ((await resolveTerminalColumnsFor(this.store, live.id)).includes(live.column)) return false;
232563
- if (isDurableBlockedTask(live) || isDurableBlockedError(live.error)) {
232449
+ if (isDurableBlockedTask(live)) {
232564
232450
  executorLog.log(
232565
- `${live.id}: graph failure resume skipped \u2014 durable BLOCKED park honored (class from error/metadata)`
232451
+ `${live.id}: graph failure resume skipped \u2014 durable BLOCKED park honored (task-dependency block)`
232566
232452
  );
232567
232453
  return false;
232568
232454
  }
232569
- if (await this.parkDurableBlockedFromRecentLog(live)) {
232570
- return false;
232571
- }
232572
232455
  if (failedNode === COMPLETION_SUMMARY_NODE_ID) return false;
232573
232456
  const incompleteSteps = hasNonTerminalWorkflowSteps(live);
232574
232457
  const implementationIncompleteMergeFailure = this.isMergeGraphFailure(failedNode) && failureValue === "implementation-incomplete";
@@ -233749,7 +233632,7 @@ ${summary}`,
233749
233632
  executorLog.warn(`\u26A1 ${task.id} transient error \u2014 retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}: ${errorMessage5}`);
233750
233633
  await this.store.logEntry(task.id, `Transient error (retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}): ${errorMessage5}`, void 0, this.getRunContextFor(task.id));
233751
233634
  }
233752
- if (worktreePath && existsSync65(worktreePath)) {
233635
+ if (worktreePath && existsSync66(worktreePath)) {
233753
233636
  try {
233754
233637
  const settings2 = await this.store.getSettings();
233755
233638
  await removeWorktree({
@@ -233830,7 +233713,7 @@ ${summary}`,
233830
233713
  const settings2 = await this.store.getSettings();
233831
233714
  const preserveProgress = settings2.preserveProgressOnStuckRequeue !== false;
233832
233715
  await this.resetStepsIfWorkLost(latestTask);
233833
- if (worktreePath && existsSync65(worktreePath)) {
233716
+ if (worktreePath && existsSync66(worktreePath)) {
233834
233717
  try {
233835
233718
  await removeWorktree({
233836
233719
  worktreePath,
@@ -234113,7 +233996,7 @@ ${summary}`,
234113
233996
  nodeId: detail.effectiveNodeId ?? detail.nodeId ?? null,
234114
233997
  agentId: engineRunContext.agentId ?? null
234115
233998
  });
234116
- let isResuming = !!task.sessionFile && existsSync65(task.sessionFile);
233999
+ let isResuming = !!task.sessionFile && existsSync66(task.sessionFile);
234117
234000
  if (isResuming) {
234118
234001
  const persistedWorktreePath = await extractPersistedSessionWorktreePath(task.sessionFile, this.rootDir, settings);
234119
234002
  if (!isSessionWorktreeCompatible(persistedWorktreePath, worktreePath)) {
@@ -234894,7 +234777,7 @@ ${summary}`,
234894
234777
  return;
234895
234778
  } else {
234896
234779
  executorLog.log(`${task.id} paused \u2014 moving to todo`);
234897
- if (worktreePath && existsSync65(worktreePath)) {
234780
+ if (worktreePath && existsSync66(worktreePath)) {
234898
234781
  try {
234899
234782
  const settings2 = await this.store.getSettings();
234900
234783
  await removeWorktree({
@@ -235291,7 +235174,7 @@ ${summary}`,
235291
235174
  executorLog.warn(`\u26A1 ${task.id} transient error \u2014 retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}: ${errorMessage5}`);
235292
235175
  await this.store.logEntry(task.id, `Transient error (retry ${attempt}/${MAX_RECOVERY_RETRIES} in ${delay6}): ${errorMessage5}`, void 0, this.getRunContextFor(task.id));
235293
235176
  }
235294
- if (worktreePath && existsSync65(worktreePath)) {
235177
+ if (worktreePath && existsSync66(worktreePath)) {
235295
235178
  try {
235296
235179
  const settings2 = await this.store.getSettings();
235297
235180
  await removeWorktree({
@@ -235427,7 +235310,7 @@ ${summary}`,
235427
235310
  const settings2 = await this.store.getSettings();
235428
235311
  const preserveProgress = settings2.preserveProgressOnStuckRequeue !== false;
235429
235312
  await this.resetStepsIfWorkLost(latestTask);
235430
- if (worktreePath && existsSync65(worktreePath)) {
235313
+ if (worktreePath && existsSync66(worktreePath)) {
235431
235314
  try {
235432
235315
  await removeWorktree({
235433
235316
  worktreePath,
@@ -235854,7 +235737,7 @@ ${summary}`,
235854
235737
  for (const repoRel of Object.keys(workspaceWorktrees).sort()) {
235855
235738
  const repo = workspaceWorktrees[repoRel];
235856
235739
  const expectedBranch = repo.branch || canonicalFusionBranchName(task.id);
235857
- if (!existsSync65(repo.worktreePath)) {
235740
+ if (!existsSync66(repo.worktreePath)) {
235858
235741
  executorLog.log(`${task.id}: workspace worktree for ${repoRel} not found at ${repo.worktreePath} \u2014 skipping git validation`);
235859
235742
  continue;
235860
235743
  }
@@ -235986,7 +235869,7 @@ ${summary}`,
235986
235869
  expected: `resolvable task worktree under ${resolveWorktreesDir(this.rootDir, settings)}/*`
235987
235870
  };
235988
235871
  }
235989
- if (!existsSync65(worktreePath)) {
235872
+ if (!existsSync66(worktreePath)) {
235990
235873
  executorLog.log(
235991
235874
  `${task.id}: worktree directory not found at ${worktreePath} \u2014 skipping git validation for task completion`
235992
235875
  );
@@ -236315,10 +236198,10 @@ ${summary}`,
236315
236198
  { description: '"completed" (default) finishes the task; "blocked" honestly parks it as failed because the work cannot proceed. Use "blocked" instead of skipping steps + completing when you are stuck.' }
236316
236199
  )),
236317
236200
  blockedBy: Type7.Optional(Type7.Array(Type7.String(), {
236318
- description: 'When outcome="blocked": task IDs (e.g. ["FN-8145"]) and/or PR refs (e.g. ["pr:2398"]) that must clear before this task can proceed. Task IDs become real dependency edges; PR refs are stored as external blockers (durable park until the PR merges/closes).'
236201
+ description: 'When outcome="blocked": Fusion task IDs (e.g. ["FN-8145"]) that must complete before this task can proceed. Task IDs become real dependency edges. Open GitHub PRs are not valid blockers.'
236319
236202
  })),
236320
236203
  reason: Type7.Optional(Type7.String({
236321
- description: 'Required when outcome="blocked": concrete explanation of what is blocking the work and what is needed to unblock it. File-claim / open-PR collisions should name the PR (e.g. "actively claimed by PR #2398").'
236204
+ description: 'Required when outcome="blocked": concrete explanation of what is blocking the work and what is needed to unblock it.'
236322
236205
  }))
236323
236206
  }),
236324
236207
  execute: async (_id, params) => {
@@ -236377,7 +236260,7 @@ ${summary}`,
236377
236260
  }, this.getRunContextFor(taskId));
236378
236261
  await store.logEntry(
236379
236262
  taskId,
236380
- thrashExhausted ? `${parkError} \u2014 durable external block thrash-exhausted (signature=${classification.thrashSignature}); parked failed, no auto-requeue` : classification.externalBlockers.length > 0 ? `${parkError} \u2014 durable external block (${classification.class}; pr=${classification.prNumbers.join(",") || "none"}; tasks=${blockedByIds.join(",") || "none"}) \u2014 parked failed (honest blocked exit; steps preserved)` : `${parkError} \u2014 recorded dependencies: ${blockedByIds.join(", ")} \u2014 parked failed (honest blocked exit; steps preserved)`,
236263
+ thrashExhausted ? `${parkError} \u2014 durable external block thrash-exhausted (signature=${classification.thrashSignature}); parked failed, no auto-requeue` : `${parkError} \u2014 recorded dependencies: ${blockedByIds.join(", ")} \u2014 parked failed (honest blocked exit; steps preserved)`,
236381
236264
  void 0,
236382
236265
  this.getRunContextFor(taskId)
236383
236266
  );
@@ -236396,18 +236279,17 @@ ${summary}`,
236396
236279
  parkedAs: autoReplanPark ? "auto-replan" : "failed",
236397
236280
  blockedClass: classification.class,
236398
236281
  thrashCount,
236399
- thrashExhausted,
236400
- prNumbers: classification.prNumbers
236282
+ thrashExhausted
236401
236283
  }
236402
236284
  });
236403
236285
  await this.persistTokenUsage(taskId);
236404
236286
  executorLog.log(
236405
- `\u26D4 ${taskId} ${autoReplanPark ? "parked for automatic replan via blocked exit (plan defect, no dependencies)" : thrashExhausted ? `parked failed via blocked thrash-exhaustion (class=${classification.class})` : `parked failed via durable blocked exit (class=${classification.class}; blockedBy tasks: ${blockedByIds.join(", ") || "none"}; pr: ${classification.prNumbers.join(",") || "none"})`}`
236287
+ `\u26D4 ${taskId} ${autoReplanPark ? "parked for automatic replan via blocked exit (plan defect, no dependencies)" : thrashExhausted ? `parked failed via blocked thrash-exhaustion (class=${classification.class})` : `parked failed via durable blocked exit (class=${classification.class}; blockedBy tasks: ${blockedByIds.join(", ") || "none"})`}`
236406
236288
  );
236407
236289
  return {
236408
236290
  content: [{
236409
236291
  type: "text",
236410
- text: autoReplanPark ? "Task parked as blocked with no external/file-claim blocker \u2014 queued for automatic replan so the plan can resolve the conflict. Steps left in their true statuses; no completion recorded." : thrashExhausted ? "Task parked as blocked (failed) after repeated identical durable blocks \u2014 no further automatic retries. Resolve the external claim/PR or replan manually." : blockedByIds.length > 0 ? `Task parked as blocked (failed). Recorded ${blockedByIds.length} blocking task dependency(ies); it will requeue once they complete. Steps left in their true statuses; no completion recorded.` : classification.prNumbers.length > 0 ? `Task parked as blocked (failed) on open PR #${classification.prNumbers.join(", #")}. It will not auto-replan or re-execute until that claim clears or an operator retries. Steps preserved.` : "Task parked as blocked (failed) on a durable external/file-claim blocker. No automatic replan. Steps preserved."
236292
+ text: autoReplanPark ? "Task parked as blocked with no blocking task dependencies \u2014 queued for automatic replan so the plan can resolve the conflict. Steps left in their true statuses; no completion recorded." : thrashExhausted ? "Task parked as blocked (failed) after repeated identical durable blocks \u2014 no further automatic retries. Resolve the blocking tasks or replan manually." : `Task parked as blocked (failed). Recorded ${blockedByIds.length} blocking task dependency(ies); it will requeue once they complete. Steps left in their true statuses; no completion recorded.`
236411
236293
  }],
236412
236294
  details: {}
236413
236295
  };
@@ -238465,7 +238347,7 @@ ${detectedQuestion}
238465
238347
  * rather than fail the task permanently.
238466
238348
  */
238467
238349
  async resolveWorktreeStartPoint(startPoint, taskId) {
238468
- const command = isAbsolute18(startPoint) && existsSync65(startPoint) ? `git -C "${startPoint}" rev-parse --verify HEAD^{commit}` : `git rev-parse --verify "${startPoint}^{commit}"`;
238350
+ const command = isAbsolute18(startPoint) && existsSync66(startPoint) ? `git -C "${startPoint}" rev-parse --verify HEAD^{commit}` : `git rev-parse --verify "${startPoint}^{commit}"`;
238469
238351
  try {
238470
238352
  const { stdout } = await execAsync36(command, { cwd: this.rootDir });
238471
238353
  return stdout.trim() || startPoint;
@@ -238688,7 +238570,7 @@ ${detectedQuestion}
238688
238570
  throw error3;
238689
238571
  }
238690
238572
  };
238691
- if (existsSync65(path14)) {
238573
+ if (existsSync66(path14)) {
238692
238574
  const isRegistered = await this.isRegisteredWorktree(path14);
238693
238575
  if (!isRegistered) {
238694
238576
  await this.store.logEntry(
@@ -239304,7 +239186,7 @@ ${detectedQuestion}
239304
239186
  const stillRegistered = await isRegisteredGitWorktree2(this.rootDir, worktreePath).catch(() => true);
239305
239187
  const activeOwner2 = await this.findActiveWorktreeOwner(worktreePath, taskId).catch(() => "unknown");
239306
239188
  let safeToRemove = isInsideWorktreesDir(this.rootDir, worktreePath, settings) && !stillRegistered && activeOwner2 === null;
239307
- if (safeToRemove && existsSync65(worktreePath)) {
239189
+ if (safeToRemove && existsSync66(worktreePath)) {
239308
239190
  try {
239309
239191
  if (lstatSync3(worktreePath).isSymbolicLink()) {
239310
239192
  safeToRemove = false;
@@ -239332,7 +239214,7 @@ ${detectedQuestion}
239332
239214
  const pruneMsg = pruneErr instanceof Error ? pruneErr.message : String(pruneErr);
239333
239215
  executorLog.warn(`${taskId}: git worktree prune failed during stale-path cleanup of ${worktreePath}: ${pruneMsg}`);
239334
239216
  }
239335
- if (existsSync65(worktreePath)) {
239217
+ if (existsSync66(worktreePath)) {
239336
239218
  try {
239337
239219
  await rm12(worktreePath, { recursive: true, force: true });
239338
239220
  } catch (rmErr) {
@@ -239779,7 +239661,7 @@ ${detectedQuestion}
239779
239661
  this.clearPausedAborted(taskId);
239780
239662
  await this.resetStepsIfWorkLost(latestTask);
239781
239663
  let cleanupFailed = false;
239782
- if (worktreePath && existsSync65(worktreePath)) {
239664
+ if (worktreePath && existsSync66(worktreePath)) {
239783
239665
  try {
239784
239666
  await removeWorktree({
239785
239667
  worktreePath,
@@ -243866,7 +243748,7 @@ var init_overseer_noop_finalize_veto = __esm({
243866
243748
 
243867
243749
  // ../engine/src/merger-ai-worktree.ts
243868
243750
  import { execFile as execFile27 } from "node:child_process";
243869
- import { appendFileSync as appendFileSync2, existsSync as existsSync66, mkdirSync as mkdirSync11, readdirSync as readdirSync12, readFileSync as readFileSync24, realpathSync as realpathSync11, rmSync as rmSync9, statSync as statSync13 } from "node:fs";
243751
+ import { appendFileSync as appendFileSync2, existsSync as existsSync67, mkdirSync as mkdirSync11, readdirSync as readdirSync12, readFileSync as readFileSync24, realpathSync as realpathSync11, rmSync as rmSync9, statSync as statSync13 } from "node:fs";
243870
243752
  import { rm as rm13 } from "node:fs/promises";
243871
243753
  import { tmpdir as tmpdir10 } from "node:os";
243872
243754
  import { isAbsolute as isAbsolute19, join as join79, relative as relative17 } from "node:path";
@@ -243901,7 +243783,7 @@ function isBenignAbsentWorktreeError(err) {
243901
243783
  }
243902
243784
  function ensureAiMergeRootIgnored(projectRootDir, settings) {
243903
243785
  const excludePath = join79(projectRootDir, ".git", "info", "exclude");
243904
- if (!existsSync66(excludePath)) return;
243786
+ if (!existsSync67(excludePath)) return;
243905
243787
  try {
243906
243788
  const current = readFileSync24(excludePath, "utf-8");
243907
243789
  const legacyAiMergeRoot = resolveLegacyAiMergeRootPath(projectRootDir);
@@ -244032,7 +243914,7 @@ async function cleanupAiMergeWorktree(input) {
244032
243914
  const cleanupMetadata = { taskId, mergeRoot: canonicalRoot, requestedMergeRoot: mergeRoot };
244033
243915
  let alreadyAbsent = false;
244034
243916
  if (worktreeAdded) {
244035
- if (!existsSync66(canonicalRoot) && !existsSync66(mergeRoot)) {
243917
+ if (!existsSync67(canonicalRoot) && !existsSync67(mergeRoot)) {
244036
243918
  alreadyAbsent = true;
244037
243919
  await log43(`AI merge cleanup: worktree ${canonicalRoot} was already absent before git removal; treating cleanup as idempotent`);
244038
243920
  await audit.git({ type: "merge:ai-worktree-cleanup", target: canonicalRoot, metadata: { ...cleanupMetadata, phase: "git-remove", success: true, alreadyAbsent: true, idempotent: true, code: "ENOENT" } });
@@ -250354,12 +250236,12 @@ The note must be specific (what/where/why). Prefer citing File Scope, PROMPT, a
250354
250236
  });
250355
250237
 
250356
250238
  // ../engine/src/overseer-watchdog.ts
250357
- import { existsSync as existsSync67, readFileSync as readFileSync25 } from "node:fs";
250239
+ import { existsSync as existsSync68, readFileSync as readFileSync25 } from "node:fs";
250358
250240
  import { dirname as dirname34, join as join82, relative as relative18, resolve as resolve40, sep as sep11 } from "node:path";
250359
250241
  import { homedir as homedir12 } from "node:os";
250360
250242
  function defaultReadText(path14) {
250361
250243
  try {
250362
- if (!existsSync67(path14)) return null;
250244
+ if (!existsSync68(path14)) return null;
250363
250245
  return readFileSync25(path14, "utf8");
250364
250246
  } catch {
250365
250247
  return null;
@@ -256160,7 +256042,7 @@ var init_adapters = __esm({
256160
256042
  });
256161
256043
 
256162
256044
  // ../engine/src/cli-agent/resume-coordinator.ts
256163
- import { existsSync as existsSync68 } from "node:fs";
256045
+ import { existsSync as existsSync69 } from "node:fs";
256164
256046
  import { execFile as execFile30 } from "node:child_process";
256165
256047
  import { promisify as promisify62 } from "node:util";
256166
256048
  async function defaultIsWorktreeDirty(worktreePath) {
@@ -256205,7 +256087,7 @@ var init_resume_coordinator = __esm({
256205
256087
  this.reattachTelemetry = opts.reattachTelemetry;
256206
256088
  this.maxResumeAttempts = opts.maxResumeAttempts ?? DEFAULT_MAX_RESUME_ATTEMPTS;
256207
256089
  this.resumeBackoffBaseMs = opts.resumeBackoffBaseMs ?? DEFAULT_RESUME_BACKOFF_BASE_MS;
256208
- this.worktreeExists = opts.worktreeExists ?? ((p2) => existsSync68(p2));
256090
+ this.worktreeExists = opts.worktreeExists ?? ((p2) => existsSync69(p2));
256209
256091
  this.isWorktreeDirty = opts.isWorktreeDirty ?? defaultIsWorktreeDirty;
256210
256092
  this.log = opts.log ?? (() => {
256211
256093
  });
@@ -280583,11 +280465,11 @@ var init_task_lookup_error = __esm({
280583
280465
  });
280584
280466
 
280585
280467
  // ../dashboard/src/cli-package-version.ts
280586
- import { existsSync as existsSync69, readFileSync as readFileSync26 } from "node:fs";
280468
+ import { existsSync as existsSync70, readFileSync as readFileSync26 } from "node:fs";
280587
280469
  import { dirname as dirname37, resolve as resolve43 } from "node:path";
280588
280470
  import { fileURLToPath as fileURLToPath5 } from "node:url";
280589
280471
  function readPackageVersion(pkgPath, packageNames) {
280590
- if (!existsSync69(pkgPath)) {
280472
+ if (!existsSync70(pkgPath)) {
280591
280473
  return null;
280592
280474
  }
280593
280475
  try {
@@ -294043,7 +293925,7 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
294043
293925
  };
294044
293926
  router.get("/tasks/:id/stranded-refinement", async (req, res) => {
294045
293927
  try {
294046
- const { existsSync: existsSync118 } = await import("node:fs");
293928
+ const { existsSync: existsSync119 } = await import("node:fs");
294047
293929
  const { join: join153 } = await import("node:path");
294048
293930
  const { store: scopedStore } = await getProjectContext2(req);
294049
293931
  const task = await scopedStore.getTask(req.params.id);
@@ -294062,7 +293944,7 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
294062
293944
  ageMs: Math.max(0, Date.now() - Date.parse(task.createdAt))
294063
293945
  };
294064
293946
  const promptPath = join153(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
294065
- const promptExists = existsSync118(promptPath);
293947
+ const promptExists = existsSync119(promptPath);
294066
293948
  const dependencyDetails = await Promise.all((task.dependencies ?? []).map(async (dependencyId) => {
294067
293949
  try {
294068
293950
  const depTask = await scopedStore.getTask(dependencyId);
@@ -298823,7 +298705,7 @@ __export(chat_exports, {
298823
298705
  });
298824
298706
  import { EventEmitter as EventEmitter40 } from "node:events";
298825
298707
  import { randomUUID as randomUUID50 } from "node:crypto";
298826
- import { existsSync as existsSync70 } from "node:fs";
298708
+ import { existsSync as existsSync71 } from "node:fs";
298827
298709
  import { join as join90, resolve as resolve48, relative as relative20 } from "node:path";
298828
298710
  import { SessionManager as SessionManager3 } from "@earendil-works/pi-coding-agent";
298829
298711
  function __getChatDiagnostics() {
@@ -299030,7 +298912,7 @@ function createTaskVerificationTools(taskStore, actionGateContext) {
299030
298912
  const profile = typeof raw.profile === "string" ? raw.profile : "verify:fast";
299031
298913
  if (!taskId || !profiles.has(profile)) return { content: [{ type: "text", text: "ERROR: task_id and an allowlisted profile are required; raw commands are not accepted." }], isError: true, details: {} };
299032
298914
  const task = await taskStore.getTask(taskId);
299033
- if (!task || !(await wipColumnsForTask(taskStore, taskId)).has(task.column) || !task.worktree || !existsSync70(task.worktree)) return { content: [{ type: "text", text: "ERROR: verification requires an in-progress task with a live executor worktree." }], isError: true, details: {} };
298915
+ if (!task || !(await wipColumnsForTask(taskStore, taskId)).has(task.column) || !task.worktree || !existsSync71(task.worktree)) return { content: [{ type: "text", text: "ERROR: verification requires an in-progress task with a live executor worktree." }], isError: true, details: {} };
299034
298916
  const settings = await taskStore.getSettings();
299035
298917
  const command = profile === "verify:fast" ? "pnpm verify:fast" : typeof settings.testCommand === "string" ? settings.testCommand : "";
299036
298918
  if (!command) return { content: [{ type: "text", text: "ERROR: the selected verification profile is not configured." }], isError: true, details: {} };
@@ -299861,7 +299743,7 @@ When you need structured input, or whenever you present options, choices, or a d
299861
299743
  * keep the CLI session stable across user messages.
299862
299744
  */
299863
299745
  async resolveCliSessionManager(session) {
299864
- if (session.cliSessionFile && existsSync70(session.cliSessionFile)) {
299746
+ if (session.cliSessionFile && existsSync71(session.cliSessionFile)) {
299865
299747
  try {
299866
299748
  return SessionManager3.open(session.cliSessionFile);
299867
299749
  } catch (err) {
@@ -351746,7 +351628,7 @@ var init_cli_spawn = __esm({
351746
351628
  // ../../plugins/fusion-plugin-hermes-runtime/src/fusion-skill-install.ts
351747
351629
  import {
351748
351630
  cpSync as cpSync2,
351749
- existsSync as existsSync72,
351631
+ existsSync as existsSync73,
351750
351632
  lstatSync as lstatSync4,
351751
351633
  mkdirSync as mkdirSync13,
351752
351634
  readFileSync as readFileSync28,
@@ -351776,7 +351658,7 @@ function getFusionSkillSourceCandidates(moduleUrl = import.meta.url) {
351776
351658
  function resolveBundledFusionSkillSource() {
351777
351659
  const candidates = getFusionSkillSourceCandidates();
351778
351660
  for (const candidate of candidates) {
351779
- if (existsSync72(join97(candidate, "SKILL.md"))) return candidate;
351661
+ if (existsSync73(join97(candidate, "SKILL.md"))) return candidate;
351780
351662
  }
351781
351663
  return null;
351782
351664
  }
@@ -351794,7 +351676,7 @@ function installFusionSkillIntoHermesHome(options = {}) {
351794
351676
  try {
351795
351677
  mkdirSync13(dirname40(targetDir), { recursive: true });
351796
351678
  let replaced = false;
351797
- if (existsSync72(targetDir) || isBrokenSymlink(targetDir)) {
351679
+ if (existsSync73(targetDir) || isBrokenSymlink(targetDir)) {
351798
351680
  const stat20 = lstatSync4(targetDir);
351799
351681
  if (stat20.isSymbolicLink()) {
351800
351682
  const currentTarget = safeReadlink(targetDir);
@@ -351865,14 +351747,14 @@ function safeReadlink(path14) {
351865
351747
  function isBrokenSymlink(path14) {
351866
351748
  try {
351867
351749
  const stat20 = lstatSync4(path14);
351868
- return stat20.isSymbolicLink() && !existsSync72(path14);
351750
+ return stat20.isSymbolicLink() && !existsSync73(path14);
351869
351751
  } catch {
351870
351752
  return false;
351871
351753
  }
351872
351754
  }
351873
351755
  function looksLikePriorFusionInstall(path14) {
351874
351756
  const skillMd = join97(path14, "SKILL.md");
351875
- if (!existsSync72(skillMd)) return false;
351757
+ if (!existsSync73(skillMd)) return false;
351876
351758
  try {
351877
351759
  const body = readFileSync28(skillMd, "utf-8");
351878
351760
  return /\bfusion\b/i.test(body) && /\bskill\b/i.test(body);
@@ -351883,7 +351765,7 @@ function looksLikePriorFusionInstall(path14) {
351883
351765
  function looksLikeFusionSkillTarget(path14) {
351884
351766
  if (!path14) return false;
351885
351767
  if (basename28(path14).toLowerCase() === FUSION_SKILL_NAME) return true;
351886
- return existsSync72(join97(path14, "SKILL.md"));
351768
+ return existsSync73(join97(path14, "SKILL.md"));
351887
351769
  }
351888
351770
  var FUSION_SKILL_NAME;
351889
351771
  var init_fusion_skill_install = __esm({
@@ -354906,7 +354788,7 @@ var init_provider2 = __esm({
354906
354788
  });
354907
354789
 
354908
354790
  // ../../plugins/fusion-plugin-grok-runtime/src/acp/cli-spawn.ts
354909
- import { existsSync as existsSync74 } from "node:fs";
354791
+ import { existsSync as existsSync75 } from "node:fs";
354910
354792
  import { dirname as dirname42, isAbsolute as isAbsolute28, join as join101, resolve as resolve59 } from "node:path";
354911
354793
  import { fileURLToPath as fileURLToPath9 } from "node:url";
354912
354794
  function asTrimmedString(value) {
@@ -354929,7 +354811,7 @@ function bundledClaudeBridgeBinPath(pluginRoot = pluginRootDir()) {
354929
354811
  }
354930
354812
  function resolveBundledClaudeBridgeBinary(options = {}) {
354931
354813
  const root = options.pluginRoot ?? pluginRootDir();
354932
- const exists2 = options.exists ?? existsSync74;
354814
+ const exists2 = options.exists ?? existsSync75;
354933
354815
  const candidate = bundledClaudeBridgeBinPath(root);
354934
354816
  if (!exists2(candidate)) {
354935
354817
  return {
@@ -356278,7 +356160,7 @@ var init_mcp_forwarding = __esm({
356278
356160
  // ../../plugins/fusion-plugin-grok-runtime/src/skill-loader.ts
356279
356161
  import {
356280
356162
  cpSync as cpSync3,
356281
- existsSync as existsSync75,
356163
+ existsSync as existsSync76,
356282
356164
  mkdirSync as mkdirSync14,
356283
356165
  mkdtempSync as mkdtempSync3,
356284
356166
  readdirSync as readdirSync14,
@@ -356291,7 +356173,7 @@ import { tmpdir as tmpdir16 } from "node:os";
356291
356173
  import { basename as basename30, dirname as dirname44, join as join103, resolve as resolve61 } from "node:path";
356292
356174
  import { fileURLToPath as fileURLToPath10 } from "node:url";
356293
356175
  function isSkillDir(dir2) {
356294
- return existsSync75(join103(dir2, "SKILL.md"));
356176
+ return existsSync76(join103(dir2, "SKILL.md"));
356295
356177
  }
356296
356178
  function pushUnique(out, candidate) {
356297
356179
  if (!candidate) return;
@@ -356355,7 +356237,7 @@ function resolveBundledFusionSkillSource2(moduleUrl = import.meta.url) {
356355
356237
  function installSkillDir(sourceDir, targetDir) {
356356
356238
  if (!isSkillDir(sourceDir)) return false;
356357
356239
  mkdirSync14(dirname44(targetDir), { recursive: true });
356358
- if (existsSync75(targetDir)) {
356240
+ if (existsSync76(targetDir)) {
356359
356241
  rmSync11(targetDir, { recursive: true, force: true });
356360
356242
  }
356361
356243
  try {
@@ -356371,7 +356253,7 @@ function installSkillDir(sourceDir, targetDir) {
356371
356253
  }
356372
356254
  }
356373
356255
  function collectSkillsFromRoot(root, out) {
356374
- if (!existsSync75(root)) return;
356256
+ if (!existsSync76(root)) return;
356375
356257
  if (isSkillDir(root)) {
356376
356258
  out.set(basename30(root), root);
356377
356259
  return;
@@ -356410,7 +356292,7 @@ function stageGrokSessionSkills(options = {}) {
356410
356292
  installSkillDir(source, join103(skillsDir, name2));
356411
356293
  }
356412
356294
  for (const [name2, source] of installed) {
356413
- if (!existsSync75(join103(skillsDir, name2))) {
356295
+ if (!existsSync76(join103(skillsDir, name2))) {
356414
356296
  installSkillDir(source, join103(skillsDir, name2));
356415
356297
  }
356416
356298
  }
@@ -356479,7 +356361,7 @@ var init_skill_loader = __esm({
356479
356361
 
356480
356362
  // ../../plugins/fusion-plugin-grok-runtime/src/tool-bridge.ts
356481
356363
  import { createServer as createServer2 } from "node:http";
356482
- import { existsSync as existsSync76, writeFileSync as writeFileSync15 } from "node:fs";
356364
+ import { existsSync as existsSync77, writeFileSync as writeFileSync15 } from "node:fs";
356483
356365
  import { tmpdir as tmpdir17 } from "node:os";
356484
356366
  import { dirname as dirname45, join as join104 } from "node:path";
356485
356367
  import { fileURLToPath as fileURLToPath11 } from "node:url";
@@ -356525,7 +356407,7 @@ async function startFusionToolBridge(tools) {
356525
356407
  const defs = toolsToMcpToolDefs2(tools);
356526
356408
  if (defs.length === 0) return null;
356527
356409
  const serverPath = fusionToolsMcpServerPath();
356528
- if (!existsSync76(serverPath)) {
356410
+ if (!existsSync77(serverPath)) {
356529
356411
  throw missingMcpSchemaServerError(serverPath);
356530
356412
  }
356531
356413
  const byName = /* @__PURE__ */ new Map();
@@ -356966,7 +356848,7 @@ var init_src11 = __esm({
356966
356848
  });
356967
356849
 
356968
356850
  // ../../plugins/fusion-plugin-claude-runtime/src/acp/cli-spawn.ts
356969
- import { existsSync as existsSync77 } from "node:fs";
356851
+ import { existsSync as existsSync78 } from "node:fs";
356970
356852
  import { dirname as dirname46, isAbsolute as isAbsolute29, join as join105, resolve as resolve62 } from "node:path";
356971
356853
  import { fileURLToPath as fileURLToPath12 } from "node:url";
356972
356854
  function asTrimmedString2(value) {
@@ -356989,7 +356871,7 @@ function bundledClaudeBridgeBinPath2(pluginRoot = pluginRootDir2()) {
356989
356871
  }
356990
356872
  function resolveBundledClaudeBridgeBinary2(options = {}) {
356991
356873
  const root = options.pluginRoot ?? pluginRootDir2();
356992
- const exists2 = options.exists ?? existsSync77;
356874
+ const exists2 = options.exists ?? existsSync78;
356993
356875
  const candidate = bundledClaudeBridgeBinPath2(root);
356994
356876
  if (!exists2(candidate)) {
356995
356877
  return {
@@ -358224,7 +358106,7 @@ var init_acp2 = __esm({
358224
358106
 
358225
358107
  // ../../plugins/fusion-plugin-claude-runtime/src/cli-spawn.ts
358226
358108
  import { spawn as spawn21 } from "node:child_process";
358227
- import { existsSync as existsSync78 } from "node:fs";
358109
+ import { existsSync as existsSync79 } from "node:fs";
358228
358110
  import { basename as basename32, dirname as dirname48, isAbsolute as isAbsolute30, join as join107, resolve as resolve64 } from "node:path";
358229
358111
  import { fileURLToPath as fileURLToPath13 } from "node:url";
358230
358112
  function pluginRootDir3() {
@@ -358236,7 +358118,7 @@ function bundledClaudeBridgeBinPath3(pluginRoot = pluginRootDir3()) {
358236
358118
  }
358237
358119
  function resolveBundledClaudeBridgeBinary3(options = {}) {
358238
358120
  const candidate = bundledClaudeBridgeBinPath3(options.pluginRoot ?? pluginRootDir3());
358239
- const exists2 = options.exists ?? existsSync78;
358121
+ const exists2 = options.exists ?? existsSync79;
358240
358122
  if (!exists2(candidate) || !isAbsolute30(candidate)) return { kind: "not_resolved", requested: CLAUDE_CODE_CLI_ACP_BINARY3, path: candidate, reason: `Staged ${CLAUDE_CODE_CLI_ACP_BINARY3} bridge was not found at ${candidate}` };
358241
358123
  return { kind: "resolved", requested: CLAUDE_CODE_CLI_ACP_BINARY3, path: candidate };
358242
358124
  }
@@ -358399,7 +358281,7 @@ var init_mcp_forwarding2 = __esm({
358399
358281
  // ../../plugins/fusion-plugin-claude-runtime/src/skill-loader.ts
358400
358282
  import {
358401
358283
  cpSync as cpSync4,
358402
- existsSync as existsSync79,
358284
+ existsSync as existsSync80,
358403
358285
  mkdirSync as mkdirSync15,
358404
358286
  mkdtempSync as mkdtempSync4,
358405
358287
  readdirSync as readdirSync15,
@@ -358412,7 +358294,7 @@ import { tmpdir as tmpdir18 } from "node:os";
358412
358294
  import { basename as basename33, dirname as dirname49, join as join108, resolve as resolve65 } from "node:path";
358413
358295
  import { fileURLToPath as fileURLToPath14 } from "node:url";
358414
358296
  function isSkillDir2(dir2) {
358415
- return existsSync79(join108(dir2, "SKILL.md"));
358297
+ return existsSync80(join108(dir2, "SKILL.md"));
358416
358298
  }
358417
358299
  function pushUnique2(out, candidate) {
358418
358300
  if (!candidate) return;
@@ -358476,7 +358358,7 @@ function resolveBundledFusionSkillSource3(moduleUrl = import.meta.url) {
358476
358358
  function installSkillDir2(sourceDir, targetDir) {
358477
358359
  if (!isSkillDir2(sourceDir)) return false;
358478
358360
  mkdirSync15(dirname49(targetDir), { recursive: true });
358479
- if (existsSync79(targetDir)) {
358361
+ if (existsSync80(targetDir)) {
358480
358362
  rmSync12(targetDir, { recursive: true, force: true });
358481
358363
  }
358482
358364
  try {
@@ -358492,7 +358374,7 @@ function installSkillDir2(sourceDir, targetDir) {
358492
358374
  }
358493
358375
  }
358494
358376
  function collectSkillsFromRoot2(root, out) {
358495
- if (!existsSync79(root)) return;
358377
+ if (!existsSync80(root)) return;
358496
358378
  if (isSkillDir2(root)) {
358497
358379
  out.set(basename33(root), root);
358498
358380
  return;
@@ -358531,7 +358413,7 @@ function stageClaudeSessionSkills(options = {}) {
358531
358413
  installSkillDir2(source, join108(skillsDir, name2));
358532
358414
  }
358533
358415
  for (const [name2, source] of installed) {
358534
- if (!existsSync79(join108(skillsDir, name2))) {
358416
+ if (!existsSync80(join108(skillsDir, name2))) {
358535
358417
  installSkillDir2(source, join108(skillsDir, name2));
358536
358418
  }
358537
358419
  }
@@ -358600,7 +358482,7 @@ var init_skill_loader2 = __esm({
358600
358482
 
358601
358483
  // ../../plugins/fusion-plugin-claude-runtime/src/tool-bridge.ts
358602
358484
  import { createServer as createServer3 } from "node:http";
358603
- import { existsSync as existsSync80, rmSync as rmSync13, writeFileSync as writeFileSync17 } from "node:fs";
358485
+ import { existsSync as existsSync81, rmSync as rmSync13, writeFileSync as writeFileSync17 } from "node:fs";
358604
358486
  import { tmpdir as tmpdir19 } from "node:os";
358605
358487
  import { dirname as dirname50, join as join109 } from "node:path";
358606
358488
  import { fileURLToPath as fileURLToPath15 } from "node:url";
@@ -358646,7 +358528,7 @@ async function startFusionToolBridge2(tools, options = {}) {
358646
358528
  const defs = toolsToMcpToolDefs3(tools);
358647
358529
  if (defs.length === 0) return null;
358648
358530
  const serverPath = fusionToolsMcpServerPath2();
358649
- if (!existsSync80(serverPath)) {
358531
+ if (!existsSync81(serverPath)) {
358650
358532
  throw missingMcpSchemaServerError2(serverPath);
358651
358533
  }
358652
358534
  const byName = /* @__PURE__ */ new Map();
@@ -359458,7 +359340,7 @@ var init_provider6 = __esm({
359458
359340
  });
359459
359341
 
359460
359342
  // ../../plugins/fusion-plugin-omp-runtime/src/acp/cli-spawn.ts
359461
- import { existsSync as existsSync81 } from "node:fs";
359343
+ import { existsSync as existsSync82 } from "node:fs";
359462
359344
  import { dirname as dirname51, isAbsolute as isAbsolute31, join as join110, resolve as resolve66 } from "node:path";
359463
359345
  import { fileURLToPath as fileURLToPath16 } from "node:url";
359464
359346
  function asTrimmedString3(value) {
@@ -359481,7 +359363,7 @@ function bundledClaudeBridgeBinPath4(pluginRoot = pluginRootDir4()) {
359481
359363
  }
359482
359364
  function resolveBundledClaudeBridgeBinary4(options = {}) {
359483
359365
  const root = options.pluginRoot ?? pluginRootDir4();
359484
- const exists2 = options.exists ?? existsSync81;
359366
+ const exists2 = options.exists ?? existsSync82;
359485
359367
  const candidate = bundledClaudeBridgeBinPath4(root);
359486
359368
  if (!exists2(candidate)) {
359487
359369
  return {
@@ -360793,7 +360675,7 @@ var init_mcp_forwarding3 = __esm({
360793
360675
 
360794
360676
  // ../../plugins/fusion-plugin-omp-runtime/src/tool-bridge.ts
360795
360677
  import { createServer as createServer4 } from "node:http";
360796
- import { existsSync as existsSync82, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "node:fs";
360678
+ import { existsSync as existsSync83, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "node:fs";
360797
360679
  import { tmpdir as tmpdir20 } from "node:os";
360798
360680
  import { dirname as dirname53, join as join112 } from "node:path";
360799
360681
  import { fileURLToPath as fileURLToPath17 } from "node:url";
@@ -360820,7 +360702,7 @@ function fusionToolsMcpServerPath3() {
360820
360702
  join112(here, "..", "mcp-schema-server.cjs")
360821
360703
  ];
360822
360704
  for (const candidate of candidates) {
360823
- if (existsSync82(candidate)) return candidate;
360705
+ if (existsSync83(candidate)) return candidate;
360824
360706
  }
360825
360707
  return null;
360826
360708
  }
@@ -360958,7 +360840,7 @@ var init_tool_bridge3 = __esm({
360958
360840
  });
360959
360841
 
360960
360842
  // ../../plugins/fusion-plugin-omp-runtime/src/runtime-adapter.ts
360961
- import { existsSync as existsSync83 } from "node:fs";
360843
+ import { existsSync as existsSync84 } from "node:fs";
360962
360844
  function compactDiagnostic3(value) {
360963
360845
  return value.replace(/\s+/g, " ").trim();
360964
360846
  }
@@ -361149,7 +361031,7 @@ var init_runtime_adapter9 = __esm({
361149
361031
  const command = server.command.trim();
361150
361032
  if (!command) return false;
361151
361033
  if (command.includes("/") || command.includes("\\")) {
361152
- return existsSync83(command);
361034
+ return existsSync84(command);
361153
361035
  }
361154
361036
  return true;
361155
361037
  });
@@ -368063,7 +367945,7 @@ var init_auth_provider_catalog = __esm({
368063
367945
  // ../dashboard/src/routes/register-auth-routes.ts
368064
367946
  import { tmpdir as tmpdir21 } from "node:os";
368065
367947
  import { join as join116 } from "node:path";
368066
- import { existsSync as existsSync84, readFileSync as readFileSync29 } from "node:fs";
367948
+ import { existsSync as existsSync85, readFileSync as readFileSync29 } from "node:fs";
368067
367949
  function parseGitHubCopilotDeviceCode(instructions) {
368068
367950
  const match = instructions.match(/Enter code:\s*([A-Z0-9-]+)\b/i);
368069
367951
  return match?.[1];
@@ -368821,7 +368703,7 @@ var init_register_auth_routes = __esm({
368821
368703
  let acpAuthReason;
368822
368704
  try {
368823
368705
  const signalPath = join116(tmpdir21(), "fusion-acp-bridge-auth.json");
368824
- if (existsSync84(signalPath)) {
368706
+ if (existsSync85(signalPath)) {
368825
368707
  const sig = JSON.parse(readFileSync29(signalPath, "utf8"));
368826
368708
  if (sig?.authFailed) {
368827
368709
  acpAuthFailed = true;
@@ -370920,7 +370802,7 @@ import { spawn as spawn27 } from "node:child_process";
370920
370802
  import {
370921
370803
  chmodSync as chmodSync4,
370922
370804
  cpSync as cpSync5,
370923
- existsSync as existsSync85,
370805
+ existsSync as existsSync86,
370924
370806
  lstatSync as lstatSync5,
370925
370807
  mkdirSync as mkdirSync16,
370926
370808
  readlinkSync as readlinkSync3,
@@ -371035,20 +370917,20 @@ function runStreamingCommand(command, args, options) {
371035
370917
  function resolveBunExecutable() {
371036
370918
  if (process.env.BUN_INSTALL) {
371037
370919
  const candidate = join119(process.env.BUN_INSTALL, "bin", process.platform === "win32" ? "bun.exe" : "bun");
371038
- if (existsSync85(candidate)) return candidate;
370920
+ if (existsSync86(candidate)) return candidate;
371039
370921
  }
371040
370922
  const homeBun = join119(homedir19(), ".bun", "bin", process.platform === "win32" ? "bun.exe" : "bun");
371041
- if (existsSync85(homeBun)) return homeBun;
370923
+ if (existsSync86(homeBun)) return homeBun;
371042
370924
  return "bun";
371043
370925
  }
371044
370926
  function installLocalFnBinary(distDir, onLog, paths2 = resolveFnBinaryLocalPaths()) {
371045
370927
  const srcBinary = join119(distDir, process.platform === "win32" ? "fn.exe" : "fn");
371046
370928
  const srcClient = join119(distDir, "client");
371047
370929
  const srcRuntime = join119(distDir, "runtime");
371048
- if (!existsSync85(srcBinary)) {
370930
+ if (!existsSync86(srcBinary)) {
371049
370931
  throw new Error(`Built binary missing at ${srcBinary}. Did the Bun compile step fail?`);
371050
370932
  }
371051
- if (!existsSync85(srcClient)) {
370933
+ if (!existsSync86(srcClient)) {
371052
370934
  throw new Error(`Dashboard client assets missing at ${srcClient}.`);
371053
370935
  }
371054
370936
  mkdirSync16(paths2.installDir, { recursive: true });
@@ -371062,14 +370944,14 @@ function installLocalFnBinary(distDir, onLog, paths2 = resolveFnBinaryLocalPaths
371062
370944
  onLog("system", `Installing client assets \u2192 ${join119(paths2.installDir, "client")}`);
371063
370945
  rmSync14(join119(paths2.installDir, "client"), { recursive: true, force: true });
371064
370946
  cpSync5(srcClient, join119(paths2.installDir, "client"), { recursive: true });
371065
- if (existsSync85(srcRuntime)) {
370947
+ if (existsSync86(srcRuntime)) {
371066
370948
  onLog("system", `Installing runtime assets \u2192 ${join119(paths2.installDir, "runtime")}`);
371067
370949
  rmSync14(join119(paths2.installDir, "runtime"), { recursive: true, force: true });
371068
370950
  cpSync5(srcRuntime, join119(paths2.installDir, "runtime"), { recursive: true });
371069
370951
  }
371070
370952
  for (const shim of [paths2.fnShimPath, paths2.fusionShimPath]) {
371071
370953
  try {
371072
- if (existsSync85(shim) || isSymlink(shim)) {
370954
+ if (existsSync86(shim) || isSymlink(shim)) {
371073
370955
  unlinkSync6(shim);
371074
370956
  }
371075
370957
  } catch {
@@ -371091,7 +370973,7 @@ function removeLocalFnShims(onLog, paths2 = resolveFnBinaryLocalPaths()) {
371091
370973
  const installReal = resolve69(paths2.binaryPath);
371092
370974
  for (const shim of [paths2.fnShimPath, paths2.fusionShimPath]) {
371093
370975
  try {
371094
- if (!existsSync85(shim) && !isSymlink(shim)) {
370976
+ if (!existsSync86(shim) && !isSymlink(shim)) {
371095
370977
  onLog("system", `No shim at ${shim}`);
371096
370978
  continue;
371097
370979
  }
@@ -371123,10 +371005,10 @@ async function runLinkLocalFnBinary(sourceRoot, onLog) {
371123
371005
  const buildScript = join119(sourceRoot, "scripts", "build-workspace.mjs");
371124
371006
  const cliBuild = join119(sourceRoot, "packages", "cli", "build.ts");
371125
371007
  const distDir = join119(sourceRoot, "packages", "cli", "dist");
371126
- if (!existsSync85(buildScript)) {
371008
+ if (!existsSync86(buildScript)) {
371127
371009
  return { success: false, error: `Build script missing: ${buildScript}` };
371128
371010
  }
371129
- if (!existsSync85(cliBuild)) {
371011
+ if (!existsSync86(cliBuild)) {
371130
371012
  return { success: false, error: `CLI build entry missing: ${cliBuild}` };
371131
371013
  }
371132
371014
  onLog("system", "Step 1/3 \u2014 full workspace package build\u2026");
@@ -371202,7 +371084,7 @@ var init_fn_binary_local_install = __esm({
371202
371084
 
371203
371085
  // ../dashboard/src/routes/register-system-routes.ts
371204
371086
  import { randomUUID as randomUUID66 } from "node:crypto";
371205
- import { existsSync as existsSync86 } from "node:fs";
371087
+ import { existsSync as existsSync87 } from "node:fs";
371206
371088
  import { join as join120 } from "node:path";
371207
371089
  function rejectCrossOrigin(req, res) {
371208
371090
  const origin = req.headers.origin;
@@ -371394,7 +371276,7 @@ function registerSystemRoutes(ctx, deps) {
371394
371276
  const restartAfter = body.restart !== false && scope !== "plugins";
371395
371277
  const { args, label } = rebuildScopes[scope];
371396
371278
  const scriptPath = join120(root, args[0]);
371397
- if (!existsSync86(scriptPath)) {
371279
+ if (!existsSync87(scriptPath)) {
371398
371280
  throw new ApiError(409, `Build script missing: ${scriptPath}`);
371399
371281
  }
371400
371282
  const job = {
@@ -382634,7 +382516,7 @@ var init_reliability_metrics = __esm({
382634
382516
  });
382635
382517
 
382636
382518
  // ../dashboard/src/view-chunk-manifest.ts
382637
- import { existsSync as existsSync87, readFileSync as readFileSync31, statSync as statSync15 } from "node:fs";
382519
+ import { existsSync as existsSync88, readFileSync as readFileSync31, statSync as statSync15 } from "node:fs";
382638
382520
  import { join as join124, resolve as resolve73 } from "node:path";
382639
382521
  function warnOnce(set, key, message) {
382640
382522
  if (set.has(key)) {
@@ -382656,7 +382538,7 @@ function loadViewChunkManifest(clientDir) {
382656
382538
  if (cached2 && cached2.mtimeMs === mtimeMs) {
382657
382539
  return cached2.entries;
382658
382540
  }
382659
- if (!existsSync87(manifestPath)) {
382541
+ if (!existsSync88(manifestPath)) {
382660
382542
  warnOnce(warnedMissingManifest, cacheKey, `[dashboard] View chunk manifest missing: ${manifestPath}`);
382661
382543
  const empty = {};
382662
382544
  manifestCache.set(cacheKey, { entries: empty, mtimeMs });
@@ -383234,7 +383116,7 @@ var init_provider_health_monitor = __esm({
383234
383116
  import express3 from "express";
383235
383117
  import { randomUUID as randomUUID67 } from "node:crypto";
383236
383118
  import { join as join125, dirname as dirname57 } from "node:path";
383237
- import { existsSync as existsSync88, readFileSync as readFileSync32, statSync as statSync16 } from "node:fs";
383119
+ import { existsSync as existsSync89, readFileSync as readFileSync32, statSync as statSync16 } from "node:fs";
383238
383120
  import { fileURLToPath as fileURLToPath18 } from "node:url";
383239
383121
  import { createSecureServer as createHttp2SecureServer } from "node:http2";
383240
383122
  import { WebSocketServer as WebSocketServer2 } from "ws";
@@ -383556,7 +383438,7 @@ function createServer5(store, options) {
383556
383438
  getTerminalService(store.getRootDir());
383557
383439
  const isHeadless = options?.headless === true;
383558
383440
  const execDir = dirname57(process.execPath);
383559
- const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync88(join125(execDir, "client", "index.html")) ? join125(execDir, "client") : existsSync88(join125(__dirname2, "..", "dist", "client")) ? join125(__dirname2, "..", "dist", "client") : join125(__dirname2, "..", "client");
383441
+ const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync89(join125(execDir, "client", "index.html")) ? join125(execDir, "client") : existsSync89(join125(__dirname2, "..", "dist", "client")) ? join125(__dirname2, "..", "dist", "client") : join125(__dirname2, "..", "client");
383560
383442
  let cachedIndexClientDir = null;
383561
383443
  let cachedIndexHtml = null;
383562
383444
  let cachedIndexMtimeMs = null;
@@ -383611,7 +383493,7 @@ ${injection}`) : cachedIndexHtml.replace("</head>", `${injection}</head>`);
383611
383493
  }
383612
383494
  });
383613
383495
  });
383614
- if (existsSync88(join125(clientDir, "index.html"))) {
383496
+ if (existsSync89(join125(clientDir, "index.html"))) {
383615
383497
  app.get(["/", "/index.html"], serveIndexHtml);
383616
383498
  app.use(express3.static(clientDir, { index: false }));
383617
383499
  }
@@ -385670,7 +385552,7 @@ var init_src15 = __esm({
385670
385552
  import { Type as Type9 } from "typebox";
385671
385553
  import { StringEnum } from "@earendil-works/pi-ai";
385672
385554
  import { resolve as resolve75, relative as relative25, isAbsolute as isAbsolute33, sep as sep22, basename as basename36, extname as extname5, join as join127 } from "node:path";
385673
- import { existsSync as existsSync89 } from "node:fs";
385555
+ import { existsSync as existsSync90 } from "node:fs";
385674
385556
  import { AsyncLocalStorage as AsyncLocalStorage8 } from "node:async_hooks";
385675
385557
  function resolveProjectRoot2(cwd) {
385676
385558
  const worktreeProjectRoot = typeof getProjectRootFromWorktree === "function" ? getProjectRootFromWorktree(cwd) : null;
@@ -385678,12 +385560,12 @@ function resolveProjectRoot2(cwd) {
385678
385560
  warnedMissingProjectRootResolver = true;
385679
385561
  console.warn("[fusion-extension] @fusion/core.getProjectRootFromWorktree is unavailable; using filesystem fallback resolution.");
385680
385562
  }
385681
- if (worktreeProjectRoot && existsSync89(join127(worktreeProjectRoot, ".fusion"))) {
385563
+ if (worktreeProjectRoot && existsSync90(join127(worktreeProjectRoot, ".fusion"))) {
385682
385564
  return worktreeProjectRoot;
385683
385565
  }
385684
385566
  let current = resolve75(cwd);
385685
385567
  while (true) {
385686
- if (existsSync89(join127(current, ".fusion"))) {
385568
+ if (existsSync90(join127(current, ".fusion"))) {
385687
385569
  return current;
385688
385570
  }
385689
385571
  const parent2 = resolve75(current, "..");
@@ -386568,7 +386450,7 @@ var init_migration_holding_server = __esm({
386568
386450
 
386569
386451
  // src/commands/ensure-project-registered.ts
386570
386452
  import { exec as exec49 } from "node:child_process";
386571
- import { existsSync as existsSync90, mkdirSync as mkdirSync17 } from "node:fs";
386453
+ import { existsSync as existsSync91, mkdirSync as mkdirSync17 } from "node:fs";
386572
386454
  import { basename as basename37, join as join128 } from "node:path";
386573
386455
  import { promisify as promisify74 } from "node:util";
386574
386456
  function stampProjectIdentityBestEffort(cwd, project, logPrefix) {
@@ -386596,7 +386478,7 @@ async function ensureCwdProjectRegistered(options) {
386596
386478
  }
386597
386479
  try {
386598
386480
  const fusionDir = join128(cwd, ".fusion");
386599
- if (!existsSync90(fusionDir)) {
386481
+ if (!existsSync91(fusionDir)) {
386600
386482
  mkdirSync17(fusionDir, { recursive: true });
386601
386483
  }
386602
386484
  const projectName = await detectProjectName(cwd);
@@ -386626,7 +386508,7 @@ async function ensureCwdProjectRegistered(options) {
386626
386508
  }
386627
386509
  }
386628
386510
  async function detectProjectName(dir2) {
386629
- if (!existsSync90(join128(dir2, ".git"))) {
386511
+ if (!existsSync91(join128(dir2, ".git"))) {
386630
386512
  return basename37(dir2) || "my-project";
386631
386513
  }
386632
386514
  try {
@@ -386658,7 +386540,7 @@ var init_ensure_project_registered = __esm({
386658
386540
  });
386659
386541
 
386660
386542
  // src/commands/provider-settings.ts
386661
- import { existsSync as existsSync91, readFileSync as readFileSync33, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18 } from "node:fs";
386543
+ import { existsSync as existsSync92, readFileSync as readFileSync33, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18 } from "node:fs";
386662
386544
  import { join as join129, dirname as dirname59, basename as basename38 } from "node:path";
386663
386545
  function siblingAgentDir2(agentDir, siblingRoot) {
386664
386546
  if (basename38(agentDir) !== "agent") {
@@ -386667,7 +386549,7 @@ function siblingAgentDir2(agentDir, siblingRoot) {
386667
386549
  return join129(dirname59(dirname59(agentDir)), siblingRoot, "agent");
386668
386550
  }
386669
386551
  function readJsonObject4(path14) {
386670
- if (!existsSync91(path14)) {
386552
+ if (!existsSync92(path14)) {
386671
386553
  return {};
386672
386554
  }
386673
386555
  try {
@@ -386712,7 +386594,7 @@ var init_provider_auth2 = __esm({
386712
386594
 
386713
386595
  // src/commands/auth-paths.ts
386714
386596
  import { homedir as homedir20 } from "node:os";
386715
- import { existsSync as existsSync92, readFileSync as readFileSync34 } from "node:fs";
386597
+ import { existsSync as existsSync93, readFileSync as readFileSync34 } from "node:fs";
386716
386598
  import { join as join130 } from "node:path";
386717
386599
  function getFusionAgentDir2(home = process.env.HOME || process.env.USERPROFILE || homedir20()) {
386718
386600
  return join130(home, ".fusion", "agent");
@@ -386731,13 +386613,13 @@ function getLegacyModelsPaths2(home = process.env.HOME || process.env.USERPROFIL
386731
386613
  }
386732
386614
  function getModelRegistryModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir20()) {
386733
386615
  const fusionModelsPath = getFusionModelsPath2(home);
386734
- if (existsSync92(fusionModelsPath)) {
386616
+ if (existsSync93(fusionModelsPath)) {
386735
386617
  return fusionModelsPath;
386736
386618
  }
386737
- return getLegacyModelsPaths2(home).find((modelsPath) => existsSync92(modelsPath)) ?? fusionModelsPath;
386619
+ return getLegacyModelsPaths2(home).find((modelsPath) => existsSync93(modelsPath)) ?? fusionModelsPath;
386738
386620
  }
386739
386621
  function readJsonObject5(path14) {
386740
- if (!existsSync92(path14)) {
386622
+ if (!existsSync93(path14)) {
386741
386623
  return {};
386742
386624
  }
386743
386625
  try {
@@ -386755,13 +386637,13 @@ function getPackageManagerAgentDir2(home = process.env.HOME || process.env.USERP
386755
386637
  const legacyAgentDir = getLegacyAgentDir(home);
386756
386638
  const fusionSettings = readJsonObject5(join130(fusionAgentDir, "settings.json"));
386757
386639
  const legacySettings = readJsonObject5(join130(legacyAgentDir, "settings.json"));
386758
- if (hasPackageManagerSettings3(fusionSettings) || !existsSync92(legacyAgentDir)) {
386640
+ if (hasPackageManagerSettings3(fusionSettings) || !existsSync93(legacyAgentDir)) {
386759
386641
  return fusionAgentDir;
386760
386642
  }
386761
386643
  if (hasPackageManagerSettings3(legacySettings)) {
386762
386644
  return legacyAgentDir;
386763
386645
  }
386764
- return existsSync92(fusionAgentDir) ? fusionAgentDir : legacyAgentDir;
386646
+ return existsSync93(fusionAgentDir) ? fusionAgentDir : legacyAgentDir;
386765
386647
  }
386766
386648
  var init_auth_paths2 = __esm({
386767
386649
  "src/commands/auth-paths.ts"() {
@@ -387008,7 +386890,7 @@ var init_project_context = __esm({
387008
386890
  // src/commands/claude-skills.ts
387009
386891
  import {
387010
386892
  cpSync as cpSync6,
387011
- existsSync as existsSync93,
386893
+ existsSync as existsSync94,
387012
386894
  lstatSync as lstatSync6,
387013
386895
  mkdirSync as mkdirSync19,
387014
386896
  readlinkSync as readlinkSync4,
@@ -387037,7 +386919,7 @@ function isPiClaudeCliConfigured(globalSettings) {
387037
386919
  function resolveFusionSkillSource() {
387038
386920
  const here = fileURLToPath19(import.meta.url);
387039
386921
  const candidate = resolve77(dirname61(here), "..", "..", "skill", FUSION_SKILL_NAME4);
387040
- return existsSync93(candidate) ? candidate : null;
386922
+ return existsSync94(candidate) ? candidate : null;
387041
386923
  }
387042
386924
  function installFusionSkillIntoProject(projectPath, options = {}) {
387043
386925
  const target = join131(projectPath, ".claude", "skills", FUSION_SKILL_NAME4);
@@ -387055,7 +386937,7 @@ function installFusionSkillIntoProject(projectPath, options = {}) {
387055
386937
  try {
387056
386938
  mkdirSync19(dirname61(target), { recursive: true });
387057
386939
  let replaced = false;
387058
- if (existsSync93(target) || isBrokenSymlink2(target)) {
386940
+ if (existsSync94(target) || isBrokenSymlink2(target)) {
387059
386941
  const stat20 = lstatSync6(target);
387060
386942
  if (stat20.isSymbolicLink()) {
387061
386943
  const current = safeReadlink2(target);
@@ -387066,7 +386948,7 @@ function installFusionSkillIntoProject(projectPath, options = {}) {
387066
386948
  replaced = true;
387067
386949
  } else {
387068
386950
  const skillMd = join131(target, "SKILL.md");
387069
- if (!existsSync93(skillMd)) {
386951
+ if (!existsSync94(skillMd)) {
387070
386952
  return {
387071
386953
  outcome: "failed",
387072
386954
  target,
@@ -387125,7 +387007,7 @@ function isBrokenSymlink2(path14) {
387125
387007
  try {
387126
387008
  const stat20 = lstatSync6(path14);
387127
387009
  if (!stat20.isSymbolicLink()) return false;
387128
- return !existsSync93(path14);
387010
+ return !existsSync94(path14);
387129
387011
  } catch {
387130
387012
  return false;
387131
387013
  }
@@ -387222,7 +387104,7 @@ var init_claude_skills_runner = __esm({
387222
387104
  });
387223
387105
 
387224
387106
  // src/commands/claude-cli-extension.ts
387225
- import { existsSync as existsSync94, readFileSync as readFileSync35 } from "node:fs";
387107
+ import { existsSync as existsSync95, readFileSync as readFileSync35 } from "node:fs";
387226
387108
  import { createRequire as createRequire10 } from "node:module";
387227
387109
  import { dirname as dirname62, resolve as resolve78 } from "node:path";
387228
387110
  import { fileURLToPath as fileURLToPath20 } from "node:url";
@@ -387231,7 +387113,7 @@ function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
387231
387113
  const here = dirname62(fileURLToPath20(moduleUrl));
387232
387114
  for (const rel of ["pi-claude-cli", "../pi-claude-cli", "../../pi-claude-cli"]) {
387233
387115
  const candidate = resolve78(here, rel, "package.json");
387234
- if (existsSync94(candidate)) {
387116
+ if (existsSync95(candidate)) {
387235
387117
  pkgJsonPath = candidate;
387236
387118
  break;
387237
387119
  }
@@ -387267,7 +387149,7 @@ function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
387267
387149
  };
387268
387150
  }
387269
387151
  const entryPath = resolve78(dirname62(pkgJsonPath), rawEntry);
387270
- if (!existsSync94(entryPath)) {
387152
+ if (!existsSync95(entryPath)) {
387271
387153
  return {
387272
387154
  status: "missing-entry",
387273
387155
  reason: `@fusion/pi-claude-cli extension file not found at ${entryPath}`
@@ -387318,7 +387200,7 @@ var init_claude_cli_extension = __esm({
387318
387200
  });
387319
387201
 
387320
387202
  // src/commands/droid-cli-extension.ts
387321
- import { existsSync as existsSync95, readFileSync as readFileSync36 } from "node:fs";
387203
+ import { existsSync as existsSync96, readFileSync as readFileSync36 } from "node:fs";
387322
387204
  import { createRequire as createRequire11 } from "node:module";
387323
387205
  import { dirname as dirname63, resolve as resolve79 } from "node:path";
387324
387206
  import { fileURLToPath as fileURLToPath21 } from "node:url";
@@ -387327,7 +387209,7 @@ function resolveDroidCliExtensionFromModuleUrl(moduleUrl) {
387327
387209
  const here = dirname63(fileURLToPath21(moduleUrl));
387328
387210
  for (const rel of ["droid-cli", "../droid-cli", "../../droid-cli"]) {
387329
387211
  const candidate = resolve79(here, rel, "package.json");
387330
- if (existsSync95(candidate)) {
387212
+ if (existsSync96(candidate)) {
387331
387213
  pkgJsonPath = candidate;
387332
387214
  break;
387333
387215
  }
@@ -387363,7 +387245,7 @@ function resolveDroidCliExtensionFromModuleUrl(moduleUrl) {
387363
387245
  };
387364
387246
  }
387365
387247
  const entryPath = resolve79(dirname63(pkgJsonPath), rawEntry);
387366
- if (!existsSync95(entryPath)) {
387248
+ if (!existsSync96(entryPath)) {
387367
387249
  return {
387368
387250
  status: "missing-entry",
387369
387251
  reason: `@fusion/droid-cli extension file not found at ${entryPath}`
@@ -387414,7 +387296,7 @@ var init_droid_cli_extension = __esm({
387414
387296
  });
387415
387297
 
387416
387298
  // src/commands/llama-cpp-extension.ts
387417
- import { existsSync as existsSync96, readFileSync as readFileSync37 } from "node:fs";
387299
+ import { existsSync as existsSync97, readFileSync as readFileSync37 } from "node:fs";
387418
387300
  import { createRequire as createRequire12 } from "node:module";
387419
387301
  import { dirname as dirname64, resolve as resolve80 } from "node:path";
387420
387302
  import { fileURLToPath as fileURLToPath22 } from "node:url";
@@ -387423,7 +387305,7 @@ function resolveLlamaCppExtensionFromModuleUrl(moduleUrl) {
387423
387305
  const here = dirname64(fileURLToPath22(moduleUrl));
387424
387306
  for (const rel of ["pi-llama-cpp", "../pi-llama-cpp", "../../pi-llama-cpp", "../../../pi-llama-cpp"]) {
387425
387307
  const candidate = resolve80(here, rel, "package.json");
387426
- if (existsSync96(candidate)) {
387308
+ if (existsSync97(candidate)) {
387427
387309
  pkgJsonPath = candidate;
387428
387310
  break;
387429
387311
  }
@@ -387459,7 +387341,7 @@ function resolveLlamaCppExtensionFromModuleUrl(moduleUrl) {
387459
387341
  };
387460
387342
  }
387461
387343
  const entryPath = resolve80(dirname64(pkgJsonPath), rawEntry);
387462
- if (!existsSync96(entryPath)) {
387344
+ if (!existsSync97(entryPath)) {
387463
387345
  return {
387464
387346
  status: "missing-entry",
387465
387347
  reason: `@fusion/pi-llama-cpp extension file not found at ${entryPath}`
@@ -387558,7 +387440,7 @@ var init_update_cache = __esm({
387558
387440
  });
387559
387441
 
387560
387442
  // src/commands/self-extension.ts
387561
- import { existsSync as existsSync97, readFileSync as readFileSync39 } from "node:fs";
387443
+ import { existsSync as existsSync98, readFileSync as readFileSync39 } from "node:fs";
387562
387444
  import { dirname as dirname65, resolve as resolve81 } from "node:path";
387563
387445
  import { fileURLToPath as fileURLToPath23 } from "node:url";
387564
387446
  function resolveSelfExtension() {
@@ -387566,7 +387448,7 @@ function resolveSelfExtension() {
387566
387448
  let pkgDir;
387567
387449
  let cur = here;
387568
387450
  for (let i = 0; i < 5; i++) {
387569
- if (existsSync97(resolve81(cur, "package.json"))) {
387451
+ if (existsSync98(resolve81(cur, "package.json"))) {
387570
387452
  try {
387571
387453
  const parsed = JSON.parse(readFileSync39(resolve81(cur, "package.json"), "utf-8"));
387572
387454
  if (parsed.name === "@runfusion/fusion") {
@@ -387590,7 +387472,7 @@ function resolveSelfExtension() {
387590
387472
  return { status: "missing", reason: `Failed to read @runfusion/fusion package.json: ${err instanceof Error ? err.message : String(err)}` };
387591
387473
  }
387592
387474
  const srcEntry = resolve81(pkgDir, "src", "extension.ts");
387593
- if (existsSync97(srcEntry)) {
387475
+ if (existsSync98(srcEntry)) {
387594
387476
  return { status: "ok", path: srcEntry, packageVersion: pkgJson.version ?? "unknown" };
387595
387477
  }
387596
387478
  const extensions = pkgJson.pi?.extensions;
@@ -387602,7 +387484,7 @@ function resolveSelfExtension() {
387602
387484
  return { status: "missing", reason: "@runfusion/fusion pi.extensions[0] is not a valid path string" };
387603
387485
  }
387604
387486
  const entryPath = resolve81(pkgDir, rawEntry);
387605
- if (!existsSync97(entryPath)) {
387487
+ if (!existsSync98(entryPath)) {
387606
387488
  return { status: "missing", reason: `@runfusion/fusion extension file not found at ${entryPath}` };
387607
387489
  }
387608
387490
  return { status: "ok", path: entryPath, packageVersion: pkgJson.version ?? "unknown" };
@@ -396064,7 +395946,7 @@ import { join as join134, resolve as pathResolve2 } from "node:path";
396064
395946
  import { execFile as execFileCb, spawn as spawn31 } from "node:child_process";
396065
395947
  import { promisify as promisify75 } from "node:util";
396066
395948
  import { stat as stat18, readdir as readdir16, readFile as fsReadFile4 } from "node:fs/promises";
396067
- import { existsSync as existsSync98, readFileSync as readFileSync40 } from "node:fs";
395949
+ import { existsSync as existsSync99, readFileSync as readFileSync40 } from "node:fs";
396068
395950
  import { fileURLToPath as fileURLToPath25 } from "node:url";
396069
395951
  import { DefaultPackageManager as DefaultPackageManager2, discoverAndLoadExtensions as discoverAndLoadExtensions2, createExtensionRuntime as createExtensionRuntime2 } from "@earendil-works/pi-coding-agent";
396070
395952
  async function countActiveTasks(store, tasks2) {
@@ -398366,7 +398248,7 @@ function resolveFusionSourceWorkspaceRoot() {
398366
398248
  try {
398367
398249
  let dir2 = pathResolve2(fileURLToPath25(import.meta.url), "..");
398368
398250
  for (let i = 0; i < 10; i++) {
398369
- if (existsSync98(join134(dir2, "pnpm-workspace.yaml"))) {
398251
+ if (existsSync99(join134(dir2, "pnpm-workspace.yaml"))) {
398370
398252
  try {
398371
398253
  const pkg = JSON.parse(readFileSync40(join134(dir2, "package.json"), "utf8"));
398372
398254
  return pkg?.name === "fusion-workspace" ? dir2 : void 0;
@@ -400768,7 +400650,7 @@ __export(desktop_exports, {
400768
400650
  });
400769
400651
  import { spawn as spawn32 } from "node:child_process";
400770
400652
  import { once as once2 } from "node:events";
400771
- import { existsSync as existsSync99 } from "node:fs";
400653
+ import { existsSync as existsSync100 } from "node:fs";
400772
400654
  import { dirname as dirname67, isAbsolute as isAbsolute34, join as join137, resolve as resolve83 } from "node:path";
400773
400655
  import { createRequire as createRequire13 } from "node:module";
400774
400656
  import { fileURLToPath as fileURLToPath26 } from "node:url";
@@ -400877,7 +400759,7 @@ function terminateProcess(child, signal = "SIGTERM") {
400877
400759
  }
400878
400760
  function resolveDevDesktopEntry(rootDir) {
400879
400761
  const desktopEntry = join137(rootDir, "packages", "desktop", "dist", "main.js");
400880
- if (existsSync99(desktopEntry)) {
400762
+ if (existsSync100(desktopEntry)) {
400881
400763
  return desktopEntry;
400882
400764
  }
400883
400765
  throw new Error(
@@ -400888,17 +400770,17 @@ function resolvePackagedDesktopEntry() {
400888
400770
  const override = process.env.FUSION_DESKTOP_ENTRY;
400889
400771
  if (override) {
400890
400772
  const resolvedOverride = isAbsolute34(override) ? override : resolve83(process.cwd(), override);
400891
- if (existsSync99(resolvedOverride)) {
400773
+ if (existsSync100(resolvedOverride)) {
400892
400774
  return resolvedOverride;
400893
400775
  }
400894
400776
  throw new Error(`Fusion desktop runtime override is missing: ${resolvedOverride}`);
400895
400777
  }
400896
400778
  const packagedEntry = resolve83(cliModuleDir, "desktop", "main.js");
400897
- if (existsSync99(packagedEntry)) {
400779
+ if (existsSync100(packagedEntry)) {
400898
400780
  return packagedEntry;
400899
400781
  }
400900
400782
  const sourceCheckoutEntry = resolve83(cliModuleDir, "..", "..", "dist", "desktop", "main.js");
400901
- if (existsSync99(sourceCheckoutEntry)) {
400783
+ if (existsSync100(sourceCheckoutEntry)) {
400902
400784
  return sourceCheckoutEntry;
400903
400785
  }
400904
400786
  throw new Error(
@@ -401530,7 +401412,7 @@ __export(task_exports, {
401530
401412
  runTaskUpdate: () => runTaskUpdate
401531
401413
  });
401532
401414
  import { createInterface as createInterface3 } from "node:readline/promises";
401533
- import { watchFile, unwatchFile, statSync as statSync17, existsSync as existsSync100, readFileSync as readFileSync41 } from "node:fs";
401415
+ import { watchFile, unwatchFile, statSync as statSync17, existsSync as existsSync101, readFileSync as readFileSync41 } from "node:fs";
401534
401416
  import { basename as basename40, join as join138 } from "node:path";
401535
401417
  function columnLabel2(column) {
401536
401418
  return COLUMN_LABELS[column] ?? column;
@@ -402104,7 +401986,7 @@ async function runTaskLogs(id, options = {}, projectName) {
402104
401986
  if (options.follow) {
402105
401987
  const projectPath = context.projectPath ?? process.cwd();
402106
401988
  const logPath = join138(projectPath, ".fusion", "tasks", id, "agent.log");
402107
- if (!existsSync100(logPath)) {
401989
+ if (!existsSync101(logPath)) {
402108
401990
  console.log(`
402109
401991
  Waiting for log file to be created...`);
402110
401992
  }
@@ -403788,7 +403670,7 @@ var settings_import_exports = {};
403788
403670
  __export(settings_import_exports, {
403789
403671
  runSettingsImport: () => runSettingsImport
403790
403672
  });
403791
- import { existsSync as existsSync101 } from "node:fs";
403673
+ import { existsSync as existsSync102 } from "node:fs";
403792
403674
  import { resolve as resolve85 } from "node:path";
403793
403675
  async function runSettingsImport(filePath, options = {}) {
403794
403676
  const scope = options.scope ?? "both";
@@ -403807,7 +403689,7 @@ async function runSettingsImport(filePath, options = {}) {
403807
403689
  };
403808
403690
  try {
403809
403691
  const resolvedPath = resolve85(filePath);
403810
- if (!existsSync101(resolvedPath)) {
403692
+ if (!existsSync102(resolvedPath)) {
403811
403693
  console.error(`Error: File not found: ${filePath}`);
403812
403694
  await exitWithStore(1);
403813
403695
  return;
@@ -403915,7 +403797,7 @@ __export(mcp_exports, {
403915
403797
  runMcpRemove: () => runMcpRemove,
403916
403798
  runMcpValidate: () => runMcpValidate
403917
403799
  });
403918
- import { existsSync as existsSync102 } from "node:fs";
403800
+ import { existsSync as existsSync103 } from "node:fs";
403919
403801
  import { readFile as readFile60, writeFile as writeFile41 } from "node:fs/promises";
403920
403802
  import { resolve as resolve86 } from "node:path";
403921
403803
  async function createGlobalSettingsStore() {
@@ -404253,7 +404135,7 @@ async function runMcpImport(filePath, opts = {}) {
404253
404135
  const scope = normalizeScope(opts.scope);
404254
404136
  context = await loadContext(opts.projectName, scope === "project");
404255
404137
  const resolvedPath = resolve86(filePath);
404256
- if (!existsSync102(resolvedPath)) throw new Error(`File not found: ${filePath}`);
404138
+ if (!existsSync103(resolvedPath)) throw new Error(`File not found: ${filePath}`);
404257
404139
  const imported = importMcpServersJson(await readFile60(resolvedPath, "utf-8"), { scope });
404258
404140
  if (imported.errors.length > 0) throw new Error(`Invalid MCP import file:
404259
404141
  ${imported.errors.map((error3) => ` - ${error3}`).join("\n")}`);
@@ -404370,7 +404252,7 @@ var init_mcp = __esm({
404370
404252
  });
404371
404253
 
404372
404254
  // src/project-resolver.ts
404373
- import { existsSync as existsSync103, statSync as statSync18 } from "node:fs";
404255
+ import { existsSync as existsSync104, statSync as statSync18 } from "node:fs";
404374
404256
  import { basename as basename41, dirname as dirname68, join as join140, normalize as normalize9, resolve as resolve87 } from "node:path";
404375
404257
  import { createInterface as createInterface4 } from "node:readline/promises";
404376
404258
  async function getCentralCore() {
@@ -404453,7 +404335,7 @@ async function resolveProject2(options = {}) {
404453
404335
  { searchedName: options.project, availableProjects: projects2.map((p2) => p2.name) }
404454
404336
  );
404455
404337
  }
404456
- if (!existsSync103(match.path)) {
404338
+ if (!existsSync104(match.path)) {
404457
404339
  throw new ProjectResolutionError(
404458
404340
  `Project "${match.name}" is registered but the directory no longer exists: ${match.path}
404459
404341
 
@@ -404471,7 +404353,7 @@ Run \`fn project remove ` + match.name + "` to clean up the registry entry.",
404471
404353
  const normalizedKbDir = normalize9(fusionDir);
404472
404354
  const match = allProjects2.find((p2) => normalize9(p2.path) === normalizedKbDir);
404473
404355
  if (match) {
404474
- if (!existsSync103(match.path)) {
404356
+ if (!existsSync104(match.path)) {
404475
404357
  throw new ProjectResolutionError(
404476
404358
  `Project "${match.name}" is registered but the directory no longer exists: ${match.path}
404477
404359
 
@@ -404597,7 +404479,7 @@ Run \`fn project add ` + fusionDir + "` to register it, or use --project <name>.
404597
404479
  }
404598
404480
  if (allProjects.length === 1) {
404599
404481
  const project = allProjects[0];
404600
- if (!existsSync103(project.path)) {
404482
+ if (!existsSync104(project.path)) {
404601
404483
  throw new ProjectResolutionError(
404602
404484
  `The only registered project "${project.name}" has a missing directory: ${project.path}
404603
404485
 
@@ -405587,7 +405469,7 @@ __export(db_exports, {
405587
405469
  runDbMigrate: () => runDbMigrate,
405588
405470
  runDbVacuum: () => runDbVacuum
405589
405471
  });
405590
- import { existsSync as existsSync104 } from "node:fs";
405472
+ import { existsSync as existsSync105 } from "node:fs";
405591
405473
  import { copyFile as copyFile3, mkdir as mkdir41 } from "node:fs/promises";
405592
405474
  import { join as join141 } from "node:path";
405593
405475
  function formatBytes9(bytes) {
@@ -405668,7 +405550,7 @@ async function runDbMigrate(projectName, opts = {}) {
405668
405550
  const fusionDir = join141(projectRoot, ".fusion");
405669
405551
  const globalDir = resolveGlobalDir();
405670
405552
  const sources = defaultMigrationSources(fusionDir, globalDir);
405671
- const presentSources = sources.filter((s3) => existsSync104(s3.sqlitePath));
405553
+ const presentSources = sources.filter((s3) => existsSync105(s3.sqlitePath));
405672
405554
  if (presentSources.length === 0) {
405673
405555
  console.error(
405674
405556
  `fn db migrate: no legacy SQLite files found under ${fusionDir} (or ${globalDir}). Nothing to migrate.`
@@ -405795,7 +405677,7 @@ async function createPreMigrationBackup(fusionDir, globalDir, sources) {
405795
405677
  const backupDir = join141(globalDir, "migration-backups", `pre-migrate-${ts2}`);
405796
405678
  await mkdir41(backupDir, { recursive: true });
405797
405679
  for (const s3 of sources) {
405798
- if (existsSync104(s3.sqlitePath)) {
405680
+ if (existsSync105(s3.sqlitePath)) {
405799
405681
  const dest = join141(backupDir, s3.sqlitePath.split("/").pop() ?? "source.db");
405800
405682
  await copyFile3(s3.sqlitePath, dest);
405801
405683
  }
@@ -406691,7 +406573,7 @@ __export(project_exports2, {
406691
406573
  runProjectShow: () => runProjectShow
406692
406574
  });
406693
406575
  import { resolve as resolve89, isAbsolute as isAbsolute35, relative as relative26, basename as basename42, join as join142 } from "node:path";
406694
- import { existsSync as existsSync105, statSync as statSync19 } from "node:fs";
406576
+ import { existsSync as existsSync106, statSync as statSync19 } from "node:fs";
406695
406577
  import { createInterface as createInterface8 } from "node:readline/promises";
406696
406578
  function formatDisplayPath(projectPath) {
406697
406579
  const rel = relative26(process.cwd(), projectPath);
@@ -406845,7 +406727,7 @@ async function runProjectAdd(name2, path14, options = {}) {
406845
406727
  projectPath = pathInput.trim() || defaultPath;
406846
406728
  }
406847
406729
  const absolutePath2 = isAbsolute35(projectPath) ? projectPath : resolve89(process.cwd(), projectPath);
406848
- if (!existsSync105(absolutePath2)) {
406730
+ if (!existsSync106(absolutePath2)) {
406849
406731
  console.error(`
406850
406732
  \u2717 Path does not exist: ${projectPath}`);
406851
406733
  rl.close();
@@ -406895,7 +406777,7 @@ async function runProjectAdd(name2, path14, options = {}) {
406895
406777
  process.exit(1);
406896
406778
  }
406897
406779
  const absolutePath = isAbsolute35(projectPath) ? projectPath : resolve89(process.cwd(), projectPath);
406898
- if (!existsSync105(absolutePath)) {
406780
+ if (!existsSync106(absolutePath)) {
406899
406781
  console.error(`
406900
406782
  \u2717 Path does not exist: ${projectPath}
406901
406783
  `);
@@ -407180,7 +407062,7 @@ var init_project2 = __esm({
407180
407062
  });
407181
407063
 
407182
407064
  // src/commands/skill-installation.ts
407183
- import { cpSync as cpSync7, existsSync as existsSync106, mkdirSync as mkdirSync20 } from "node:fs";
407065
+ import { cpSync as cpSync7, existsSync as existsSync107, mkdirSync as mkdirSync20 } from "node:fs";
407184
407066
  import { homedir as homedir21 } from "node:os";
407185
407067
  import { dirname as dirname69, join as join143, resolve as resolve90 } from "node:path";
407186
407068
  import { fileURLToPath as fileURLToPath27 } from "node:url";
@@ -407194,7 +407076,7 @@ function getSupportedSkillInstallTargets(homeDir = process.env.HOME || process.e
407194
407076
  function resolveBundledFusionSkillSource4() {
407195
407077
  const here = fileURLToPath27(import.meta.url);
407196
407078
  const source = resolve90(dirname69(here), "..", "..", "skill", FUSION_SKILL_NAME5);
407197
- return existsSync106(source) ? source : null;
407079
+ return existsSync107(source) ? source : null;
407198
407080
  }
407199
407081
  function installBundledFusionSkill(options = {}) {
407200
407082
  const sourceDir = options.sourceDir ?? resolveBundledFusionSkillSource4();
@@ -407212,7 +407094,7 @@ function installBundledFusionSkill(options = {}) {
407212
407094
  }
407213
407095
  const results = targets.map((target) => {
407214
407096
  try {
407215
- if (existsSync106(target.targetDir)) {
407097
+ if (existsSync107(target.targetDir)) {
407216
407098
  return {
407217
407099
  client: target.client,
407218
407100
  targetDir: target.targetDir,
@@ -407251,7 +407133,7 @@ var init_exports = {};
407251
407133
  __export(init_exports, {
407252
407134
  runInit: () => runInit
407253
407135
  });
407254
- import { existsSync as existsSync107, mkdirSync as mkdirSync21, writeFileSync as writeFileSync20, readFileSync as readFileSync42 } from "node:fs";
407136
+ import { existsSync as existsSync108, mkdirSync as mkdirSync21, writeFileSync as writeFileSync20, readFileSync as readFileSync42 } from "node:fs";
407255
407137
  import { join as join144, resolve as resolve91, basename as basename43 } from "node:path";
407256
407138
  import { exec as exec51 } from "node:child_process";
407257
407139
  import { promisify as promisify77 } from "node:util";
@@ -407259,10 +407141,10 @@ async function runInit(options = {}) {
407259
407141
  const cwd = options.path ? resolve91(options.path) : process.cwd();
407260
407142
  const fusionDir = join144(cwd, ".fusion");
407261
407143
  const dbPath = join144(fusionDir, "fusion.db");
407262
- const hasDbPath = existsSync107(dbPath);
407144
+ const hasDbPath = existsSync108(dbPath);
407263
407145
  const hasValidDb = hasDbPath && isValidSqliteDatabaseFile(dbPath);
407264
407146
  const hasIdentity = hasProjectIdentity(fusionDir);
407265
- if (existsSync107(fusionDir) && (hasIdentity || hasValidDb)) {
407147
+ if (existsSync108(fusionDir) && (hasIdentity || hasValidDb)) {
407266
407148
  const central2 = new CentralCore();
407267
407149
  await central2.init();
407268
407150
  const existing = await central2.getProjectByPath(cwd);
@@ -407291,7 +407173,7 @@ async function runInit(options = {}) {
407291
407173
  await central2.close();
407292
407174
  return;
407293
407175
  }
407294
- if (existsSync107(fusionDir) && !hasIdentity && hasDbPath && !hasValidDb) {
407176
+ if (existsSync108(fusionDir) && !hasIdentity && hasDbPath && !hasValidDb) {
407295
407177
  throw new Error(
407296
407178
  `Existing database at ${dbPath} is not a valid SQLite database. Restore it from .fusion/backups or move it aside before re-running fn init.`
407297
407179
  );
@@ -407299,7 +407181,7 @@ async function runInit(options = {}) {
407299
407181
  const projectName = options.name ?? await detectProjectName2(cwd);
407300
407182
  console.log(`Initializing fn project: "${projectName}"`);
407301
407183
  console.log(` Path: ${cwd}`);
407302
- if (!existsSync107(fusionDir)) {
407184
+ if (!existsSync108(fusionDir)) {
407303
407185
  mkdirSync21(fusionDir, { recursive: true });
407304
407186
  console.log(` \u2713 Created .fusion/ directory`);
407305
407187
  }
@@ -407380,7 +407262,7 @@ async function runInit(options = {}) {
407380
407262
  }
407381
407263
  }
407382
407264
  async function detectProjectName2(dir2) {
407383
- if (!existsSync107(join144(dir2, ".git"))) {
407265
+ if (!existsSync108(join144(dir2, ".git"))) {
407384
407266
  return basename43(dir2) || "my-project";
407385
407267
  }
407386
407268
  try {
@@ -407402,7 +407284,7 @@ async function detectProjectName2(dir2) {
407402
407284
  async function addLocalStorageToGitignore(cwd) {
407403
407285
  const gitignorePath = join144(cwd, ".gitignore");
407404
407286
  let content = "";
407405
- if (existsSync107(gitignorePath)) {
407287
+ if (existsSync108(gitignorePath)) {
407406
407288
  try {
407407
407289
  content = readFileSync42(gitignorePath, "utf-8");
407408
407290
  } catch {
@@ -407444,7 +407326,7 @@ async function initializeGitRepo(cwd) {
407444
407326
  await ensureGitConfig(cwd, "user.name", "Fusion");
407445
407327
  await ensureGitConfig(cwd, "user.email", "noreply@runfusion.ai");
407446
407328
  const gitkeepPath = join144(cwd, ".gitkeep");
407447
- if (!existsSync107(gitkeepPath)) {
407329
+ if (!existsSync108(gitkeepPath)) {
407448
407330
  writeFileSync20(gitkeepPath, "\n");
407449
407331
  }
407450
407332
  await execAsync48("git add .gitkeep", { cwd, timeout: 1e4 });
@@ -407510,7 +407392,7 @@ __export(onboard_exports, {
407510
407392
  persistLocalProviderRegistry: () => persistLocalProviderRegistry,
407511
407393
  runOnboard: () => runOnboard
407512
407394
  });
407513
- import { existsSync as existsSync108, mkdirSync as mkdirSync22, readFileSync as readFileSync43, renameSync as renameSync6, unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "node:fs";
407395
+ import { existsSync as existsSync109, mkdirSync as mkdirSync22, readFileSync as readFileSync43, renameSync as renameSync6, unlinkSync as unlinkSync8, writeFileSync as writeFileSync21 } from "node:fs";
407514
407396
  import { dirname as dirname70 } from "node:path";
407515
407397
  import { createInterface as createInterface9 } from "node:readline";
407516
407398
  function createPromptSession(input = process.stdin) {
@@ -407639,7 +407521,7 @@ function composeLocalProviderRegistry(existing, config3) {
407639
407521
  return { ...existing, providers };
407640
407522
  }
407641
407523
  function registryHasProvider(path14, providerId) {
407642
- if (!existsSync108(path14)) return false;
407524
+ if (!existsSync109(path14)) return false;
407643
407525
  try {
407644
407526
  const registry3 = JSON.parse(readFileSync43(path14, "utf8"));
407645
407527
  return isObject2(registry3) && isObject2(registry3.providers) && isObject2(registry3.providers[providerId]);
@@ -407649,7 +407531,7 @@ function registryHasProvider(path14, providerId) {
407649
407531
  }
407650
407532
  function persistLocalProviderRegistry(path14, config3) {
407651
407533
  let existing = {};
407652
- if (existsSync108(path14)) {
407534
+ if (existsSync109(path14)) {
407653
407535
  try {
407654
407536
  existing = JSON.parse(readFileSync43(path14, "utf8"));
407655
407537
  } catch {
@@ -407664,7 +407546,7 @@ function persistLocalProviderRegistry(path14, config3) {
407664
407546
  `, { mode: 384 });
407665
407547
  renameSync6(tempPath, path14);
407666
407548
  } finally {
407667
- if (existsSync108(tempPath)) unlinkSync8(tempPath);
407549
+ if (existsSync109(tempPath)) unlinkSync8(tempPath);
407668
407550
  }
407669
407551
  }
407670
407552
  function validateMaxConcurrent(input) {
@@ -407699,7 +407581,7 @@ async function runOnboard(options = {}) {
407699
407581
  const prompts = createPromptSession(options.input);
407700
407582
  try {
407701
407583
  const centralDbPath = getDefaultCentralDbPath();
407702
- if (existsSync108(centralDbPath)) {
407584
+ if (existsSync109(centralDbPath)) {
407703
407585
  console.log(`\u2713 Central DB already exists: ${centralDbPath}`);
407704
407586
  } else {
407705
407587
  const ranCentralDb = await runSkippableStep(prompts, "Central DB", async () => {
@@ -407996,7 +407878,7 @@ var agent_import_exports = {};
407996
407878
  __export(agent_import_exports, {
407997
407879
  runAgentImport: () => runAgentImport
407998
407880
  });
407999
- import { existsSync as existsSync109, mkdirSync as mkdirSync23, readFileSync as readFileSync44, statSync as statSync20, writeFileSync as writeFileSync22 } from "node:fs";
407881
+ import { existsSync as existsSync110, mkdirSync as mkdirSync23, readFileSync as readFileSync44, statSync as statSync20, writeFileSync as writeFileSync22 } from "node:fs";
408000
407882
  import { resolve as resolve92 } from "node:path";
408001
407883
  function slugifyPathSegment(input) {
408002
407884
  if (!input || typeof input !== "string") {
@@ -408055,7 +407937,7 @@ async function importSkillsToProject(projectPath, skills, companySlug, dryRun) {
408055
407937
  const skillSlug = slugifyPathSegment(skill.name);
408056
407938
  const skillDir = resolve92(baseSkillsDir, skillSlug);
408057
407939
  const skillPath = resolve92(skillDir, "SKILL.md");
408058
- if (existsSync109(skillPath)) {
407940
+ if (existsSync110(skillPath)) {
408059
407941
  result2.skipped.push(skill.name);
408060
407942
  continue;
408061
407943
  }
@@ -408116,7 +407998,7 @@ async function runAgentImport(source, options) {
408116
407998
  const dryRun = options?.dryRun ?? false;
408117
407999
  const skipExisting = options?.skipExisting ?? false;
408118
408000
  const sourcePath = resolve92(source);
408119
- if (!existsSync109(sourcePath)) {
408001
+ if (!existsSync110(sourcePath)) {
408120
408002
  console.error(`Path not found: ${sourcePath}`);
408121
408003
  process.exit(1);
408122
408004
  }
@@ -408990,7 +408872,7 @@ __export(plugin_exports2, {
408990
408872
  runPluginSetupStatus: () => runPluginSetupStatus,
408991
408873
  runPluginUninstall: () => runPluginUninstall
408992
408874
  });
408993
- import { existsSync as existsSync110 } from "node:fs";
408875
+ import { existsSync as existsSync111 } from "node:fs";
408994
408876
  import { dirname as dirname71, extname as extname6, join as join145, resolve as resolve96 } from "node:path";
408995
408877
  import { readFile as readFile63, stat as stat19 } from "node:fs/promises";
408996
408878
  import * as readline from "node:readline";
@@ -409085,7 +408967,7 @@ async function resolvePluginEntryFile(pluginDir) {
409085
408967
  }
409086
408968
  const packageJsonPath = join145(absoluteInputPath, "package.json");
409087
408969
  let selectedCandidate;
409088
- if (existsSync110(packageJsonPath)) {
408970
+ if (existsSync111(packageJsonPath)) {
409089
408971
  const packageJson = JSON.parse(await readFile63(packageJsonPath, "utf-8"));
409090
408972
  const exportsRecord = asRecord6(packageJson.exports);
409091
408973
  const dotExport = exportsRecord?.["."];
@@ -409134,7 +409016,7 @@ async function loadManifestFromPath(pluginPath) {
409134
409016
  const inputStats = await statPath(absoluteInputPath);
409135
409017
  const manifestDir = inputStats?.isFile() ? dirname71(absoluteInputPath) : absoluteInputPath;
409136
409018
  const manifestPath = join145(manifestDir, "manifest.json");
409137
- if (!existsSync110(manifestPath)) {
409019
+ if (!existsSync111(manifestPath)) {
409138
409020
  throw new Error(`Plugin manifest not found at: ${manifestPath}`);
409139
409021
  }
409140
409022
  const content = await readFile63(manifestPath, "utf-8");
@@ -409192,7 +409074,7 @@ async function runPluginInstall(source, options) {
409192
409074
  console.error("Please provide a local path to the plugin directory.");
409193
409075
  process.exit(1);
409194
409076
  }
409195
- if (!existsSync110(source)) {
409077
+ if (!existsSync111(source)) {
409196
409078
  console.error(`Plugin path does not exist: ${source}`);
409197
409079
  process.exit(1);
409198
409080
  }
@@ -409515,7 +409397,7 @@ __export(plugin_scaffold_exports, {
409515
409397
  runPluginCreate: () => runPluginCreate,
409516
409398
  runPluginNew: () => runPluginNew
409517
409399
  });
409518
- import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, existsSync as existsSync111, readFileSync as readFileSync45 } from "node:fs";
409400
+ import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, existsSync as existsSync112, readFileSync as readFileSync45 } from "node:fs";
409519
409401
  import { join as join146, dirname as dirname72, resolve as resolve97 } from "node:path";
409520
409402
  import { fileURLToPath as fileURLToPath28 } from "node:url";
409521
409403
  function toTitleCase(str) {
@@ -409536,7 +409418,7 @@ function resolveTargetPath(name2, output) {
409536
409418
  };
409537
409419
  }
409538
409420
  function ensureTargetPathAvailable(targetDir, targetPath) {
409539
- if (existsSync111(targetPath)) {
409421
+ if (existsSync112(targetPath)) {
409540
409422
  console.error(`Error: Directory '${targetDir}' already exists.`);
409541
409423
  console.error("Please choose a different name or remove the existing directory.");
409542
409424
  process.exit(1);
@@ -409551,7 +409433,7 @@ function readOwnCliVersion() {
409551
409433
  }
409552
409434
  for (let i = 0; i < 8; i += 1) {
409553
409435
  const pkgPath = resolve97(currentDir, "package.json");
409554
- if (existsSync111(pkgPath)) {
409436
+ if (existsSync112(pkgPath)) {
409555
409437
  try {
409556
409438
  const parsed = JSON.parse(readFileSync45(pkgPath, "utf-8"));
409557
409439
  if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
@@ -409913,7 +409795,7 @@ var plugin_dev_exports = {};
409913
409795
  __export(plugin_dev_exports, {
409914
409796
  runPluginDev: () => runPluginDev
409915
409797
  });
409916
- import { existsSync as existsSync112, watch as watch2 } from "node:fs";
409798
+ import { existsSync as existsSync113, watch as watch2 } from "node:fs";
409917
409799
  import { join as join147, resolve as resolve98 } from "node:path";
409918
409800
  async function runSupervisedCommand(command, cwd, timeoutMs = 12e4) {
409919
409801
  await new Promise((resolvePromise, rejectPromise) => {
@@ -409959,7 +409841,7 @@ async function defaultBuildFn(pluginDir) {
409959
409841
  await runSupervisedCommand("npm run build", pluginDir);
409960
409842
  }
409961
409843
  function defaultWatchFn(pluginDir, onChange) {
409962
- const watchPath = existsSync112(join147(pluginDir, "src")) ? join147(pluginDir, "src") : pluginDir;
409844
+ const watchPath = existsSync113(join147(pluginDir, "src")) ? join147(pluginDir, "src") : pluginDir;
409963
409845
  try {
409964
409846
  const watcher = watch2(watchPath, { recursive: true }, onChange);
409965
409847
  return { close: () => watcher.close() };
@@ -409975,7 +409857,7 @@ function shouldUseWatcher(options) {
409975
409857
  return Boolean(process.stdout.isTTY && process.stdin.isTTY);
409976
409858
  }
409977
409859
  async function runPluginDev(source, options) {
409978
- if (!existsSync112(source)) {
409860
+ if (!existsSync113(source)) {
409979
409861
  console.error(`Plugin path does not exist: ${source}`);
409980
409862
  process.exit(1);
409981
409863
  }
@@ -410095,7 +409977,7 @@ __export(plugin_publish_exports, {
410095
409977
  collectPluginPreflight: () => collectPluginPreflight,
410096
409978
  runPluginPublish: () => runPluginPublish
410097
409979
  });
410098
- import { existsSync as existsSync113 } from "node:fs";
409980
+ import { existsSync as existsSync114 } from "node:fs";
410099
409981
  import { readFile as readFile64 } from "node:fs/promises";
410100
409982
  import { join as join148, resolve as resolve99 } from "node:path";
410101
409983
  import { pathToFileURL as pathToFileURL2 } from "node:url";
@@ -410256,7 +410138,7 @@ function statusIcon(status) {
410256
410138
  return "\u2717";
410257
410139
  }
410258
410140
  async function runPluginPublish(source, options) {
410259
- if (!existsSync113(source)) {
410141
+ if (!existsSync114(source)) {
410260
410142
  console.error(`Plugin path does not exist: ${source}`);
410261
410143
  process.exit(1);
410262
410144
  }
@@ -410825,7 +410707,7 @@ __export(update_exports, {
410825
410707
  runUpdate: () => runUpdate
410826
410708
  });
410827
410709
  import { exec as exec52 } from "node:child_process";
410828
- import { existsSync as existsSync114, readFileSync as readFileSync46 } from "node:fs";
410710
+ import { existsSync as existsSync115, readFileSync as readFileSync46 } from "node:fs";
410829
410711
  import { promisify as promisify78 } from "node:util";
410830
410712
  import { dirname as dirname73, resolve as resolve102 } from "node:path";
410831
410713
  import { fileURLToPath as fileURLToPath29 } from "node:url";
@@ -410888,7 +410770,7 @@ function readOwnCliVersion2() {
410888
410770
  }
410889
410771
  for (let i = 0; i < 8; i += 1) {
410890
410772
  const pkgPath = resolve102(currentDir, "package.json");
410891
- if (existsSync114(pkgPath)) {
410773
+ if (existsSync115(pkgPath)) {
410892
410774
  try {
410893
410775
  const parsed = JSON.parse(readFileSync46(pkgPath, "utf-8"));
410894
410776
  if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
@@ -411169,7 +411051,7 @@ __export(onboard_autolaunch_exports, {
411169
411051
  maybeAutoLaunchOnboarding: () => maybeAutoLaunchOnboarding,
411170
411052
  shouldAutoLaunchOnboarding: () => shouldAutoLaunchOnboarding
411171
411053
  });
411172
- import { existsSync as existsSync115 } from "node:fs";
411054
+ import { existsSync as existsSync116 } from "node:fs";
411173
411055
  import { join as join150 } from "node:path";
411174
411056
  function shouldAutoLaunchOnboarding(input) {
411175
411057
  const env = input.env ?? process.env;
@@ -411234,7 +411116,7 @@ async function maybeAutoLaunchOnboarding(deps) {
411234
411116
  let centralDbExists = true;
411235
411117
  let projectInitialized = false;
411236
411118
  try {
411237
- const pathExists4 = deps.pathExists ?? existsSync115;
411119
+ const pathExists4 = deps.pathExists ?? existsSync116;
411238
411120
  const centralDbPath = deps.centralDbPath ?? getDefaultCentralDbPath();
411239
411121
  const cwd = deps.cwd ?? process.cwd();
411240
411122
  const projectMarkerPath = join150(cwd, ".fusion", "project.json");
@@ -411295,7 +411177,7 @@ __export(native_patch_exports, {
411295
411177
  setupNativeResolution: () => setupNativeResolution
411296
411178
  });
411297
411179
  import { join as join151, basename as basename44, dirname as dirname74 } from "node:path";
411298
- import { existsSync as existsSync116, copyFileSync as copyFileSync2, mkdirSync as mkdirSync25, symlinkSync as symlinkSync7, rmSync as rmSync16, lstatSync as lstatSync7, readlinkSync as readlinkSync5 } from "node:fs";
411180
+ import { existsSync as existsSync117, copyFileSync as copyFileSync2, mkdirSync as mkdirSync25, symlinkSync as symlinkSync7, rmSync as rmSync16, lstatSync as lstatSync7, readlinkSync as readlinkSync5 } from "node:fs";
411299
411181
  import { tmpdir as tmpdir22 } from "node:os";
411300
411182
  function findStagedNativeDir2() {
411301
411183
  const platform6 = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : process.platform === "win32" ? "win32" : "unknown";
@@ -411303,12 +411185,12 @@ function findStagedNativeDir2() {
411303
411185
  const prebuildName = `${platform6}-${arch}`;
411304
411186
  const execDir = dirname74(process.execPath);
411305
411187
  const nextToBinary = join151(execDir, "runtime", prebuildName);
411306
- if (existsSync116(join151(nextToBinary, "pty.node"))) {
411188
+ if (existsSync117(join151(nextToBinary, "pty.node"))) {
411307
411189
  return nextToBinary;
411308
411190
  }
411309
411191
  if (process.env.FUSION_RUNTIME_DIR) {
411310
411192
  const envPath = join151(process.env.FUSION_RUNTIME_DIR, prebuildName);
411311
- if (existsSync116(join151(envPath, "pty.node"))) {
411193
+ if (existsSync117(join151(envPath, "pty.node"))) {
411312
411194
  return envPath;
411313
411195
  }
411314
411196
  }
@@ -411318,11 +411200,11 @@ function cleanupStaleBunfsLinks() {
411318
411200
  if (process.platform === "win32") return;
411319
411201
  const bunfsRoot = "/$bunfs/root";
411320
411202
  try {
411321
- if (existsSync116(bunfsRoot)) {
411203
+ if (existsSync117(bunfsRoot)) {
411322
411204
  const stats = lstatSync7(bunfsRoot);
411323
411205
  if (stats.isSymbolicLink()) {
411324
411206
  const target = readlinkSync5(bunfsRoot);
411325
- if (target.includes("fn-bunfs-") && !existsSync116(target)) {
411207
+ if (target.includes("fn-bunfs-") && !existsSync117(target)) {
411326
411208
  rmSync16(bunfsRoot);
411327
411209
  console.log("[fn-native-patch] Cleaned up stale /$bunfs/root symlink");
411328
411210
  }
@@ -411350,14 +411232,14 @@ function setupNativeResolution() {
411350
411232
  mkdirSync25(platformDir, { recursive: true });
411351
411233
  const ptyNodeDest = join151(platformDir, "pty.node");
411352
411234
  copyFileSync2(join151(nativeDir, "pty.node"), ptyNodeDest);
411353
- if (existsSync116(join151(nativeDir, "spawn-helper"))) {
411235
+ if (existsSync117(join151(nativeDir, "spawn-helper"))) {
411354
411236
  copyFileSync2(join151(nativeDir, "spawn-helper"), join151(platformDir, "spawn-helper"));
411355
411237
  }
411356
411238
  process.env.FUSION_FAKE_BUNFS_ROOT = tmpRoot;
411357
411239
  if (process.platform !== "win32") {
411358
411240
  const bunfsRoot = "/$bunfs/root";
411359
411241
  try {
411360
- if (existsSync116(bunfsRoot)) {
411242
+ if (existsSync117(bunfsRoot)) {
411361
411243
  const stats = lstatSync7(bunfsRoot);
411362
411244
  if (stats.isSymbolicLink()) {
411363
411245
  rmSync16(bunfsRoot);
@@ -411380,7 +411262,7 @@ function setupNativeResolution() {
411380
411262
  function cleanupNativeResolution() {
411381
411263
  if (bunfsSymlinkPath && process.platform !== "win32") {
411382
411264
  try {
411383
- if (existsSync116(bunfsSymlinkPath)) {
411265
+ if (existsSync117(bunfsSymlinkPath)) {
411384
411266
  const stats = lstatSync7(bunfsSymlinkPath);
411385
411267
  if (stats.isSymbolicLink()) {
411386
411268
  rmSync16(bunfsSymlinkPath);
@@ -411427,7 +411309,7 @@ var init_native_patch = __esm({
411427
411309
 
411428
411310
  // src/bin.ts
411429
411311
  init_output();
411430
- import { existsSync as existsSync117, mkdtempSync as mkdtempSync5, readFileSync as readFileSync47, symlinkSync as symlinkSync8, writeFileSync as writeFileSync24 } from "node:fs";
411312
+ import { existsSync as existsSync118, mkdtempSync as mkdtempSync5, readFileSync as readFileSync47, symlinkSync as symlinkSync8, writeFileSync as writeFileSync24 } from "node:fs";
411431
411313
  import { createRequire as createRequire14 } from "node:module";
411432
411314
  import { join as join152, dirname as dirname75, resolve as resolve103 } from "node:path";
411433
411315
  import { tmpdir as tmpdir23 } from "node:os";
@@ -411452,7 +411334,7 @@ function configurePiPackage() {
411452
411334
  packageJson = JSON.parse(readFileSync47(piPackagePath, "utf-8"));
411453
411335
  for (const entry of ["dist", "docs", "examples", "README.md", "CHANGELOG.md"]) {
411454
411336
  const source = join152(piPackageDir, entry);
411455
- if (existsSync117(source)) {
411337
+ if (existsSync118(source)) {
411456
411338
  symlinkSync8(source, join152(tmp, entry));
411457
411339
  }
411458
411340
  }
@@ -411472,7 +411354,7 @@ setInterval(() => {
411472
411354
  performance4.clearResourceTimings();
411473
411355
  }, 1e3).unref();
411474
411356
  function loadEnvFile(path14) {
411475
- if (!existsSync117(path14)) return;
411357
+ if (!existsSync118(path14)) return;
411476
411358
  const contents = readFileSync47(path14, "utf-8");
411477
411359
  for (const rawLine of contents.split(/\r?\n/)) {
411478
411360
  const line2 = rawLine.trim();
@@ -411995,7 +411877,7 @@ function readOwnCliVersion3() {
411995
411877
  }
411996
411878
  for (let i = 0; i < 8; i += 1) {
411997
411879
  const pkgPath = resolve103(currentDir, "package.json");
411998
- if (existsSync117(pkgPath)) {
411880
+ if (existsSync118(pkgPath)) {
411999
411881
  try {
412000
411882
  const parsed = JSON.parse(readFileSync47(pkgPath, "utf-8"));
412001
411883
  if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {