@runfusion/fusion 0.74.0-beta.2 → 0.74.0-beta.3

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 (112) hide show
  1. package/dist/bin.js +847 -655
  2. package/dist/child-process-worker.js +414 -231
  3. package/dist/client/.vite/manifest.json +268 -268
  4. package/dist/client/assets/{AgentDetailView-DH4Cn5iG.js → AgentDetailView-D0J_GDct.js} +1 -1
  5. package/dist/client/assets/{AgentPermissionPolicyEditor-BycC7HhP.js → AgentPermissionPolicyEditor-BBAwprvO.js} +1 -1
  6. package/dist/client/assets/{AgentsView-Dkij8Sm8.js → AgentsView-DTY5DIav.js} +3 -3
  7. package/dist/client/assets/{ChatView-DAsZY1We.js → ChatView-CRoW2tRJ.js} +1 -1
  8. package/dist/client/assets/{CommandCenter-jTzBo-pg.js → CommandCenter-BieyKvKb.js} +1 -1
  9. package/dist/client/assets/{DevServerView-CxlacYJp.js → DevServerView-CLR1LmhK.js} +1 -1
  10. package/dist/client/assets/{DirectoryPicker-DsCk3Nsw.js → DirectoryPicker-B-olNAvT.js} +1 -1
  11. package/dist/client/assets/{DocumentsView-8EI6KNBY.js → DocumentsView-CG_-pnXU.js} +1 -1
  12. package/dist/client/assets/{EvalsView-kYnaIk11.js → EvalsView-Xp0zCUlr.js} +1 -1
  13. package/dist/client/assets/{ExperimentalAgentOnboardingModal-ce6DROKD.js → ExperimentalAgentOnboardingModal-z8m5V5yv.js} +1 -1
  14. package/dist/client/assets/{GoalsView-BVlTtw-u.js → GoalsView-Bd-4g949.js} +1 -1
  15. package/dist/client/assets/{InsightsView-BKQeROkb.js → InsightsView-tCgg66wJ.js} +1 -1
  16. package/dist/client/assets/{MemoryView-DCzTnxsV.js → MemoryView-Dqgsd_0E.js} +1 -1
  17. package/dist/client/assets/{PiExtensionsManager-C94HwDz5.js → PiExtensionsManager-GzGoWgb5.js} +1 -1
  18. package/dist/client/assets/{PluginManager-C3DegklW.js → PluginManager-BWdqEqr9.js} +1 -1
  19. package/dist/client/assets/{PullRequestView-CrE89UL7.js → PullRequestView-CQq1G1kY.js} +1 -1
  20. package/dist/client/assets/{ReportModal-BD1ZUDdV.js → ReportModal-C-3rBFhw.js} +1 -1
  21. package/dist/client/assets/{ResearchView-eMiRw1EM.js → ResearchView-CS1HwDg_.js} +1 -1
  22. package/dist/client/assets/{SecretsView-6qK8Idb7.js → SecretsView-C6RP9Rkw.js} +1 -1
  23. package/dist/client/assets/{SessionTerminal-DtFLyUaK.js → SessionTerminal-C9nCSefk.js} +1 -1
  24. package/dist/client/assets/SettingsModal-C1oEklYy.css +1 -0
  25. package/dist/client/assets/{SettingsModal-BkOSlfyr.js → SettingsModal-D3DCvCfP.js} +1 -1
  26. package/dist/client/assets/{SettingsModal-DSq-_qwo.js → SettingsModal-D4mjT8hw.js} +3 -3
  27. package/dist/client/assets/{SettingsTextareaRow-Btyx5kaR.js → SettingsTextareaRow-zBVXQbcC.js} +1 -1
  28. package/dist/client/assets/{SetupWizardModal-Blhx-dRt.js → SetupWizardModal-C9r1dd-h.js} +2 -2
  29. package/dist/client/assets/{SkillsView-DGE5kYc3.js → SkillsView-DFyUBWd8.js} +1 -1
  30. package/dist/client/assets/{TodoView-YSGI7ATd.js → TodoView-BC8f952m.js} +1 -1
  31. package/dist/client/assets/{WorkflowNodeEditor-CZiEThu2.js → WorkflowNodeEditor-UTX757WH.js} +1 -1
  32. package/dist/client/assets/{agent-import-generation-DQeNZMAm.js → agent-import-generation-DN0q1xEo.js} +1 -1
  33. package/dist/client/assets/{app-DJIiVHdA.js → app-BP57l_5h.js} +1 -1
  34. package/dist/client/assets/{app-hQw_x2KJ.js → app-D4frL0Ka.js} +1 -1
  35. package/dist/client/assets/{app-DaikOPcV.js → app-niWDkeV8.js} +3 -3
  36. package/dist/client/assets/{app-Dn1u7zJ9.js → app-sLOwmHAE.js} +1 -1
  37. package/dist/client/assets/{app-DMZ_RusZ.js → app-vRWwM-aD.js} +1 -1
  38. package/dist/client/assets/{app-DxTbBEMH.js → app-zPyey_fg.js} +1 -1
  39. package/dist/client/assets/{architectureDiagram-3BPJPVTR-DhaJNKa4.js → architectureDiagram-3BPJPVTR-D-nqJ95-.js} +1 -1
  40. package/dist/client/assets/{blockDiagram-GPEHLZMM-pKpg7gJU.js → blockDiagram-GPEHLZMM--OlkXlyS.js} +1 -1
  41. package/dist/client/assets/{c4Diagram-AAUBKEIU-DVPXKJnr.js → c4Diagram-AAUBKEIU-CH7PaWgs.js} +1 -1
  42. package/dist/client/assets/channel-FJNMzlkv.js +1 -0
  43. package/dist/client/assets/{chunk-2J33WTMH-CHt90T5z.js → chunk-2J33WTMH-CpHDwqg2.js} +1 -1
  44. package/dist/client/assets/{chunk-4BX2VUAB-DsWFYy0a.js → chunk-4BX2VUAB-BdW4tdnc.js} +1 -1
  45. package/dist/client/assets/{chunk-55IACEB6-D8XiXEo8.js → chunk-55IACEB6-b3tBFiuH.js} +1 -1
  46. package/dist/client/assets/{chunk-727SXJPM-DlUYBn_Y.js → chunk-727SXJPM-DifknEtv.js} +1 -1
  47. package/dist/client/assets/{chunk-AQP2D5EJ-BSdPOr9q.js → chunk-AQP2D5EJ-DHIZNZ4Z.js} +1 -1
  48. package/dist/client/assets/{chunk-FMBD7UC4-B9IAeBld.js → chunk-FMBD7UC4-BLRLYW2y.js} +1 -1
  49. package/dist/client/assets/{chunk-ND2GUHAM-CmxnYQrR.js → chunk-ND2GUHAM-Dh8f06Ld.js} +1 -1
  50. package/dist/client/assets/{chunk-QZHKN3VN-Dxp6Po_j.js → chunk-QZHKN3VN-CpzUiemt.js} +1 -1
  51. package/dist/client/assets/classDiagram-4FO5ZUOK-BOenhjVP.js +1 -0
  52. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BOenhjVP.js +1 -0
  53. package/dist/client/assets/common-13IRj_PO.js +1 -0
  54. package/dist/client/assets/common-BBynATth.js +1 -0
  55. package/dist/client/assets/common-BG-vw0tL.js +1 -0
  56. package/dist/client/assets/common-DSo46rnH.js +1 -0
  57. package/dist/client/assets/common-DbOCE-0i.js +1 -0
  58. package/dist/client/assets/common-DnXF4Jmj.js +1 -0
  59. package/dist/client/assets/{cose-bilkent-S5V4N54A-BNl3bhpS.js → cose-bilkent-S5V4N54A-CE2RJ_k0.js} +1 -1
  60. package/dist/client/assets/{dagre-BM42HDAG-DFs7WCcz.js → dagre-BM42HDAG-CCs_xlYw.js} +1 -1
  61. package/dist/client/assets/{dashboard-view-vc8kgLMs.js → dashboard-view-D5qv61fP.js} +1 -1
  62. package/dist/client/assets/{dashboard-view-ZGxLEL9r.js → dashboard-view-Eg7Jyvnm.js} +1 -1
  63. package/dist/client/assets/{dashboard-view-DnoTcnIo.js → dashboard-view-Z6H-k0uR.js} +1 -1
  64. package/dist/client/assets/{diagram-2AECGRRQ-C2PVozvu.js → diagram-2AECGRRQ-CF60Q-de.js} +1 -1
  65. package/dist/client/assets/{diagram-5GNKFQAL-DFJ5b9H8.js → diagram-5GNKFQAL-DDcGMlua.js} +1 -1
  66. package/dist/client/assets/{diagram-KO2AKTUF-D335CW-c.js → diagram-KO2AKTUF-YgvJ4DQf.js} +1 -1
  67. package/dist/client/assets/{diagram-LMA3HP47-DSfhroAW.js → diagram-LMA3HP47-Bi-j9nGw.js} +1 -1
  68. package/dist/client/assets/{diagram-OG6HWLK6-8iGveM-Z.js → diagram-OG6HWLK6-DEmMqnwc.js} +1 -1
  69. package/dist/client/assets/{erDiagram-TEJ5UH35-Xc56MEEi.js → erDiagram-TEJ5UH35-DwmZwhiW.js} +1 -1
  70. package/dist/client/assets/{flowDiagram-I6XJVG4X-DjCU9WbD.js → flowDiagram-I6XJVG4X-B5ITa_HJ.js} +1 -1
  71. package/dist/client/assets/{folder-open-BRrB44UX.js → folder-open-BVxA7YtM.js} +1 -1
  72. package/dist/client/assets/{ganttDiagram-6RSMTGT7-CXQE1bea.js → ganttDiagram-6RSMTGT7-BgAPwh9w.js} +1 -1
  73. package/dist/client/assets/{gitGraphDiagram-PVQCEYII--mrSABLC.js → gitGraphDiagram-PVQCEYII-DTtGzZFj.js} +1 -1
  74. package/dist/client/assets/{index-C2xsZoNG.js → index-idkERMsE.js} +289 -289
  75. package/dist/client/assets/{infoDiagram-5YYISTIA-CTS_nljP.js → infoDiagram-5YYISTIA-CkSnTje1.js} +1 -1
  76. package/dist/client/assets/{ishikawaDiagram-YF4QCWOH-CpV5x3gk.js → ishikawaDiagram-YF4QCWOH-jn5VNpMh.js} +1 -1
  77. package/dist/client/assets/{journeyDiagram-JHISSGLW-BK2QCMnt.js → journeyDiagram-JHISSGLW-BpaqoXaI.js} +1 -1
  78. package/dist/client/assets/{kanban-definition-UN3LZRKU-B4srpspY.js → kanban-definition-UN3LZRKU-CpfjJoBN.js} +1 -1
  79. package/dist/client/assets/{mermaid.core-B8DVAt21.js → mermaid.core-DZNGPQzF.js} +4 -4
  80. package/dist/client/assets/{mindmap-definition-RKZ34NQL-CsmmiPpA.js → mindmap-definition-RKZ34NQL-BdbX1EJa.js} +1 -1
  81. package/dist/client/assets/{pieDiagram-4H26LBE5-BahLDqf4.js → pieDiagram-4H26LBE5-Xn0322tJ.js} +1 -1
  82. package/dist/client/assets/{puzzle-BFPQsuIa.js → puzzle-CPx1RP2g.js} +1 -1
  83. package/dist/client/assets/{quadrantDiagram-W4KKPZXB-Bo3u0wTU.js → quadrantDiagram-W4KKPZXB-OOHqqw5y.js} +1 -1
  84. package/dist/client/assets/{requirementDiagram-4Y6WPE33-DYkYsz7d.js → requirementDiagram-4Y6WPE33-Dvj6zvaB.js} +1 -1
  85. package/dist/client/assets/{sankeyDiagram-5OEKKPKP-BCbh0BSY.js → sankeyDiagram-5OEKKPKP-DEkEqthK.js} +1 -1
  86. package/dist/client/assets/{sequenceDiagram-3UESZ5HK-C2AP9GlE.js → sequenceDiagram-3UESZ5HK-BPc9ncPj.js} +1 -1
  87. package/dist/client/assets/{shield-alert-tlZOi02c.js → shield-alert-baoKRyU6.js} +1 -1
  88. package/dist/client/assets/{standing-instructions-template-C0Rzv9Mr.js → standing-instructions-template-CkqsGC1L.js} +1 -1
  89. package/dist/client/assets/{stateDiagram-AJRCARHV-CARkH0ug.js → stateDiagram-AJRCARHV-DywhjHIx.js} +1 -1
  90. package/dist/client/assets/{stateDiagram-v2-BHNVJYJU-C2He043y.js → stateDiagram-v2-BHNVJYJU-D7t7x4uT.js} +1 -1
  91. package/dist/client/assets/{timeline-definition-PNZ67QCA-MvbYneEM.js → timeline-definition-PNZ67QCA-BH3CKgrg.js} +1 -1
  92. package/dist/client/assets/{upload-DWK0F17Z.js → upload-DtIvOGwM.js} +1 -1
  93. package/dist/client/assets/{users-1AkDfM14.js → users-DcxsxPlj.js} +1 -1
  94. package/dist/client/assets/{vennDiagram-CIIHVFJN-DOjzzLqc.js → vennDiagram-CIIHVFJN-CCDllBgJ.js} +1 -1
  95. package/dist/client/assets/{wardley-L42UT6IY-Di70vhu2.js → wardley-L42UT6IY-C43hFLXh.js} +1 -1
  96. package/dist/client/assets/{wardleyDiagram-YWT4CUSO-nK6ARhDv.js → wardleyDiagram-YWT4CUSO-__f9rI8w.js} +1 -1
  97. package/dist/client/assets/{xychartDiagram-2RQKCTM6-C7_y76B7.js → xychartDiagram-2RQKCTM6-DY-fpQ_x.js} +1 -1
  98. package/dist/client/index.html +1 -1
  99. package/dist/client/version.json +1 -1
  100. package/dist/extension.js +551 -368
  101. package/package.json +1 -1
  102. package/skill/fusion/references/engine-tools.md +1 -1
  103. package/dist/client/assets/SettingsModal-BTfZlghk.css +0 -1
  104. package/dist/client/assets/channel-xFBfK0sX.js +0 -1
  105. package/dist/client/assets/classDiagram-4FO5ZUOK-BFBVD968.js +0 -1
  106. package/dist/client/assets/classDiagram-v2-Q7XG4LA2-BFBVD968.js +0 -1
  107. package/dist/client/assets/common-BDp2y6CF.js +0 -1
  108. package/dist/client/assets/common-BnEo5fLN.js +0 -1
  109. package/dist/client/assets/common-Bzr_Y8h4.js +0 -1
  110. package/dist/client/assets/common-CvwyFzfv.js +0 -1
  111. package/dist/client/assets/common-CztCXRkz.js +0 -1
  112. package/dist/client/assets/common-DPe2mbb7.js +0 -1
package/dist/bin.js CHANGED
@@ -5605,7 +5605,7 @@ var init_sql = __esm({
5605
5605
  return new SQL([new StringChunk(str)]);
5606
5606
  }
5607
5607
  sql2.raw = raw;
5608
- function join155(chunks, separator) {
5608
+ function join156(chunks, separator) {
5609
5609
  const result2 = [];
5610
5610
  for (const [i, chunk] of chunks.entries()) {
5611
5611
  if (i > 0 && separator !== void 0) {
@@ -5615,7 +5615,7 @@ var init_sql = __esm({
5615
5615
  }
5616
5616
  return new SQL(result2);
5617
5617
  }
5618
- sql2.join = join155;
5618
+ sql2.join = join156;
5619
5619
  function identifier(value) {
5620
5620
  return new Name(value);
5621
5621
  }
@@ -10263,7 +10263,7 @@ var init_select2 = __esm({
10263
10263
  const baseTableName = this.tableName;
10264
10264
  const tableName = getTableLikeName(table);
10265
10265
  for (const item of extractUsedTable(table)) this.usedTables.add(item);
10266
- if (typeof tableName === "string" && this.config.joins?.some((join155) => join155.alias === tableName)) {
10266
+ if (typeof tableName === "string" && this.config.joins?.some((join156) => join156.alias === tableName)) {
10267
10267
  throw new Error(`Alias "${tableName}" is already used in this query`);
10268
10268
  }
10269
10269
  if (!this.isPartialSelect) {
@@ -11798,7 +11798,7 @@ var init_update = __esm({
11798
11798
  createJoin(joinType) {
11799
11799
  return (table, on) => {
11800
11800
  const tableName = getTableLikeName(table);
11801
- if (typeof tableName === "string" && this.config.joins.some((join155) => join155.alias === tableName)) {
11801
+ if (typeof tableName === "string" && this.config.joins.some((join156) => join156.alias === tableName)) {
11802
11802
  throw new Error(`Alias "${tableName}" is already used in this query`);
11803
11803
  }
11804
11804
  if (typeof on === "function") {
@@ -11894,10 +11894,10 @@ var init_update = __esm({
11894
11894
  const fromFields = this.getTableLikeFields(this.config.from);
11895
11895
  fields[tableName] = fromFields;
11896
11896
  }
11897
- for (const join155 of this.config.joins) {
11898
- const tableName2 = getTableLikeName(join155.table);
11899
- if (typeof tableName2 === "string" && !is(join155.table, SQL)) {
11900
- const fromFields = this.getTableLikeFields(join155.table);
11897
+ for (const join156 of this.config.joins) {
11898
+ const tableName2 = getTableLikeName(join156.table);
11899
+ if (typeof tableName2 === "string" && !is(join156.table, SQL)) {
11900
+ const fromFields = this.getTableLikeFields(join156.table);
11901
11901
  fields[tableName2] = fromFields;
11902
11902
  }
11903
11903
  }
@@ -20501,26 +20501,26 @@ function validateParallelism(nodes2, outgoing, nodesById) {
20501
20501
  }
20502
20502
  const joinsReached = /* @__PURE__ */ new Set();
20503
20503
  for (const edge of branchEdges) {
20504
- const join156 = walkBranchToJoin(edge.to, split.id, outgoing, nodesById);
20505
- if (!join156) {
20504
+ const join157 = walkBranchToJoin(edge.to, split.id, outgoing, nodesById);
20505
+ if (!join157) {
20506
20506
  throw new WorkflowIrError(`split '${split.id}' has a branch with no reachable matching join`);
20507
20507
  }
20508
- joinsReached.add(join156);
20508
+ joinsReached.add(join157);
20509
20509
  }
20510
20510
  if (joinsReached.size !== 1) {
20511
20511
  throw new WorkflowIrError(`split '${split.id}' branches converge on more than one join`);
20512
20512
  }
20513
20513
  const joinId = [...joinsReached][0];
20514
- const join155 = nodesById.get(joinId);
20515
- const mode = join155.config?.mode;
20514
+ const join156 = nodesById.get(joinId);
20515
+ const mode = join156.config?.mode;
20516
20516
  if (mode && typeof mode === "object" && "quorum" in mode) {
20517
20517
  const n = mode.quorum;
20518
20518
  if (typeof n !== "number" || !Number.isInteger(n) || n < 1) {
20519
- throw new WorkflowIrError(`join '${join155.id}' quorum must be a positive integer`);
20519
+ throw new WorkflowIrError(`join '${join156.id}' quorum must be a positive integer`);
20520
20520
  }
20521
20521
  if (n > branchEdges.length) {
20522
20522
  throw new WorkflowIrError(
20523
- `join '${join155.id}' quorum(${n}) exceeds the split's ${branchEdges.length} branches`
20523
+ `join '${join156.id}' quorum(${n}) exceeds the split's ${branchEdges.length} branches`
20524
20524
  );
20525
20525
  }
20526
20526
  }
@@ -24076,14 +24076,14 @@ async function detectWorkspaceRepos(dir2, runner = runGitCommand, timeout2 = DEF
24076
24076
  return [];
24077
24077
  }
24078
24078
  const { stat: stat20 } = await import("node:fs/promises");
24079
- const { join: join155 } = await import("node:path");
24079
+ const { join: join156 } = await import("node:path");
24080
24080
  const found = [];
24081
24081
  const EXCLUDED_ENTRIES = /* @__PURE__ */ new Set(["node_modules", ".fusion", ".git", ".pi"]);
24082
24082
  for (const entry of entries) {
24083
24083
  if (EXCLUDED_ENTRIES.has(entry)) continue;
24084
- const childDir = join155(dir2, entry);
24084
+ const childDir = join156(dir2, entry);
24085
24085
  try {
24086
- const s3 = await stat20(join155(childDir, ".git"));
24086
+ const s3 = await stat20(join156(childDir, ".git"));
24087
24087
  if (!s3.isDirectory() && !s3.isFile()) continue;
24088
24088
  } catch {
24089
24089
  continue;
@@ -24096,9 +24096,9 @@ async function detectWorkspaceRepos(dir2, runner = runGitCommand, timeout2 = DEF
24096
24096
  }
24097
24097
  async function isWorkspaceModeExplicitlyDisabled(projectPath) {
24098
24098
  try {
24099
- const { readFile: readFile63 } = await import("node:fs/promises");
24100
- const { join: join155 } = await import("node:path");
24101
- const raw = await readFile63(join155(projectPath, ".fusion", "config.json"), "utf-8");
24099
+ const { readFile: readFile64 } = await import("node:fs/promises");
24100
+ const { join: join156 } = await import("node:path");
24101
+ const raw = await readFile64(join156(projectPath, ".fusion", "config.json"), "utf-8");
24102
24102
  const config3 = JSON.parse(raw);
24103
24103
  return config3.settings?.workspaceMode === false;
24104
24104
  } catch {
@@ -24106,12 +24106,12 @@ async function isWorkspaceModeExplicitlyDisabled(projectPath) {
24106
24106
  }
24107
24107
  }
24108
24108
  async function setWorkspaceModeInConfig(projectPath, value) {
24109
- const { readFile: readFile63, writeFile: writeFile44, mkdir: mkdir42 } = await import("node:fs/promises");
24110
- const { join: join155 } = await import("node:path");
24111
- const configPath = join155(projectPath, ".fusion", "config.json");
24109
+ const { readFile: readFile64, writeFile: writeFile44, mkdir: mkdir42 } = await import("node:fs/promises");
24110
+ const { join: join156 } = await import("node:path");
24111
+ const configPath = join156(projectPath, ".fusion", "config.json");
24112
24112
  let config3 = {};
24113
24113
  try {
24114
- config3 = JSON.parse(await readFile63(configPath, "utf-8"));
24114
+ config3 = JSON.parse(await readFile64(configPath, "utf-8"));
24115
24115
  } catch (err) {
24116
24116
  if (err?.code !== "ENOENT") throw err;
24117
24117
  }
@@ -24120,7 +24120,7 @@ async function setWorkspaceModeInConfig(projectPath, value) {
24120
24120
  }
24121
24121
  const settings = config3.settings;
24122
24122
  settings.workspaceMode = value;
24123
- await mkdir42(join155(projectPath, ".fusion"), { recursive: true });
24123
+ await mkdir42(join156(projectPath, ".fusion"), { recursive: true });
24124
24124
  await writeFile44(configPath, JSON.stringify(config3, null, 2), "utf-8");
24125
24125
  }
24126
24126
  function isInRootRelativePath(entry, pathMod) {
@@ -24133,12 +24133,12 @@ function isInRootRelativePath(entry, pathMod) {
24133
24133
  return true;
24134
24134
  }
24135
24135
  async function loadWorkspaceConfig(rootDir) {
24136
- const { readFile: readFile63 } = await import("node:fs/promises");
24136
+ const { readFile: readFile64 } = await import("node:fs/promises");
24137
24137
  const pathMod = await import("node:path");
24138
- const { join: join155 } = pathMod;
24139
- const configPath = join155(rootDir, ".fusion", WORKSPACE_CONFIG_FILENAME);
24138
+ const { join: join156 } = pathMod;
24139
+ const configPath = join156(rootDir, ".fusion", WORKSPACE_CONFIG_FILENAME);
24140
24140
  try {
24141
- const raw = await readFile63(configPath, "utf-8");
24141
+ const raw = await readFile64(configPath, "utf-8");
24142
24142
  const parsed = JSON.parse(raw);
24143
24143
  if (parsed !== null && typeof parsed === "object" && "repos" in parsed && Array.isArray(parsed.repos) && parsed.repos.every((r) => typeof r === "string")) {
24144
24144
  const rawRepos = parsed.repos;
@@ -24152,11 +24152,11 @@ async function loadWorkspaceConfig(rootDir) {
24152
24152
  }
24153
24153
  async function saveWorkspaceConfig(rootDir, config3) {
24154
24154
  const { mkdir: mkdir42, writeFile: writeFile44 } = await import("node:fs/promises");
24155
- const { join: join155 } = await import("node:path");
24156
- const fusionDir = join155(rootDir, ".fusion");
24155
+ const { join: join156 } = await import("node:path");
24156
+ const fusionDir = join156(rootDir, ".fusion");
24157
24157
  await mkdir42(fusionDir, { recursive: true });
24158
24158
  await writeFile44(
24159
- join155(fusionDir, WORKSPACE_CONFIG_FILENAME),
24159
+ join156(fusionDir, WORKSPACE_CONFIG_FILENAME),
24160
24160
  JSON.stringify(config3, null, 2),
24161
24161
  "utf-8"
24162
24162
  );
@@ -38985,11 +38985,11 @@ async function rekeyFallbackProjectPartition(db, fallbackProjectId, registeredPr
38985
38985
  const parentKey = `${fk.parentSchema}.${fk.parentTable}`;
38986
38986
  if (!targetKeys.has(parentKey)) continue;
38987
38987
  const childTarget = targetKeys.has(`${fk.childSchema}.${fk.childTable}`);
38988
- const join155 = fk.childColumns.map((column, index3) => `child.${quoteIdentifier(column)} IS NOT DISTINCT FROM parent.${quoteIdentifier(fk.parentColumns[index3])}`).join(" AND ");
38988
+ const join156 = fk.childColumns.map((column, index3) => `child.${quoteIdentifier(column)} IS NOT DISTINCT FROM parent.${quoteIdentifier(fk.parentColumns[index3])}`).join(" AND ");
38989
38989
  const registeredChildScope = childTarget ? ` AND child.${quoteIdentifier("project_id")} = ${quoteLiteral(registeredProjectId)}` : "";
38990
38990
  const unreplaced = await tx.execute(sql.raw(`SELECT EXISTS (
38991
38991
  SELECT 1 FROM ${relationName({ schema: fk.childSchema, table: fk.childTable })} child
38992
- JOIN ${relationName({ schema: fk.parentSchema, table: fk.parentTable })} parent ON ${join155}
38992
+ JOIN ${relationName({ schema: fk.parentSchema, table: fk.parentTable })} parent ON ${join156}
38993
38993
  JOIN fusion_rekey_conflict_candidates parent_candidate
38994
38994
  ON parent_candidate.schema_name = ${quoteLiteral(fk.parentSchema)}
38995
38995
  AND parent_candidate.table_name = ${quoteLiteral(fk.parentTable)}
@@ -49826,8 +49826,8 @@ var require_CronFileParser = __commonJS({
49826
49826
  * @throws If file cannot be read
49827
49827
  */
49828
49828
  static async parseFile(filePath) {
49829
- const { readFile: readFile63 } = await Promise.resolve().then(() => __importStar(__require("fs/promises")));
49830
- const data = await readFile63(filePath, "utf8");
49829
+ const { readFile: readFile64 } = await Promise.resolve().then(() => __importStar(__require("fs/promises")));
49830
+ const data = await readFile64(filePath, "utf8");
49831
49831
  return _CronFileParser.#parseContent(data);
49832
49832
  }
49833
49833
  /**
@@ -133433,8 +133433,8 @@ var require_graceful_fs = __commonJS({
133433
133433
  fs11.createReadStream = createReadStream6;
133434
133434
  fs11.createWriteStream = createWriteStream2;
133435
133435
  var fs$readFile = fs11.readFile;
133436
- fs11.readFile = readFile63;
133437
- function readFile63(path14, options, cb) {
133436
+ fs11.readFile = readFile64;
133437
+ function readFile64(path14, options, cb) {
133438
133438
  if (typeof options === "function")
133439
133439
  cb = options, options = null;
133440
133440
  return go$readFile(path14, options, cb);
@@ -136150,10 +136150,10 @@ async function runHoldReleaseSweep(store, deps) {
136150
136150
  }
136151
136151
  return result2;
136152
136152
  }
136153
- async function issueRelease(store, deps, task, target, ir2) {
136153
+ async function issueRelease(store, deps, task, target, ir2, options = {}) {
136154
136154
  const targetColumn = findColumn2(ir2, target);
136155
136155
  const targetIsProcessing = targetColumn ? resolveColumnFlags(targetColumn).countsTowardWip === true : false;
136156
- if (targetIsProcessing && await isUnplannedForExecution(store, task, ir2)) {
136156
+ if (targetIsProcessing && !options.allowUnplanned && await isUnplannedForExecution(store, task, ir2)) {
136157
136157
  schedulerLog.log(`Hold release for ${task.id} blocked \u2014 card is unplanned and cannot enter processing column ${target}`);
136158
136158
  return false;
136159
136159
  }
@@ -136195,7 +136195,7 @@ async function issueRelease(store, deps, task, target, ir2) {
136195
136195
  return false;
136196
136196
  }
136197
136197
  }
136198
- async function promoteHeldTask(store, taskId, deps = {}) {
136198
+ async function promoteHeldTask(store, taskId, deps = {}, options = {}) {
136199
136199
  const task = await store.getTask(taskId);
136200
136200
  if (!task) return { released: false, rejection: "task-not-found" };
136201
136201
  const ir2 = await resolveWorkflowIrForTask(store, taskId);
@@ -136206,17 +136206,50 @@ async function promoteHeldTask(store, taskId, deps = {}) {
136206
136206
  if (!target) return { released: false, rejection: "no-release-target" };
136207
136207
  const targetColumn = findColumn2(ir2, target);
136208
136208
  const targetIsProcessing = targetColumn ? resolveColumnFlags(targetColumn).countsTowardWip === true : false;
136209
- if (targetIsProcessing && await isUnplannedForExecution(store, task, ir2)) {
136209
+ const unplanned = targetIsProcessing && await isUnplannedForExecution(store, task, ir2);
136210
+ if (unplanned && options.force !== true) {
136210
136211
  return { released: false, rejection: "unplanned-for-execution", toColumn: target };
136211
136212
  }
136213
+ let promoted = task;
136214
+ if (unplanned) {
136215
+ if (task.status === "needs-replan" || task.status === "plan-review-unavailable") {
136216
+ try {
136217
+ await store.updateTask(task.id, { status: null });
136218
+ promoted = { ...task, status: void 0 };
136219
+ } catch (error3) {
136220
+ schedulerLog.warn(
136221
+ `Force-promote for ${task.id} could not clear replan status: ${error3 instanceof Error ? error3.message : String(error3)}`
136222
+ );
136223
+ }
136224
+ }
136225
+ if (typeof store.recordRunAuditEvent === "function") {
136226
+ try {
136227
+ await store.recordRunAuditEvent({
136228
+ domain: "database",
136229
+ mutationType: "task:promote-forced-unplanned",
136230
+ target: task.id,
136231
+ taskId: task.id,
136232
+ agentId: "system",
136233
+ runId: `promote-force-${task.id}`,
136234
+ metadata: { fromColumn: task.column, toColumn: target, priorStatus: task.status ?? null }
136235
+ });
136236
+ } catch {
136237
+ }
136238
+ }
136239
+ schedulerLog.log(`Force-promote for ${task.id} bypassing unplanned gate into ${target} (operator override)`);
136240
+ }
136212
136241
  const released = await issueRelease(
136213
136242
  store,
136214
136243
  { now: () => Date.now(), reserveSlot: deps.reserveSlot, allocateWorktree: deps.allocateWorktree },
136215
- task,
136244
+ promoted,
136216
136245
  target,
136217
- ir2
136246
+ ir2,
136247
+ { allowUnplanned: unplanned }
136218
136248
  );
136219
- return released ? { released: true, toColumn: target } : { released: false, rejection: "capacity-exhausted-or-no-slot" };
136249
+ if (!released) {
136250
+ return { released: false, rejection: "capacity-exhausted-or-no-slot" };
136251
+ }
136252
+ return { released: true, toColumn: target, forcedUnplanned: unplanned || void 0 };
136220
136253
  }
136221
136254
  async function releaseHeldTaskByEvent(store, taskId, eventTag, deps = {}) {
136222
136255
  const task = await store.getTask(taskId);
@@ -162389,6 +162422,86 @@ var init_research_step_runner = __esm({
162389
162422
  }
162390
162423
  });
162391
162424
 
162425
+ // ../engine/src/plan-artifact-writeback.ts
162426
+ import { readFile as readFile29 } from "node:fs/promises";
162427
+ import { join as join61 } from "node:path";
162428
+ function relativePromptPath(taskId) {
162429
+ return `.fusion/tasks/${taskId}/PROMPT.md`;
162430
+ }
162431
+ async function readIfPresent(path14) {
162432
+ try {
162433
+ return await readFile29(path14, "utf-8");
162434
+ } catch {
162435
+ return null;
162436
+ }
162437
+ }
162438
+ async function reconcileWorktreePlanArtifact(options) {
162439
+ const { store, taskId, rootDir, planningCwd, logger: logger3 } = options;
162440
+ const relPath = relativePromptPath(taskId);
162441
+ const rootContent = await readIfPresent(join61(rootDir, relPath));
162442
+ if (planningCwd === rootDir) {
162443
+ return { outcome: "not-worktree", content: rootContent ?? void 0 };
162444
+ }
162445
+ const worktreeContent = await readIfPresent(join61(planningCwd, relPath));
162446
+ if (worktreeContent === null) {
162447
+ return { outcome: "no-worktree-artifact", content: rootContent ?? void 0 };
162448
+ }
162449
+ if (worktreeContent.trim().length === 0) {
162450
+ return { outcome: "worktree-artifact-empty", content: rootContent ?? void 0 };
162451
+ }
162452
+ if (rootContent === worktreeContent) {
162453
+ return { outcome: "already-authoritative", content: rootContent };
162454
+ }
162455
+ try {
162456
+ await store.updateTask(taskId, { prompt: worktreeContent });
162457
+ logger3?.log?.(
162458
+ `${taskId}: recovered a worktree-local PROMPT.md into the project .fusion folder (${planningCwd})`
162459
+ );
162460
+ return { outcome: "recovered", content: worktreeContent };
162461
+ } catch (error3) {
162462
+ const message = error3 instanceof Error ? error3.message : String(error3);
162463
+ logger3?.warn?.(
162464
+ `${taskId}: failed to copy the worktree-local PROMPT.md back into the project .fusion folder: ${message}`
162465
+ );
162466
+ return { outcome: "recovery-failed", content: rootContent ?? void 0 };
162467
+ }
162468
+ }
162469
+ async function mirrorPlanToProjectDb(store, taskId, content, options = {}) {
162470
+ if (content.trim().length === 0) return false;
162471
+ if (typeof store.upsertTaskDocument !== "function") return false;
162472
+ try {
162473
+ if (typeof store.getTaskDocument === "function") {
162474
+ const existing = await store.getTaskDocument(taskId, PLAN_DOCUMENT_KEY);
162475
+ if (typeof existing?.content === "string" && existing.content === content) return false;
162476
+ }
162477
+ await store.upsertTaskDocument(taskId, {
162478
+ key: PLAN_DOCUMENT_KEY,
162479
+ content,
162480
+ author: options.author ?? "agent"
162481
+ });
162482
+ return true;
162483
+ } catch (error3) {
162484
+ const message = error3 instanceof Error ? error3.message : String(error3);
162485
+ options.logger?.warn?.(`${taskId}: failed to mirror the plan into the project database: ${message}`);
162486
+ return false;
162487
+ }
162488
+ }
162489
+ async function persistPlanArtifact(options) {
162490
+ const result2 = await reconcileWorktreePlanArtifact(options);
162491
+ const mirrored = result2.content ? await mirrorPlanToProjectDb(options.store, options.taskId, result2.content, {
162492
+ author: options.author,
162493
+ logger: options.logger
162494
+ }) : false;
162495
+ return { ...result2, mirrored };
162496
+ }
162497
+ var PLAN_DOCUMENT_KEY;
162498
+ var init_plan_artifact_writeback = __esm({
162499
+ "../engine/src/plan-artifact-writeback.ts"() {
162500
+ "use strict";
162501
+ PLAN_DOCUMENT_KEY = "plan";
162502
+ }
162503
+ });
162504
+
162392
162505
  // ../engine/src/auto-recovery-handlers/message-delivery.ts
162393
162506
  import { setTimeout as delay2 } from "node:timers/promises";
162394
162507
  var baseLog, MessageDeliveryAutoRecoveryHandler;
@@ -164398,7 +164511,7 @@ var init_worktree_prune = __esm({
164398
164511
 
164399
164512
  // ../engine/src/worktree-stale-lock.ts
164400
164513
  import { exec as exec8 } from "node:child_process";
164401
- import { readFile as readFile30, stat as stat8, unlink as unlink9 } from "node:fs/promises";
164514
+ import { readFile as readFile31, stat as stat8, unlink as unlink9 } from "node:fs/promises";
164402
164515
  import { dirname as dirname23, resolve as resolve26 } from "node:path";
164403
164516
  import { promisify as promisify12 } from "node:util";
164404
164517
  function parseIndexLockPath(stderr) {
@@ -164423,7 +164536,7 @@ async function resolveOwningWorktreePath(input) {
164423
164536
  if (!worktreeName) return void 0;
164424
164537
  const gitdirFile = resolve26(dirname23(input.lockPath), "gitdir");
164425
164538
  try {
164426
- const gitdirRef = (await readFile30(gitdirFile, "utf-8")).trim();
164539
+ const gitdirRef = (await readFile31(gitdirFile, "utf-8")).trim();
164427
164540
  if (gitdirRef) {
164428
164541
  const resolvedGitdirRef = resolve26(dirname23(gitdirFile), gitdirRef);
164429
164542
  if (resolvedGitdirRef.endsWith("/.git") || resolvedGitdirRef.endsWith("\\.git")) {
@@ -165802,7 +165915,7 @@ import { exec as exec11, execFile as execFile9 } from "node:child_process";
165802
165915
  import { promisify as promisify15 } from "node:util";
165803
165916
  import { existsSync as existsSync47, lstatSync as lstatSync2, readdirSync as readdirSync7, readFileSync as readFileSync16, rmSync as rmSync5, realpathSync as realpathSync6 } from "node:fs";
165804
165917
  import { mkdir as mkdir24 } from "node:fs/promises";
165805
- import { basename as basename15, dirname as dirname24, join as join61, relative as relative8, resolve as resolve29, isAbsolute as isAbsolute9 } from "node:path";
165918
+ import { basename as basename15, dirname as dirname24, join as join62, relative as relative8, resolve as resolve29, isAbsolute as isAbsolute9 } from "node:path";
165806
165919
  async function getWorktrunkBinary(settings) {
165807
165920
  const cacheKey = `${process.env.HOME ?? ""}::${settings.binaryPath ?? ""}`;
165808
165921
  const cached2 = _worktrunkBinaryCache.get(cacheKey);
@@ -165953,7 +166066,7 @@ async function isRegisteredGitWorktree2(rootDir, worktreePath) {
165953
166066
  return (await getRegisteredWorktreePaths(rootDir)).has(canonicalizePath(worktreePath));
165954
166067
  }
165955
166068
  function hasRequiredWorktreeFiles(worktreePath) {
165956
- return existsSync47(join61(worktreePath, ".git"));
166069
+ return existsSync47(join62(worktreePath, ".git"));
165957
166070
  }
165958
166071
  async function isInsideGitWorkTree2(worktreePath) {
165959
166072
  try {
@@ -166086,7 +166199,7 @@ async function scanIdleWorktrees(rootDir, store, settings) {
166086
166199
  let dirs;
166087
166200
  try {
166088
166201
  const entries = readdirSync7(worktreesDir, { withFileTypes: true });
166089
- dirs = entries.filter((e) => e.isDirectory() && !isAiMergeContainerDir(e.name)).map((e) => join61(worktreesDir, e.name));
166202
+ dirs = entries.filter((e) => e.isDirectory() && !isAiMergeContainerDir(e.name)).map((e) => join62(worktreesDir, e.name));
166090
166203
  } catch (err) {
166091
166204
  const errorMessage4 = err instanceof Error ? err.message : String(err);
166092
166205
  worktreePoolLog.warn(`Failed to read .worktrees/ directory: ${errorMessage4}`);
@@ -166118,7 +166231,7 @@ async function cleanupOrphanedWorktrees(rootDir, store, settings) {
166118
166231
  let dirs = [];
166119
166232
  if (existsSync47(worktreesDir)) {
166120
166233
  try {
166121
- dirs = readdirSync7(worktreesDir, { withFileTypes: true }).filter((e) => e.isDirectory() && !isAiMergeContainerDir(e.name)).map((e) => join61(worktreesDir, e.name));
166234
+ dirs = readdirSync7(worktreesDir, { withFileTypes: true }).filter((e) => e.isDirectory() && !isAiMergeContainerDir(e.name)).map((e) => join62(worktreesDir, e.name));
166122
166235
  } catch (err) {
166123
166236
  const errorMessage4 = err instanceof Error ? err.message : String(err);
166124
166237
  worktreePoolLog.warn(`Failed to read .worktrees/ directory for cleanup: ${errorMessage4}`);
@@ -166196,11 +166309,11 @@ async function reapOrphanWorktrees(projectRoot, settings) {
166196
166309
  entries = readdirSync7(worktreesDir, { withFileTypes: true }).filter((e) => {
166197
166310
  if (!e.isDirectory() || isAiMergeContainerDir(e.name)) return false;
166198
166311
  try {
166199
- return lstatSync2(join61(worktreesDir, e.name)).isDirectory() && !lstatSync2(join61(worktreesDir, e.name)).isSymbolicLink();
166312
+ return lstatSync2(join62(worktreesDir, e.name)).isDirectory() && !lstatSync2(join62(worktreesDir, e.name)).isSymbolicLink();
166200
166313
  } catch {
166201
166314
  return false;
166202
166315
  }
166203
- }).map((e) => ({ name: e.name, fullPath: join61(worktreesDir, e.name) }));
166316
+ }).map((e) => ({ name: e.name, fullPath: join62(worktreesDir, e.name) }));
166204
166317
  } catch (err) {
166205
166318
  const msg = err instanceof Error ? err.message : String(err);
166206
166319
  worktreePoolLog.warn(`reapOrphanWorktrees: failed to read .worktrees/ \u2014 ${msg}`);
@@ -166219,7 +166332,7 @@ async function reapOrphanWorktrees(projectRoot, settings) {
166219
166332
  if (registered2.has(resolvedFull)) {
166220
166333
  continue;
166221
166334
  }
166222
- const dotGit = join61(resolvedFull, ".git");
166335
+ const dotGit = join62(resolvedFull, ".git");
166223
166336
  if (existsSync47(dotGit)) {
166224
166337
  if (!dotGitPointerIsDangling(dotGit)) {
166225
166338
  worktreePoolLog.log(`reapOrphanWorktrees: skipping ${name2} (has .git entry but not in registered list \u2014 may be partially registered)`);
@@ -166585,27 +166698,27 @@ var init_worktree_pool = __esm({
166585
166698
 
166586
166699
  // ../engine/src/worktree-paths.ts
166587
166700
  import { homedir as homedir10 } from "node:os";
166588
- import { basename as basename16, isAbsolute as isAbsolute10, join as join62, relative as relative9, resolve as resolve30 } from "node:path";
166701
+ import { basename as basename16, isAbsolute as isAbsolute10, join as join63, relative as relative9, resolve as resolve30 } from "node:path";
166589
166702
  function isAiMergeContainerDir(name2) {
166590
166703
  return name2 === AI_MERGE_DIRNAME;
166591
166704
  }
166592
166705
  function resolveAiMergeRootPath(rootDir, settings) {
166593
- return join62(resolveWorktreesDir(rootDir, settings), AI_MERGE_DIRNAME);
166706
+ return join63(resolveWorktreesDir(rootDir, settings), AI_MERGE_DIRNAME);
166594
166707
  }
166595
166708
  function resolveLegacyAiMergeRootPath(rootDir) {
166596
- return join62(rootDir, ".fusion", "ai-merge");
166709
+ return join63(rootDir, ".fusion", "ai-merge");
166597
166710
  }
166598
166711
  function resolveWorktreesDir(rootDir, settings) {
166599
166712
  const configured = settings?.worktreesDir;
166600
166713
  if (!configured) {
166601
- return join62(rootDir, ".worktrees");
166714
+ return join63(rootDir, ".worktrees");
166602
166715
  }
166603
166716
  const expandedHome = configured.replace(/^~(?=$|[\\/])/, homedir10());
166604
166717
  const expandedRepo = expandedHome.replaceAll("{repo}", basename16(rootDir));
166605
166718
  return resolve30(rootDir, expandedRepo);
166606
166719
  }
166607
166720
  function resolveTaskWorktreePath(rootDir, settings, worktreeName) {
166608
- return join62(resolveWorktreesDir(rootDir, settings), worktreeName);
166721
+ return join63(resolveWorktreesDir(rootDir, settings), worktreeName);
166609
166722
  }
166610
166723
  async function resolveTaskWorktreePathForBackend(rootDir, worktreeName, settings, backend, branch) {
166611
166724
  if (backend.kind === "worktrunk" && backend.resolveWorktreePath) {
@@ -167719,9 +167832,9 @@ function assertInRootRepoRelPath(repoRelPath, sep23, isAbsolute36, normalize10)
167719
167832
  async function acquireWorkspaceRepoWorktree(opts) {
167720
167833
  const { repoRelPath, workspaceRootDir, task, store, settings, logger: logger3, secretsStore, audit, runContext, runConfiguredCommand: runConfiguredCommand2, taskEnv } = opts;
167721
167834
  const registry3 = opts.registry ?? activeSessionRegistry;
167722
- const { join: join155, isAbsolute: isAbsolute36, normalize: normalize10, sep: sep23 } = await import("node:path");
167835
+ const { join: join156, isAbsolute: isAbsolute36, normalize: normalize10, sep: sep23 } = await import("node:path");
167723
167836
  assertInRootRepoRelPath(repoRelPath, sep23, isAbsolute36, normalize10);
167724
- const repoAbsPath = join155(workspaceRootDir, repoRelPath);
167837
+ const repoAbsPath = join156(workspaceRootDir, repoRelPath);
167725
167838
  const existing = task.workspaceWorktrees?.[repoRelPath];
167726
167839
  if (existing) {
167727
167840
  let live = existsSync49(existing.worktreePath);
@@ -169445,7 +169558,7 @@ import { execFile as execFile11 } from "node:child_process";
169445
169558
  import { createRequire as createRequire6 } from "node:module";
169446
169559
  import { mkdtemp, rm as rm7, writeFile as writeFile24 } from "node:fs/promises";
169447
169560
  import { tmpdir as tmpdir4 } from "node:os";
169448
- import { join as join63 } from "node:path";
169561
+ import { join as join64 } from "node:path";
169449
169562
  function getTransformSync() {
169450
169563
  if (!cachedTransformSync) {
169451
169564
  const req = createRequire6(import.meta.url);
@@ -169532,9 +169645,9 @@ function readStdin() {
169532
169645
  async function runCodeNode(opts) {
169533
169646
  const timeoutMs = resolveCodeNodeTimeout(opts.timeoutMs);
169534
169647
  const compiled = await compileCodeNodeSource(opts.source);
169535
- const dir2 = await mkdtemp(join63(tmpdir4(), "fusion-code-node-"));
169536
- const userModuleFile = join63(dir2, "user.mjs");
169537
- const harnessFile = join63(dir2, "harness.mjs");
169648
+ const dir2 = await mkdtemp(join64(tmpdir4(), "fusion-code-node-"));
169649
+ const userModuleFile = join64(dir2, "user.mjs");
169650
+ const harnessFile = join64(dir2, "harness.mjs");
169538
169651
  try {
169539
169652
  await writeFile24(userModuleFile, compiled, "utf8");
169540
169653
  await writeFile24(harnessFile, buildChildHarness(userModuleFile), "utf8");
@@ -169762,11 +169875,11 @@ var init_code_node_runner = __esm({
169762
169875
  });
169763
169876
 
169764
169877
  // ../engine/src/agent-tools.ts
169765
- import { appendFile as appendFile3, mkdir as mkdir26, readFile as readFile31, readdir as readdir9, realpath, stat as stat9, writeFile as writeFile25 } from "node:fs/promises";
169878
+ import { appendFile as appendFile3, mkdir as mkdir26, readFile as readFile32, readdir as readdir9, realpath, stat as stat9, writeFile as writeFile25 } from "node:fs/promises";
169766
169879
  import { existsSync as existsSync50 } from "node:fs";
169767
169880
  import { createHash as createHash16, randomUUID as randomUUID46 } from "node:crypto";
169768
169881
  import { tmpdir as tmpdir5 } from "node:os";
169769
- import { extname as extname3, isAbsolute as isAbsolute12, join as join64, relative as relative11, resolve as resolve32, sep as sep9 } from "node:path";
169882
+ import { extname as extname3, isAbsolute as isAbsolute12, join as join65, relative as relative11, resolve as resolve32, sep as sep9 } from "node:path";
169770
169883
  import { Type as Type2 } from "@earendil-works/pi-ai";
169771
169884
  function sanitizeAgentMemoryId(agentId) {
169772
169885
  return agentId.trim().replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "agent";
@@ -169778,16 +169891,16 @@ function agentDreamsDisplayPath(agentId) {
169778
169891
  return `${AGENT_MEMORY_ROOT3}/${sanitizeAgentMemoryId(agentId)}/${AGENT_DREAMS_FILENAME2}`;
169779
169892
  }
169780
169893
  function agentMemoryDirectory(rootDir, agentId) {
169781
- return join64(rootDir, AGENT_MEMORY_ROOT3, sanitizeAgentMemoryId(agentId));
169894
+ return join65(rootDir, AGENT_MEMORY_ROOT3, sanitizeAgentMemoryId(agentId));
169782
169895
  }
169783
169896
  function agentMemoryFilePath(rootDir, agentId) {
169784
- return join64(agentMemoryDirectory(rootDir, agentId), AGENT_MEMORY_FILENAME2);
169897
+ return join65(agentMemoryDirectory(rootDir, agentId), AGENT_MEMORY_FILENAME2);
169785
169898
  }
169786
169899
  function agentDreamsFilePath(rootDir, agentId) {
169787
- return join64(agentMemoryDirectory(rootDir, agentId), AGENT_DREAMS_FILENAME2);
169900
+ return join65(agentMemoryDirectory(rootDir, agentId), AGENT_DREAMS_FILENAME2);
169788
169901
  }
169789
169902
  function agentDailyFilePath(rootDir, agentId, date5 = /* @__PURE__ */ new Date()) {
169790
- return join64(agentMemoryDirectory(rootDir, agentId), `${date5.toISOString().slice(0, 10)}.md`);
169903
+ return join65(agentMemoryDirectory(rootDir, agentId), `${date5.toISOString().slice(0, 10)}.md`);
169791
169904
  }
169792
169905
  async function readAgentMemoryWorkspaceLongTerm(rootDir, agentId) {
169793
169906
  const safeRoot = typeof rootDir === "string" ? rootDir.trim() : "";
@@ -169801,7 +169914,7 @@ async function readAgentMemoryWorkspaceLongTerm(rootDir, agentId) {
169801
169914
  if (!fileStat.isFile()) {
169802
169915
  return "";
169803
169916
  }
169804
- const content = await readFile31(filePath, "utf-8");
169917
+ const content = await readFile32(filePath, "utf-8");
169805
169918
  return typeof content === "string" ? content.trim() : "";
169806
169919
  } catch {
169807
169920
  return "";
@@ -169880,7 +169993,7 @@ async function listAgentMemoryFiles2(rootDir, agentMemory) {
169880
169993
  }
169881
169994
  for (const entry of entries) {
169882
169995
  if (!DAILY_AGENT_MEMORY_RE2.test(entry)) continue;
169883
- const absPath = join64(dir2, entry);
169996
+ const absPath = join65(dir2, entry);
169884
169997
  const fileStat = await stat9(absPath);
169885
169998
  if (fileStat.isFile()) {
169886
169999
  files.push({
@@ -169903,7 +170016,7 @@ async function searchAgentMemoryFile(rootDir, agentMemory, query, limit) {
169903
170016
  }
169904
170017
  const results = [];
169905
170018
  for (const file of await listAgentMemoryFiles2(rootDir, agentMemory)) {
169906
- const content = await readFile31(file.absPath, "utf-8");
170019
+ const content = await readFile32(file.absPath, "utf-8");
169907
170020
  const lines = content.split("\n");
169908
170021
  for (let index3 = 0; index3 < lines.length; index3 += 8) {
169909
170022
  const chunk = lines.slice(index3, index3 + 12).join("\n").trim();
@@ -170049,7 +170162,7 @@ function resolveAgentMemoryPath(rootDir, agentId, path14) {
170049
170162
  return null;
170050
170163
  }
170051
170164
  return {
170052
- absPath: join64(agentMemoryDirectory(rootDir, agentId), filename),
170165
+ absPath: join65(agentMemoryDirectory(rootDir, agentId), filename),
170053
170166
  displayPath: `${prefix}${filename}`
170054
170167
  };
170055
170168
  }
@@ -170059,7 +170172,7 @@ async function getAgentMemoryWindow(rootDir, agentMemory, path14, startLine = 1,
170059
170172
  return null;
170060
170173
  }
170061
170174
  await syncAgentMemoryFile(rootDir, agentMemory);
170062
- const content = await readFile31(resolved.absPath, "utf-8");
170175
+ const content = await readFile32(resolved.absPath, "utf-8");
170063
170176
  const lines = content.split("\n");
170064
170177
  const start = Math.max(1, Math.floor(startLine));
170065
170178
  const count2 = Math.max(1, Math.min(Math.floor(lineCount), 200));
@@ -170718,6 +170831,9 @@ function createTaskPromptWriteTool(store, taskId, runContext) {
170718
170831
  if (persisted?.prompt !== params.content) {
170719
170832
  throw new Error("authoritative PROMPT.md read-back did not match the requested content; persistence could not be verified");
170720
170833
  }
170834
+ await mirrorPlanToProjectDb(store, taskId, params.content, {
170835
+ author: runContext?.agentId ?? "agent"
170836
+ });
170721
170837
  return {
170722
170838
  content: [{ type: "text", text: `Updated PROMPT.md for ${taskId}.` }],
170723
170839
  details: {}
@@ -171006,7 +171122,7 @@ async function readArtifactFileFromPath(params, baseDir) {
171006
171122
  if (!mimeType) {
171007
171123
  throw new Error(`Could not infer a MIME type from ${resolvedPath}; pass mimeType explicitly.`);
171008
171124
  }
171009
- const data = await readFile31(canonicalPath);
171125
+ const data = await readFile32(canonicalPath);
171010
171126
  if (params.type === "image") {
171011
171127
  if (!mimeType.startsWith("image/")) {
171012
171128
  throw new Error(`image artifacts require an image/* mimeType, got ${mimeType}.`);
@@ -171349,25 +171465,33 @@ function createTaskPromoteTool(store, currentTaskId) {
171349
171465
  return {
171350
171466
  name: "fn_task_promote",
171351
171467
  label: "Promote Held Task",
171352
- description: "Manually promote a held task out of its hold column, releasing it regardless of the hold's release kind (the explicit operator action a 'manual' hold waits for). Defaults to the current task. Returns the destination column, or a rejection reason when the task is not held or the destination is full.",
171468
+ description: "Manually promote a held task out of its hold column, releasing it regardless of the hold's release kind (the explicit operator action a 'manual' hold waits for). Defaults to the current task. Returns the destination column, or a rejection reason when the task is not held or the destination is full. Pass force:true to start execution even when planning or plan review is still outstanding (that waives the plan gate and cancels the pending replan; capacity still applies).",
171353
171469
  parameters: taskPromoteParams,
171354
171470
  execute: async (_id, params) => {
171355
171471
  const taskId = params.task_id?.trim() || currentTaskId;
171472
+ const force = params.force === true;
171356
171473
  try {
171357
- const outcome = await promoteHeldTask(store, taskId);
171474
+ const outcome = await promoteHeldTask(store, taskId, {}, { force });
171358
171475
  if (outcome.released) {
171476
+ const forcedNote = outcome.forcedUnplanned ? " Forced past the outstanding planning/plan review \u2014 the pending replan was cancelled." : "";
171359
171477
  return {
171360
171478
  content: [{
171361
171479
  type: "text",
171362
- text: `Promoted ${taskId} to column '${outcome.toColumn}'.`
171480
+ text: `Promoted ${taskId} to column '${outcome.toColumn}'.${forcedNote}`
171363
171481
  }],
171364
- details: { taskId, released: true, toColumn: outcome.toColumn }
171482
+ details: {
171483
+ taskId,
171484
+ released: true,
171485
+ toColumn: outcome.toColumn,
171486
+ forcedUnplanned: outcome.forcedUnplanned === true
171487
+ }
171365
171488
  };
171366
171489
  }
171490
+ const forceHint = outcome.rejection === "unplanned-for-execution" ? " Pass force:true to start execution anyway." : "";
171367
171491
  return {
171368
171492
  content: [{
171369
171493
  type: "text",
171370
- text: `ERROR: Could not promote ${taskId}: ${outcome.rejection ?? "unknown"}.`
171494
+ text: `ERROR: Could not promote ${taskId}: ${outcome.rejection ?? "unknown"}.${forceHint}`
171371
171495
  }],
171372
171496
  details: { taskId, released: false, rejection: outcome.rejection },
171373
171497
  isError: true
@@ -173591,6 +173715,7 @@ var init_agent_tools = __esm({
173591
173715
  init_provider_registry();
173592
173716
  init_research_step_runner();
173593
173717
  init_logger3();
173718
+ init_plan_artifact_writeback();
173594
173719
  init_web_fetch();
173595
173720
  init_agent_action_gate();
173596
173721
  init_message_delivery();
@@ -173770,6 +173895,19 @@ var init_agent_tools = __esm({
173770
173895
  taskPromoteParams = Type2.Object({
173771
173896
  task_id: Type2.Optional(
173772
173897
  Type2.String({ description: "Held task to promote. Defaults to the current task." })
173898
+ ),
173899
+ /*
173900
+ FNXC:WorkflowScheduling 2026-07-25-05:40:
173901
+ Agent-native parity with the dashboard's force-promote override: an agent that
173902
+ has read the card and judged the pending replan / Plan Review not worth waiting
173903
+ for can start execution anyway. Opt-in per call and never defaulted on — the
173904
+ automatic surfaces (hold-release sweep, webhook release) still cannot force, so
173905
+ FN-7648 holds for everything that is not an explicit promote request.
173906
+ */
173907
+ force: Type2.Optional(
173908
+ Type2.Boolean({
173909
+ description: "Start execution even when the task is still waiting on planning or plan review (rejection 'unplanned-for-execution'). Waives ONLY that gate \u2014 hold membership and downstream capacity still apply \u2014 and cancels the pending replan. Default false."
173910
+ })
173773
173911
  )
173774
173912
  });
173775
173913
  workflowCreateParams = Type2.Object({
@@ -178078,7 +178216,7 @@ Follow instructions precisely and avoid unrelated changes.`,
178078
178216
 
178079
178217
  // ../engine/src/spec-validation/task-document-references.ts
178080
178218
  import { access as access7 } from "node:fs/promises";
178081
- import { join as join65 } from "node:path";
178219
+ import { join as join66 } from "node:path";
178082
178220
  function normalizePathToken(token) {
178083
178221
  return token.replace(/^[`([{"']+/, "").replace(/[`),.;:!?\]}'"]+$/, "");
178084
178222
  }
@@ -178166,7 +178304,7 @@ async function detectDanglingTaskDocReferences(promptContent, opts) {
178166
178304
  }
178167
178305
  const dangling = [];
178168
178306
  for (const [path14, sections] of references.entries()) {
178169
- const absPath = join65(opts.rootDir, path14);
178307
+ const absPath = join66(opts.rootDir, path14);
178170
178308
  if (await existsImpl(absPath)) continue;
178171
178309
  dangling.push({ path: path14, sections: Array.from(sections).sort() });
178172
178310
  }
@@ -178427,8 +178565,8 @@ var init_session_skill_context = __esm({
178427
178565
  });
178428
178566
 
178429
178567
  // ../engine/src/agent-memory-index.ts
178430
- import { readFile as readFile32 } from "node:fs/promises";
178431
- import { join as join66 } from "node:path";
178568
+ import { readFile as readFile33 } from "node:fs/promises";
178569
+ import { join as join67 } from "node:path";
178432
178570
  function clampUtf8(input, maxBytes) {
178433
178571
  if (Buffer.byteLength(input, "utf8") <= maxBytes) return input;
178434
178572
  let out = "";
@@ -178460,7 +178598,7 @@ function parseHeadings(content) {
178460
178598
  }
178461
178599
  async function buildFileSection(sectionHeader, displayPath, fsPath) {
178462
178600
  try {
178463
- const content = await readFile32(fsPath, "utf-8");
178601
+ const content = await readFile33(fsPath, "utf-8");
178464
178602
  const headings = parseHeadings(content);
178465
178603
  const lines = [sectionHeader, `- ${displayPath}`];
178466
178604
  for (const entry of headings) {
@@ -178476,9 +178614,9 @@ async function buildFileSection(sectionHeader, displayPath, fsPath) {
178476
178614
  async function buildMemoryIndex({ rootDir, agentId }) {
178477
178615
  const safeAgentId = agentId.trim().replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/^-+|-+$/g, "") || "agent";
178478
178616
  const agentDisplayPath = `.fusion/agent-memory/${safeAgentId}/MEMORY.md`;
178479
- const agentFsPath = join66(rootDir, ".fusion", "agent-memory", safeAgentId, "MEMORY.md");
178617
+ const agentFsPath = join67(rootDir, ".fusion", "agent-memory", safeAgentId, "MEMORY.md");
178480
178618
  const projectDisplayPath = ".fusion/memory/MEMORY.md";
178481
- const projectFsPath = join66(rootDir, ".fusion", "memory", "MEMORY.md");
178619
+ const projectFsPath = join67(rootDir, ".fusion", "memory", "MEMORY.md");
178482
178620
  const [agentSection, projectSection] = await Promise.all([
178483
178621
  buildFileSection("## Agent Memory Index (use fn_memory_search / fn_memory_get to read)", agentDisplayPath, agentFsPath),
178484
178622
  buildFileSection("## Project Memory Index", projectDisplayPath, projectFsPath)
@@ -178497,7 +178635,7 @@ var init_agent_memory_index = __esm({
178497
178635
  });
178498
178636
 
178499
178637
  // ../engine/src/agent-instructions.ts
178500
- import { readFile as readFile33, writeFile as writeFile26, mkdir as mkdir27, access as access8 } from "node:fs/promises";
178638
+ import { readFile as readFile34, writeFile as writeFile26, mkdir as mkdir27, access as access8 } from "node:fs/promises";
178501
178639
  import { constants as fsConstants3 } from "node:fs";
178502
178640
  import { isAbsolute as isAbsolute13, resolve as resolve33, relative as relative12, normalize as normalize7, sep as sep10, dirname as dirname28 } from "node:path";
178503
178641
  function trimAndClamp(value, maxLength, label, agentId) {
@@ -178559,7 +178697,7 @@ async function resolveAgentHeartbeatProcedure(agent, rootDir) {
178559
178697
  return null;
178560
178698
  }
178561
178699
  try {
178562
- const content = await readFile33(filePath, "utf-8");
178700
+ const content = await readFile34(filePath, "utf-8");
178563
178701
  const normalized = trimAndClamp(
178564
178702
  content,
178565
178703
  MAX_INSTRUCTIONS_TEXT_LENGTH2,
@@ -178705,7 +178843,7 @@ async function resolveAgentInstructions(agent, rootDir, ratingSummary, inclusion
178705
178843
  const filePath = resolveValidatedInstructionsPath(agent.instructionsPath, rootDir, agent.id);
178706
178844
  if (filePath) {
178707
178845
  try {
178708
- const content = await readFile33(filePath, "utf-8");
178846
+ const content = await readFile34(filePath, "utf-8");
178709
178847
  const normalizedContent = trimAndClamp(
178710
178848
  content,
178711
178849
  MAX_INSTRUCTIONS_TEXT_LENGTH2,
@@ -186712,8 +186850,8 @@ var init_mission_symbol_admission = __esm({
186712
186850
 
186713
186851
  // ../engine/src/scheduler.ts
186714
186852
  import { existsSync as existsSync54 } from "node:fs";
186715
- import { readFile as readFile34 } from "node:fs/promises";
186716
- import { join as join67 } from "node:path";
186853
+ import { readFile as readFile35 } from "node:fs/promises";
186854
+ import { join as join68 } from "node:path";
186717
186855
  function logTaskRouting(taskId, node) {
186718
186856
  const message = `Task ${taskId} routed to node=${node.nodeId ?? "local"} (source=${node.source})`;
186719
186857
  if (node.nodeId === void 0) {
@@ -187346,16 +187484,16 @@ var init_scheduler = __esm({
187346
187484
  if (typeof this.store.getTasksDir !== "function") {
187347
187485
  return { valid: true };
187348
187486
  }
187349
- const taskDir = join67(this.store.getTasksDir(), id);
187487
+ const taskDir = join68(this.store.getTasksDir(), id);
187350
187488
  if (!existsSync54(taskDir)) {
187351
187489
  return { valid: false, reason: "missing directory" };
187352
187490
  }
187353
- const promptPath = join67(taskDir, "PROMPT.md");
187491
+ const promptPath = join68(taskDir, "PROMPT.md");
187354
187492
  if (!existsSync54(promptPath)) {
187355
187493
  return { valid: false, reason: "missing or empty PROMPT.md" };
187356
187494
  }
187357
187495
  try {
187358
- const content = await readFile34(promptPath, "utf-8");
187496
+ const content = await readFile35(promptPath, "utf-8");
187359
187497
  if (!content || content.trim().length === 0) {
187360
187498
  return { valid: false, reason: "missing or empty PROMPT.md" };
187361
187499
  }
@@ -187725,7 +187863,7 @@ var init_scheduler = __esm({
187725
187863
  todo = (await Promise.all(
187726
187864
  todo.map(async (t) => {
187727
187865
  try {
187728
- const content = await readFile34(getPromptPath(this.store.getTasksDir(), t.id), "utf-8");
187866
+ const content = await readFile35(getPromptPath(this.store.getTasksDir(), t.id), "utf-8");
187729
187867
  if (isUnplannedSeedPrompt(content, t.id, t.title, t.description)) return null;
187730
187868
  } catch {
187731
187869
  }
@@ -191292,10 +191430,10 @@ var init_verification_utils = __esm({
191292
191430
  import { exec as exec23 } from "node:child_process";
191293
191431
  import { createHash as createHash18 } from "node:crypto";
191294
191432
  import { existsSync as existsSync55, readFileSync as readFileSync18, writeFileSync as writeFileSync7 } from "node:fs";
191295
- import { join as join68 } from "node:path";
191433
+ import { join as join69 } from "node:path";
191296
191434
  import { promisify as promisify32 } from "node:util";
191297
191435
  function hasInstallState(rootDir) {
191298
- return existsSync55(join68(rootDir, "node_modules")) || existsSync55(join68(rootDir, ".pnp.cjs"));
191436
+ return existsSync55(join69(rootDir, "node_modules")) || existsSync55(join69(rootDir, ".pnp.cjs"));
191299
191437
  }
191300
191438
  function getConfiguredWorktreeInitCommand(settings) {
191301
191439
  const trimmed = settings?.worktreeInitCommand?.trim();
@@ -191304,17 +191442,17 @@ function getConfiguredWorktreeInitCommand(settings) {
191304
191442
  function getDependencySyncCommand(rootDir, settings) {
191305
191443
  const configuredCommand = getConfiguredWorktreeInitCommand(settings);
191306
191444
  if (configuredCommand) return configuredCommand;
191307
- if (existsSync55(join68(rootDir, "pnpm-lock.yaml"))) return "pnpm install --frozen-lockfile";
191308
- if (existsSync55(join68(rootDir, "package-lock.json"))) return "npm install";
191309
- if (existsSync55(join68(rootDir, "yarn.lock"))) return "yarn install --frozen-lockfile";
191310
- if (existsSync55(join68(rootDir, "bun.lock")) || existsSync55(join68(rootDir, "bun.lockb"))) {
191445
+ if (existsSync55(join69(rootDir, "pnpm-lock.yaml"))) return "pnpm install --frozen-lockfile";
191446
+ if (existsSync55(join69(rootDir, "package-lock.json"))) return "npm install";
191447
+ if (existsSync55(join69(rootDir, "yarn.lock"))) return "yarn install --frozen-lockfile";
191448
+ if (existsSync55(join69(rootDir, "bun.lock")) || existsSync55(join69(rootDir, "bun.lockb"))) {
191311
191449
  return "bun install --frozen-lockfile";
191312
191450
  }
191313
191451
  return null;
191314
191452
  }
191315
191453
  function computeLockfileHash(rootDir) {
191316
191454
  for (const name2 of LOCKFILE_CANDIDATES) {
191317
- const p2 = join68(rootDir, name2);
191455
+ const p2 = join69(rootDir, name2);
191318
191456
  if (existsSync55(p2)) {
191319
191457
  try {
191320
191458
  return createHash18("sha256").update(readFileSync18(p2)).digest("hex");
@@ -191327,7 +191465,7 @@ function computeLockfileHash(rootDir) {
191327
191465
  }
191328
191466
  function readInstallMarker(rootDir) {
191329
191467
  try {
191330
- const value = readFileSync18(join68(rootDir, INSTALL_MARKER_RELPATH), "utf-8").trim();
191468
+ const value = readFileSync18(join69(rootDir, INSTALL_MARKER_RELPATH), "utf-8").trim();
191331
191469
  return value || null;
191332
191470
  } catch {
191333
191471
  return null;
@@ -191335,7 +191473,7 @@ function readInstallMarker(rootDir) {
191335
191473
  }
191336
191474
  function writeInstallMarker(rootDir, hash) {
191337
191475
  try {
191338
- writeFileSync7(join68(rootDir, INSTALL_MARKER_RELPATH), hash);
191476
+ writeFileSync7(join69(rootDir, INSTALL_MARKER_RELPATH), hash);
191339
191477
  } catch {
191340
191478
  }
191341
191479
  }
@@ -191426,7 +191564,7 @@ var init_merge_dependency_sync = __esm({
191426
191564
  "../engine/src/merge-dependency-sync.ts"() {
191427
191565
  "use strict";
191428
191566
  execAsync21 = promisify32(exec23);
191429
- INSTALL_MARKER_RELPATH = join68("node_modules", ".fusion-install-marker");
191567
+ INSTALL_MARKER_RELPATH = join69("node_modules", ".fusion-install-marker");
191430
191568
  LOCKFILE_CANDIDATES = ["pnpm-lock.yaml", "package-lock.json", "yarn.lock", "bun.lockb", "bun.lock"];
191431
191569
  INSTALL_TIMEOUT_MS = 3e5;
191432
191570
  }
@@ -191803,7 +191941,7 @@ var init_merger_glob = __esm({
191803
191941
 
191804
191942
  // ../engine/src/merger-workspace-test-commands.ts
191805
191943
  import { existsSync as existsSync56, readdirSync as readdirSync9, readFileSync as readFileSync19 } from "node:fs";
191806
- import { basename as basename18, dirname as dirname31, join as join69 } from "node:path";
191944
+ import { basename as basename18, dirname as dirname31, join as join70 } from "node:path";
191807
191945
  import { execSync as execSync4 } from "node:child_process";
191808
191946
  function quoteArg2(value) {
191809
191947
  return `'${value.replace(/'/g, "'\\''")}'`;
@@ -191834,14 +191972,14 @@ function resolveWorkspacePackageRoots(rootDir, globs) {
191834
191972
  for (const glob2 of globs) {
191835
191973
  const starIdx = glob2.indexOf("*");
191836
191974
  if (starIdx === -1) {
191837
- const candidate = join69(rootDir, glob2);
191838
- if (existsSync56(join69(candidate, "package.json"))) {
191975
+ const candidate = join70(rootDir, glob2);
191976
+ if (existsSync56(join70(candidate, "package.json"))) {
191839
191977
  roots.push(glob2);
191840
191978
  }
191841
191979
  continue;
191842
191980
  }
191843
191981
  const prefix = glob2.slice(0, starIdx);
191844
- const parentDir = join69(rootDir, prefix.replace(/\/$/, ""));
191982
+ const parentDir = join70(rootDir, prefix.replace(/\/$/, ""));
191845
191983
  let entries;
191846
191984
  try {
191847
191985
  entries = readdirSync9(parentDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
@@ -191850,8 +191988,8 @@ function resolveWorkspacePackageRoots(rootDir, globs) {
191850
191988
  }
191851
191989
  for (const entry of entries) {
191852
191990
  const relPath = `${prefix.replace(/\/$/, "")}/${entry}`;
191853
- const absPath = join69(rootDir, relPath);
191854
- if (existsSync56(join69(absPath, "package.json"))) {
191991
+ const absPath = join70(rootDir, relPath);
191992
+ if (existsSync56(join70(absPath, "package.json"))) {
191855
191993
  roots.push(relPath);
191856
191994
  }
191857
191995
  }
@@ -191874,7 +192012,7 @@ function mapChangedFilesToPackageNames(changedFiles, packageRoots, rootDir) {
191874
192012
  }
191875
192013
  if (bestRoot !== null) {
191876
192014
  try {
191877
- const pkgJsonPath = join69(rootDir, bestRoot, "package.json");
192015
+ const pkgJsonPath = join70(rootDir, bestRoot, "package.json");
191878
192016
  const raw = readFileSync19(pkgJsonPath, "utf-8");
191879
192017
  const parsed = JSON.parse(raw);
191880
192018
  if (parsed.name) {
@@ -191891,7 +192029,7 @@ function packageNamesForFiles(rootDir, files) {
191891
192029
  if (files.length === 0) return [];
191892
192030
  let workspaceContent;
191893
192031
  try {
191894
- workspaceContent = readFileSync19(join69(rootDir, "pnpm-workspace.yaml"), "utf-8");
192032
+ workspaceContent = readFileSync19(join70(rootDir, "pnpm-workspace.yaml"), "utf-8");
191895
192033
  } catch {
191896
192034
  return [];
191897
192035
  }
@@ -191902,7 +192040,7 @@ function packageNamesForFiles(rootDir, files) {
191902
192040
  return mapChangedFilesToPackageNames(files, packageRoots, rootDir);
191903
192041
  }
191904
192042
  function deriveScopedPnpmTestCommand(rootDir, baseBranch, branch) {
191905
- const workspacePath = join69(rootDir, "pnpm-workspace.yaml");
192043
+ const workspacePath = join70(rootDir, "pnpm-workspace.yaml");
191906
192044
  let workspaceContent;
191907
192045
  try {
191908
192046
  workspaceContent = readFileSync19(workspacePath, "utf-8");
@@ -191940,7 +192078,7 @@ function deriveScopedPnpmTestCommand(rootDir, baseBranch, branch) {
191940
192078
  function deriveFileScopedPnpmTestCommand(rootDir, baseBranch, branch) {
191941
192079
  let workspaceContent;
191942
192080
  try {
191943
- workspaceContent = readFileSync19(join69(rootDir, "pnpm-workspace.yaml"), "utf-8");
192081
+ workspaceContent = readFileSync19(join70(rootDir, "pnpm-workspace.yaml"), "utf-8");
191944
192082
  } catch {
191945
192083
  return null;
191946
192084
  }
@@ -191982,7 +192120,7 @@ function deriveFileScopedPnpmTestCommand(rootDir, baseBranch, branch) {
191982
192120
  ];
191983
192121
  for (const candidate of candidates) {
191984
192122
  const normalized = candidate.startsWith("./") ? candidate.slice(2) : candidate;
191985
- if (existsSync56(join69(rootDir, normalized))) {
192123
+ if (existsSync56(join70(rootDir, normalized))) {
191986
192124
  resolvedTests.add(normalized);
191987
192125
  }
191988
192126
  }
@@ -192010,7 +192148,7 @@ function deriveFileScopedPnpmTestCommand(rootDir, baseBranch, branch) {
192010
192148
  let name2 = bestRoot;
192011
192149
  try {
192012
192150
  const parsed = JSON.parse(
192013
- readFileSync19(join69(rootDir, bestRoot, "package.json"), "utf-8")
192151
+ readFileSync19(join70(rootDir, bestRoot, "package.json"), "utf-8")
192014
192152
  );
192015
192153
  if (parsed.name) name2 = parsed.name;
192016
192154
  } catch {
@@ -192054,8 +192192,8 @@ function inferDefaultTestCommand(rootDir, explicitTestCommand, explicitBuildComm
192054
192192
  };
192055
192193
  }
192056
192194
  const buildSource = explicitBuildCommand?.trim() ? "explicit" : void 0;
192057
- if (existsSync56(join69(rootDir, "pnpm-lock.yaml"))) {
192058
- if (existsSync56(join69(rootDir, "pnpm-workspace.yaml"))) {
192195
+ if (existsSync56(join70(rootDir, "pnpm-lock.yaml"))) {
192196
+ if (existsSync56(join70(rootDir, "pnpm-workspace.yaml"))) {
192059
192197
  if (baseBranch?.trim() && branch?.trim()) {
192060
192198
  try {
192061
192199
  const scoped = deriveScopedPnpmTestCommand(rootDir, baseBranch.trim(), branch.trim());
@@ -192074,13 +192212,13 @@ function inferDefaultTestCommand(rootDir, explicitTestCommand, explicitBuildComm
192074
192212
  }
192075
192213
  return { command: "pnpm test", testSource: "inferred", buildSource };
192076
192214
  }
192077
- if (existsSync56(join69(rootDir, "yarn.lock"))) {
192215
+ if (existsSync56(join70(rootDir, "yarn.lock"))) {
192078
192216
  return { command: "yarn test", testSource: "inferred", buildSource };
192079
192217
  }
192080
- if (existsSync56(join69(rootDir, "bun.lock")) || existsSync56(join69(rootDir, "bun.lockb"))) {
192218
+ if (existsSync56(join70(rootDir, "bun.lock")) || existsSync56(join70(rootDir, "bun.lockb"))) {
192081
192219
  return { command: "bun test", testSource: "inferred", buildSource };
192082
192220
  }
192083
- if (existsSync56(join69(rootDir, "package-lock.json"))) {
192221
+ if (existsSync56(join70(rootDir, "package-lock.json"))) {
192084
192222
  return { command: "npm test", testSource: "inferred", buildSource };
192085
192223
  }
192086
192224
  return null;
@@ -194357,7 +194495,7 @@ var init_merger_integration_worktree = __esm({
194357
194495
  import { execFile as execFile23, spawn as spawn7 } from "node:child_process";
194358
194496
  import { promisify as promisify43 } from "node:util";
194359
194497
  import { copyFileSync, existsSync as existsSync57, mkdirSync as mkdirSync9, mkdtempSync as mkdtempSync2, readFileSync as readFileSync20, rmSync as rmSync7, writeFileSync as writeFileSync8 } from "node:fs";
194360
- import { dirname as dirname32, join as join70 } from "node:path";
194498
+ import { dirname as dirname32, join as join71 } from "node:path";
194361
194499
  import { tmpdir as tmpdir6 } from "node:os";
194362
194500
  async function runGit4(args, cwd, timeoutMs) {
194363
194501
  const result2 = await execFileAsync16("git", ["-c", "core.quotePath=false", ...args], {
@@ -194443,9 +194581,9 @@ async function syncWorktreeToHead(input) {
194443
194581
  if (mode === "ff-only") {
194444
194582
  return { kind: "skipped-dirty", fromSha: previousSha, reason: "ff-only-mode-requires-clean-tree", dirtyFiles, untrackedFiles };
194445
194583
  }
194446
- const stageDir = mkdtempSync2(join70(tmpdir6(), "fusion-worktree-sync-"));
194447
- const patchPath = join70(stageDir, "edits.patch");
194448
- const untrackedDir = join70(stageDir, "untracked");
194584
+ const stageDir = mkdtempSync2(join71(tmpdir6(), "fusion-worktree-sync-"));
194585
+ const patchPath = join71(stageDir, "edits.patch");
194586
+ const untrackedDir = join71(stageDir, "untracked");
194449
194587
  let preserveStageDir = false;
194450
194588
  try {
194451
194589
  mkdirSync9(untrackedDir, { recursive: true });
@@ -194465,8 +194603,8 @@ async function syncWorktreeToHead(input) {
194465
194603
  }
194466
194604
  }
194467
194605
  for (const rel of untrackedFiles) {
194468
- const src = join70(worktreePath, rel);
194469
- const dst = join70(untrackedDir, rel);
194606
+ const src = join71(worktreePath, rel);
194607
+ const dst = join71(untrackedDir, rel);
194470
194608
  try {
194471
194609
  mkdirSync9(dirname32(dst), { recursive: true });
194472
194610
  copyFileSync(src, dst);
@@ -194529,13 +194667,13 @@ async function syncWorktreeToHead(input) {
194529
194667
  const restored = [];
194530
194668
  const untrackedSkippedAsTracked = [];
194531
194669
  for (const rel of untrackedFiles) {
194532
- const src = join70(untrackedDir, rel);
194670
+ const src = join71(untrackedDir, rel);
194533
194671
  if (!existsSync57(src)) continue;
194534
194672
  if (trackedAtHead.has(rel)) {
194535
194673
  untrackedSkippedAsTracked.push(rel);
194536
194674
  continue;
194537
194675
  }
194538
- const dst = join70(worktreePath, rel);
194676
+ const dst = join71(worktreePath, rel);
194539
194677
  try {
194540
194678
  mkdirSync9(dirname32(dst), { recursive: true });
194541
194679
  const data = readFileSync20(src);
@@ -194604,8 +194742,8 @@ var init_worktree_ref_sync = __esm({
194604
194742
 
194605
194743
  // ../engine/src/merger-scope-auto-widen.ts
194606
194744
  import { exec as exec30 } from "node:child_process";
194607
- import { readFile as readFile35, writeFile as writeFile27 } from "node:fs/promises";
194608
- import { join as join71 } from "node:path";
194745
+ import { readFile as readFile36, writeFile as writeFile27 } from "node:fs/promises";
194746
+ import { join as join72 } from "node:path";
194609
194747
  import { promisify as promisify44 } from "node:util";
194610
194748
  function quoteArg4(value) {
194611
194749
  return `'${value.replace(/'/g, `'\\''`)}'`;
@@ -194744,8 +194882,8 @@ function parseScopeEntries(section) {
194744
194882
  async function appendAutoWidenedScopeToPrompt(params) {
194745
194883
  const { store, taskId, files } = params;
194746
194884
  if (files.length === 0) return [];
194747
- const promptPath = join71(store.getTaskDir(taskId), "PROMPT.md");
194748
- const prompt = await readFile35(promptPath, "utf-8");
194885
+ const promptPath = join72(store.getTaskDir(taskId), "PROMPT.md");
194886
+ const prompt = await readFile36(promptPath, "utf-8");
194749
194887
  const { before, section, after } = splitPromptSections(prompt);
194750
194888
  const existing = parseScopeEntries(section);
194751
194889
  const toAdd = files.filter((file) => !existing.has(file));
@@ -194901,7 +195039,7 @@ import * as childProcess4 from "node:child_process";
194901
195039
  import { promisify as promisify45 } from "node:util";
194902
195040
  import { existsSync as existsSync58, readFileSync as readFileSync21, writeFileSync as writeFileSync9, unlinkSync as unlinkSync3, renameSync as renameSync5 } from "node:fs";
194903
195041
  import { createHash as createHash20 } from "node:crypto";
194904
- import { join as join72, resolve as resolve36 } from "node:path";
195042
+ import { join as join73, resolve as resolve36 } from "node:path";
194905
195043
  import { hostname as hostname2 } from "node:os";
194906
195044
  import { Type as Type4 } from "typebox";
194907
195045
  function mergerCommitEnv() {
@@ -195214,7 +195352,7 @@ async function runDeterministicVerification(store, rootDir, taskId, testCommand,
195214
195352
  const deterministicVerificationMessage = "Running deterministic merge verification" + (hasTestCommand ? ` (test${testSourceDisplayLabel}: ${normalizedTestCommand})` : "") + (hasBuildCommand ? ` (build${buildSource === "inferred" ? " [inferred]" : ""}: ${normalizedBuildCommand})` : "");
195215
195353
  await store.logEntry(taskId, deterministicVerificationMessage);
195216
195354
  await store.appendAgentLog(taskId, deterministicVerificationMessage, "status", void 0, "merger");
195217
- const bootstrapScriptPath = join72(rootDir, "scripts/ensure-test-artifacts.mjs");
195355
+ const bootstrapScriptPath = join73(rootDir, "scripts/ensure-test-artifacts.mjs");
195218
195356
  if (hasTestCommand || hasBuildCommand) {
195219
195357
  if (!existsSync58(bootstrapScriptPath)) {
195220
195358
  const bootstrapMissingMessage = `${taskId}: [verification:bootstrap] script missing at scripts/ensure-test-artifacts.mjs \u2014 skipping preamble`;
@@ -195713,7 +195851,7 @@ async function stashTreesEqual(rootDir, aSha, bSha) {
195713
195851
  }
195714
195852
  function writeActiveMergerStatus(rootDir, taskId) {
195715
195853
  try {
195716
- const statusPath = join72(rootDir, ".git", ACTIVE_MERGER_STATUS_FILENAME);
195854
+ const statusPath = join73(rootDir, ".git", ACTIVE_MERGER_STATUS_FILENAME);
195717
195855
  const payload = {
195718
195856
  taskId,
195719
195857
  pid: process.pid,
@@ -195742,7 +195880,7 @@ function clearActiveMergerStatus(statusPath, taskId) {
195742
195880
  }
195743
195881
  function readActiveMergerStatus(rootDir) {
195744
195882
  try {
195745
- const statusPath = join72(rootDir, ".git", ACTIVE_MERGER_STATUS_FILENAME);
195883
+ const statusPath = join73(rootDir, ".git", ACTIVE_MERGER_STATUS_FILENAME);
195746
195884
  if (!existsSync58(statusPath)) return null;
195747
195885
  const raw = readFileSync21(statusPath, "utf-8");
195748
195886
  const parsed = JSON.parse(raw);
@@ -196315,7 +196453,7 @@ async function findFilesWithConflictMarkers(rootDir, files) {
196315
196453
  const stillConflicted = [];
196316
196454
  for (const file of files) {
196317
196455
  try {
196318
- const fullPath = join72(rootDir, file);
196456
+ const fullPath = join73(rootDir, file);
196319
196457
  if (!existsSync58(fullPath)) continue;
196320
196458
  const { stdout } = await execAsync29(
196321
196459
  `git grep -l -e "^<<<<<<< " -e "^=======$" -e "^>>>>>>> " --no-index -- ${quoteArg3(fullPath)}`,
@@ -196342,7 +196480,7 @@ async function tryRecoverHardFailApply(params) {
196342
196480
  if (!patchText.trim()) {
196343
196481
  mergerLog.warn(`${taskId}: autostash ${sha.slice(0, 7)} produced empty patch; cannot 3-way recover`);
196344
196482
  } else {
196345
- const patchPath = join72(rootDir, ".git", `fusion-autostash-${sha.slice(0, 7)}.patch`);
196483
+ const patchPath = join73(rootDir, ".git", `fusion-autostash-${sha.slice(0, 7)}.patch`);
196346
196484
  writeFileSync9(patchPath, patchText, "utf-8");
196347
196485
  try {
196348
196486
  await execAsync29(`git apply --3way --whitespace=nowarn ${quoteArg3(patchPath)}`, { cwd: rootDir });
@@ -197830,13 +197968,13 @@ async function isCherryPickInProgress(rootDir) {
197830
197968
  cwd: rootDir,
197831
197969
  encoding: "utf-8"
197832
197970
  });
197833
- const cherryPickHeadPath = join72(rootDir, cherryPickHeadPathOut.trim());
197971
+ const cherryPickHeadPath = join73(rootDir, cherryPickHeadPathOut.trim());
197834
197972
  if (existsSync58(cherryPickHeadPath)) return true;
197835
197973
  const { stdout: sequencerPathOut } = await execAsync29("git rev-parse --git-path sequencer", {
197836
197974
  cwd: rootDir,
197837
197975
  encoding: "utf-8"
197838
197976
  });
197839
- const sequencerPath = join72(rootDir, sequencerPathOut.trim());
197977
+ const sequencerPath = join73(rootDir, sequencerPathOut.trim());
197840
197978
  return existsSync58(sequencerPath);
197841
197979
  } catch {
197842
197980
  return false;
@@ -202879,7 +203017,7 @@ import { promisify as promisify46 } from "node:util";
202879
203017
  import { setImmediate as setImmediateCb2 } from "node:timers";
202880
203018
  import { existsSync as existsSync59, mkdirSync as mkdirSync10, readdirSync as readdirSync10, readFileSync as readFileSync22, realpathSync as realpathSync7, rmSync as rmSync8, statSync as statSync10, writeFileSync as writeFileSync10 } from "node:fs";
202881
203019
  import { tmpdir as tmpdir7 } from "node:os";
202882
- import { isAbsolute as isAbsolute14, join as join73, relative as relative13, resolve as resolve37 } from "node:path";
203020
+ import { isAbsolute as isAbsolute14, join as join74, relative as relative13, resolve as resolve37 } from "node:path";
202883
203021
  function resolveRepoLocalAiMergeRoot(rootDir, settings) {
202884
203022
  return resolveAiMergeRootPath(rootDir, settings);
202885
203023
  }
@@ -202912,9 +203050,9 @@ async function preserveWorktreeChanges(repoDir, worktreePath, taskId) {
202912
203050
  return null;
202913
203051
  }
202914
203052
  const diff = (await execAsync30("git diff HEAD --binary", { cwd: worktreePath, encoding: "utf-8", maxBuffer: 10 * 1024 * 1024 })).stdout;
202915
- const recoveryDir = join73(repoDir, ".fusion", "recovery");
203053
+ const recoveryDir = join74(repoDir, ".fusion", "recovery");
202916
203054
  mkdirSync10(recoveryDir, { recursive: true });
202917
- const patchPath = join73(recoveryDir, `${taskId.toLowerCase()}-${formatRecoveryTimestamp()}.patch`);
203055
+ const patchPath = join74(recoveryDir, `${taskId.toLowerCase()}-${formatRecoveryTimestamp()}.patch`);
202918
203056
  writeFileSync10(patchPath, diff, "utf-8");
202919
203057
  return patchPath;
202920
203058
  } catch (error3) {
@@ -204347,6 +204485,35 @@ var init_self_healing = __esm({
204347
204485
  }
204348
204486
  return false;
204349
204487
  }
204488
+ /**
204489
+ * FNXC:WorkflowRecovery 2026-07-25-09:40:
204490
+ * Single shared decision for "is this branch tip's foreign `Fusion-Task-Id`/`Fusion-Task-Lineage` trailer real
204491
+ * evidence of cross-task contamination, or just an inherited start point?"
204492
+ *
204493
+ * A task branch cut from the integration branch points at whatever landed last. When the task has not committed
204494
+ * anything of its own (planning aborted, spec revise, operator move back to `todo`), the branch tip IS that
204495
+ * previous task's commit — a foreign trailer with zero foreign intent. FN-1406 hit exactly this: `fusion/fn-1406`
204496
+ * was cut from `main` at FN-1401's landed commit, planning ended without a commit, and the reclaim sweep logged
204497
+ * `already-merged rejected ... owner=FN-1401 reason=foreign-task-tip` every pass instead of clearing the stale
204498
+ * worktree/branch metadata.
204499
+ *
204500
+ * Merge-base-to-tip diff proof separates the two: no unique diff means the branch carries no task content, so the
204501
+ * foreign trailer is inherited and the caller may treat the row as stale metadata. The one exception is when the
204502
+ * base ALREADY has an explicit commit for this task — then the branch should have been sitting on the task's own
204503
+ * landed commit, and a foreign tip is genuine misbinding worth rejecting.
204504
+ *
204505
+ * Callers: already-merged recovery (`branchTipForeignOwnership`), branch-misbound recovery
204506
+ * (`isBranchTipMisboundToTask`), and the self-owned-branch reclaim sweep's `tip-already-merged` arm. Keeping the
204507
+ * three on one helper is the point — the reclaim arm drifted without the diff proof and that was the bug.
204508
+ */
204509
+ async foreignTipRejection(input) {
204510
+ const { taskId, lineageId, branchTip, baseBranch, ownership } = input;
204511
+ if (ownership.rejectionReason !== "foreign-task" && ownership.rejectionReason !== "foreign-lineage") return null;
204512
+ const hasNoUniqueDiff = await this.branchHasNoUniqueDiff(branchTip, baseBranch).catch(() => false);
204513
+ const baseAlreadyHasCurrentTask = hasNoUniqueDiff ? await this.baseHasExplicitTaskOwnership(taskId, lineageId, baseBranch).catch(() => false) : false;
204514
+ if (hasNoUniqueDiff && !baseAlreadyHasCurrentTask) return null;
204515
+ return ownership.rejectionReason === "foreign-task" ? { reason: "foreign-task-tip", owner: ownership.ownerTaskId } : { reason: "foreign-lineage-tip", owner: ownership.ownerLineageId };
204516
+ }
204350
204517
  async rejectForeignAlreadyMergedCandidate(input) {
204351
204518
  const { task, candidateSha, candidateOwner, taskBranch, baseBranch, reason, phase } = input;
204352
204519
  await this.store.logEntry(
@@ -204388,20 +204555,14 @@ var init_self_healing = __esm({
204388
204555
  }
204389
204556
  const sha = stdout.trim();
204390
204557
  if (!sha) return null;
204391
- const hasNoUniqueDiff = await this.branchHasNoUniqueDiff(sha, baseBranch).catch(() => false);
204392
204558
  let ownership;
204393
204559
  try {
204394
204560
  ownership = await this.readCommitTaskOwnership(sha, taskId, lineageId);
204395
204561
  } catch {
204396
204562
  return { sha, reason: "ownership-unverifiable" };
204397
204563
  }
204398
- const baseAlreadyHasCurrentTask = hasNoUniqueDiff ? await this.baseHasExplicitTaskOwnership(taskId, lineageId, baseBranch).catch(() => false) : false;
204399
- if ((!hasNoUniqueDiff || baseAlreadyHasCurrentTask) && ownership.rejectionReason === "foreign-task") {
204400
- return { sha, owner: ownership.ownerTaskId, reason: "foreign-task-tip" };
204401
- }
204402
- if ((!hasNoUniqueDiff || baseAlreadyHasCurrentTask) && ownership.rejectionReason === "foreign-lineage") {
204403
- return { sha, owner: ownership.ownerLineageId, reason: "foreign-lineage-tip" };
204404
- }
204564
+ const rejection = await this.foreignTipRejection({ taskId, lineageId, branchTip: sha, baseBranch, ownership });
204565
+ if (rejection) return { sha, owner: rejection.owner, reason: rejection.reason };
204405
204566
  return null;
204406
204567
  }
204407
204568
  async resolveSelfHealingMergeTarget(task, settings, phase) {
@@ -205617,14 +205778,21 @@ var init_self_healing = __esm({
205617
205778
  if (!ownership) {
205618
205779
  continue;
205619
205780
  }
205620
- if (ownership?.rejectionReason === "foreign-task" || ownership?.rejectionReason === "foreign-lineage") {
205781
+ const foreignRejection = await this.foreignTipRejection({
205782
+ taskId: task.id,
205783
+ lineageId: task.lineageId,
205784
+ branchTip: inspection.tipSha,
205785
+ baseBranch: inspection.integrationRef,
205786
+ ownership
205787
+ });
205788
+ if (foreignRejection) {
205621
205789
  await this.rejectForeignAlreadyMergedCandidate({
205622
205790
  task,
205623
205791
  candidateSha: inspection.tipSha,
205624
- candidateOwner: ownership.rejectionReason === "foreign-task" ? ownership.ownerTaskId : ownership.ownerLineageId,
205792
+ candidateOwner: foreignRejection.owner,
205625
205793
  taskBranch: branchName,
205626
205794
  baseBranch: inspection.integrationRef,
205627
- reason: ownership.rejectionReason === "foreign-task" ? "foreign-task-tip" : "foreign-lineage-tip",
205795
+ reason: foreignRejection.reason,
205628
205796
  phase: "tip-already-merged"
205629
205797
  });
205630
205798
  continue;
@@ -209564,7 +209732,7 @@ var init_self_healing = __esm({
209564
209732
  const unrecoverableRepos = [];
209565
209733
  for (const repoRel of repoKeys) {
209566
209734
  const entry = workspaceWorktrees[repoRel];
209567
- const repoRootDir = join73(this.options.rootDir, repoRel);
209735
+ const repoRootDir = join74(this.options.rootDir, repoRel);
209568
209736
  let integrationBranch;
209569
209737
  try {
209570
209738
  integrationBranch = await resolveIntegrationBranch(
@@ -209858,7 +210026,7 @@ var init_self_healing = __esm({
209858
210026
  if ((this.orphanWorktreeRemovalFailures.get(worktreePath) ?? 0) >= MAX_STARVATION_DROPS) {
209859
210027
  continue;
209860
210028
  }
209861
- const repoRootDir = join73(this.options.rootDir, repoRel);
210029
+ const repoRootDir = join74(this.options.rootDir, repoRel);
209862
210030
  let success = false;
209863
210031
  let reason = "removed";
209864
210032
  try {
@@ -210779,7 +210947,7 @@ var init_self_healing = __esm({
210779
210947
  if (testWorkerRoot) {
210780
210948
  try {
210781
210949
  for (const entry of readdirSync10(testWorkerRoot)) {
210782
- if (entry.startsWith("redir-")) roots.push(join73(testWorkerRoot, entry));
210950
+ if (entry.startsWith("redir-")) roots.push(join74(testWorkerRoot, entry));
210783
210951
  }
210784
210952
  } catch {
210785
210953
  }
@@ -210793,7 +210961,7 @@ var init_self_healing = __esm({
210793
210961
  } catch {
210794
210962
  continue;
210795
210963
  }
210796
- for (const entry of entries) paths2.push(join73(root, entry));
210964
+ for (const entry of entries) paths2.push(join74(root, entry));
210797
210965
  }
210798
210966
  return paths2;
210799
210967
  }
@@ -211029,14 +211197,10 @@ var init_self_healing = __esm({
211029
211197
  maxBuffer: 1024 * 1024
211030
211198
  });
211031
211199
  const branchTip = tipOut.trim();
211032
- const hasNoUniqueDiff = await this.branchHasNoUniqueDiff(branchTip, baseBranch).catch(() => false);
211033
211200
  const ownership = await this.readCommitTaskOwnership(branchTip, taskId, lineageId);
211034
- const baseAlreadyHasCurrentTask = hasNoUniqueDiff ? await this.baseHasExplicitTaskOwnership(taskId, lineageId, baseBranch).catch(() => false) : false;
211035
- if ((!hasNoUniqueDiff || baseAlreadyHasCurrentTask) && ownership.rejectionReason === "foreign-task") {
211036
- return { misbound: false, branchTip, landed: null, rejection: { reason: "foreign-task-tip", owner: ownership.ownerTaskId } };
211037
- }
211038
- if ((!hasNoUniqueDiff || baseAlreadyHasCurrentTask) && ownership.rejectionReason === "foreign-lineage") {
211039
- return { misbound: false, branchTip, landed: null, rejection: { reason: "foreign-lineage-tip", owner: ownership.ownerLineageId } };
211201
+ const rejection = await this.foreignTipRejection({ taskId, lineageId, branchTip, baseBranch, ownership });
211202
+ if (rejection) {
211203
+ return { misbound: false, branchTip, landed: null, rejection };
211040
211204
  }
211041
211205
  const hasTaskId = ownership.ownerTaskId === taskId;
211042
211206
  const hasLineage = lineageId ? ownership.ownerLineageId === lineageId : false;
@@ -212698,7 +212862,7 @@ var init_self_healing = __esm({
212698
212862
  let processedMarkers = 0;
212699
212863
  for (const task of candidates) {
212700
212864
  try {
212701
- const promptPath = join73(this.options.rootDir, ".fusion", "tasks", task.id, "PROMPT.md");
212865
+ const promptPath = join74(this.options.rootDir, ".fusion", "tasks", task.id, "PROMPT.md");
212702
212866
  if (!existsSync59(promptPath)) {
212703
212867
  continue;
212704
212868
  }
@@ -213085,7 +213249,7 @@ var init_self_healing = __esm({
213085
213249
  if (!existsSync59(worktreesDir)) return 0;
213086
213250
  let dirs;
213087
213251
  try {
213088
- dirs = readdirSync10(worktreesDir, { withFileTypes: true }).filter((e) => e.isDirectory() && !isAiMergeContainerDir(e.name)).map((e) => join73(worktreesDir, e.name));
213252
+ dirs = readdirSync10(worktreesDir, { withFileTypes: true }).filter((e) => e.isDirectory() && !isAiMergeContainerDir(e.name)).map((e) => join74(worktreesDir, e.name));
213089
213253
  } catch (err) {
213090
213254
  log28.warn(`Failed to read .worktrees/ for unregistered orphan reap: ${err instanceof Error ? err.message : String(err)}`);
213091
213255
  return 0;
@@ -213155,7 +213319,7 @@ var init_self_healing = __esm({
213155
213319
  }
213156
213320
  if (entries.length === 0) continue;
213157
213321
  for (const entry of entries) {
213158
- const path14 = join73(tempRoot, entry);
213322
+ const path14 = join74(tempRoot, entry);
213159
213323
  let canonicalPath = path14;
213160
213324
  let cleanupReason = "stale";
213161
213325
  try {
@@ -213393,8 +213557,8 @@ var init_self_healing = __esm({
213393
213557
  // ../engine/src/triage.ts
213394
213558
  import { Type as Type5 } from "@earendil-works/pi-ai";
213395
213559
  import { exec as exec33 } from "node:child_process";
213396
- import { readFile as readFile36, writeFile as writeFile28, rm as rm9 } from "node:fs/promises";
213397
- import { join as join74 } from "node:path";
213560
+ import { readFile as readFile37, writeFile as writeFile28, rm as rm9 } from "node:fs/promises";
213561
+ import { join as join75 } from "node:path";
213398
213562
  import { promisify as promisify47 } from "node:util";
213399
213563
  function inlineTaskListFallback(lines, opts = {}) {
213400
213564
  const maxChars = Math.max(1, Math.floor(opts.maxChars ?? MAX_TASK_LIST_TEXT_CHARS));
@@ -213445,10 +213609,10 @@ async function readAttachmentContents(rootDir, taskId, attachments) {
213445
213609
  if (!attachments || attachments.length === 0) {
213446
213610
  return { attachmentContents, imageContents };
213447
213611
  }
213448
- const { readFile: readFile63 } = await import("node:fs/promises");
213449
- const { join: join155 } = await import("node:path");
213612
+ const { readFile: readFile64 } = await import("node:fs/promises");
213613
+ const { join: join156 } = await import("node:path");
213450
213614
  for (const att of attachments) {
213451
- const filePath = join155(
213615
+ const filePath = join156(
213452
213616
  rootDir,
213453
213617
  ".fusion",
213454
213618
  "tasks",
@@ -213458,7 +213622,7 @@ async function readAttachmentContents(rootDir, taskId, attachments) {
213458
213622
  );
213459
213623
  try {
213460
213624
  if (IMAGE_MIME_TYPES.has(att.mimeType)) {
213461
- const data = await readFile63(filePath);
213625
+ const data = await readFile64(filePath);
213462
213626
  const detectedMimeType = detectImageMimeFromBytes(data);
213463
213627
  const imageMimeType2 = detectedMimeType ?? att.mimeType;
213464
213628
  if (detectedMimeType && detectedMimeType !== att.mimeType) {
@@ -213475,7 +213639,7 @@ async function readAttachmentContents(rootDir, taskId, attachments) {
213475
213639
  text: null
213476
213640
  });
213477
213641
  } else {
213478
- const data = await readFile63(filePath, "utf-8");
213642
+ const data = await readFile64(filePath, "utf-8");
213479
213643
  const text3 = data.length > TEXT_INLINE_LIMIT ? data.slice(0, TEXT_INLINE_LIMIT) + "\n... (truncated at 50KB)" : data;
213480
213644
  attachmentContents.push({
213481
213645
  originalName: att.originalName,
@@ -213716,6 +213880,7 @@ var init_triage = __esm({
213716
213880
  init_prompt_layers();
213717
213881
  init_fallback_model_observer();
213718
213882
  init_logger3();
213883
+ init_plan_artifact_writeback();
213719
213884
  init_mcp_resolution();
213720
213885
  init_usage_limit_detector();
213721
213886
  init_transient_error_detector();
@@ -214272,8 +214437,8 @@ var init_triage = __esm({
214272
214437
  }
214273
214438
  const settings = await mergeEffectiveSettings(this.store, task, await this.store.getSettings());
214274
214439
  const approvalRequired = resolvePlanApprovalRequired(settings);
214275
- const promptPath = join74(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md");
214276
- const written = await readFile36(promptPath, "utf-8").catch((err) => {
214440
+ const promptPath = join75(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md");
214441
+ const written = await readFile37(promptPath, "utf-8").catch((err) => {
214277
214442
  const msg = err instanceof Error ? err.message : String(err);
214278
214443
  planLog.warn(`${task.id}: failed to read PROMPT.md during planning recovery (${promptPath}): ${msg}`);
214279
214444
  return "";
@@ -214311,8 +214476,8 @@ var init_triage = __esm({
214311
214476
  return true;
214312
214477
  }
214313
214478
  async readNonEmptyPromptDraft(taskId, context) {
214314
- const promptPath = join74(this.rootDir, ".fusion", "tasks", taskId, "PROMPT.md");
214315
- const written = await readFile36(promptPath, "utf-8").catch((err) => {
214479
+ const promptPath = join75(this.rootDir, ".fusion", "tasks", taskId, "PROMPT.md");
214480
+ const written = await readFile37(promptPath, "utf-8").catch((err) => {
214316
214481
  const msg = err instanceof Error ? err.message : String(err);
214317
214482
  planLog.warn(`${taskId}: failed to read PROMPT.md during ${context} (${promptPath}): ${msg}`);
214318
214483
  return "";
@@ -214476,8 +214641,8 @@ var init_triage = __esm({
214476
214641
  continue;
214477
214642
  }
214478
214643
  try {
214479
- const promptPath = join74(this.rootDir, ".fusion", "tasks", todoTask.id, "PROMPT.md");
214480
- const content = await readFile36(promptPath, "utf-8");
214644
+ const promptPath = join75(this.rootDir, ".fusion", "tasks", todoTask.id, "PROMPT.md");
214645
+ const content = await readFile37(promptPath, "utf-8");
214481
214646
  if (isUnplannedSeedPrompt(content, todoTask.id, todoTask.title, todoTask.description)) {
214482
214647
  eligibleTodoTasks.push(todoTask);
214483
214648
  }
@@ -214688,7 +214853,7 @@ var init_triage = __esm({
214688
214853
  const detail = await this.store.getTask(task.id);
214689
214854
  const currentTask = detail ?? task;
214690
214855
  const settings = await mergeEffectiveSettings(this.store, currentTask, await this.store.getSettings());
214691
- const promptPath = `.fusion/tasks/${task.id}/PROMPT.md`;
214856
+ const promptPath = relativePromptPath(task.id);
214692
214857
  const isFast = task.executionMode === "fast";
214693
214858
  const leanPlanning = settings.leanPlanning === true || isFast;
214694
214859
  const agentWork = async () => {
@@ -215024,8 +215189,22 @@ You are ${assignedAgent.name}${assignedAgent.title?.trim() ? `, ${assignedAgent.
215024
215189
  }
215025
215190
  return;
215026
215191
  }
215027
- const written = await readFile36(
215028
- join74(this.rootDir, promptPath),
215192
+ const planPersistence = await persistPlanArtifact({
215193
+ store: this.store,
215194
+ taskId: task.id,
215195
+ rootDir: this.rootDir,
215196
+ planningCwd,
215197
+ author: "triage",
215198
+ logger: { log: (m2) => planLog.log(m2), warn: (m2) => planLog.warn(m2) }
215199
+ });
215200
+ if (planPersistence.outcome === "recovered") {
215201
+ await this.store.logEntry(
215202
+ task.id,
215203
+ "Recovered the plan written inside the task worktree into the project .fusion folder"
215204
+ ).catch(() => void 0);
215205
+ }
215206
+ const written = await readFile37(
215207
+ join75(this.rootDir, promptPath),
215029
215208
  "utf-8"
215030
215209
  ).catch((err) => {
215031
215210
  const msg = err instanceof Error ? err.message : String(err);
@@ -215642,7 +215821,7 @@ Remove or replace these ids and call fn_task_create again.`
215642
215821
  if (isNearDuplicateCanonicalInactive(canonicalTask ?? void 0)) {
215643
215822
  if (canClearInactiveMarker) {
215644
215823
  if (!await this.runIfStillPlanningUnderTaskLock(task, async () => {
215645
- await rm9(join74(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
215824
+ await rm9(join75(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
215646
215825
  })) return;
215647
215826
  await this.updatePlanningStateIfStillCurrent(task, { paused: false, pausedReason: null, status: null });
215648
215827
  }
@@ -215653,7 +215832,7 @@ Remove or replace these ids and call fn_task_create again.`
215653
215832
  if (resolution === "prompt" && keepAcknowledged) {
215654
215833
  if (canClearInactiveMarker) {
215655
215834
  if (!await this.runIfStillPlanningUnderTaskLock(task, async () => {
215656
- await rm9(join74(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
215835
+ await rm9(join75(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
215657
215836
  })) return;
215658
215837
  await this.updatePlanningStateIfStillCurrent(task, {
215659
215838
  paused: false,
@@ -215694,7 +215873,7 @@ Remove or replace these ids and call fn_task_create again.`
215694
215873
  return;
215695
215874
  }
215696
215875
  if (!await this.runIfStillPlanningUnderTaskLock(task, async () => {
215697
- await rm9(join74(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
215876
+ await rm9(join75(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
215698
215877
  })) return;
215699
215878
  if (!await this.updatePlanningStateIfStillCurrent(task, {
215700
215879
  paused: false,
@@ -215759,7 +215938,7 @@ Remove or replace these ids and call fn_task_create again.`
215759
215938
  let nextPrompt = applyOriginalDescription(written, originalDescription);
215760
215939
  nextPrompt = applyFrontendUxCriteria(nextPrompt, parsedFileScope);
215761
215940
  if (nextPrompt !== written) {
215762
- const promptPath = join74(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md");
215941
+ const promptPath = join75(this.rootDir, ".fusion", "tasks", task.id, "PROMPT.md");
215763
215942
  try {
215764
215943
  if (!await this.runIfStillPlanningUnderTaskLock(task, async () => {
215765
215944
  await writeFile28(promptPath, nextPrompt, "utf-8");
@@ -215771,6 +215950,10 @@ Remove or replace these ids and call fn_task_create again.`
215771
215950
  }
215772
215951
  }
215773
215952
  }
215953
+ await mirrorPlanToProjectDb(this.store, task.id, written, {
215954
+ author: "triage",
215955
+ logger: { warn: (m2) => planLog.warn(m2) }
215956
+ });
215774
215957
  let taskIntentSignature = {
215775
215958
  routePaths: [],
215776
215959
  filePaths: [],
@@ -216017,10 +216200,10 @@ Remove or replace these ids and call fn_task_create again.`
216017
216200
  });
216018
216201
 
216019
216202
  // ../engine/src/review-artifacts/feature-video.ts
216020
- import { access as access9, mkdtemp as mkdtemp2, readFile as readFile37, rm as rm10 } from "node:fs/promises";
216203
+ import { access as access9, mkdtemp as mkdtemp2, readFile as readFile38, rm as rm10 } from "node:fs/promises";
216021
216204
  import { constants as constants2 } from "node:fs";
216022
216205
  import { tmpdir as tmpdir8 } from "node:os";
216023
- import { join as join75 } from "node:path";
216206
+ import { join as join76 } from "node:path";
216024
216207
  function shouldGenerateReviewArtifacts(task, settings) {
216025
216208
  return isReviewArtifactGenerationEligible(settings, task.prompt);
216026
216209
  }
@@ -216046,7 +216229,7 @@ async function generateFeatureVideo(options) {
216046
216229
  let browser;
216047
216230
  let context;
216048
216231
  try {
216049
- recordingDir = await mkdtemp2(join75(tmpdir8(), "fusion-feature-video-"));
216232
+ recordingDir = await mkdtemp2(join76(tmpdir8(), "fusion-feature-video-"));
216050
216233
  try {
216051
216234
  browser = await client.launch({ executablePath, headless: true });
216052
216235
  } catch {
@@ -216064,7 +216247,7 @@ async function generateFeatureVideo(options) {
216064
216247
  await (options.sleep ?? defaultSleep)(Math.min(Math.max(options.durationMs ?? DEFAULT_DURATION_MS, 0), MAX_DURATION_MS));
216065
216248
  await context.close();
216066
216249
  context = void 0;
216067
- const data = await readFile37(await video.path());
216250
+ const data = await readFile38(await video.path());
216068
216251
  if (data.byteLength > (options.maxBytes ?? DEFAULT_MAX_BYTES2)) {
216069
216252
  return { status: "failed", reason: "size-cap-exceeded" };
216070
216253
  }
@@ -216213,16 +216396,16 @@ async function persistBranchState(persistence, state) {
216213
216396
  );
216214
216397
  }
216215
216398
  }
216216
- function resolveJoinConfig(join155) {
216217
- const rawMode = join155.config?.mode;
216399
+ function resolveJoinConfig(join156) {
216400
+ const rawMode = join156.config?.mode;
216218
216401
  let mode = "all";
216219
216402
  if (rawMode === "all" || rawMode === "any") mode = rawMode;
216220
216403
  else if (rawMode && typeof rawMode === "object" && "quorum" in rawMode) {
216221
216404
  const n = rawMode.quorum;
216222
216405
  if (typeof n === "number" && Number.isInteger(n) && n > 0) mode = { quorum: n };
216223
- else throw new WorkflowIrError(`join '${join155.id}' quorum must be a positive integer`);
216406
+ else throw new WorkflowIrError(`join '${join156.id}' quorum must be a positive integer`);
216224
216407
  }
216225
- const rawFail = join155.config?.onBranchFailure;
216408
+ const rawFail = join156.config?.onBranchFailure;
216226
216409
  const onBranchFailure = rawFail === "collect" ? "collect" : "fail-fast";
216227
216410
  return { mode, onBranchFailure };
216228
216411
  }
@@ -216238,9 +216421,9 @@ async function runSplitJoin(split, env) {
216238
216421
  if (branchEdges.length === 0) {
216239
216422
  throw new WorkflowIrError(`split '${split.id}' has no traversable branches`);
216240
216423
  }
216241
- const join155 = findMatchingJoin(branchEdges[0].to, env);
216242
- if (!join155) throw new WorkflowIrError(`split '${split.id}' has no reachable matching join`);
216243
- const joinConfig = resolveJoinConfig(env.nodeMap.get(join155));
216424
+ const join156 = findMatchingJoin(branchEdges[0].to, env);
216425
+ if (!join156) throw new WorkflowIrError(`split '${split.id}' has no reachable matching join`);
216426
+ const joinConfig = resolveJoinConfig(env.nodeMap.get(join156));
216244
216427
  const controller = new AbortController();
216245
216428
  const branchCount = branchEdges.length;
216246
216429
  const required2 = requiredCompletions(joinConfig.mode, branchCount);
@@ -216276,7 +216459,7 @@ async function runSplitJoin(split, env) {
216276
216459
  };
216277
216460
  const branchPromises = branchEdges.map((edge) => {
216278
216461
  const branchId = edge.to;
216279
- return walkBranch(branchId, join155, env, controller.signal, visitedNodeIds).then((result2) => {
216462
+ return walkBranch(branchId, join156, env, controller.signal, visitedNodeIds).then((result2) => {
216280
216463
  branchOutcomes.push({ branchId, outcome: result2.outcome, nodeId: result2.lastNodeId });
216281
216464
  if (result2.outcome === "success") succeeded += 1;
216282
216465
  else failed += 1;
@@ -216294,7 +216477,7 @@ async function runSplitJoin(split, env) {
216294
216477
  });
216295
216478
  const outcome = await joinReached;
216296
216479
  await Promise.allSettled(branchPromises);
216297
- return { joinNodeId: join155, outcome, branchOutcomes, visitedNodeIds };
216480
+ return { joinNodeId: join156, outcome, branchOutcomes, visitedNodeIds };
216298
216481
  }
216299
216482
  async function walkBranch(startNodeId, joinId, env, signal, visitedNodeIds) {
216300
216483
  let currentId = startNodeId;
@@ -219710,7 +219893,7 @@ var init_workspace_paths = __esm({
219710
219893
 
219711
219894
  // ../engine/src/cli-agent/hook-scripts.ts
219712
219895
  import { mkdir as mkdir28, rm as rm11, writeFile as writeFile29 } from "node:fs/promises";
219713
- import { join as join76 } from "node:path";
219896
+ import { join as join77 } from "node:path";
219714
219897
  function shellSingleQuote(value) {
219715
219898
  return `'${value.replace(/'/g, `'\\''`)}'`;
219716
219899
  }
@@ -219782,8 +219965,8 @@ exit 0
219782
219965
  async function writeSessionHookScripts(opts) {
219783
219966
  const { sessionId, token, endpointUrl, dir: dir2 } = opts;
219784
219967
  await mkdir28(dir2, { recursive: true, mode: 448 });
219785
- const hookScriptPath = join76(dir2, HOOK_SCRIPT_NAMES.hook);
219786
- const notifyScriptPath = join76(dir2, HOOK_SCRIPT_NAMES.notify);
219968
+ const hookScriptPath = join77(dir2, HOOK_SCRIPT_NAMES.hook);
219969
+ const notifyScriptPath = join77(dir2, HOOK_SCRIPT_NAMES.notify);
219787
219970
  await writeFile29(hookScriptPath, buildHookScriptContent({ sessionId, token, endpointUrl }), {
219788
219971
  mode: 448
219789
219972
  });
@@ -219942,7 +220125,7 @@ var init_autonomy = __esm({
219942
220125
  // ../engine/src/cli-agent/task-session.ts
219943
220126
  import { mkdtemp as mkdtemp3, rm as rm12 } from "node:fs/promises";
219944
220127
  import { tmpdir as tmpdir9 } from "node:os";
219945
- import { join as join77 } from "node:path";
220128
+ import { join as join78 } from "node:path";
219946
220129
  function launchCliTaskSession(opts) {
219947
220130
  return CliTaskSession.launch(opts);
219948
220131
  }
@@ -220008,9 +220191,9 @@ var init_task_session = __esm({
220008
220191
  isApproved: opts.isAutonomyApproved ?? (() => false)
220009
220192
  });
220010
220193
  const root = opts.hookDirRoot ?? tmpdir9();
220011
- const hookDir = await mkdtemp3(join77(root, "fusion-cli-hooks-"));
220012
- const hookScriptPath = join77(hookDir, HOOK_SCRIPT_NAMES.hook);
220013
- const settingsPath = join77(hookDir, "settings.json");
220194
+ const hookDir = await mkdtemp3(join78(root, "fusion-cli-hooks-"));
220195
+ const hookScriptPath = join78(hookDir, HOOK_SCRIPT_NAMES.hook);
220196
+ const settingsPath = join78(hookDir, "settings.json");
220014
220197
  const cliAgentSettings = opts.config.cliAgentSettings ?? null;
220015
220198
  const operatorEnvAdditions = (cliAgentSettings?.envAdditions ?? []).filter(
220016
220199
  (k2) => !/^FUSION_/i.test(k2)
@@ -220252,7 +220435,7 @@ var init_task_session = __esm({
220252
220435
  // ../engine/src/pty-native.ts
220253
220436
  import * as fs7 from "node:fs";
220254
220437
  import { createRequire as createRequire7 } from "node:module";
220255
- import { join as join78, dirname as dirname33 } from "node:path";
220438
+ import { join as join79, dirname as dirname33 } from "node:path";
220256
220439
  function getNativePrebuildName() {
220257
220440
  const platform6 = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : process.platform === "win32" ? "win32" : "unknown";
220258
220441
  const arch = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "x64" : "unknown";
@@ -220262,12 +220445,12 @@ function findInstalledNodePtyNativeDir() {
220262
220445
  try {
220263
220446
  const packageJsonPath = require4.resolve("node-pty/package.json");
220264
220447
  const pkgRoot = dirname33(packageJsonPath);
220265
- const releaseDir = join78(pkgRoot, "build", "Release");
220266
- if (fs7.existsSync(join78(releaseDir, "pty.node"))) {
220448
+ const releaseDir = join79(pkgRoot, "build", "Release");
220449
+ if (fs7.existsSync(join79(releaseDir, "pty.node"))) {
220267
220450
  return releaseDir;
220268
220451
  }
220269
- const prebuildDir = join78(pkgRoot, "prebuilds", getNativePrebuildName());
220270
- if (fs7.existsSync(join78(prebuildDir, "pty.node"))) {
220452
+ const prebuildDir = join79(pkgRoot, "prebuilds", getNativePrebuildName());
220453
+ if (fs7.existsSync(join79(prebuildDir, "pty.node"))) {
220271
220454
  return prebuildDir;
220272
220455
  }
220273
220456
  return null;
@@ -220278,14 +220461,14 @@ function findInstalledNodePtyNativeDir() {
220278
220461
  function findStagedNativeDir() {
220279
220462
  const prebuildName = getNativePrebuildName();
220280
220463
  if (process.env.FUSION_RUNTIME_DIR) {
220281
- const envPath = join78(process.env.FUSION_RUNTIME_DIR, prebuildName);
220282
- if (fs7.existsSync(join78(envPath, "pty.node"))) {
220464
+ const envPath = join79(process.env.FUSION_RUNTIME_DIR, prebuildName);
220465
+ if (fs7.existsSync(join79(envPath, "pty.node"))) {
220283
220466
  return envPath;
220284
220467
  }
220285
220468
  }
220286
220469
  const execDir = dirname33(process.execPath);
220287
- const nextToBinary = join78(execDir, "runtime", prebuildName);
220288
- if (fs7.existsSync(join78(nextToBinary, "pty.node"))) {
220470
+ const nextToBinary = join79(execDir, "runtime", prebuildName);
220471
+ if (fs7.existsSync(join79(nextToBinary, "pty.node"))) {
220289
220472
  return nextToBinary;
220290
220473
  }
220291
220474
  return null;
@@ -220308,8 +220491,8 @@ function ensureNodePtyNativePermissions() {
220308
220491
  candidateDirs.add(installedNativeDir);
220309
220492
  }
220310
220493
  for (const nativeDir of candidateDirs) {
220311
- const helperPath = join78(nativeDir, "spawn-helper");
220312
- const nativeModulePath = join78(nativeDir, "pty.node");
220494
+ const helperPath = join79(nativeDir, "spawn-helper");
220495
+ const nativeModulePath = join79(nativeDir, "pty.node");
220313
220496
  try {
220314
220497
  fs7.chmodSync(helperPath, 493);
220315
220498
  } catch {
@@ -220339,7 +220522,7 @@ async function loadPtyModule() {
220339
220522
  process.env.NODE_PTY_SPAWN_HELPER_DIR = nativeDir;
220340
220523
  }
220341
220524
  process.env.FUSION_NATIVE_ASSETS_PATH = nativeDir;
220342
- const nativePath = join78(nativeDir, "pty.node");
220525
+ const nativePath = join79(nativeDir, "pty.node");
220343
220526
  if (fs7.existsSync(nativePath)) {
220344
220527
  try {
220345
220528
  const nativeModule = { exports: {} };
@@ -221878,7 +222061,7 @@ var init_file_scope2 = __esm({
221878
222061
 
221879
222062
  // ../engine/src/run-verification-tool.ts
221880
222063
  import { existsSync as existsSync64, readdirSync as readdirSync11, readFileSync as readFileSync23 } from "node:fs";
221881
- import { isAbsolute as isAbsolute16, join as join79, relative as relative14 } from "node:path";
222064
+ import { isAbsolute as isAbsolute16, join as join80, relative as relative14 } from "node:path";
221882
222065
  import { Type as Type6 } from "@earendil-works/pi-ai";
221883
222066
  function shellSplit(input) {
221884
222067
  const tokens = [];
@@ -221993,7 +222176,7 @@ function findWorkspacePackageDir(rootDir, packageName) {
221993
222176
  for (const candidate of candidates) {
221994
222177
  if (!candidate) continue;
221995
222178
  try {
221996
- const pkg = JSON.parse(readFileSync23(join79(rootDir, candidate, "package.json"), "utf8"));
222179
+ const pkg = JSON.parse(readFileSync23(join80(rootDir, candidate, "package.json"), "utf8"));
221997
222180
  if (pkg.name === packageName) {
221998
222181
  packageDirCache.set(cacheKey, candidate);
221999
222182
  return candidate;
@@ -222008,7 +222191,7 @@ function findWorkspacePackageDir(rootDir, packageName) {
222008
222191
  while (queue2.length > 0) {
222009
222192
  const current = queue2.shift();
222010
222193
  if (!current) break;
222011
- const abs = join79(rootDir, current.dir);
222194
+ const abs = join80(rootDir, current.dir);
222012
222195
  let entries;
222013
222196
  try {
222014
222197
  entries = readdirSync11(abs, { withFileTypes: true });
@@ -222018,9 +222201,9 @@ function findWorkspacePackageDir(rootDir, packageName) {
222018
222201
  for (const entry of entries) {
222019
222202
  if (!entry.isDirectory()) continue;
222020
222203
  if (entry.name === "node_modules" || entry.name === "dist") continue;
222021
- const child = join79(current.dir, entry.name);
222204
+ const child = join80(current.dir, entry.name);
222022
222205
  try {
222023
- const pkg = JSON.parse(readFileSync23(join79(rootDir, child, "package.json"), "utf8"));
222206
+ const pkg = JSON.parse(readFileSync23(join80(rootDir, child, "package.json"), "utf8"));
222024
222207
  if (pkg.name === packageName) {
222025
222208
  packageDirCache.set(cacheKey, child);
222026
222209
  return child;
@@ -222040,7 +222223,7 @@ function toPackageRelativeFilter(token, rootDir, packageDir) {
222040
222223
  return normalized.slice(normalizedPackageDir.length + 1);
222041
222224
  }
222042
222225
  if (isAbsolute16(token)) {
222043
- const rel = relative14(join79(rootDir, packageDir), token).replace(/\\/g, "/");
222226
+ const rel = relative14(join80(rootDir, packageDir), token).replace(/\\/g, "/");
222044
222227
  if (!rel.startsWith("../") && rel !== "..") return rel;
222045
222228
  }
222046
222229
  return token;
@@ -222297,7 +222480,7 @@ function createRunVerificationTool(opts) {
222297
222480
  if (params.cwd && isAbsolute16(params.cwd)) {
222298
222481
  resolvedCwd = params.cwd;
222299
222482
  } else if (params.cwd) {
222300
- resolvedCwd = join79(worktreePath, params.cwd);
222483
+ resolvedCwd = join80(worktreePath, params.cwd);
222301
222484
  } else {
222302
222485
  resolvedCwd = worktreePath;
222303
222486
  }
@@ -222330,7 +222513,7 @@ function createRunVerificationTool(opts) {
222330
222513
  warnings.push(...normalized.warnings);
222331
222514
  }
222332
222515
  if (effectiveCommand.trimStart().startsWith("pnpm --filter")) {
222333
- const modulesYaml = join79(rootDir, "node_modules", ".modules.yaml");
222516
+ const modulesYaml = join80(rootDir, "node_modules", ".modules.yaml");
222334
222517
  if (!existsSync64(modulesYaml)) {
222335
222518
  const installCmd = "pnpm install --prefer-offline";
222336
222519
  const msg = `node_modules/.modules.yaml not found in workspace root \u2014 auto-prepending \`${installCmd}\` before running the command.`;
@@ -222675,9 +222858,9 @@ var init_pseudo_pause = __esm({
222675
222858
  import { exec as exec38, execFile as execFile26, execSync as execSync7 } from "node:child_process";
222676
222859
  import { promisify as promisify53 } from "node:util";
222677
222860
  import { setImmediate as setImmediateCb3 } from "node:timers";
222678
- import { basename as basename19, delimiter as delimiter2, isAbsolute as isAbsolute18, join as join80, relative as relative16, resolve as resolvePath3 } from "node:path";
222861
+ import { basename as basename19, delimiter as delimiter2, isAbsolute as isAbsolute18, join as join81, relative as relative16, resolve as resolvePath3 } from "node:path";
222679
222862
  import { existsSync as existsSync65, lstatSync as lstatSync3, realpathSync as realpathSync9 } from "node:fs";
222680
- import { readFile as readFile38, rm as rm13, writeFile as writeFile30 } from "node:fs/promises";
222863
+ import { readFile as readFile39, rm as rm13, writeFile as writeFile30 } from "node:fs/promises";
222681
222864
  import { Type as Type7 } from "@earendil-works/pi-ai";
222682
222865
  import { SessionManager as SessionManager2 } from "@earendil-works/pi-coding-agent";
222683
222866
  function mergeAdditionalSkillPaths2(...pathGroups) {
@@ -222691,7 +222874,7 @@ function isWorkflowStepSkillDiscoverable(skillName, additionalSkillPaths, ceSkil
222691
222874
  return false;
222692
222875
  }
222693
222876
  return (additionalSkillPaths ?? []).some(
222694
- (skillPath) => basename19(skillPath) === bareSkillName2 && existsSync65(join80(skillPath, "SKILL.md")) || existsSync65(join80(skillPath, bareSkillName2, "SKILL.md"))
222877
+ (skillPath) => basename19(skillPath) === bareSkillName2 && existsSync65(join81(skillPath, "SKILL.md")) || existsSync65(join81(skillPath, bareSkillName2, "SKILL.md"))
222695
222878
  );
222696
222879
  }
222697
222880
  function getPromptSection(prompt, heading) {
@@ -223000,7 +223183,7 @@ function normalizeWorktreePath(pathValue) {
223000
223183
  }
223001
223184
  async function extractPersistedSessionWorktreePath(sessionFile, rootDir, settings) {
223002
223185
  try {
223003
- const content = await readFile38(sessionFile, "utf-8");
223186
+ const content = await readFile39(sessionFile, "utf-8");
223004
223187
  const matches = content.match(buildSessionWorktreePathRegex(rootDir, settings)) ?? [];
223005
223188
  if (matches.length === 0) return null;
223006
223189
  const normalizedCounts = /* @__PURE__ */ new Map();
@@ -226448,7 +226631,7 @@ ${info.feedback}`, revisionKey),
226448
226631
  const authoritativeAgentLayer = this.store.getAsyncLayer();
226449
226632
  if (!this.authoritativeAssignedAgentStore || authoritativeAgentLayer && !this.authoritativeAssignedAgentStore.backendMode) {
226450
226633
  this.authoritativeAssignedAgentStore = new AgentStore({
226451
- rootDir: join80(this.rootDir, ".fusion"),
226634
+ rootDir: join81(this.rootDir, ".fusion"),
226452
226635
  taskStore: this.store,
226453
226636
  ...authoritativeAgentLayer ? { asyncLayer: authoritativeAgentLayer } : {}
226454
226637
  });
@@ -230908,7 +231091,7 @@ Graph value: ${failureValue}` : ""}`, budget.key),
230908
231091
  const activeMergeStatuses = /* @__PURE__ */ new Set(["merging", "merging-pr", "merging-fix"]);
230909
231092
  const isActiveTask = activeColumns.has(task.column) || activeMergeStatuses.has(task.status ?? "");
230910
231093
  if (!isActiveTask) {
230911
- const tasksDir = join80(this.store.getFusionDir(), "tasks");
231094
+ const tasksDir = join81(this.store.getFusionDir(), "tasks");
230912
231095
  const promptPath = getPromptPath(tasksDir, task.id);
230913
231096
  const staleness = await evaluateSpecStaleness({ settings, promptPath, task });
230914
231097
  if (staleness.isStale) {
@@ -234769,10 +234952,10 @@ Please fix the issues so the verification can pass on the next attempt.`,
234769
234952
  * The section is replaced entirely to avoid accumulation of old feedback.
234770
234953
  */
234771
234954
  async injectWorkflowStepFailureInstructions(task, failureFeedback, stepName, retry2) {
234772
- const promptPath = join80(this.store.getFusionDir(), "tasks", task.id, "PROMPT.md");
234955
+ const promptPath = join81(this.store.getFusionDir(), "tasks", task.id, "PROMPT.md");
234773
234956
  let content;
234774
234957
  try {
234775
- content = await readFile38(promptPath, "utf-8");
234958
+ content = await readFile39(promptPath, "utf-8");
234776
234959
  } catch {
234777
234960
  executorLog.warn(`${task.id}: PROMPT.md not found at ${promptPath}, skipping workflow failure injection`);
234778
234961
  return;
@@ -241311,7 +241494,7 @@ import { execFile as execFile27 } from "node:child_process";
241311
241494
  import { appendFileSync as appendFileSync2, existsSync as existsSync66, mkdirSync as mkdirSync11, readdirSync as readdirSync12, readFileSync as readFileSync24, realpathSync as realpathSync10, rmSync as rmSync9, statSync as statSync13 } from "node:fs";
241312
241495
  import { rm as rm14 } from "node:fs/promises";
241313
241496
  import { tmpdir as tmpdir10 } from "node:os";
241314
- import { isAbsolute as isAbsolute19, join as join81, relative as relative17 } from "node:path";
241497
+ import { isAbsolute as isAbsolute19, join as join82, relative as relative17 } from "node:path";
241315
241498
  import { promisify as promisify56 } from "node:util";
241316
241499
  async function git4(args, cwd, opts = {}) {
241317
241500
  const { stdout } = await execFileAsync20("git", args, {
@@ -241342,7 +241525,7 @@ function isBenignAbsentWorktreeError(err) {
241342
241525
  return /is not a working tree|No such file or directory|spawn\s+.*\bENOENT\b/i.test(description);
241343
241526
  }
241344
241527
  function ensureAiMergeRootIgnored(projectRootDir, settings) {
241345
- const excludePath = join81(projectRootDir, ".git", "info", "exclude");
241528
+ const excludePath = join82(projectRootDir, ".git", "info", "exclude");
241346
241529
  if (!existsSync66(excludePath)) return;
241347
241530
  try {
241348
241531
  const current = readFileSync24(excludePath, "utf-8");
@@ -241374,7 +241557,7 @@ function getAiMergeTempSearchRoots(projectRootDir, settings) {
241374
241557
  if (testWorkerRoot) {
241375
241558
  try {
241376
241559
  for (const entry of readdirSync12(testWorkerRoot)) {
241377
- if (entry.startsWith("redir-")) roots.push(join81(testWorkerRoot, entry));
241560
+ if (entry.startsWith("redir-")) roots.push(join82(testWorkerRoot, entry));
241378
241561
  }
241379
241562
  } catch {
241380
241563
  }
@@ -241397,7 +241580,7 @@ async function pruneExistingAiMergeWorktrees(taskId, projectRootDir, audit, log3
241397
241580
  continue;
241398
241581
  }
241399
241582
  for (const entry of entries) {
241400
- const candidatePath = join81(tempRoot, entry);
241583
+ const candidatePath = join82(tempRoot, entry);
241401
241584
  let canonicalPath = candidatePath;
241402
241585
  try {
241403
241586
  canonicalPath = realpathSync10(candidatePath);
@@ -241820,7 +242003,7 @@ import { promisify as promisify57 } from "node:util";
241820
242003
  import { realpathSync as realpathSync11, readdirSync as readdirSync13 } from "node:fs";
241821
242004
  import { mkdtemp as mkdtemp4 } from "node:fs/promises";
241822
242005
  import { tmpdir as tmpdir11 } from "node:os";
241823
- import { join as join82 } from "node:path";
242006
+ import { join as join83 } from "node:path";
241824
242007
  async function git5(args, cwd, opts = {}) {
241825
242008
  const { stdout } = await execFileAsync21("git", args, {
241826
242009
  cwd,
@@ -241892,7 +242075,7 @@ function listAiMergeWorktreeCandidates(taskId, projectRootDir, settings) {
241892
242075
  if (testWorkerRoot) {
241893
242076
  try {
241894
242077
  for (const entry of readdirSync13(testWorkerRoot)) {
241895
- if (entry.startsWith("redir-")) roots.push(join82(testWorkerRoot, entry));
242078
+ if (entry.startsWith("redir-")) roots.push(join83(testWorkerRoot, entry));
241896
242079
  }
241897
242080
  } catch {
241898
242081
  }
@@ -241905,7 +242088,7 @@ function listAiMergeWorktreeCandidates(taskId, projectRootDir, settings) {
241905
242088
  } catch {
241906
242089
  continue;
241907
242090
  }
241908
- for (const entry of entries) candidates.push(join82(root, entry));
242091
+ for (const entry of entries) candidates.push(join83(root, entry));
241909
242092
  }
241910
242093
  return candidates;
241911
242094
  }
@@ -242239,7 +242422,7 @@ async function landOneRepo(repoRootDir, branch, integrationBranch, ctx) {
242239
242422
  registeredMergePaths.add(pathToRegister);
242240
242423
  };
242241
242424
  try {
242242
- mergeRoot = await mkdtemp4(join82(resolveAiMergeRoot(repoRootDir, settings), `fusion-ai-merge-${taskId.toLowerCase()}-`));
242425
+ mergeRoot = await mkdtemp4(join83(resolveAiMergeRoot(repoRootDir, settings), `fusion-ai-merge-${taskId.toLowerCase()}-`));
242243
242426
  registerMergeRoot(mergeRoot);
242244
242427
  await git5(["worktree", "add", "--detach", mergeRoot, tipSha], repoRootDir);
242245
242428
  worktreeAdded = true;
@@ -242735,7 +242918,7 @@ async function landWorkspaceTask(store, task, workspaceRootDir, options = {}, de
242735
242918
  for (const repoRel of repoKeys) {
242736
242919
  throwIfAborted2(options.signal, taskId);
242737
242920
  const entry = workspaceWorktrees[repoRel];
242738
- const repoRootDir = join82(workspaceRootDir, repoRel);
242921
+ const repoRootDir = join83(workspaceRootDir, repoRel);
242739
242922
  let integrationBranch;
242740
242923
  try {
242741
242924
  integrationBranch = await resolveIntegrationBranch(
@@ -243052,7 +243235,7 @@ async function pushAfterMergeToRemote(input) {
243052
243235
  let worktreeAdded = false;
243053
243236
  const registeredPaths = /* @__PURE__ */ new Set();
243054
243237
  try {
243055
- pushRoot = await mkdtemp4(join82(resolveAiMergeRoot(projectRootDir, settings), `fusion-ai-merge-push-${taskId.toLowerCase()}-`));
243238
+ pushRoot = await mkdtemp4(join83(resolveAiMergeRoot(projectRootDir, settings), `fusion-ai-merge-push-${taskId.toLowerCase()}-`));
243056
243239
  for (const p2 of [pushRoot]) {
243057
243240
  activeSessionRegistry.registerPath(p2, { taskId, kind: "ai-merge", ownerKey: `ai-merge-push:${taskId}` });
243058
243241
  registeredPaths.add(p2);
@@ -243359,7 +243542,7 @@ var init_merger_ai = __esm({
243359
243542
 
243360
243543
  // ../engine/src/task-revert.ts
243361
243544
  import { exec as exec41 } from "node:child_process";
243362
- import { join as join83 } from "node:path";
243545
+ import { join as join84 } from "node:path";
243363
243546
  import { promisify as promisify58 } from "node:util";
243364
243547
  function quoteShellArg7(value) {
243365
243548
  return `'${value.replace(/'/g, `'\\''`)}'`;
@@ -243809,7 +243992,7 @@ async function resolveWorkspaceTaskRevertCommits(task, opts) {
243809
243992
  const result2 = {};
243810
243993
  for (const repoRel of repoKeys) {
243811
243994
  const entry = workspaceWorktrees[repoRel];
243812
- const repoRootDir = join83(opts.workspaceRootDir, repoRel);
243995
+ const repoRootDir = join84(opts.workspaceRootDir, repoRel);
243813
243996
  const landedSha = workspaceLandedShas[repoRel] ?? entry?.landedSha;
243814
243997
  if (landedSha && !entry?.baseCommitSha) {
243815
243998
  result2[repoRel] = { commits: [landedSha], source: "squash" };
@@ -243876,7 +244059,7 @@ async function revertWorkspaceTask(opts) {
243876
244059
  });
243877
244060
  const contexts = [];
243878
244061
  for (const repoRel of repoKeys) {
243879
- const repoRootDir = join83(workspaceRootDir, repoRel);
244062
+ const repoRootDir = join84(workspaceRootDir, repoRel);
243880
244063
  let integrationBranch;
243881
244064
  try {
243882
244065
  integrationBranch = await resolveIntegrationBranch(repoRootDir, { ...opts.settings, integrationBranch: void 0, baseBranch: void 0 });
@@ -244001,7 +244184,7 @@ async function prepareWorkspaceRevertPrBranches(opts) {
244001
244184
  });
244002
244185
  const contexts = [];
244003
244186
  for (const repoRel of repoKeys) {
244004
- const repoRootDir = join83(workspaceRootDir, repoRel);
244187
+ const repoRootDir = join84(workspaceRootDir, repoRel);
244005
244188
  let integrationBranch;
244006
244189
  try {
244007
244190
  integrationBranch = await resolveIntegrationBranch(repoRootDir, { ...opts.settings, integrationBranch: void 0, baseBranch: void 0 });
@@ -244342,7 +244525,7 @@ async function readOptionalTextFile(filePath) {
244342
244525
  }
244343
244526
  async function discoverMcpServers(opts) {
244344
244527
  const homeDir = opts.homeDir ?? process.env.HOME ?? process.env.USERPROFILE ?? osHomedir();
244345
- const readFile63 = opts.readFile ?? readOptionalTextFile;
244528
+ const readFile64 = opts.readFile ?? readOptionalTextFile;
244346
244529
  const sources = getMcpDiscoverySources({
244347
244530
  homeDir,
244348
244531
  platform: osPlatform(),
@@ -244353,7 +244536,7 @@ async function discoverMcpServers(opts) {
244353
244536
  for (const source of sources) {
244354
244537
  let contents;
244355
244538
  try {
244356
- contents = await readFile63(source.path);
244539
+ contents = await readFile64(source.path);
244357
244540
  } catch (error3) {
244358
244541
  errors.push(`${source.label}: ${error3 instanceof Error ? error3.message : String(error3)}`);
244359
244542
  continue;
@@ -244903,7 +245086,7 @@ var agent_reflection_exports = {};
244903
245086
  __export(agent_reflection_exports, {
244904
245087
  AgentReflectionService: () => AgentReflectionService
244905
245088
  });
244906
- import { readFile as readFile39 } from "node:fs/promises";
245089
+ import { readFile as readFile40 } from "node:fs/promises";
244907
245090
  import { isAbsolute as isAbsolute20, resolve as resolve38 } from "node:path";
244908
245091
  var reflectionLog, REFLECTION_SYSTEM_PROMPT, DEFAULT_OUTCOME_LIMIT, AgentReflectionService;
244909
245092
  var init_agent_reflection = __esm({
@@ -245462,7 +245645,7 @@ Rules:
245462
245645
  if (agent.instructionsPath?.trim()) {
245463
245646
  const resolvedPath = isAbsolute20(agent.instructionsPath) ? agent.instructionsPath : resolve38(this.rootDir, agent.instructionsPath);
245464
245647
  try {
245465
- const content = await readFile39(resolvedPath, "utf-8");
245648
+ const content = await readFile40(resolvedPath, "utf-8");
245466
245649
  if (content.trim()) {
245467
245650
  pieces.push(content.trim());
245468
245651
  }
@@ -247570,7 +247753,7 @@ The note must be specific (what/where/why). Prefer citing File Scope, PROMPT, a
247570
247753
 
247571
247754
  // ../engine/src/overseer-watchdog.ts
247572
247755
  import { existsSync as existsSync67, readFileSync as readFileSync25 } from "node:fs";
247573
- import { dirname as dirname34, join as join84, relative as relative18, resolve as resolve39, sep as sep11 } from "node:path";
247756
+ import { dirname as dirname34, join as join85, relative as relative18, resolve as resolve39, sep as sep11 } from "node:path";
247574
247757
  import { homedir as homedir11 } from "node:os";
247575
247758
  function defaultReadText(path14) {
247576
247759
  try {
@@ -247599,7 +247782,7 @@ function discoverOverseerWatchdogFiles(options) {
247599
247782
  };
247600
247783
  if (agentDir) {
247601
247784
  for (const name2 of WATCHDOG_FILENAMES) {
247602
- tryAdd(join84(agentDir, name2), "user", 999);
247785
+ tryAdd(join85(agentDir, name2), "user", 999);
247603
247786
  }
247604
247787
  }
247605
247788
  let current = cwd;
@@ -247607,9 +247790,9 @@ function discoverOverseerWatchdogFiles(options) {
247607
247790
  for (let hop = 0; hop < 64; hop++) {
247608
247791
  const depth = relative18(cwd, current) === "" ? 0 : relative18(cwd, current).split(sep11).filter(Boolean).length;
247609
247792
  for (const name2 of WATCHDOG_FILENAMES) {
247610
- tryAdd(join84(current, name2), "project", depth);
247611
- tryAdd(join84(current, ".fusion", name2), "project", depth);
247612
- tryAdd(join84(current, ".omp", name2), "project", depth);
247793
+ tryAdd(join85(current, name2), "project", depth);
247794
+ tryAdd(join85(current, ".fusion", name2), "project", depth);
247795
+ tryAdd(join85(current, ".omp", name2), "project", depth);
247613
247796
  }
247614
247797
  if (current === stopAt) break;
247615
247798
  const parent2 = dirname34(current);
@@ -255912,7 +256095,7 @@ __export(child_process_runtime_exports, {
255912
256095
  import { EventEmitter as EventEmitter29 } from "node:events";
255913
256096
  import { fork } from "node:child_process";
255914
256097
  import { fileURLToPath as fileURLToPath4 } from "node:url";
255915
- import { dirname as dirname35, join as join85 } from "node:path";
256098
+ import { dirname as dirname35, join as join86 } from "node:path";
255916
256099
  var HealthMonitor, ChildProcessRuntime;
255917
256100
  var init_child_process_runtime = __esm({
255918
256101
  "../engine/src/runtimes/child-process-runtime.ts"() {
@@ -256074,7 +256257,7 @@ var init_child_process_runtime = __esm({
256074
256257
  const isCompiled = !import.meta.url.endsWith(".ts");
256075
256258
  const currentDir = dirname35(fileURLToPath4(import.meta.url));
256076
256259
  const workerFile = isCompiled ? "child-process-worker.js" : "child-process-worker.ts";
256077
- return join85(currentDir, workerFile);
256260
+ return join86(currentDir, workerFile);
256078
256261
  }
256079
256262
  /**
256080
256263
  * Set up event forwarding from IPC host to runtime listeners.
@@ -262341,7 +262524,7 @@ import { mkdirSync as mkdirSync12 } from "node:fs";
262341
262524
  import { access as access10, unlink as unlink10, writeFile as writeFile32 } from "node:fs/promises";
262342
262525
  import net2 from "node:net";
262343
262526
  import { platform as platform3, tmpdir as tmpdir12 } from "node:os";
262344
- import { join as join86 } from "node:path";
262527
+ import { join as join87 } from "node:path";
262345
262528
  import { createHash as createHash24 } from "node:crypto";
262346
262529
  function projectHash(projectId) {
262347
262530
  return createHash24("sha1").update(projectId).digest("hex").slice(0, 16);
@@ -262351,10 +262534,10 @@ function computeEngineSocketPath(projectId) {
262351
262534
  if (platform3() === "win32") {
262352
262535
  return `\\\\.\\pipe\\fusion-engine-${hash}`;
262353
262536
  }
262354
- return join86(tmpdir12(), `fusion-engine-${hash}.sock`);
262537
+ return join87(tmpdir12(), `fusion-engine-${hash}.sock`);
262355
262538
  }
262356
262539
  function computeEngineLockFilePath(workingDir) {
262357
- return join86(workingDir, ".fusion", "engine.lock");
262540
+ return join87(workingDir, ".fusion", "engine.lock");
262358
262541
  }
262359
262542
  async function ensureLockTargetExists(lockPath) {
262360
262543
  try {
@@ -262364,7 +262547,7 @@ async function ensureLockTargetExists(lockPath) {
262364
262547
  }
262365
262548
  }
262366
262549
  async function acquireLockfile(workingDir, onCompromised) {
262367
- const dir2 = join86(workingDir, ".fusion");
262550
+ const dir2 = join87(workingDir, ".fusion");
262368
262551
  mkdirSync12(dir2, { recursive: true });
262369
262552
  const path14 = computeEngineLockFilePath(workingDir);
262370
262553
  await ensureLockTargetExists(path14);
@@ -272048,8 +272231,8 @@ var init_project_store_resolver = __esm({
272048
272231
 
272049
272232
  // ../dashboard/src/plugin-routes.ts
272050
272233
  import { Router } from "express";
272051
- import { access as access11, stat as stat10, readFile as readFile40 } from "node:fs/promises";
272052
- import { join as join87, isAbsolute as isAbsolute22, dirname as dirname36, basename as basename21 } from "node:path";
272234
+ import { access as access11, stat as stat10, readFile as readFile41 } from "node:fs/promises";
272235
+ import { join as join88, isAbsolute as isAbsolute22, dirname as dirname36, basename as basename21 } from "node:path";
272053
272236
  function isPluginRouteResponse(result2) {
272054
272237
  if (!result2 || typeof result2 !== "object" || Array.isArray(result2)) {
272055
272238
  return false;
@@ -272062,7 +272245,7 @@ async function loadRegistryManifest() {
272062
272245
  return cachedRegistryManifest;
272063
272246
  }
272064
272247
  try {
272065
- const raw = await readFile40(registryManifestUrl, "utf-8");
272248
+ const raw = await readFile41(registryManifestUrl, "utf-8");
272066
272249
  cachedRegistryManifest = JSON.parse(raw);
272067
272250
  return cachedRegistryManifest;
272068
272251
  } catch (error3) {
@@ -272159,7 +272342,7 @@ async function resolvePluginManifest(sourcePath) {
272159
272342
  if (!sourceStat.isDirectory()) {
272160
272343
  throw badRequest(`Path is not a directory: ${sourcePath}`);
272161
272344
  }
272162
- const directManifestPath = join87(sourcePath, "manifest.json");
272345
+ const directManifestPath = join88(sourcePath, "manifest.json");
272163
272346
  try {
272164
272347
  await access11(directManifestPath);
272165
272348
  const manifest = await readAndValidateManifest(directManifestPath);
@@ -272170,7 +272353,7 @@ async function resolvePluginManifest(sourcePath) {
272170
272353
  const dirName = basename21(sourcePath).toLowerCase();
272171
272354
  if (DIST_DIR_NAMES.has(dirName)) {
272172
272355
  const parentDir = dirname36(sourcePath);
272173
- const parentManifestPath = join87(parentDir, "manifest.json");
272356
+ const parentManifestPath = join88(parentDir, "manifest.json");
272174
272357
  try {
272175
272358
  await access11(parentManifestPath);
272176
272359
  const manifest = await readAndValidateManifest(parentManifestPath);
@@ -272186,7 +272369,7 @@ async function resolvePluginManifest(sourcePath) {
272186
272369
  async function readAndValidateManifest(manifestPath) {
272187
272370
  let content;
272188
272371
  try {
272189
- content = await readFile40(manifestPath, "utf-8");
272372
+ content = await readFile41(manifestPath, "utf-8");
272190
272373
  } catch (err) {
272191
272374
  throw badRequest(`Cannot read manifest at ${manifestPath}: ${err.message}`);
272192
272375
  }
@@ -273255,7 +273438,7 @@ var init_issue_image_attachments = __esm({
273255
273438
  import { exec as exec45 } from "node:child_process";
273256
273439
  import { mkdtemp as mkdtemp6, rm as rm15 } from "node:fs/promises";
273257
273440
  import { tmpdir as tmpdir13 } from "node:os";
273258
- import { join as join88 } from "node:path";
273441
+ import { join as join89 } from "node:path";
273259
273442
  import { promisify as promisify65 } from "node:util";
273260
273443
  function resolveCommentAuthor(input) {
273261
273444
  const login = input.login || "unknown";
@@ -274501,8 +274684,8 @@ var init_github = __esm({
274501
274684
  { timeout: 3e4, maxBuffer: 10 * 1024 * 1024 }
274502
274685
  );
274503
274686
  const mergeBase = mergeBaseStdout.trim();
274504
- const indexDir = await mkdtemp6(join88(tmpdir13(), "fn-pr-conflict-"));
274505
- const indexPath = join88(indexDir, "index");
274687
+ const indexDir = await mkdtemp6(join89(tmpdir13(), "fn-pr-conflict-"));
274688
+ const indexPath = join89(indexDir, "index");
274506
274689
  const gitEnv = { ...process.env, GIT_INDEX_FILE: indexPath };
274507
274690
  try {
274508
274691
  await execAsync40(`git -C ${quoteGitArg(opts.repoRoot)} read-tree -m ${quoteGitArg(mergeBase)} ${quoteGitArg(baseRef)} ${quoteGitArg(headRef)}`, {
@@ -276717,7 +276900,7 @@ var init_github = __esm({
276717
276900
  });
276718
276901
 
276719
276902
  // ../dashboard/src/artifact-media.ts
276720
- import { readFile as readFile41 } from "node:fs/promises";
276903
+ import { readFile as readFile42 } from "node:fs/promises";
276721
276904
  import { resolve as resolve41, sep as sep13 } from "node:path";
276722
276905
  function resolveArtifactMediaPath(scopedStore, artifact) {
276723
276906
  if (!artifact.uri) return null;
@@ -276733,7 +276916,7 @@ function resolveArtifactMediaPath(scopedStore, artifact) {
276733
276916
  async function readArtifactMediaBytes(scopedStore, artifact) {
276734
276917
  const mediaPath = resolveArtifactMediaPath(scopedStore, artifact);
276735
276918
  if (!mediaPath) throw badRequest("Artifact has no stored media");
276736
- return readFile41(mediaPath);
276919
+ return readFile42(mediaPath);
276737
276920
  }
276738
276921
  var init_artifact_media = __esm({
276739
276922
  "../dashboard/src/artifact-media.ts"() {
@@ -279758,8 +279941,8 @@ var init_knowledge_index_refresh = __esm({
279758
279941
  // ../dashboard/src/pr-metadata-generator.ts
279759
279942
  import { promisify as promisify66 } from "node:util";
279760
279943
  import { exec as execCb } from "node:child_process";
279761
- import { access as access12, readFile as readFile42 } from "node:fs/promises";
279762
- import { join as join89 } from "node:path";
279944
+ import { access as access12, readFile as readFile43 } from "node:fs/promises";
279945
+ import { join as join90 } from "node:path";
279763
279946
  function buildFallbackPrMetadata(task) {
279764
279947
  return {
279765
279948
  title: task.title ?? task.id,
@@ -279959,14 +280142,14 @@ async function generatePrMetadata(input) {
279959
280142
  ]), combinedSignal);
279960
280143
  let promptContent = "";
279961
280144
  try {
279962
- const promptPath = join89(repoRoot, ".fusion", "tasks", task.id, "PROMPT.md");
279963
- promptContent = (await raceWithAbort(readFile42(promptPath, "utf8"), combinedSignal)).trim();
280145
+ const promptPath = join90(repoRoot, ".fusion", "tasks", task.id, "PROMPT.md");
280146
+ promptContent = (await raceWithAbort(readFile43(promptPath, "utf8"), combinedSignal)).trim();
279964
280147
  } catch {
279965
280148
  promptContent = "";
279966
280149
  }
279967
- const templatePath = join89(repoRoot, ".github", "pull_request_template.md");
280150
+ const templatePath = join90(repoRoot, ".github", "pull_request_template.md");
279968
280151
  const templateExists = await raceWithAbort(access12(templatePath).then(() => true).catch(() => false), combinedSignal);
279969
- const template = templateExists ? await raceWithAbort(readFile42(templatePath, "utf8"), combinedSignal) : "";
280152
+ const template = templateExists ? await raceWithAbort(readFile43(templatePath, "utf8"), combinedSignal) : "";
279970
280153
  const model = resolveTitleSummarizerSettingsModel(settings);
279971
280154
  const systemPrompt = [PR_METADATA_SYSTEM_PROMPT];
279972
280155
  const titleGuidance = settings.prTitlePromptInstructions?.trim();
@@ -280151,8 +280334,8 @@ var init_resolve_diff_base = __esm({
280151
280334
  });
280152
280335
 
280153
280336
  // ../dashboard/src/pr-conflict-resolver.ts
280154
- import { access as access13, mkdir as mkdir29, readFile as readFile43, rm as rm16 } from "node:fs/promises";
280155
- import { join as join90, resolve as resolve43 } from "node:path";
280337
+ import { access as access13, mkdir as mkdir29, readFile as readFile44, rm as rm16 } from "node:fs/promises";
280338
+ import { join as join91, resolve as resolve43 } from "node:path";
280156
280339
  function asSessionPluginRunner(runner) {
280157
280340
  if (!runner) return void 0;
280158
280341
  if (typeof runner.getRuntimeById === "function") {
@@ -280201,7 +280384,7 @@ async function findFilesWithConflictMarkers2(rootDir, files) {
280201
280384
  const conflicted = [];
280202
280385
  for (const file of files) {
280203
280386
  try {
280204
- const contents = await readFile43(join90(rootDir, file), "utf8");
280387
+ const contents = await readFile44(join91(rootDir, file), "utf8");
280205
280388
  if (/^<<<<<<< /m.test(contents) || /^=======$/m.test(contents) || /^>>>>>>> /m.test(contents)) {
280206
280389
  conflicted.push(file);
280207
280390
  }
@@ -280286,11 +280469,11 @@ async function resolvePrConflicts(input) {
280286
280469
  const task = await store.getTask(taskId);
280287
280470
  const branchName = getHeadBranch(taskId);
280288
280471
  const reusableWorktree = await resolveUsableWorktree(task.worktree, branchName);
280289
- const tempWorktreePath = join90(rootDir, ".fusion", "worktrees", `conflict-${taskId.toLowerCase()}`);
280472
+ const tempWorktreePath = join91(rootDir, ".fusion", "worktrees", `conflict-${taskId.toLowerCase()}`);
280290
280473
  const cwd = reusableWorktree ?? tempWorktreePath;
280291
280474
  const createdTemporaryWorktree = !reusableWorktree;
280292
280475
  if (createdTemporaryWorktree) {
280293
- await mkdir29(join90(rootDir, ".fusion", "worktrees"), { recursive: true });
280476
+ await mkdir29(join91(rootDir, ".fusion", "worktrees"), { recursive: true });
280294
280477
  await rm16(tempWorktreePath, { recursive: true, force: true });
280295
280478
  await runGitCommand2(["worktree", "add", "--force", tempWorktreePath, branchName], rootDir, GIT_TIMEOUT_MS10);
280296
280479
  }
@@ -288118,7 +288301,7 @@ var init_auth_middleware = __esm({
288118
288301
  // ../dashboard/src/routes/register-task-workflow-routes.ts
288119
288302
  import { createReadStream } from "node:fs";
288120
288303
  import { stat as stat11 } from "node:fs/promises";
288121
- import { join as join91 } from "node:path";
288304
+ import { join as join92 } from "node:path";
288122
288305
  async function clearRebuiltSpecWorkflowPins(store, taskId) {
288123
288306
  const maybeStore = store;
288124
288307
  try {
@@ -289301,13 +289484,16 @@ ${normalizedDescription}`;
289301
289484
  const existing = await scopedStore.getTask(req.params.id);
289302
289485
  const rootDir = scopedStore.getRootDir();
289303
289486
  const allocateWorktree = existing ? (task2, reservedNames) => planTaskWorktreePath(task2, rootDir, settings.worktreeNaming, reservedNames, settings) : void 0;
289304
- const result2 = await promoteHeldTask(scopedStore, req.params.id, { allocateWorktree });
289487
+ const force = req.body?.force === true;
289488
+ const result2 = await promoteHeldTask(scopedStore, req.params.id, { allocateWorktree }, { force });
289305
289489
  if (!result2.released) {
289306
289490
  if (result2.rejection === "unplanned-for-execution") {
289307
289491
  throw new ApiError(409, "Task is not ready for execution (plan review or planning still outstanding)", {
289308
289492
  code: "unplanned-for-execution",
289309
289493
  messageKey: "board.rejection.unplannedForExecution",
289310
- retryable: true
289494
+ retryable: true,
289495
+ // Tells the board this rejection has an operator override available.
289496
+ forceable: true
289311
289497
  });
289312
289498
  }
289313
289499
  if (result2.rejection === "capacity-exhausted-or-no-slot") {
@@ -289449,14 +289635,14 @@ ${normalizedDescription}`;
289449
289635
  }
289450
289636
  const cleanupPreparedBranches = async () => {
289451
289637
  for (const repoBranch of prepared.repos) {
289452
- const repoRootDir = join91(rootDir, repoBranch.repo);
289638
+ const repoRootDir = join92(rootDir, repoBranch.repo);
289453
289639
  await runGitCommand3(["checkout", repoBranch.integrationBranch], repoRootDir, 1e4).catch(() => void 0);
289454
289640
  await runGitCommand3(["branch", "-D", revertBranch], repoRootDir, 1e4).catch(() => void 0);
289455
289641
  }
289456
289642
  };
289457
289643
  const targets = [];
289458
289644
  for (const repoBranch of prepared.repos) {
289459
- const gitRepo = getCurrentRepo(join91(rootDir, repoBranch.repo));
289645
+ const gitRepo = getCurrentRepo(join92(rootDir, repoBranch.repo));
289460
289646
  if (!gitRepo) {
289461
289647
  await cleanupPreparedBranches();
289462
289648
  res.json({
@@ -289499,7 +289685,7 @@ ${normalizedDescription}`;
289499
289685
  resultRepos.push({ repo: target.repoBranch.repo, revertBranch, prUrl: prInfo2.url, prNumber: prInfo2.number, existingPr: true });
289500
289686
  continue;
289501
289687
  }
289502
- await runGitCommand3(["push", "-u", "origin", revertBranch], join91(rootDir, target.repoBranch.repo), 6e4);
289688
+ await runGitCommand3(["push", "-u", "origin", revertBranch], join92(rootDir, target.repoBranch.repo), 6e4);
289503
289689
  const prTitle = `revert(${task.id}): undo landed work (${target.repoBranch.repo})`;
289504
289690
  const prBody = `This PR reverts the work landed by task ${task.id} in sub-repo \`${target.repoBranch.repo}\`.
289505
289691
 
@@ -289813,8 +289999,8 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
289813
289999
  });
289814
290000
  if (retrySpecification) {
289815
290001
  const { rm: rm23 } = await import("node:fs/promises");
289816
- const { join: join155 } = await import("node:path");
289817
- const promptPath = join155(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
290002
+ const { join: join156 } = await import("node:path");
290003
+ const promptPath = join156(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
289818
290004
  await rm23(promptPath, { force: true });
289819
290005
  await scopedStore.logEntry(req.params.id, "Retry requested from dashboard (planning retry budget reset)");
289820
290006
  const updated2 = await scopedStore.getTask(req.params.id);
@@ -290526,10 +290712,10 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
290526
290712
  await scopedStore.logEntry(task.id, "Plan approved by user");
290527
290713
  let approvedPlanFingerprint;
290528
290714
  try {
290529
- const { readFile: readFile63 } = await import("node:fs/promises");
290530
- const { join: join155 } = await import("node:path");
290531
- const promptPath = join155(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
290532
- const promptText2 = await readFile63(promptPath, "utf8");
290715
+ const { readFile: readFile64 } = await import("node:fs/promises");
290716
+ const { join: join156 } = await import("node:path");
290717
+ const promptPath = join156(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
290718
+ const promptText2 = await readFile64(promptPath, "utf8");
290533
290719
  approvedPlanFingerprint = computePlanApprovalFingerprint(promptText2);
290534
290720
  } catch {
290535
290721
  }
@@ -290562,8 +290748,8 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
290562
290748
  await scopedStore.logEntry(task.id, "Plan rejected by user", "Specification will be regenerated");
290563
290749
  await scopedStore.updateTask(task.id, { status: void 0, approvedPlanFingerprint: null });
290564
290750
  const { rm: rm23 } = await import("node:fs/promises");
290565
- const { join: join155 } = await import("node:path");
290566
- const promptPath = join155(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
290751
+ const { join: join156 } = await import("node:path");
290752
+ const promptPath = join156(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
290567
290753
  await rm23(promptPath, { force: true });
290568
290754
  const updated = await scopedStore.getTask(task.id);
290569
290755
  res.json(updated);
@@ -290586,7 +290772,7 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
290586
290772
  router.get("/tasks/:id/stranded-refinement", async (req, res) => {
290587
290773
  try {
290588
290774
  const { existsSync: existsSync118 } = await import("node:fs");
290589
- const { join: join155 } = await import("node:path");
290775
+ const { join: join156 } = await import("node:path");
290590
290776
  const { store: scopedStore } = await getProjectContext2(req);
290591
290777
  const task = await scopedStore.getTask(req.params.id);
290592
290778
  if (task.sourceType !== "task_refine") {
@@ -290602,7 +290788,7 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
290602
290788
  nextRecoveryAt: task.nextRecoveryAt,
290603
290789
  ageMs: Math.max(0, Date.now() - Date.parse(task.createdAt))
290604
290790
  };
290605
- const promptPath = join155(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
290791
+ const promptPath = join156(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
290606
290792
  const promptExists = existsSync118(promptPath);
290607
290793
  const dependencyDetails = await Promise.all((task.dependencies ?? []).map(async (dependencyId) => {
290608
290794
  try {
@@ -291221,8 +291407,8 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
291221
291407
  if (task.column === "triage" || task.column === respecifyTarget) {
291222
291408
  await scopedStore.logEntry(task.id, "AI spec revision requested", feedback);
291223
291409
  const { rm: rm24 } = await import("node:fs/promises");
291224
- const { join: join156 } = await import("node:path");
291225
- const promptPath2 = join156(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
291410
+ const { join: join157 } = await import("node:path");
291411
+ const promptPath2 = join157(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
291226
291412
  await rm24(promptPath2, { force: true });
291227
291413
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
291228
291414
  const updated2 = await scopedStore.getTask(task.id);
@@ -291238,8 +291424,8 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
291238
291424
  await scopedStore.logEntry(task.id, "AI spec revision requested", feedback);
291239
291425
  const updated = await scopedStore.moveTask(task.id, respecifyTarget);
291240
291426
  const { rm: rm23 } = await import("node:fs/promises");
291241
- const { join: join155 } = await import("node:path");
291242
- const promptPath = join155(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
291427
+ const { join: join156 } = await import("node:path");
291428
+ const promptPath = join156(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
291243
291429
  await rm23(promptPath, { force: true });
291244
291430
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
291245
291431
  res.json(updated);
@@ -291272,8 +291458,8 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
291272
291458
  });
291273
291459
  }
291274
291460
  const { rm: rm23 } = await import("node:fs/promises");
291275
- const { join: join155 } = await import("node:path");
291276
- const promptPath = join155(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
291461
+ const { join: join156 } = await import("node:path");
291462
+ const promptPath = join156(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
291277
291463
  await rm23(promptPath, { force: true });
291278
291464
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
291279
291465
  const updated = await scopedStore.getTask(task.id);
@@ -291659,7 +291845,7 @@ See \`GET /api/tasks/${task.id}/diff\` for the landed diff being reverted.
291659
291845
  const task = await scopedStore.updateTask(req.params.id, updates);
291660
291846
  if (dismissNearDuplicate === true && task.sourceMetadata?.duplicateSource === "triage-marker") {
291661
291847
  const { rm: rm23 } = await import("node:fs/promises");
291662
- await rm23(join91(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
291848
+ await rm23(join92(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md"), { force: true });
291663
291849
  }
291664
291850
  const manualUnlinkRequested = hasBodyField("githubTracking") && validatedGithubTracking !== null && typeof validatedGithubTracking === "object" && validatedGithubTracking.issue === null;
291665
291851
  const disableRequested = hasBodyField("githubTracking") && validatedGithubTracking !== null && typeof validatedGithubTracking === "object" && validatedGithubTracking.enabled === false;
@@ -294524,7 +294710,7 @@ var init_chat_attachment_config = __esm({
294524
294710
  });
294525
294711
 
294526
294712
  // ../dashboard/src/chat-attachment-content.ts
294527
- import { readFile as readFile44 } from "node:fs/promises";
294713
+ import { readFile as readFile45 } from "node:fs/promises";
294528
294714
  import { basename as basename22, resolve as resolve46 } from "node:path";
294529
294715
  function getAttachmentDirectory(rootDir, scope) {
294530
294716
  if (scope.kind === "session") {
@@ -294570,7 +294756,7 @@ async function readChatAttachmentContents(rootDir, scope, attachments, diagnosti
294570
294756
  const filePath = resolve46(attachmentDir, safeName);
294571
294757
  try {
294572
294758
  if (IMAGE_MIME_TYPES2.has(attachment.mimeType)) {
294573
- const data2 = await readFile44(filePath);
294759
+ const data2 = await readFile45(filePath);
294574
294760
  const detectedMimeType = detectImageMimeFromBytes(data2);
294575
294761
  const imageMimeType2 = detectedMimeType ?? attachment.mimeType;
294576
294762
  if (detectedMimeType && detectedMimeType !== attachment.mimeType) {
@@ -294594,7 +294780,7 @@ async function readChatAttachmentContents(rootDir, scope, attachments, diagnosti
294594
294780
  diagnostics9?.warn(`Skipping non-inlineable chat attachment '${attachment.filename}' (${attachment.mimeType}) for ${getScopeLabel(scope)}`);
294595
294781
  continue;
294596
294782
  }
294597
- const data = await readFile44(filePath, "utf-8");
294783
+ const data = await readFile45(filePath, "utf-8");
294598
294784
  const text3 = data.length > CHAT_TEXT_INLINE_LIMIT ? `${data.slice(0, CHAT_TEXT_INLINE_LIMIT)}${TRUNCATION_SUFFIX}` : data;
294599
294785
  attachmentContents.push({
294600
294786
  originalName: attachment.originalName,
@@ -295253,7 +295439,7 @@ __export(chat_exports, {
295253
295439
  import { EventEmitter as EventEmitter40 } from "node:events";
295254
295440
  import { randomUUID as randomUUID53 } from "node:crypto";
295255
295441
  import { existsSync as existsSync70 } from "node:fs";
295256
- import { join as join92, resolve as resolve47, relative as relative20 } from "node:path";
295442
+ import { join as join93, resolve as resolve47, relative as relative20 } from "node:path";
295257
295443
  import { SessionManager as SessionManager3 } from "@earendil-works/pi-coding-agent";
295258
295444
  function __getChatDiagnostics() {
295259
295445
  return _diagnostics;
@@ -295788,7 +295974,7 @@ function validateFilePath(basePath, filePath) {
295788
295974
  throw new Error(`Access denied: Absolute paths not allowed`);
295789
295975
  }
295790
295976
  const resolvedBase = resolve47(basePath);
295791
- const resolvedPath = resolve47(join92(resolvedBase, decodedPath));
295977
+ const resolvedPath = resolve47(join93(resolvedBase, decodedPath));
295792
295978
  const relativePath = relative20(resolvedBase, resolvedPath);
295793
295979
  if (relativePath.startsWith("..") || relativePath.startsWith("../") || relativePath === "..") {
295794
295980
  throw new Error(`Access denied: Path traversal detected`);
@@ -297583,7 +297769,7 @@ var init_rate_limit = __esm({
297583
297769
  import { randomUUID as randomUUID54 } from "node:crypto";
297584
297770
  import { createReadStream as createReadStream2 } from "node:fs";
297585
297771
  import { mkdir as mkdir30, rm as rm17, writeFile as writeFile33 } from "node:fs/promises";
297586
- import { basename as basename23, join as join93, resolve as resolve48 } from "node:path";
297772
+ import { basename as basename23, join as join94, resolve as resolve48 } from "node:path";
297587
297773
  function resolveAttachmentPath(rootDir, sessionId, filename) {
297588
297774
  const sessionDir = resolve48(rootDir, ".fusion", "chat-attachments", sessionId);
297589
297775
  const safeName = basename23(filename);
@@ -297636,7 +297822,7 @@ function registerChatRoutes(ctx, deps) {
297636
297822
  await mkdir30(sessionDir, { recursive: true });
297637
297823
  const sanitizedFilename = (file.originalname || "attachment").replace(/[^a-zA-Z0-9._-]/g, "_");
297638
297824
  const filename = `${Date.now()}-${sanitizedFilename}`;
297639
- const filePath = join93(sessionDir, filename);
297825
+ const filePath = join94(sessionDir, filename);
297640
297826
  await writeFile33(filePath, file.buffer);
297641
297827
  return {
297642
297828
  id: `att-${randomUUID54().slice(0, 8)}`,
@@ -298408,7 +298594,7 @@ var init_register_chat_routes = __esm({
298408
298594
  import { randomUUID as randomUUID55 } from "node:crypto";
298409
298595
  import { createReadStream as createReadStream3 } from "node:fs";
298410
298596
  import { mkdir as mkdir31, writeFile as writeFile34 } from "node:fs/promises";
298411
- import { basename as basename24, join as join94, resolve as resolve49 } from "node:path";
298597
+ import { basename as basename24, join as join95, resolve as resolve49 } from "node:path";
298412
298598
  function isSlugCollisionError(err) {
298413
298599
  const message = err instanceof Error ? err.message.toLowerCase() : String(err).toLowerCase();
298414
298600
  return message.includes("slug") || message.includes("exists");
@@ -298743,7 +298929,7 @@ function registerChatRoomRoutes(ctx, deps) {
298743
298929
  await mkdir31(roomDir, { recursive: true });
298744
298930
  const sanitizedFilename = (file.originalname || "attachment").replace(/[^a-zA-Z0-9._-]/g, "_");
298745
298931
  const filename = `${Date.now()}-${sanitizedFilename}`;
298746
- const filePath = join94(roomDir, filename);
298932
+ const filePath = join95(roomDir, filename);
298747
298933
  await writeFile34(filePath, file.buffer);
298748
298934
  const attachment = {
298749
298935
  id: `att-${randomUUID55().slice(0, 8)}`,
@@ -307323,7 +307509,7 @@ var init_terminal = __esm({
307323
307509
  });
307324
307510
 
307325
307511
  // ../dashboard/src/file-service.ts
307326
- import { join as join95, resolve as resolve52, relative as relative21, dirname as dirname38, basename as basename26 } from "node:path";
307512
+ import { join as join96, resolve as resolve52, relative as relative21, dirname as dirname38, basename as basename26 } from "node:path";
307327
307513
  import { readdir as readdir10, readFile as fsReadFile2, writeFile as fsWriteFile, stat as stat13, copyFile as fsCopyFile, rename as fsRename, rm as fsRm, mkdir as mkdir33, access as access14 } from "node:fs/promises";
307328
307514
  async function getTaskBasePath(store, taskId) {
307329
307515
  try {
@@ -307336,7 +307522,7 @@ async function getTaskBasePath(store, taskId) {
307336
307522
  }
307337
307523
  }
307338
307524
  const rootDir = store.getRootDir();
307339
- return resolve52(join95(rootDir, ".fusion", "tasks", taskId));
307525
+ return resolve52(join96(rootDir, ".fusion", "tasks", taskId));
307340
307526
  } catch (err) {
307341
307527
  const error3 = err;
307342
307528
  if (error3.code === "ENOENT" || error3.message && error3.message.includes("not found")) {
@@ -307368,7 +307554,7 @@ function validatePath(basePath, filePath, options = {}) {
307368
307554
  throw new FileServiceError(`Access denied: Absolute paths not allowed`, "EINVAL");
307369
307555
  }
307370
307556
  const resolvedBase = resolve52(basePath);
307371
- const resolvedPath = resolve52(join95(resolvedBase, filePath));
307557
+ const resolvedPath = resolve52(join96(resolvedBase, filePath));
307372
307558
  const relativePath = relative21(resolvedBase, resolvedPath);
307373
307559
  if (relativePath.startsWith("..") || relativePath.startsWith("../") || relativePath === "..") {
307374
307560
  throw new FileServiceError(`Access denied: Path traversal detected`, "EINVAL");
@@ -307409,7 +307595,7 @@ async function listFilesForBasePath(basePath, subPath, options = {}) {
307409
307595
  const entries = await readdir10(targetPath, { withFileTypes: true });
307410
307596
  const fileNodes = [];
307411
307597
  for (const entry of entries) {
307412
- const entryPath = join95(targetPath, entry.name);
307598
+ const entryPath = join96(targetPath, entry.name);
307413
307599
  const entryStats = await stat13(entryPath);
307414
307600
  fileNodes.push({
307415
307601
  name: entry.name,
@@ -307535,7 +307721,7 @@ async function listFiles2(store, taskId, subPath) {
307535
307721
  const taskBase = await getTaskBasePath(store, taskId);
307536
307722
  return listFilesForBasePath(taskBase, subPath);
307537
307723
  }
307538
- async function readFile45(store, taskId, filePath) {
307724
+ async function readFile46(store, taskId, filePath) {
307539
307725
  const taskBase = await getTaskBasePath(store, taskId);
307540
307726
  return readFileForBasePath(taskBase, filePath);
307541
307727
  }
@@ -307790,7 +307976,7 @@ async function renameWorkspaceFile(store, workspace, filePath, newName) {
307790
307976
  }
307791
307977
  throw err;
307792
307978
  }
307793
- const destPath = join95(dirname38(resolvedPath), newName);
307979
+ const destPath = join96(dirname38(resolvedPath), newName);
307794
307980
  if (pathOptions.allowAbsolutePaths !== true || !filePath.startsWith("/")) {
307795
307981
  const destRelative = relative21(resolve52(workspaceBase), destPath);
307796
307982
  if (destRelative.startsWith("..") || destRelative.startsWith("../") || destRelative === "..") {
@@ -307887,7 +308073,7 @@ function isHiddenPathSegment(name2) {
307887
308073
  return name2.startsWith(".");
307888
308074
  }
307889
308075
  async function walkDirForMarkdown(basePath, currentRelative, results, options) {
307890
- const currentPath = currentRelative ? join95(basePath, currentRelative) : basePath;
308076
+ const currentPath = currentRelative ? join96(basePath, currentRelative) : basePath;
307891
308077
  let entries;
307892
308078
  try {
307893
308079
  entries = await readdir10(currentPath, { withFileTypes: true });
@@ -307895,7 +308081,7 @@ async function walkDirForMarkdown(basePath, currentRelative, results, options) {
307895
308081
  return;
307896
308082
  }
307897
308083
  for (const entry of entries) {
307898
- const entryRelativePath = currentRelative ? join95(currentRelative, entry.name) : entry.name;
308084
+ const entryRelativePath = currentRelative ? join96(currentRelative, entry.name) : entry.name;
307899
308085
  if (entry.isDirectory()) {
307900
308086
  if (MARKDOWN_SCAN_EXCLUDED_DIRS.has(entry.name)) {
307901
308087
  continue;
@@ -307912,7 +308098,7 @@ async function walkDirForMarkdown(basePath, currentRelative, results, options) {
307912
308098
  if (!options.showHidden && isHiddenPathSegment(entry.name)) {
307913
308099
  continue;
307914
308100
  }
307915
- const fullPath = join95(basePath, entryRelativePath);
308101
+ const fullPath = join96(basePath, entryRelativePath);
307916
308102
  let fileStats;
307917
308103
  try {
307918
308104
  fileStats = await stat13(fullPath);
@@ -307962,7 +308148,7 @@ async function scanMarkdownFiles(store, options) {
307962
308148
  return;
307963
308149
  }
307964
308150
  for (const entry of entries) {
307965
- const entryRelativePath = relativeDir ? join95(relativeDir, entry.name) : entry.name;
308151
+ const entryRelativePath = relativeDir ? join96(relativeDir, entry.name) : entry.name;
307966
308152
  let shouldRecurse = entry.isDirectory();
307967
308153
  if (!shouldRecurse && typeof entry.isSymbolicLink === "function" && entry.isSymbolicLink()) {
307968
308154
  let symlinkPath;
@@ -308052,8 +308238,8 @@ async function searchWorkspaceFiles(store, workspace, query) {
308052
308238
  if (entry.isDirectory() && EXCLUDED_DIRS.has(entry.name)) {
308053
308239
  continue;
308054
308240
  }
308055
- const fullPath = join95(dir2, entry.name);
308056
- const relPath = join95(relativeDir, entry.name);
308241
+ const fullPath = join96(dir2, entry.name);
308242
+ const relPath = join96(relativeDir, entry.name);
308057
308243
  if (entry.isFile()) {
308058
308244
  if (entry.name.toLowerCase().includes(lowerQuery)) {
308059
308245
  results.push({
@@ -308074,8 +308260,8 @@ async function copyDirectoryRecursive(source, destination) {
308074
308260
  await mkdir33(destination, { recursive: true });
308075
308261
  const entries = await readdir10(source, { withFileTypes: true });
308076
308262
  for (const entry of entries) {
308077
- const sourcePath = join95(source, entry.name);
308078
- const destPath = join95(destination, entry.name);
308263
+ const sourcePath = join96(source, entry.name);
308264
+ const destPath = join96(destination, entry.name);
308079
308265
  if (entry.isDirectory()) {
308080
308266
  await copyDirectoryRecursive(sourcePath, destPath);
308081
308267
  } else {
@@ -311364,7 +311550,7 @@ var require_BufferList = __commonJS({
311364
311550
  this.head = this.tail = null;
311365
311551
  this.length = 0;
311366
311552
  };
311367
- BufferList.prototype.join = function join155(s3) {
311553
+ BufferList.prototype.join = function join156(s3) {
311368
311554
  if (this.length === 0) return "";
311369
311555
  var p2 = this.head;
311370
311556
  var ret = "" + p2.data;
@@ -332924,7 +333110,7 @@ function registerFileWorkspaceRoutes(ctx) {
332924
333110
  try {
332925
333111
  const { store: scopedStore } = await getProjectContext2(req);
332926
333112
  const filePath = Array.isArray(req.params.filepath) ? req.params.filepath[0] : req.params.filepath ?? "";
332927
- const result2 = await readFile45(scopedStore, req.params.id, filePath);
333113
+ const result2 = await readFile46(scopedStore, req.params.id, filePath);
332928
333114
  res.json(result2);
332929
333115
  } catch (err) {
332930
333116
  if (err instanceof ApiError) {
@@ -333393,7 +333579,7 @@ var init_attribute_done_range_files = __esm({
333393
333579
 
333394
333580
  // ../dashboard/src/routes/register-session-diff-routes.ts
333395
333581
  import { access as access16 } from "node:fs/promises";
333396
- import { join as join96 } from "node:path";
333582
+ import { join as join97 } from "node:path";
333397
333583
  async function worktreeStillBelongsToTask(worktree, expectedBranch) {
333398
333584
  if (!expectedBranch) return true;
333399
333585
  try {
@@ -333711,7 +333897,7 @@ async function computeWorkspaceTaskFiles(task, rootDir, timeoutMs) {
333711
333897
  }
333712
333898
  }
333713
333899
  if (repoFiles.length === 0 && entry.baseCommitSha && entry.landedSha) {
333714
- const repoRootDir = join96(rootDir, repoRel);
333900
+ const repoRootDir = join97(rootDir, repoRel);
333715
333901
  try {
333716
333902
  const rangeFiles = await collectDoneRangeFiles(`${entry.baseCommitSha}..${entry.landedSha}`, repoRootDir);
333717
333903
  repoFiles = rangeFiles.map((file) => ({
@@ -334658,7 +334844,7 @@ var init_exec_file = __esm({
334658
334844
 
334659
334845
  // ../dashboard/src/lib/codebase-metrics.ts
334660
334846
  import { spawn as spawn12 } from "node:child_process";
334661
- import { lstat as lstat2, readdir as readdir11, readFile as readFile46, realpath as realpath2 } from "node:fs/promises";
334847
+ import { lstat as lstat2, readdir as readdir11, readFile as readFile47, realpath as realpath2 } from "node:fs/promises";
334662
334848
  import { basename as basename27, resolve as resolve53, sep as sep14 } from "node:path";
334663
334849
  function countPreTokenPieces(text3) {
334664
334850
  let pieces = 0;
@@ -334808,7 +334994,7 @@ async function computeCodebaseMetrics(rootDir, options = {}) {
334808
334994
  truncated = true;
334809
334995
  break;
334810
334996
  }
334811
- const contents = await readFile46(candidate);
334997
+ const contents = await readFile47(candidate);
334812
334998
  if (isBinary(contents)) continue;
334813
334999
  sourceByteCount += contents.length;
334814
335000
  sourceFileCount++;
@@ -334875,7 +335061,7 @@ var init_codebase_metrics = __esm({
334875
335061
 
334876
335062
  // ../dashboard/src/routes/register-project-routes.ts
334877
335063
  import * as fsPromises from "node:fs/promises";
334878
- import { dirname as dirname39, isAbsolute as isAbsolute26, join as join97 } from "node:path";
335064
+ import { dirname as dirname39, isAbsolute as isAbsolute26, join as join98 } from "node:path";
334879
335065
  var access17, stat14, mkdir34, readdir12, rm18, registerProjectRoutes;
334880
335066
  var init_register_project_routes = __esm({
334881
335067
  "../dashboard/src/routes/register-project-routes.ts"() {
@@ -335149,7 +335335,7 @@ var init_register_project_routes = __esm({
335149
335335
  }
335150
335336
  }
335151
335337
  let hasFusionDir = false;
335152
- const fusionDirPath = join97(normalizedPath, ".fusion");
335338
+ const fusionDirPath = join98(normalizedPath, ".fusion");
335153
335339
  try {
335154
335340
  await access17(fusionDirPath);
335155
335341
  hasFusionDir = true;
@@ -335264,9 +335450,9 @@ var init_register_project_routes = __esm({
335264
335450
  const entries = await readdir12(searchPath, { withFileTypes: true });
335265
335451
  for (const entry of entries) {
335266
335452
  if (!entry.isDirectory()) continue;
335267
- const dirPath = join97(searchPath, entry.name);
335268
- const fusionDir = join97(dirPath, ".fusion");
335269
- if (readProjectIdentity(fusionDir) !== null || isValidSqliteDatabaseFile(join97(fusionDir, "fusion.db"))) {
335453
+ const dirPath = join98(searchPath, entry.name);
335454
+ const fusionDir = join98(dirPath, ".fusion");
335455
+ if (readProjectIdentity(fusionDir) !== null || isValidSqliteDatabaseFile(join98(fusionDir, "fusion.db"))) {
335270
335456
  detected.push({
335271
335457
  path: dirPath,
335272
335458
  suggestedName: entry.name,
@@ -342633,7 +342819,7 @@ var init_register_secrets_sync_inbound_routes = __esm({
342633
342819
  });
342634
342820
 
342635
342821
  // ../dashboard/src/routes/register-agent-core-routes.ts
342636
- import { mkdir as mkdir35, readdir as readdir13, readFile as readFile47, rm as rm19, writeFile as writeFile36 } from "node:fs/promises";
342822
+ import { mkdir as mkdir35, readdir as readdir13, readFile as readFile48, rm as rm19, writeFile as writeFile36 } from "node:fs/promises";
342637
342823
  import path8 from "node:path";
342638
342824
  function parsePermissionsInput(input) {
342639
342825
  if (typeof input !== "object" || input === null || Array.isArray(input)) {
@@ -343068,7 +343254,7 @@ function registerAgentCoreRoutes(ctx, deps) {
343068
343254
  if (!mimeType) {
343069
343255
  throw notFound("Avatar not found");
343070
343256
  }
343071
- const fileBuffer = await readFile47(path8.join(agentDir, avatarFile));
343257
+ const fileBuffer = await readFile48(path8.join(agentDir, avatarFile));
343072
343258
  res.setHeader("Content-Type", mimeType);
343073
343259
  res.setHeader("Cache-Control", "public, max-age=3600");
343074
343260
  res.send(fileBuffer);
@@ -345723,7 +345909,7 @@ Rules:
345723
345909
  import { createWriteStream } from "node:fs";
345724
345910
  import * as fsPromises2 from "node:fs/promises";
345725
345911
  import { tmpdir as tmpdir14 } from "node:os";
345726
- import { join as join98, resolve as resolve54 } from "node:path";
345912
+ import { join as join99, resolve as resolve54 } from "node:path";
345727
345913
  import { Readable } from "node:stream";
345728
345914
  import { pipeline as streamPipeline } from "node:stream/promises";
345729
345915
  function registerAgentImportExportRoutes(ctx) {
@@ -345764,7 +345950,7 @@ function registerAgentImportExportRoutes(ctx) {
345764
345950
  } else if (typeof outputDir === "string") {
345765
345951
  throw badRequest("outputDir cannot be empty");
345766
345952
  } else {
345767
- resolvedOutputDir = await mkdtemp7(join98(tmpdir14(), "fusion-agent-export-"));
345953
+ resolvedOutputDir = await mkdtemp7(join99(tmpdir14(), "fusion-agent-export-"));
345768
345954
  }
345769
345955
  const result2 = await exportAgentsToDirectory2(agentsToExport, resolvedOutputDir, {
345770
345956
  companyName: typeof companyName === "string" ? companyName : void 0,
@@ -345923,7 +346109,7 @@ ${body}`;
345923
346109
  return result2;
345924
346110
  }
345925
346111
  const safeCompanySlug = companySlug ? slugifyPathSegment2(companySlug, "unknown-company") : "unknown-company";
345926
- const skillsBaseDir = join98(projectRoot, "skills", "imported", safeCompanySlug);
346112
+ const skillsBaseDir = join99(projectRoot, "skills", "imported", safeCompanySlug);
345927
346113
  const usedSlugs = /* @__PURE__ */ new Set();
345928
346114
  for (const skill of skills) {
345929
346115
  const name2 = typeof skill.name === "string" && skill.name.trim().length > 0 ? skill.name.trim() : null;
@@ -345940,8 +346126,8 @@ ${body}`;
345940
346126
  skillSlug = `${skillSlug}-${counter2}`;
345941
346127
  }
345942
346128
  usedSlugs.add(skillSlug);
345943
- const skillDir = join98(skillsBaseDir, skillSlug);
345944
- const skillPath = join98(skillDir, "SKILL.md");
346129
+ const skillDir = join99(skillsBaseDir, skillSlug);
346130
+ const skillPath = join99(skillDir, "SKILL.md");
345945
346131
  try {
345946
346132
  await access18(skillPath);
345947
346133
  result2.skipped.push(name2);
@@ -346115,8 +346301,8 @@ ${body}`;
346115
346301
  const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/${preferredBranch}.tar.gz`;
346116
346302
  let tempDir = null;
346117
346303
  try {
346118
- tempDir = await mkdtemp7(join98(tmpdir14(), `fn-agent-import-${importCompanySlug}-`));
346119
- const archivePath = join98(tempDir, "archive.tar.gz");
346304
+ tempDir = await mkdtemp7(join99(tmpdir14(), `fn-agent-import-${importCompanySlug}-`));
346305
+ const archivePath = join99(tempDir, "archive.tar.gz");
346120
346306
  const downloadController = new AbortController();
346121
346307
  const downloadTimeout = setTimeout(() => downloadController.abort(), 3e4);
346122
346308
  let archiveResponse;
@@ -347755,12 +347941,12 @@ import {
347755
347941
  unlinkSync as unlinkSync4
347756
347942
  } from "node:fs";
347757
347943
  import { homedir as homedir14 } from "node:os";
347758
- import { basename as basename29, dirname as dirname40, join as join99, resolve as resolve55 } from "node:path";
347944
+ import { basename as basename29, dirname as dirname40, join as join100, resolve as resolve55 } from "node:path";
347759
347945
  import { fileURLToPath as fileURLToPath6 } from "node:url";
347760
347946
  function resolveHermesHome(profile) {
347761
- const base = process.env.HERMES_HOME ?? join99(homedir14(), ".hermes");
347947
+ const base = process.env.HERMES_HOME ?? join100(homedir14(), ".hermes");
347762
347948
  if (!profile || profile === "default") return base;
347763
- return join99(base, "profiles", profile);
347949
+ return join100(base, "profiles", profile);
347764
347950
  }
347765
347951
  function getFusionSkillSourceCandidates(moduleUrl = import.meta.url) {
347766
347952
  const here = fileURLToPath6(moduleUrl);
@@ -347775,13 +347961,13 @@ function getFusionSkillSourceCandidates(moduleUrl = import.meta.url) {
347775
347961
  function resolveBundledFusionSkillSource() {
347776
347962
  const candidates = getFusionSkillSourceCandidates();
347777
347963
  for (const candidate of candidates) {
347778
- if (existsSync72(join99(candidate, "SKILL.md"))) return candidate;
347964
+ if (existsSync72(join100(candidate, "SKILL.md"))) return candidate;
347779
347965
  }
347780
347966
  return null;
347781
347967
  }
347782
347968
  function installFusionSkillIntoHermesHome(options = {}) {
347783
347969
  const sourceDir = options.sourceDir ?? resolveBundledFusionSkillSource();
347784
- const targetDir = join99(resolveHermesHome(options.profile), "skills", FUSION_SKILL_NAME);
347970
+ const targetDir = join100(resolveHermesHome(options.profile), "skills", FUSION_SKILL_NAME);
347785
347971
  if (!sourceDir) {
347786
347972
  return {
347787
347973
  outcome: "warning",
@@ -347870,7 +348056,7 @@ function isBrokenSymlink(path14) {
347870
348056
  }
347871
348057
  }
347872
348058
  function looksLikePriorFusionInstall(path14) {
347873
- const skillMd = join99(path14, "SKILL.md");
348059
+ const skillMd = join100(path14, "SKILL.md");
347874
348060
  if (!existsSync72(skillMd)) return false;
347875
348061
  try {
347876
348062
  const body = readFileSync28(skillMd, "utf-8");
@@ -347882,7 +348068,7 @@ function looksLikePriorFusionInstall(path14) {
347882
348068
  function looksLikeFusionSkillTarget(path14) {
347883
348069
  if (!path14) return false;
347884
348070
  if (basename29(path14).toLowerCase() === FUSION_SKILL_NAME) return true;
347885
- return existsSync72(join99(path14, "SKILL.md"));
348071
+ return existsSync72(join100(path14, "SKILL.md"));
347886
348072
  }
347887
348073
  var FUSION_SKILL_NAME;
347888
348074
  var init_fusion_skill_install = __esm({
@@ -348150,7 +348336,7 @@ var init_src8 = __esm({
348150
348336
  // ../../plugins/fusion-plugin-openclaw-runtime/src/pi-module.ts
348151
348337
  import { spawn as spawn15 } from "node:child_process";
348152
348338
  import { randomUUID as randomUUID60 } from "node:crypto";
348153
- import { readFile as readFile48 } from "node:fs/promises";
348339
+ import { readFile as readFile49 } from "node:fs/promises";
348154
348340
  function asString2(v2) {
348155
348341
  return typeof v2 === "string" && v2.trim() !== "" ? v2.trim() : void 0;
348156
348342
  }
@@ -348221,7 +348407,7 @@ function createCliSession(opts) {
348221
348407
  };
348222
348408
  }
348223
348409
  async function configureOpenClawMcpServer(opts) {
348224
- const serverValue = await readFile48(opts.serverConfigPath, "utf-8");
348410
+ const serverValue = await readFile49(opts.serverConfigPath, "utf-8");
348225
348411
  await new Promise((resolve103, reject2) => {
348226
348412
  const child = spawn15(opts.binaryPath, ["--no-color", "--profile", opts.profile, "mcp", "set", opts.serverName, serverValue], {
348227
348413
  stdio: ["ignore", "pipe", "pipe"]
@@ -348365,7 +348551,7 @@ var init_pi_module = __esm({
348365
348551
  // ../../plugins/fusion-plugin-openclaw-runtime/src/mcp-config.ts
348366
348552
  import { writeFileSync as writeFileSync13 } from "node:fs";
348367
348553
  import { tmpdir as tmpdir15 } from "node:os";
348368
- import { join as join100 } from "node:path";
348554
+ import { join as join101 } from "node:path";
348369
348555
  import { fileURLToPath as fileURLToPath7 } from "node:url";
348370
348556
  import { dirname as dirname41 } from "node:path";
348371
348557
  function toolsToMcpToolDefs(tools) {
@@ -348378,16 +348564,16 @@ function toolsToMcpToolDefs(tools) {
348378
348564
  }
348379
348565
  function writeOpenClawMcpBridgeFiles(toolDefs, cacheKey) {
348380
348566
  const suffix = cacheKey ? `${process.pid}-${cacheKey}` : `${process.pid}`;
348381
- const schemaPath = join100(tmpdir15(), `openclaw-runtime-mcp-schemas-${suffix}.json`);
348567
+ const schemaPath = join101(tmpdir15(), `openclaw-runtime-mcp-schemas-${suffix}.json`);
348382
348568
  writeFileSync13(schemaPath, JSON.stringify(toolDefs));
348383
348569
  const __filename = fileURLToPath7(import.meta.url);
348384
348570
  const __dirname3 = dirname41(__filename);
348385
- const serverPath = join100(__dirname3, "mcp-schema-server.cjs");
348571
+ const serverPath = join101(__dirname3, "mcp-schema-server.cjs");
348386
348572
  const serverConfig = {
348387
348573
  command: "node",
348388
348574
  args: [serverPath, schemaPath]
348389
348575
  };
348390
- const serverConfigPath = join100(tmpdir15(), `openclaw-runtime-mcp-server-${suffix}.json`);
348576
+ const serverConfigPath = join101(tmpdir15(), `openclaw-runtime-mcp-server-${suffix}.json`);
348391
348577
  writeFileSync13(serverConfigPath, JSON.stringify(serverConfig));
348392
348578
  return {
348393
348579
  schemaPath,
@@ -348619,7 +348805,7 @@ var init_src9 = __esm({
348619
348805
  });
348620
348806
 
348621
348807
  // ../dashboard/src/routes/plugin-bundled-runtimes.ts
348622
- import { resolve as resolve56, join as join101 } from "node:path";
348808
+ import { resolve as resolve56, join as join102 } from "node:path";
348623
348809
  import { fileURLToPath as fileURLToPath8 } from "node:url";
348624
348810
  import * as nodeFs from "node:fs";
348625
348811
  function extractBundledPluginId(pathInput) {
@@ -348638,12 +348824,12 @@ function resolveBundledPluginDirInDashboard(pluginId) {
348638
348824
  const moduleDir = resolve56(fileURLToPath8(import.meta.url), "..");
348639
348825
  const dashboardPackageRoot = resolve56(moduleDir, "..");
348640
348826
  const candidates = [
348641
- join101(dashboardPackageRoot, "dist", "plugins", pluginId),
348642
- join101(dashboardPackageRoot, "plugins", pluginId),
348643
- join101(dashboardPackageRoot, "..", "..", "plugins", pluginId)
348827
+ join102(dashboardPackageRoot, "dist", "plugins", pluginId),
348828
+ join102(dashboardPackageRoot, "plugins", pluginId),
348829
+ join102(dashboardPackageRoot, "..", "..", "plugins", pluginId)
348644
348830
  ];
348645
348831
  for (const candidate of candidates) {
348646
- if (nodeFs.existsSync(join101(candidate, "manifest.json"))) {
348832
+ if (nodeFs.existsSync(join102(candidate, "manifest.json"))) {
348647
348833
  return candidate;
348648
348834
  }
348649
348835
  }
@@ -350735,9 +350921,9 @@ var init_cli_spawn3 = __esm({
350735
350921
  });
350736
350922
 
350737
350923
  // ../../plugins/fusion-plugin-grok-runtime/src/probe.ts
350738
- import { readFile as readFile49 } from "node:fs/promises";
350924
+ import { readFile as readFile50 } from "node:fs/promises";
350739
350925
  import { homedir as homedir15 } from "node:os";
350740
- import { join as join102 } from "node:path";
350926
+ import { join as join103 } from "node:path";
350741
350927
  function buildCandidates2(binaryPath) {
350742
350928
  const configuredBinaryPath = binaryPath?.trim() || void 0;
350743
350929
  const ordered = configuredBinaryPath ? [configuredBinaryPath, ...CANDIDATES3] : [...CANDIDATES3];
@@ -350754,10 +350940,10 @@ async function probeGrokApiKeyPresence() {
350754
350940
  if (typeof envKey === "string" && envKey.trim().length > 0) {
350755
350941
  return { detected: true };
350756
350942
  }
350757
- const settingsPath = join102(homedir15(), ".grok", "user-settings.json");
350943
+ const settingsPath = join103(homedir15(), ".grok", "user-settings.json");
350758
350944
  let raw;
350759
350945
  try {
350760
- raw = await readFile49(settingsPath, "utf-8");
350946
+ raw = await readFile50(settingsPath, "utf-8");
350761
350947
  } catch {
350762
350948
  return { detected: false, reason: "No Grok API key detected by Fusion (GROK_API_KEY unset, ~/.grok/user-settings.json not found); the CLI will use its own credentials." };
350763
350949
  }
@@ -350906,7 +351092,7 @@ var init_provider2 = __esm({
350906
351092
 
350907
351093
  // ../../plugins/fusion-plugin-grok-runtime/src/acp/cli-spawn.ts
350908
351094
  import { existsSync as existsSync74 } from "node:fs";
350909
- import { dirname as dirname42, isAbsolute as isAbsolute28, join as join103, resolve as resolve58 } from "node:path";
351095
+ import { dirname as dirname42, isAbsolute as isAbsolute28, join as join104, resolve as resolve58 } from "node:path";
350910
351096
  import { fileURLToPath as fileURLToPath9 } from "node:url";
350911
351097
  function asTrimmedString(value) {
350912
351098
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
@@ -350924,7 +351110,7 @@ function pluginRootDir() {
350924
351110
  }
350925
351111
  function bundledClaudeBridgeBinPath(pluginRoot = pluginRootDir()) {
350926
351112
  const extension = process.platform === "win32" ? ".cmd" : "";
350927
- return join103(pluginRoot, "node_modules", ".bin", `${CLAUDE_CODE_CLI_ACP_BINARY}${extension}`);
351113
+ return join104(pluginRoot, "node_modules", ".bin", `${CLAUDE_CODE_CLI_ACP_BINARY}${extension}`);
350928
351114
  }
350929
351115
  function resolveBundledClaudeBridgeBinary(options = {}) {
350930
351116
  const root = options.pluginRoot ?? pluginRootDir();
@@ -352287,10 +352473,10 @@ import {
352287
352473
  } from "node:fs";
352288
352474
  import { createRequire as createRequire8 } from "node:module";
352289
352475
  import { tmpdir as tmpdir16 } from "node:os";
352290
- import { basename as basename31, dirname as dirname44, join as join105, resolve as resolve60 } from "node:path";
352476
+ import { basename as basename31, dirname as dirname44, join as join106, resolve as resolve60 } from "node:path";
352291
352477
  import { fileURLToPath as fileURLToPath10 } from "node:url";
352292
352478
  function isSkillDir(dir2) {
352293
- return existsSync75(join105(dir2, "SKILL.md"));
352479
+ return existsSync75(join106(dir2, "SKILL.md"));
352294
352480
  }
352295
352481
  function pushUnique(out, candidate) {
352296
352482
  if (!candidate) return;
@@ -352298,8 +352484,8 @@ function pushUnique(out, candidate) {
352298
352484
  if (!out.includes(resolved)) out.push(resolved);
352299
352485
  }
352300
352486
  function pushSkillLayoutsAtRoot(out, root) {
352301
- pushUnique(out, join105(root, "skill", FUSION_SKILL_NAME2));
352302
- pushUnique(out, join105(root, "packages", "cli", "skill", FUSION_SKILL_NAME2));
352487
+ pushUnique(out, join106(root, "skill", FUSION_SKILL_NAME2));
352488
+ pushUnique(out, join106(root, "packages", "cli", "skill", FUSION_SKILL_NAME2));
352303
352489
  }
352304
352490
  function walkAncestorSkillCandidates(out, startDir, maxParents = 8) {
352305
352491
  let dir2 = startDir;
@@ -352314,7 +352500,7 @@ function pushPackageRequireCandidates(out, from) {
352314
352500
  try {
352315
352501
  const require6 = createRequire8(from);
352316
352502
  const pkgJson = require6.resolve("@runfusion/fusion/package.json");
352317
- pushUnique(out, join105(dirname44(pkgJson), "skill", FUSION_SKILL_NAME2));
352503
+ pushUnique(out, join106(dirname44(pkgJson), "skill", FUSION_SKILL_NAME2));
352318
352504
  } catch {
352319
352505
  }
352320
352506
  }
@@ -352382,21 +352568,21 @@ function collectSkillsFromRoot(root, out) {
352382
352568
  return;
352383
352569
  }
352384
352570
  for (const entry of entries) {
352385
- const child = join105(root, entry);
352571
+ const child = join106(root, entry);
352386
352572
  if (isSkillDir(child)) {
352387
352573
  out.set(entry, child);
352388
352574
  }
352389
352575
  }
352390
352576
  }
352391
352577
  function stageGrokSessionSkills(options = {}) {
352392
- const pluginDir = mkdtempSync3(join105(tmpdir16(), "fusion-grok-plugin-"));
352393
- const skillsDir = join105(pluginDir, "skills");
352578
+ const pluginDir = mkdtempSync3(join106(tmpdir16(), "fusion-grok-plugin-"));
352579
+ const skillsDir = join106(pluginDir, "skills");
352394
352580
  mkdirSync14(skillsDir, { recursive: true });
352395
352581
  const installed = /* @__PURE__ */ new Map();
352396
352582
  const includeFusion = options.includeFusionSkill !== false;
352397
352583
  if (includeFusion) {
352398
352584
  const fusionSource = resolveBundledFusionSkillSource2();
352399
- if (fusionSource && installSkillDir(fusionSource, join105(skillsDir, FUSION_SKILL_NAME2))) {
352585
+ if (fusionSource && installSkillDir(fusionSource, join106(skillsDir, FUSION_SKILL_NAME2))) {
352400
352586
  installed.set(FUSION_SKILL_NAME2, fusionSource);
352401
352587
  }
352402
352588
  }
@@ -352406,15 +352592,15 @@ function stageGrokSessionSkills(options = {}) {
352406
352592
  }
352407
352593
  for (const [name2, source] of installed) {
352408
352594
  if (name2 === FUSION_SKILL_NAME2 && includeFusion) continue;
352409
- installSkillDir(source, join105(skillsDir, name2));
352595
+ installSkillDir(source, join106(skillsDir, name2));
352410
352596
  }
352411
352597
  for (const [name2, source] of installed) {
352412
- if (!existsSync75(join105(skillsDir, name2))) {
352413
- installSkillDir(source, join105(skillsDir, name2));
352598
+ if (!existsSync75(join106(skillsDir, name2))) {
352599
+ installSkillDir(source, join106(skillsDir, name2));
352414
352600
  }
352415
352601
  }
352416
352602
  writeFileSync14(
352417
- join105(pluginDir, "plugin.json"),
352603
+ join106(pluginDir, "plugin.json"),
352418
352604
  JSON.stringify(
352419
352605
  {
352420
352606
  name: "fusion-session-skills",
@@ -352480,7 +352666,7 @@ var init_skill_loader = __esm({
352480
352666
  import { createServer as createServer2 } from "node:http";
352481
352667
  import { existsSync as existsSync76, writeFileSync as writeFileSync15 } from "node:fs";
352482
352668
  import { tmpdir as tmpdir17 } from "node:os";
352483
- import { dirname as dirname45, join as join106 } from "node:path";
352669
+ import { dirname as dirname45, join as join107 } from "node:path";
352484
352670
  import { fileURLToPath as fileURLToPath11 } from "node:url";
352485
352671
  import { randomUUID as randomUUID62 } from "node:crypto";
352486
352672
  function toolsToMcpToolDefs2(tools) {
@@ -352492,7 +352678,7 @@ function toolsToMcpToolDefs2(tools) {
352492
352678
  }));
352493
352679
  }
352494
352680
  function fusionToolsMcpServerPath() {
352495
- return join106(dirname45(fileURLToPath11(import.meta.url)), "mcp-schema-server.cjs");
352681
+ return join107(dirname45(fileURLToPath11(import.meta.url)), "mcp-schema-server.cjs");
352496
352682
  }
352497
352683
  function missingMcpSchemaServerError(serverPath) {
352498
352684
  const error3 = new Error(`Fusion MCP schema server is missing: ${serverPath}`);
@@ -352533,7 +352719,7 @@ async function startFusionToolBridge(tools) {
352533
352719
  byName.set(tool.name, tool);
352534
352720
  }
352535
352721
  }
352536
- const schemaPath = join106(tmpdir17(), `fusion-grok-mcp-schemas-${process.pid}-${randomUUID62()}.json`);
352722
+ const schemaPath = join107(tmpdir17(), `fusion-grok-mcp-schemas-${process.pid}-${randomUUID62()}.json`);
352537
352723
  writeFileSync15(schemaPath, JSON.stringify(defs));
352538
352724
  const server = createServer2(async (req, res) => {
352539
352725
  if (req.method !== "POST" || req.url !== "/tool-call") {
@@ -352966,7 +353152,7 @@ var init_src11 = __esm({
352966
353152
 
352967
353153
  // ../../plugins/fusion-plugin-claude-runtime/src/acp/cli-spawn.ts
352968
353154
  import { existsSync as existsSync77 } from "node:fs";
352969
- import { dirname as dirname46, isAbsolute as isAbsolute29, join as join107, resolve as resolve61 } from "node:path";
353155
+ import { dirname as dirname46, isAbsolute as isAbsolute29, join as join108, resolve as resolve61 } from "node:path";
352970
353156
  import { fileURLToPath as fileURLToPath12 } from "node:url";
352971
353157
  function asTrimmedString2(value) {
352972
353158
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
@@ -352984,7 +353170,7 @@ function pluginRootDir2() {
352984
353170
  }
352985
353171
  function bundledClaudeBridgeBinPath2(pluginRoot = pluginRootDir2()) {
352986
353172
  const extension = process.platform === "win32" ? ".cmd" : "";
352987
- return join107(pluginRoot, "node_modules", ".bin", `${CLAUDE_CODE_CLI_ACP_BINARY2}${extension}`);
353173
+ return join108(pluginRoot, "node_modules", ".bin", `${CLAUDE_CODE_CLI_ACP_BINARY2}${extension}`);
352988
353174
  }
352989
353175
  function resolveBundledClaudeBridgeBinary2(options = {}) {
352990
353176
  const root = options.pluginRoot ?? pluginRootDir2();
@@ -354224,14 +354410,14 @@ var init_acp2 = __esm({
354224
354410
  // ../../plugins/fusion-plugin-claude-runtime/src/cli-spawn.ts
354225
354411
  import { spawn as spawn21 } from "node:child_process";
354226
354412
  import { existsSync as existsSync78 } from "node:fs";
354227
- import { basename as basename33, dirname as dirname48, isAbsolute as isAbsolute30, join as join109, resolve as resolve63 } from "node:path";
354413
+ import { basename as basename33, dirname as dirname48, isAbsolute as isAbsolute30, join as join110, resolve as resolve63 } from "node:path";
354228
354414
  import { fileURLToPath as fileURLToPath13 } from "node:url";
354229
354415
  function pluginRootDir3() {
354230
354416
  const moduleDir = dirname48(fileURLToPath13(import.meta.url));
354231
354417
  return ["src", "dist"].includes(basename33(moduleDir)) ? resolve63(moduleDir, "..") : moduleDir;
354232
354418
  }
354233
354419
  function bundledClaudeBridgeBinPath3(pluginRoot = pluginRootDir3()) {
354234
- return join109(pluginRoot, "bridge", `${CLAUDE_CODE_CLI_ACP_BINARY3}${process.platform === "win32" ? ".cmd" : ""}`);
354420
+ return join110(pluginRoot, "bridge", `${CLAUDE_CODE_CLI_ACP_BINARY3}${process.platform === "win32" ? ".cmd" : ""}`);
354235
354421
  }
354236
354422
  function resolveBundledClaudeBridgeBinary3(options = {}) {
354237
354423
  const candidate = bundledClaudeBridgeBinPath3(options.pluginRoot ?? pluginRootDir3());
@@ -354408,10 +354594,10 @@ import {
354408
354594
  } from "node:fs";
354409
354595
  import { createRequire as createRequire9 } from "node:module";
354410
354596
  import { tmpdir as tmpdir18 } from "node:os";
354411
- import { basename as basename34, dirname as dirname49, join as join110, resolve as resolve64 } from "node:path";
354597
+ import { basename as basename34, dirname as dirname49, join as join111, resolve as resolve64 } from "node:path";
354412
354598
  import { fileURLToPath as fileURLToPath14 } from "node:url";
354413
354599
  function isSkillDir2(dir2) {
354414
- return existsSync79(join110(dir2, "SKILL.md"));
354600
+ return existsSync79(join111(dir2, "SKILL.md"));
354415
354601
  }
354416
354602
  function pushUnique2(out, candidate) {
354417
354603
  if (!candidate) return;
@@ -354419,8 +354605,8 @@ function pushUnique2(out, candidate) {
354419
354605
  if (!out.includes(resolved)) out.push(resolved);
354420
354606
  }
354421
354607
  function pushSkillLayoutsAtRoot2(out, root) {
354422
- pushUnique2(out, join110(root, "skill", FUSION_SKILL_NAME3));
354423
- pushUnique2(out, join110(root, "packages", "cli", "skill", FUSION_SKILL_NAME3));
354608
+ pushUnique2(out, join111(root, "skill", FUSION_SKILL_NAME3));
354609
+ pushUnique2(out, join111(root, "packages", "cli", "skill", FUSION_SKILL_NAME3));
354424
354610
  }
354425
354611
  function walkAncestorSkillCandidates2(out, startDir, maxParents = 8) {
354426
354612
  let dir2 = startDir;
@@ -354435,7 +354621,7 @@ function pushPackageRequireCandidates2(out, from) {
354435
354621
  try {
354436
354622
  const require6 = createRequire9(from);
354437
354623
  const pkgJson = require6.resolve("@runfusion/fusion/package.json");
354438
- pushUnique2(out, join110(dirname49(pkgJson), "skill", FUSION_SKILL_NAME3));
354624
+ pushUnique2(out, join111(dirname49(pkgJson), "skill", FUSION_SKILL_NAME3));
354439
354625
  } catch {
354440
354626
  }
354441
354627
  }
@@ -354503,21 +354689,21 @@ function collectSkillsFromRoot2(root, out) {
354503
354689
  return;
354504
354690
  }
354505
354691
  for (const entry of entries) {
354506
- const child = join110(root, entry);
354692
+ const child = join111(root, entry);
354507
354693
  if (isSkillDir2(child)) {
354508
354694
  out.set(entry, child);
354509
354695
  }
354510
354696
  }
354511
354697
  }
354512
354698
  function stageClaudeSessionSkills(options = {}) {
354513
- const pluginDir = mkdtempSync4(join110(tmpdir18(), "fusion-claude-plugin-"));
354514
- const skillsDir = join110(pluginDir, "skills");
354699
+ const pluginDir = mkdtempSync4(join111(tmpdir18(), "fusion-claude-plugin-"));
354700
+ const skillsDir = join111(pluginDir, "skills");
354515
354701
  mkdirSync15(skillsDir, { recursive: true });
354516
354702
  const installed = /* @__PURE__ */ new Map();
354517
354703
  const includeFusion = options.includeFusionSkill !== false;
354518
354704
  if (includeFusion) {
354519
354705
  const fusionSource = resolveBundledFusionSkillSource3();
354520
- if (fusionSource && installSkillDir2(fusionSource, join110(skillsDir, FUSION_SKILL_NAME3))) {
354706
+ if (fusionSource && installSkillDir2(fusionSource, join111(skillsDir, FUSION_SKILL_NAME3))) {
354521
354707
  installed.set(FUSION_SKILL_NAME3, fusionSource);
354522
354708
  }
354523
354709
  }
@@ -354527,15 +354713,15 @@ function stageClaudeSessionSkills(options = {}) {
354527
354713
  }
354528
354714
  for (const [name2, source] of installed) {
354529
354715
  if (name2 === FUSION_SKILL_NAME3 && includeFusion) continue;
354530
- installSkillDir2(source, join110(skillsDir, name2));
354716
+ installSkillDir2(source, join111(skillsDir, name2));
354531
354717
  }
354532
354718
  for (const [name2, source] of installed) {
354533
- if (!existsSync79(join110(skillsDir, name2))) {
354534
- installSkillDir2(source, join110(skillsDir, name2));
354719
+ if (!existsSync79(join111(skillsDir, name2))) {
354720
+ installSkillDir2(source, join111(skillsDir, name2));
354535
354721
  }
354536
354722
  }
354537
354723
  writeFileSync16(
354538
- join110(pluginDir, "plugin.json"),
354724
+ join111(pluginDir, "plugin.json"),
354539
354725
  JSON.stringify(
354540
354726
  {
354541
354727
  name: "fusion-session-skills",
@@ -354601,7 +354787,7 @@ var init_skill_loader2 = __esm({
354601
354787
  import { createServer as createServer3 } from "node:http";
354602
354788
  import { existsSync as existsSync80, rmSync as rmSync13, writeFileSync as writeFileSync17 } from "node:fs";
354603
354789
  import { tmpdir as tmpdir19 } from "node:os";
354604
- import { dirname as dirname50, join as join111 } from "node:path";
354790
+ import { dirname as dirname50, join as join112 } from "node:path";
354605
354791
  import { fileURLToPath as fileURLToPath15 } from "node:url";
354606
354792
  import { randomBytes as randomBytes8, randomUUID as randomUUID63 } from "node:crypto";
354607
354793
  function toolsToMcpToolDefs3(tools) {
@@ -354613,7 +354799,7 @@ function toolsToMcpToolDefs3(tools) {
354613
354799
  }));
354614
354800
  }
354615
354801
  function fusionToolsMcpServerPath2() {
354616
- return join111(dirname50(fileURLToPath15(import.meta.url)), "mcp-schema-server.cjs");
354802
+ return join112(dirname50(fileURLToPath15(import.meta.url)), "mcp-schema-server.cjs");
354617
354803
  }
354618
354804
  function missingMcpSchemaServerError2(serverPath) {
354619
354805
  const error3 = new Error(`Fusion MCP schema server is missing: ${serverPath}`);
@@ -354654,7 +354840,7 @@ async function startFusionToolBridge2(tools, options = {}) {
354654
354840
  byName.set(tool.name, tool);
354655
354841
  }
354656
354842
  }
354657
- const schemaPath = join111(tmpdir19(), `fusion-claude-mcp-schemas-${process.pid}-${randomUUID63()}.json`);
354843
+ const schemaPath = join112(tmpdir19(), `fusion-claude-mcp-schemas-${process.pid}-${randomUUID63()}.json`);
354658
354844
  writeFileSync17(schemaPath, JSON.stringify(defs));
354659
354845
  const capabilityToken = randomBytes8(32).toString("base64url");
354660
354846
  const server = createServer3(async (req, res) => {
@@ -355458,7 +355644,7 @@ var init_provider6 = __esm({
355458
355644
 
355459
355645
  // ../../plugins/fusion-plugin-omp-runtime/src/acp/cli-spawn.ts
355460
355646
  import { existsSync as existsSync81 } from "node:fs";
355461
- import { dirname as dirname51, isAbsolute as isAbsolute31, join as join112, resolve as resolve65 } from "node:path";
355647
+ import { dirname as dirname51, isAbsolute as isAbsolute31, join as join113, resolve as resolve65 } from "node:path";
355462
355648
  import { fileURLToPath as fileURLToPath16 } from "node:url";
355463
355649
  function asTrimmedString3(value) {
355464
355650
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
@@ -355476,7 +355662,7 @@ function pluginRootDir4() {
355476
355662
  }
355477
355663
  function bundledClaudeBridgeBinPath4(pluginRoot = pluginRootDir4()) {
355478
355664
  const extension = process.platform === "win32" ? ".cmd" : "";
355479
- return join112(pluginRoot, "node_modules", ".bin", `${CLAUDE_CODE_CLI_ACP_BINARY4}${extension}`);
355665
+ return join113(pluginRoot, "node_modules", ".bin", `${CLAUDE_CODE_CLI_ACP_BINARY4}${extension}`);
355480
355666
  }
355481
355667
  function resolveBundledClaudeBridgeBinary4(options = {}) {
355482
355668
  const root = options.pluginRoot ?? pluginRootDir4();
@@ -356794,7 +356980,7 @@ var init_mcp_forwarding3 = __esm({
356794
356980
  import { createServer as createServer4 } from "node:http";
356795
356981
  import { existsSync as existsSync82, unlinkSync as unlinkSync5, writeFileSync as writeFileSync18 } from "node:fs";
356796
356982
  import { tmpdir as tmpdir20 } from "node:os";
356797
- import { dirname as dirname53, join as join114 } from "node:path";
356983
+ import { dirname as dirname53, join as join115 } from "node:path";
356798
356984
  import { fileURLToPath as fileURLToPath17 } from "node:url";
356799
356985
  import { randomUUID as randomUUID64 } from "node:crypto";
356800
356986
  function toolsToMcpToolDefs4(tools) {
@@ -356811,12 +356997,12 @@ function fusionToolsMcpServerPath3() {
356811
356997
  const here = dirname53(fileURLToPath17(import.meta.url));
356812
356998
  const candidates = [
356813
356999
  // Packaged CLI / same-dir as bundled.js or tool-bridge source.
356814
- join114(here, "mcp-schema-server.cjs"),
357000
+ join115(here, "mcp-schema-server.cjs"),
356815
357001
  // Source layout when running from dist/ that still has ../src assets.
356816
- join114(here, "src", "mcp-schema-server.cjs"),
356817
- join114(here, "..", "src", "mcp-schema-server.cjs"),
357002
+ join115(here, "src", "mcp-schema-server.cjs"),
357003
+ join115(here, "..", "src", "mcp-schema-server.cjs"),
356818
357004
  // Monorepo plugin root relative to src/ or dist/plugins/.../bundled.js.
356819
- join114(here, "..", "mcp-schema-server.cjs")
357005
+ join115(here, "..", "mcp-schema-server.cjs")
356820
357006
  ];
356821
357007
  for (const candidate of candidates) {
356822
357008
  if (existsSync82(candidate)) return candidate;
@@ -356853,7 +357039,7 @@ async function startFusionToolBridge3(tools) {
356853
357039
  byName.set(tool.name, tool);
356854
357040
  }
356855
357041
  }
356856
- const schemaPath = join114(tmpdir20(), `fusion-omp-mcp-schemas-${process.pid}-${randomUUID64()}.json`);
357042
+ const schemaPath = join115(tmpdir20(), `fusion-omp-mcp-schemas-${process.pid}-${randomUUID64()}.json`);
356857
357043
  writeFileSync18(schemaPath, JSON.stringify(defs));
356858
357044
  const server = createServer4(async (req, res) => {
356859
357045
  if (req.method !== "POST" || req.url !== "/tool-call") {
@@ -358805,9 +358991,9 @@ var init_hermes_model_cache = __esm({
358805
358991
  });
358806
358992
 
358807
358993
  // ../dashboard/src/routes/register-model-routes.ts
358808
- import { access as access19, readFile as readFile50 } from "node:fs/promises";
358994
+ import { access as access19, readFile as readFile51 } from "node:fs/promises";
358809
358995
  import { homedir as homedir16 } from "node:os";
358810
- import { join as join115 } from "node:path";
358996
+ import { join as join116 } from "node:path";
358811
358997
  function isRawAnthropicApiKeyCredential(credential) {
358812
358998
  return Boolean(
358813
358999
  credential && typeof credential === "object" && credential.type === "api_key" && typeof credential.key === "string" && credential.key.length > 0
@@ -358848,14 +359034,14 @@ async function getConfiguredProviderNames(authStorage) {
358848
359034
  const providers = /* @__PURE__ */ new Set();
358849
359035
  addAuthStorageConfiguredProviders(authStorage, providers);
358850
359036
  const authPaths = [
358851
- join115(home, ".fusion", "agent", "auth.json"),
358852
- join115(home, ".pi", "agent", "auth.json"),
358853
- join115(home, ".pi", "auth.json")
359037
+ join116(home, ".fusion", "agent", "auth.json"),
359038
+ join116(home, ".pi", "agent", "auth.json"),
359039
+ join116(home, ".pi", "auth.json")
358854
359040
  ];
358855
359041
  for (const authPath of authPaths) {
358856
359042
  try {
358857
359043
  await access19(authPath);
358858
- const parsed = JSON.parse(await readFile50(authPath, "utf-8"));
359044
+ const parsed = JSON.parse(await readFile51(authPath, "utf-8"));
358859
359045
  for (const [key, credential] of Object.entries(parsed)) {
358860
359046
  if (key === ANTHROPIC_SUBSCRIPTION_PROVIDER_ID4) {
358861
359047
  providers.add(ANTHROPIC_PROVIDER_ID3);
@@ -358877,14 +359063,14 @@ async function getConfiguredProviderNames(authStorage) {
358877
359063
  providers.add(ANTHROPIC_PROVIDER_ID3);
358878
359064
  }
358879
359065
  const modelsPaths = [
358880
- join115(home, ".fusion", "agent", "models.json"),
358881
- join115(home, ".pi", "agent", "models.json"),
358882
- join115(home, ".pi", "models.json")
359066
+ join116(home, ".fusion", "agent", "models.json"),
359067
+ join116(home, ".pi", "agent", "models.json"),
359068
+ join116(home, ".pi", "models.json")
358883
359069
  ];
358884
359070
  for (const modelsPath of modelsPaths) {
358885
359071
  try {
358886
359072
  await access19(modelsPath);
358887
- const parsed = JSON.parse(await readFile50(modelsPath, "utf-8"));
359073
+ const parsed = JSON.parse(await readFile51(modelsPath, "utf-8"));
358888
359074
  const provs = parsed?.providers;
358889
359075
  if (provs) {
358890
359076
  for (const [providerId, config3] of Object.entries(provs)) {
@@ -359634,7 +359820,7 @@ var init_register_custom_provider_routes = __esm({
359634
359820
  // ../dashboard/src/usage.ts
359635
359821
  import * as os11 from "node:os";
359636
359822
  import * as path13 from "node:path";
359637
- import { readFile as readFile51 } from "node:fs/promises";
359823
+ import { readFile as readFile52 } from "node:fs/promises";
359638
359824
  import * as https from "node:https";
359639
359825
  import * as child_process from "node:child_process";
359640
359826
  function getHomeDir6() {
@@ -359755,7 +359941,7 @@ function decodeJwtPayload(token) {
359755
359941
  }
359756
359942
  async function readAuthKeyFromFile(authPath, provider) {
359757
359943
  try {
359758
- const auth2 = JSON.parse(await readFile51(authPath, "utf-8"));
359944
+ const auth2 = JSON.parse(await readFile52(authPath, "utf-8"));
359759
359945
  const entry = auth2?.[provider];
359760
359946
  if (entry && (entry.type === "api_key" || entry.type === "key") && entry.key) {
359761
359947
  return entry.key;
@@ -360173,7 +360359,7 @@ async function fetchClaudeUsage(authStorage) {
360173
360359
  ];
360174
360360
  for (const p2 of credPaths) {
360175
360361
  try {
360176
- creds = JSON.parse(await readFile51(p2, "utf-8"));
360362
+ creds = JSON.parse(await readFile52(p2, "utf-8"));
360177
360363
  break;
360178
360364
  } catch {
360179
360365
  }
@@ -360366,7 +360552,7 @@ async function loadCodexCredential() {
360366
360552
  const authPath = path13.join(codexHome, "auth.json");
360367
360553
  let auth2 = null;
360368
360554
  try {
360369
- auth2 = JSON.parse(await readFile51(authPath, "utf-8"));
360555
+ auth2 = JSON.parse(await readFile52(authPath, "utf-8"));
360370
360556
  } catch {
360371
360557
  auth2 = null;
360372
360558
  }
@@ -360486,7 +360672,7 @@ async function fetchGeminiUsage() {
360486
360672
  const oauthPath = path13.join(getHomeDir6(), ".gemini", "oauth_creds.json");
360487
360673
  let oauthCreds = null;
360488
360674
  try {
360489
- oauthCreds = JSON.parse(await readFile51(oauthPath, "utf-8"));
360675
+ oauthCreds = JSON.parse(await readFile52(oauthPath, "utf-8"));
360490
360676
  } catch {
360491
360677
  usage.error = "No Gemini credentials \u2014 run 'gemini' to login";
360492
360678
  return usage;
@@ -360501,7 +360687,7 @@ async function fetchGeminiUsage() {
360501
360687
  }
360502
360688
  const settingsPath = path13.join(getHomeDir6(), ".gemini", "settings.json");
360503
360689
  try {
360504
- const settings = JSON.parse(await readFile51(settingsPath, "utf-8"));
360690
+ const settings = JSON.parse(await readFile52(settingsPath, "utf-8"));
360505
360691
  const authType = settings?.security?.auth?.selectedType;
360506
360692
  if (authType === "api-key" || authType === "vertex-ai") {
360507
360693
  usage.status = "no-auth";
@@ -360689,7 +360875,7 @@ async function fetchMinimaxUsage(authStorage) {
360689
360875
  async function readGrokUserSettingsApiKey2() {
360690
360876
  try {
360691
360877
  const settingsPath = path13.join(getHomeDir6(), ".grok", "user-settings.json");
360692
- const raw = await readFile51(settingsPath, "utf-8");
360878
+ const raw = await readFile52(settingsPath, "utf-8");
360693
360879
  const parsed = JSON.parse(raw);
360694
360880
  return typeof parsed?.apiKey === "string" && parsed.apiKey.trim().length > 0 ? parsed.apiKey.trim() : null;
360695
360881
  } catch {
@@ -360698,7 +360884,7 @@ async function readGrokUserSettingsApiKey2() {
360698
360884
  }
360699
360885
  async function readGrokCliOidcToken() {
360700
360886
  try {
360701
- const raw = await readFile51(path13.join(getHomeDir6(), ".grok", "auth.json"), "utf-8");
360887
+ const raw = await readFile52(path13.join(getHomeDir6(), ".grok", "auth.json"), "utf-8");
360702
360888
  const parsed = JSON.parse(raw);
360703
360889
  for (const entry of Object.values(parsed)) {
360704
360890
  if (entry && typeof entry.key === "string" && entry.key.trim().length > 0) {
@@ -363823,11 +364009,11 @@ var init_droid_cli_probe = __esm({
363823
364009
  });
363824
364010
 
363825
364011
  // ../dashboard/src/llama-cpp-probe.ts
363826
- import { readFile as readFile52 } from "node:fs/promises";
363827
- import { join as join117 } from "node:path";
364012
+ import { readFile as readFile53 } from "node:fs/promises";
364013
+ import { join as join118 } from "node:path";
363828
364014
  async function readJson(path14) {
363829
364015
  try {
363830
- const raw = await readFile52(path14, "utf-8");
364016
+ const raw = await readFile53(path14, "utf-8");
363831
364017
  return JSON.parse(raw);
363832
364018
  } catch {
363833
364019
  return null;
@@ -363837,18 +364023,18 @@ function normalizeUrl(url2) {
363837
364023
  return url2.trim().replace(/\/+$/, "");
363838
364024
  }
363839
364025
  async function resolveLlamaServerUrl(cwd) {
363840
- const projectCfg = await readJson(join117(cwd, ".pi", "llama-server.json"));
364026
+ const projectCfg = await readJson(join118(cwd, ".pi", "llama-server.json"));
363841
364027
  if (projectCfg?.url) return normalizeUrl(projectCfg.url);
363842
364028
  const envUrl = process.env.LLAMA_SERVER_URL;
363843
364029
  if (envUrl) return normalizeUrl(envUrl);
363844
364030
  const globalCfg = await readJson(
363845
- join117(process.env.HOME ?? ".", ".pi", "agent", "settings.json")
364031
+ join118(process.env.HOME ?? ".", ".pi", "agent", "settings.json")
363846
364032
  );
363847
364033
  if (globalCfg?.llamaServerUrl) return normalizeUrl(globalCfg.llamaServerUrl);
363848
364034
  return DEFAULT_LLAMA_SERVER_URL;
363849
364035
  }
363850
364036
  async function resolveLlamaServerApiKey() {
363851
- const authCfg = await readJson(join117(process.env.HOME ?? ".", ".pi", "agent", "auth.json"));
364037
+ const authCfg = await readJson(join118(process.env.HOME ?? ".", ".pi", "agent", "auth.json"));
363852
364038
  const key = authCfg?.["llama-server"]?.key?.trim();
363853
364039
  return key ? key : void 0;
363854
364040
  }
@@ -363929,7 +364115,7 @@ var init_auth_provider_catalog = __esm({
363929
364115
 
363930
364116
  // ../dashboard/src/routes/register-auth-routes.ts
363931
364117
  import { tmpdir as tmpdir21 } from "node:os";
363932
- import { join as join118 } from "node:path";
364118
+ import { join as join119 } from "node:path";
363933
364119
  import { existsSync as existsSync84, readFileSync as readFileSync29 } from "node:fs";
363934
364120
  function parseGitHubCopilotDeviceCode(instructions) {
363935
364121
  const match = instructions.match(/Enter code:\s*([A-Z0-9-]+)\b/i);
@@ -364594,7 +364780,7 @@ var init_register_auth_routes = __esm({
364594
364780
  let acpAuthFailed = false;
364595
364781
  let acpAuthReason;
364596
364782
  try {
364597
- const signalPath = join118(tmpdir21(), "fusion-acp-bridge-auth.json");
364783
+ const signalPath = join119(tmpdir21(), "fusion-acp-bridge-auth.json");
364598
364784
  if (existsSync84(signalPath)) {
364599
364785
  const sig = JSON.parse(readFileSync29(signalPath, "utf8"));
364600
364786
  if (sig?.authFailed) {
@@ -365619,7 +365805,7 @@ var init_register_fn_binary_routes = __esm({
365619
365805
  import { exec as exec46 } from "node:child_process";
365620
365806
  import { readFileSync as readFileSync30, realpathSync as realpathSync14 } from "node:fs";
365621
365807
  import { mkdir as mkdir37, rm as rm21, writeFile as writeFile37 } from "node:fs/promises";
365622
- import { join as join119 } from "node:path";
365808
+ import { join as join120 } from "node:path";
365623
365809
  import { promisify as promisify71 } from "node:util";
365624
365810
  function ttlForFrequency(frequency) {
365625
365811
  switch (frequency) {
@@ -365634,7 +365820,7 @@ function ttlForFrequency(frequency) {
365634
365820
  }
365635
365821
  }
365636
365822
  function getCachePath(fusionDir) {
365637
- return join119(fusionDir, CACHE_FILENAME);
365823
+ return join120(fusionDir, CACHE_FILENAME);
365638
365824
  }
365639
365825
  function buildInstallCommand(version3, force = false) {
365640
365826
  if (!SAFE_VERSION_RE.test(version3)) {
@@ -365959,8 +366145,8 @@ var init_types6 = __esm({
365959
366145
 
365960
366146
  // ../dashboard/src/stt/model-manager.ts
365961
366147
  import { createHash as createHash27, randomUUID as randomUUID67 } from "node:crypto";
365962
- import { mkdir as mkdir38, open as open4, readFile as readFile53, readdir as readdir14, rename as rename10, rm as rm22, stat as stat16, writeFile as writeFile38 } from "node:fs/promises";
365963
- import { join as join120, relative as relative22, resolve as resolve67, sep as sep18 } from "node:path";
366148
+ import { mkdir as mkdir38, open as open4, readFile as readFile54, readdir as readdir14, rename as rename10, rm as rm22, stat as stat16, writeFile as writeFile38 } from "node:fs/promises";
366149
+ import { join as join121, relative as relative22, resolve as resolve67, sep as sep18 } from "node:path";
365964
366150
  function parseSafeTarListing(listing) {
365965
366151
  for (const line2 of listing.split("\n").filter(Boolean)) {
365966
366152
  const type = line2[0];
@@ -365975,8 +366161,8 @@ function parseSafeTarListing(listing) {
365975
366161
  function createVoiceModelManager(options = {}) {
365976
366162
  const asset = options.asset ?? PARAKEET_V3_ASSET;
365977
366163
  let configuredCacheDir = options.cacheDir;
365978
- const cacheDir = () => configuredCacheDir ??= join120(resolveGlobalDir(), "models", "parakeet-v3");
365979
- const finalDir = () => join120(cacheDir(), "model");
366164
+ const cacheDir = () => configuredCacheDir ??= join121(resolveGlobalDir(), "models", "parakeet-v3");
366165
+ const finalDir = () => join121(cacheDir(), "model");
365980
366166
  let state = { status: "not-installed" };
365981
366167
  let generation = 0;
365982
366168
  let cleanupBarrier = Promise.resolve();
@@ -366039,8 +366225,8 @@ function createVoiceModelManager(options = {}) {
366039
366225
  if (!current(g2, signal)) return state;
366040
366226
  await mkdir38(cacheDir(), { recursive: true });
366041
366227
  if (!current(g2, signal)) return state;
366042
- partial2 = join120(cacheDir(), `.partial-${g2}-${randomUUID67()}`);
366043
- staging = join120(cacheDir(), `.staging-${g2}-${randomUUID67()}`);
366228
+ partial2 = join121(cacheDir(), `.partial-${g2}-${randomUUID67()}`);
366229
+ staging = join121(cacheDir(), `.staging-${g2}-${randomUUID67()}`);
366044
366230
  const file = await open4(partial2, "wx");
366045
366231
  try {
366046
366232
  const response = await (options.fetch ?? globalThis.fetch)(asset.url, { signal });
@@ -366085,10 +366271,10 @@ function createVoiceModelManager(options = {}) {
366085
366271
  }
366086
366272
  }
366087
366273
  if (!current(g2, signal)) return state;
366088
- await writeFile38(join120(staging, "manifest.json"), JSON.stringify({ filename: asset.filename, sha256: asset.sha256, installedAt: (/* @__PURE__ */ new Date()).toISOString(), expectedFiles: asset.expectedFiles }));
366274
+ await writeFile38(join121(staging, "manifest.json"), JSON.stringify({ filename: asset.filename, sha256: asset.sha256, installedAt: (/* @__PURE__ */ new Date()).toISOString(), expectedFiles: asset.expectedFiles }));
366089
366275
  await options.beforePromote?.(signal);
366090
366276
  if (!current(g2, signal)) return state;
366091
- const backup = join120(cacheDir(), `.backup-${g2}-${randomUUID67()}`);
366277
+ const backup = join121(cacheDir(), `.backup-${g2}-${randomUUID67()}`);
366092
366278
  let movedPrevious = false;
366093
366279
  try {
366094
366280
  try {
@@ -366168,9 +366354,9 @@ function createVoiceModelManager(options = {}) {
366168
366354
  publish(absent);
366169
366355
  return absent;
366170
366356
  }
366171
- const manifest = JSON.parse(await readFile53(join120(finalDir(), "manifest.json"), "utf8"));
366357
+ const manifest = JSON.parse(await readFile54(join121(finalDir(), "manifest.json"), "utf8"));
366172
366358
  if (manifest.sha256 !== asset.sha256) throw new Error("stale manifest digest");
366173
- for (const expected of asset.expectedFiles) if (!await existsFile(join120(finalDir(), expected))) throw new Error("missing expected model file");
366359
+ for (const expected of asset.expectedFiles) if (!await existsFile(join121(finalDir(), expected))) throw new Error("missing expected model file");
366174
366360
  const installed = { status: "installed", checksumVerified: true, installedPath: finalDir() };
366175
366361
  publish(installed);
366176
366362
  return installed;
@@ -366182,7 +366368,7 @@ function createVoiceModelManager(options = {}) {
366182
366368
  try {
366183
366369
  for (const entry of await readdir14(cacheDir())) {
366184
366370
  const own = /^\.(partial|staging|backup)-(\d+)-/.exec(entry);
366185
- if (own && Number(own[2]) !== active?.generation) await rm22(join120(cacheDir(), entry), { recursive: true, force: true });
366371
+ if (own && Number(own[2]) !== active?.generation) await rm22(join121(cacheDir(), entry), { recursive: true, force: true });
366186
366372
  }
366187
366373
  } catch {
366188
366374
  }
@@ -366204,7 +366390,7 @@ function createVoiceModelManager(options = {}) {
366204
366390
  try {
366205
366391
  for (const entry of await readdir14(cacheDir())) {
366206
366392
  const match = /^\.(partial|staging|backup)-(\d+)-/.exec(entry);
366207
- if (match && Number(match[2]) <= g2) await rm22(join120(cacheDir(), entry), { recursive: true, force: true });
366393
+ if (match && Number(match[2]) <= g2) await rm22(join121(cacheDir(), entry), { recursive: true, force: true });
366208
366394
  }
366209
366395
  } catch {
366210
366396
  }
@@ -366582,16 +366768,16 @@ import {
366582
366768
  unlinkSync as unlinkSync6
366583
366769
  } from "node:fs";
366584
366770
  import { homedir as homedir18 } from "node:os";
366585
- import { dirname as dirname54, join as join121, resolve as resolve68 } from "node:path";
366771
+ import { dirname as dirname54, join as join122, resolve as resolve68 } from "node:path";
366586
366772
  function resolveFnBinaryLocalPaths(home = homedir18()) {
366587
- const installDir = join121(home, ".local", "share", "fusion");
366588
- const binDir = join121(home, ".local", "bin");
366773
+ const installDir = join122(home, ".local", "share", "fusion");
366774
+ const binDir = join122(home, ".local", "bin");
366589
366775
  return {
366590
366776
  installDir,
366591
366777
  binDir,
366592
- binaryPath: join121(installDir, "fn"),
366593
- fnShimPath: join121(binDir, "fn"),
366594
- fusionShimPath: join121(binDir, "fusion")
366778
+ binaryPath: join122(installDir, "fn"),
366779
+ fnShimPath: join122(binDir, "fn"),
366780
+ fusionShimPath: join122(binDir, "fusion")
366595
366781
  };
366596
366782
  }
366597
366783
  function runStreamingCommand(command, args, options) {
@@ -366687,17 +366873,17 @@ function runStreamingCommand(command, args, options) {
366687
366873
  }
366688
366874
  function resolveBunExecutable() {
366689
366875
  if (process.env.BUN_INSTALL) {
366690
- const candidate = join121(process.env.BUN_INSTALL, "bin", process.platform === "win32" ? "bun.exe" : "bun");
366876
+ const candidate = join122(process.env.BUN_INSTALL, "bin", process.platform === "win32" ? "bun.exe" : "bun");
366691
366877
  if (existsSync85(candidate)) return candidate;
366692
366878
  }
366693
- const homeBun = join121(homedir18(), ".bun", "bin", process.platform === "win32" ? "bun.exe" : "bun");
366879
+ const homeBun = join122(homedir18(), ".bun", "bin", process.platform === "win32" ? "bun.exe" : "bun");
366694
366880
  if (existsSync85(homeBun)) return homeBun;
366695
366881
  return "bun";
366696
366882
  }
366697
366883
  function installLocalFnBinary(distDir, onLog, paths2 = resolveFnBinaryLocalPaths()) {
366698
- const srcBinary = join121(distDir, process.platform === "win32" ? "fn.exe" : "fn");
366699
- const srcClient = join121(distDir, "client");
366700
- const srcRuntime = join121(distDir, "runtime");
366884
+ const srcBinary = join122(distDir, process.platform === "win32" ? "fn.exe" : "fn");
366885
+ const srcClient = join122(distDir, "client");
366886
+ const srcRuntime = join122(distDir, "runtime");
366701
366887
  if (!existsSync85(srcBinary)) {
366702
366888
  throw new Error(`Built binary missing at ${srcBinary}. Did the Bun compile step fail?`);
366703
366889
  }
@@ -366712,13 +366898,13 @@ function installLocalFnBinary(distDir, onLog, paths2 = resolveFnBinaryLocalPaths
366712
366898
  chmodSync4(paths2.binaryPath, 493);
366713
366899
  } catch {
366714
366900
  }
366715
- onLog("system", `Installing client assets \u2192 ${join121(paths2.installDir, "client")}`);
366716
- rmSync14(join121(paths2.installDir, "client"), { recursive: true, force: true });
366717
- cpSync5(srcClient, join121(paths2.installDir, "client"), { recursive: true });
366901
+ onLog("system", `Installing client assets \u2192 ${join122(paths2.installDir, "client")}`);
366902
+ rmSync14(join122(paths2.installDir, "client"), { recursive: true, force: true });
366903
+ cpSync5(srcClient, join122(paths2.installDir, "client"), { recursive: true });
366718
366904
  if (existsSync85(srcRuntime)) {
366719
- onLog("system", `Installing runtime assets \u2192 ${join121(paths2.installDir, "runtime")}`);
366720
- rmSync14(join121(paths2.installDir, "runtime"), { recursive: true, force: true });
366721
- cpSync5(srcRuntime, join121(paths2.installDir, "runtime"), { recursive: true });
366905
+ onLog("system", `Installing runtime assets \u2192 ${join122(paths2.installDir, "runtime")}`);
366906
+ rmSync14(join122(paths2.installDir, "runtime"), { recursive: true, force: true });
366907
+ cpSync5(srcRuntime, join122(paths2.installDir, "runtime"), { recursive: true });
366722
366908
  }
366723
366909
  for (const shim of [paths2.fnShimPath, paths2.fusionShimPath]) {
366724
366910
  try {
@@ -366773,9 +366959,9 @@ function removeLocalFnShims(onLog, paths2 = resolveFnBinaryLocalPaths()) {
366773
366959
  return { removed };
366774
366960
  }
366775
366961
  async function runLinkLocalFnBinary(sourceRoot, onLog) {
366776
- const buildScript = join121(sourceRoot, "scripts", "build-workspace.mjs");
366777
- const cliBuild = join121(sourceRoot, "packages", "cli", "build.ts");
366778
- const distDir = join121(sourceRoot, "packages", "cli", "dist");
366962
+ const buildScript = join122(sourceRoot, "scripts", "build-workspace.mjs");
366963
+ const cliBuild = join122(sourceRoot, "packages", "cli", "build.ts");
366964
+ const distDir = join122(sourceRoot, "packages", "cli", "dist");
366779
366965
  if (!existsSync85(buildScript)) {
366780
366966
  return { success: false, error: `Build script missing: ${buildScript}` };
366781
366967
  }
@@ -366856,7 +367042,7 @@ var init_fn_binary_local_install = __esm({
366856
367042
  // ../dashboard/src/routes/register-system-routes.ts
366857
367043
  import { randomUUID as randomUUID69 } from "node:crypto";
366858
367044
  import { existsSync as existsSync86 } from "node:fs";
366859
- import { join as join122 } from "node:path";
367045
+ import { join as join123 } from "node:path";
366860
367046
  function rejectCrossOrigin(req, res) {
366861
367047
  const origin = req.headers.origin;
366862
367048
  if (typeof origin !== "string" || origin.length === 0) return false;
@@ -367046,7 +367232,7 @@ function registerSystemRoutes(ctx, deps) {
367046
367232
  }
367047
367233
  const restartAfter = body.restart !== false && scope !== "plugins";
367048
367234
  const { args, label } = rebuildScopes[scope];
367049
- const scriptPath = join122(root, args[0]);
367235
+ const scriptPath = join123(root, args[0]);
367050
367236
  if (!existsSync86(scriptPath)) {
367051
367237
  throw new ApiError(409, `Build script missing: ${scriptPath}`);
367052
367238
  }
@@ -372392,11 +372578,11 @@ var init_roadmap_routes3 = __esm({
372392
372578
  });
372393
372579
 
372394
372580
  // ../dashboard/src/dev-server-detect.ts
372395
- import { glob, readFile as readFile54 } from "node:fs/promises";
372396
- import { dirname as dirname55, join as join123, relative as relative23, resolve as resolve69 } from "node:path";
372581
+ import { glob, readFile as readFile55 } from "node:fs/promises";
372582
+ import { dirname as dirname55, join as join124, relative as relative23, resolve as resolve69 } from "node:path";
372397
372583
  async function readPackageJson(filePath) {
372398
372584
  try {
372399
- const raw = await readFile54(filePath, "utf-8");
372585
+ const raw = await readFile55(filePath, "utf-8");
372400
372586
  return JSON.parse(raw);
372401
372587
  } catch {
372402
372588
  return null;
@@ -372436,7 +372622,7 @@ function scoreCandidate(scriptName, pkg) {
372436
372622
  async function collectWorkspacePackageJsons(projectRoot) {
372437
372623
  const discovered = /* @__PURE__ */ new Set();
372438
372624
  try {
372439
- await readFile54(join123(projectRoot, "pnpm-workspace.yaml"), "utf-8");
372625
+ await readFile55(join124(projectRoot, "pnpm-workspace.yaml"), "utf-8");
372440
372626
  } catch {
372441
372627
  }
372442
372628
  for (const pattern of ["packages/*/package.json", "apps/*/package.json"]) {
@@ -372470,7 +372656,7 @@ function toSource(projectRoot, packageJsonPath) {
372470
372656
  async function detectDevServerScripts(projectRoot) {
372471
372657
  const root = resolve69(projectRoot);
372472
372658
  const candidates = [];
372473
- const rootPackagePath = join123(root, "package.json");
372659
+ const rootPackagePath = join124(root, "package.json");
372474
372660
  const rootPackage = await readPackageJson(rootPackagePath);
372475
372661
  if (rootPackage) {
372476
372662
  for (const script of extractScripts(rootPackage)) {
@@ -372536,10 +372722,10 @@ var init_dev_server_detect = __esm({
372536
372722
  });
372537
372723
 
372538
372724
  // ../dashboard/src/dev-server-store.ts
372539
- import { mkdir as mkdir39, readFile as readFile55, writeFile as writeFile39 } from "node:fs/promises";
372540
- import { dirname as dirname56, join as join124, resolve as resolve70 } from "node:path";
372725
+ import { mkdir as mkdir39, readFile as readFile56, writeFile as writeFile39 } from "node:fs/promises";
372726
+ import { dirname as dirname56, join as join125, resolve as resolve70 } from "node:path";
372541
372727
  function devServerFilePath(projectDir) {
372542
- return join124(resolve70(projectDir), ".fusion", "dev-server.json");
372728
+ return join125(resolve70(projectDir), ".fusion", "dev-server.json");
372543
372729
  }
372544
372730
  function normalizeState(candidate) {
372545
372731
  const defaults = DEV_SERVER_DEFAULT_STATE();
@@ -372614,7 +372800,7 @@ var init_dev_server_store = __esm({
372614
372800
  }
372615
372801
  async load() {
372616
372802
  try {
372617
- const content = await readFile55(this.filePath, "utf-8");
372803
+ const content = await readFile56(this.filePath, "utf-8");
372618
372804
  const parsed = JSON.parse(content);
372619
372805
  this.state = normalizeState(parsed?.state);
372620
372806
  this.config = normalizeConfig(parsed?.config);
@@ -375261,7 +375447,7 @@ var init_register_config_mcp_pi_settings_routes = __esm({
375261
375447
 
375262
375448
  // ../dashboard/src/routes.ts
375263
375449
  import multer from "multer";
375264
- import { resolve as resolve71, sep as sep19, join as join125, isAbsolute as isAbsolute32 } from "node:path";
375450
+ import { resolve as resolve71, sep as sep19, join as join126, isAbsolute as isAbsolute32 } from "node:path";
375265
375451
  import * as nodeFs3 from "node:fs";
375266
375452
  async function readJsonObject3(path14) {
375267
375453
  try {
@@ -375287,8 +375473,8 @@ async function getPiPackageManagerAgentDir() {
375287
375473
  const fusionAgentDir = getFusionAgentDir();
375288
375474
  const legacyAgentDir = getLegacyPiAgentDir();
375289
375475
  const [fusionSettings, legacySettings, legacyExists, fusionExists] = await Promise.all([
375290
- readJsonObject3(join125(fusionAgentDir, "settings.json")),
375291
- readJsonObject3(join125(legacyAgentDir, "settings.json")),
375476
+ readJsonObject3(join126(fusionAgentDir, "settings.json")),
375477
+ readJsonObject3(join126(legacyAgentDir, "settings.json")),
375292
375478
  pathExists2(legacyAgentDir),
375293
375479
  pathExists2(fusionAgentDir)
375294
375480
  ]);
@@ -375315,9 +375501,9 @@ async function discoverDashboardPiExtensions(cwd) {
375315
375501
  const { DefaultPackageManager: DefaultPackageManager5 } = await import("@earendil-works/pi-coding-agent");
375316
375502
  const [agentDir, legacyGlobalSettings, fusionGlobalSettings, projectSettings] = await Promise.all([
375317
375503
  getPiPackageManagerAgentDir(),
375318
- readJsonObject3(join125(getLegacyPiAgentDir(), "settings.json")),
375319
- readJsonObject3(join125(getFusionAgentDir(), "settings.json")),
375320
- readJsonObject3(join125(cwd, ".fusion", "settings.json"))
375504
+ readJsonObject3(join126(getLegacyPiAgentDir(), "settings.json")),
375505
+ readJsonObject3(join126(getFusionAgentDir(), "settings.json")),
375506
+ readJsonObject3(join126(cwd, ".fusion", "settings.json"))
375321
375507
  ]);
375322
375508
  const globalSettings = { ...legacyGlobalSettings, ...fusionGlobalSettings };
375323
375509
  const mergedSettings = { ...globalSettings, ...projectSettings };
@@ -376246,7 +376432,7 @@ function createApiRoutes(store, options) {
376246
376432
  return;
376247
376433
  }
376248
376434
  }
376249
- const { resolve: resolve103, dirname: dirname76, join: join155 } = await import("node:path");
376435
+ const { resolve: resolve103, dirname: dirname76, join: join156 } = await import("node:path");
376250
376436
  const { readdir: readdir17, stat: stat20 } = await import("node:fs/promises");
376251
376437
  const rawPath = req.query.path || process.env.HOME || process.env.USERPROFILE || "/";
376252
376438
  const showHidden = req.query.showHidden === "true";
@@ -376271,7 +376457,7 @@ function createApiRoutes(store, options) {
376271
376457
  for (const entry of dirEntries) {
376272
376458
  if (!entry.isDirectory()) continue;
376273
376459
  if (!showHidden && entry.name.startsWith(".")) continue;
376274
- const entryPath = join155(resolvedPath, entry.name);
376460
+ const entryPath = join156(resolvedPath, entry.name);
376275
376461
  let hasChildren = false;
376276
376462
  try {
376277
376463
  const subEntries = await readdir17(entryPath, { withFileTypes: true });
@@ -377988,7 +378174,7 @@ var init_reliability_metrics = __esm({
377988
378174
 
377989
378175
  // ../dashboard/src/view-chunk-manifest.ts
377990
378176
  import { existsSync as existsSync87, readFileSync as readFileSync31, statSync as statSync15 } from "node:fs";
377991
- import { join as join126, resolve as resolve72 } from "node:path";
378177
+ import { join as join127, resolve as resolve72 } from "node:path";
377992
378178
  function warnOnce(set, key, message) {
377993
378179
  if (set.has(key)) {
377994
378180
  return;
@@ -377998,7 +378184,7 @@ function warnOnce(set, key, message) {
377998
378184
  }
377999
378185
  function loadViewChunkManifest(clientDir) {
378000
378186
  const cacheKey = resolve72(clientDir);
378001
- const manifestPath = join126(cacheKey, ".vite", "manifest.json");
378187
+ const manifestPath = join127(cacheKey, ".vite", "manifest.json");
378002
378188
  let mtimeMs = null;
378003
378189
  try {
378004
378190
  mtimeMs = statSync15(manifestPath).mtimeMs;
@@ -378584,7 +378770,7 @@ var init_provider_health_monitor = __esm({
378584
378770
  // ../dashboard/src/server.ts
378585
378771
  import express3 from "express";
378586
378772
  import { randomUUID as randomUUID70 } from "node:crypto";
378587
- import { join as join127, dirname as dirname57 } from "node:path";
378773
+ import { join as join128, dirname as dirname57 } from "node:path";
378588
378774
  import { existsSync as existsSync88, readFileSync as readFileSync32, statSync as statSync16 } from "node:fs";
378589
378775
  import { fileURLToPath as fileURLToPath18 } from "node:url";
378590
378776
  import { createSecureServer as createHttp2SecureServer } from "node:http2";
@@ -378907,14 +379093,14 @@ function createServer5(store, options) {
378907
379093
  getTerminalService(store.getRootDir());
378908
379094
  const isHeadless = options?.headless === true;
378909
379095
  const execDir = dirname57(process.execPath);
378910
- const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync88(join127(execDir, "client", "index.html")) ? join127(execDir, "client") : existsSync88(join127(__dirname2, "..", "dist", "client")) ? join127(__dirname2, "..", "dist", "client") : join127(__dirname2, "..", "client");
379096
+ const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync88(join128(execDir, "client", "index.html")) ? join128(execDir, "client") : existsSync88(join128(__dirname2, "..", "dist", "client")) ? join128(__dirname2, "..", "dist", "client") : join128(__dirname2, "..", "client");
378911
379097
  let cachedIndexClientDir = null;
378912
379098
  let cachedIndexHtml = null;
378913
379099
  let cachedIndexMtimeMs = null;
378914
379100
  let cachedTemplatedIndexHtml = null;
378915
379101
  const renderIndexHtml = () => {
378916
379102
  const resolvedClientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : clientDir;
378917
- const indexPath = join127(resolvedClientDir, "index.html");
379103
+ const indexPath = join128(resolvedClientDir, "index.html");
378918
379104
  let indexMtimeMs = null;
378919
379105
  try {
378920
379106
  indexMtimeMs = statSync16(indexPath).mtimeMs;
@@ -378956,13 +379142,13 @@ ${injection}`) : cachedIndexHtml.replace("</head>", `${injection}</head>`);
378956
379142
  if (!isHeadless) {
378957
379143
  app.get("/version.json", (_req, res) => {
378958
379144
  res.setHeader("Cache-Control", "no-store, max-age=0");
378959
- res.sendFile(join127(clientDir, "version.json"), (err) => {
379145
+ res.sendFile(join128(clientDir, "version.json"), (err) => {
378960
379146
  if (err) {
378961
379147
  res.status(404).json({ version: null });
378962
379148
  }
378963
379149
  });
378964
379150
  });
378965
- if (existsSync88(join127(clientDir, "index.html"))) {
379151
+ if (existsSync88(join128(clientDir, "index.html"))) {
378966
379152
  app.get(["/", "/index.html"], serveIndexHtml);
378967
379153
  app.use(express3.static(clientDir, { index: false }));
378968
379154
  }
@@ -380292,8 +380478,8 @@ var init_server2 = __esm({
380292
380478
  });
380293
380479
 
380294
380480
  // ../dashboard/src/skills-adapter.ts
380295
- import { access as access20, readFile as readFile56, writeFile as writeFile40, mkdir as mkdir40, readdir as readdir15, stat as stat17 } from "node:fs/promises";
380296
- import { join as join128, relative as relative24, dirname as dirname58, resolve as resolve73, sep as sep21 } from "node:path";
380481
+ import { access as access20, readFile as readFile57, writeFile as writeFile40, mkdir as mkdir40, readdir as readdir15, stat as stat17 } from "node:fs/promises";
380482
+ import { join as join129, relative as relative24, dirname as dirname58, resolve as resolve73, sep as sep21 } from "node:path";
380297
380483
  async function pathExists3(path14) {
380298
380484
  try {
380299
380485
  await access20(path14);
@@ -380343,7 +380529,7 @@ function createSkillsAdapter(options) {
380343
380529
  let settings = {};
380344
380530
  if (await pathExists3(settingsPath)) {
380345
380531
  try {
380346
- settings = JSON.parse(await readFile56(settingsPath, "utf-8"));
380532
+ settings = JSON.parse(await readFile57(settingsPath, "utf-8"));
380347
380533
  } catch {
380348
380534
  }
380349
380535
  }
@@ -380423,7 +380609,7 @@ function createSkillsAdapter(options) {
380423
380609
  let settings = {};
380424
380610
  if (await pathExists3(settingsPath)) {
380425
380611
  try {
380426
- settings = JSON.parse(await readFile56(settingsPath, "utf-8"));
380612
+ settings = JSON.parse(await readFile57(settingsPath, "utf-8"));
380427
380613
  } catch {
380428
380614
  }
380429
380615
  }
@@ -380623,10 +380809,10 @@ function createSkillsAdapter(options) {
380623
380809
  } catch {
380624
380810
  skillDir = dirname58(skill.path);
380625
380811
  }
380626
- const skillMdPath = join128(skillDir, "SKILL.md");
380812
+ const skillMdPath = join129(skillDir, "SKILL.md");
380627
380813
  let skillMd = "";
380628
380814
  try {
380629
- skillMd = await readFile56(skillMdPath, "utf-8");
380815
+ skillMd = await readFile57(skillMdPath, "utf-8");
380630
380816
  } catch (error3) {
380631
380817
  const err = error3;
380632
380818
  if (err.code !== "ENOENT") {
@@ -380686,7 +380872,7 @@ function createSkillsAdapter(options) {
380686
380872
  if (fileStat.size > MAX_PREVIEW_BYTES) {
380687
380873
  return { name: name2, relativePath: normalizedRelative, content: "", isText: false };
380688
380874
  }
380689
- const buffer2 = await readFile56(targetPath);
380875
+ const buffer2 = await readFile57(targetPath);
380690
380876
  const sample = buffer2.subarray(0, Math.min(buffer2.length, 8e3));
380691
380877
  const isBinary2 = sample.includes(0);
380692
380878
  if (isBinary2) {
@@ -380885,7 +381071,7 @@ function normalizeEntry(entry) {
380885
381071
  };
380886
381072
  }
380887
381073
  function getProjectSettingsPath(rootDir) {
380888
- return join128(rootDir, ".fusion", "settings.json");
381074
+ return join129(rootDir, ".fusion", "settings.json");
380889
381075
  }
380890
381076
  var MIN_PUBLIC_SEARCH_QUERY_LENGTH;
380891
381077
  var init_skills_adapter = __esm({
@@ -380986,7 +381172,7 @@ var init_src15 = __esm({
380986
381172
  // src/extension.ts
380987
381173
  import { Type as Type9 } from "typebox";
380988
381174
  import { StringEnum } from "@earendil-works/pi-ai";
380989
- import { resolve as resolve74, relative as relative25, isAbsolute as isAbsolute33, sep as sep22, basename as basename37, extname as extname5, join as join129 } from "node:path";
381175
+ import { resolve as resolve74, relative as relative25, isAbsolute as isAbsolute33, sep as sep22, basename as basename37, extname as extname5, join as join130 } from "node:path";
380990
381176
  import { existsSync as existsSync89 } from "node:fs";
380991
381177
  import { AsyncLocalStorage as AsyncLocalStorage8 } from "node:async_hooks";
380992
381178
  function resolveProjectRoot2(cwd) {
@@ -380995,12 +381181,12 @@ function resolveProjectRoot2(cwd) {
380995
381181
  warnedMissingProjectRootResolver = true;
380996
381182
  console.warn("[fusion-extension] @fusion/core.getProjectRootFromWorktree is unavailable; using filesystem fallback resolution.");
380997
381183
  }
380998
- if (worktreeProjectRoot && existsSync89(join129(worktreeProjectRoot, ".fusion"))) {
381184
+ if (worktreeProjectRoot && existsSync89(join130(worktreeProjectRoot, ".fusion"))) {
380999
381185
  return worktreeProjectRoot;
381000
381186
  }
381001
381187
  let current = resolve74(cwd);
381002
381188
  while (true) {
381003
- if (existsSync89(join129(current, ".fusion"))) {
381189
+ if (existsSync89(join130(current, ".fusion"))) {
381004
381190
  return current;
381005
381191
  }
381006
381192
  const parent2 = resolve74(current, "..");
@@ -381866,11 +382052,11 @@ var init_migration_holding_server = __esm({
381866
382052
  // src/commands/ensure-project-registered.ts
381867
382053
  import { exec as exec48 } from "node:child_process";
381868
382054
  import { existsSync as existsSync90, mkdirSync as mkdirSync17 } from "node:fs";
381869
- import { basename as basename38, join as join130 } from "node:path";
382055
+ import { basename as basename38, join as join131 } from "node:path";
381870
382056
  import { promisify as promisify73 } from "node:util";
381871
382057
  function stampProjectIdentityBestEffort(cwd, project, logPrefix) {
381872
382058
  try {
381873
- writeProjectIdentity(join130(cwd, ".fusion"), {
382059
+ writeProjectIdentity(join131(cwd, ".fusion"), {
381874
382060
  id: project.id,
381875
382061
  createdAt: project.createdAt
381876
382062
  });
@@ -381892,7 +382078,7 @@ async function ensureCwdProjectRegistered(options) {
381892
382078
  return null;
381893
382079
  }
381894
382080
  try {
381895
- const fusionDir = join130(cwd, ".fusion");
382081
+ const fusionDir = join131(cwd, ".fusion");
381896
382082
  if (!existsSync90(fusionDir)) {
381897
382083
  mkdirSync17(fusionDir, { recursive: true });
381898
382084
  }
@@ -381923,7 +382109,7 @@ async function ensureCwdProjectRegistered(options) {
381923
382109
  }
381924
382110
  }
381925
382111
  async function detectProjectName(dir2) {
381926
- if (!existsSync90(join130(dir2, ".git"))) {
382112
+ if (!existsSync90(join131(dir2, ".git"))) {
381927
382113
  return basename38(dir2) || "my-project";
381928
382114
  }
381929
382115
  try {
@@ -381956,12 +382142,12 @@ var init_ensure_project_registered = __esm({
381956
382142
 
381957
382143
  // src/commands/provider-settings.ts
381958
382144
  import { existsSync as existsSync91, readFileSync as readFileSync33, writeFileSync as writeFileSync19, mkdirSync as mkdirSync18 } from "node:fs";
381959
- import { join as join131, dirname as dirname59, basename as basename39 } from "node:path";
382145
+ import { join as join132, dirname as dirname59, basename as basename39 } from "node:path";
381960
382146
  function siblingAgentDir2(agentDir, siblingRoot) {
381961
382147
  if (basename39(agentDir) !== "agent") {
381962
382148
  return void 0;
381963
382149
  }
381964
- return join131(dirname59(dirname59(agentDir)), siblingRoot, "agent");
382150
+ return join132(dirname59(dirname59(agentDir)), siblingRoot, "agent");
381965
382151
  }
381966
382152
  function readJsonObject4(path14) {
381967
382153
  if (!existsSync91(path14)) {
@@ -381975,13 +382161,13 @@ function readJsonObject4(path14) {
381975
382161
  }
381976
382162
  }
381977
382163
  function createReadOnlyProviderSettingsView(cwd, agentDir) {
381978
- const fusionAgentDir = agentDir.includes(`${join131(".fusion", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".fusion");
381979
- const legacyAgentDir = agentDir.includes(`${join131(".pi", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".pi");
381980
- const legacyGlobalSettings = legacyAgentDir ? readJsonObject4(join131(legacyAgentDir, "settings.json")) : {};
381981
- const fusionGlobalSettings = fusionAgentDir ? readJsonObject4(join131(fusionAgentDir, "settings.json")) : {};
381982
- const directGlobalSettings = readJsonObject4(join131(agentDir, "settings.json"));
382164
+ const fusionAgentDir = agentDir.includes(`${join132(".fusion", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".fusion");
382165
+ const legacyAgentDir = agentDir.includes(`${join132(".pi", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".pi");
382166
+ const legacyGlobalSettings = legacyAgentDir ? readJsonObject4(join132(legacyAgentDir, "settings.json")) : {};
382167
+ const fusionGlobalSettings = fusionAgentDir ? readJsonObject4(join132(fusionAgentDir, "settings.json")) : {};
382168
+ const directGlobalSettings = readJsonObject4(join132(agentDir, "settings.json"));
381983
382169
  const globalSettings = { ...legacyGlobalSettings, ...directGlobalSettings, ...fusionGlobalSettings };
381984
- const fusionProjectSettings = readJsonObject4(join131(cwd, ".fusion", "settings.json"));
382170
+ const fusionProjectSettings = readJsonObject4(join132(cwd, ".fusion", "settings.json"));
381985
382171
  const mergedSettings = { ...globalSettings, ...fusionProjectSettings };
381986
382172
  return {
381987
382173
  getGlobalSettings: () => structuredClone(globalSettings),
@@ -382010,20 +382196,20 @@ var init_provider_auth2 = __esm({
382010
382196
  // src/commands/auth-paths.ts
382011
382197
  import { homedir as homedir19 } from "node:os";
382012
382198
  import { existsSync as existsSync92, readFileSync as readFileSync34 } from "node:fs";
382013
- import { join as join132 } from "node:path";
382199
+ import { join as join133 } from "node:path";
382014
382200
  function getFusionAgentDir2(home = process.env.HOME || process.env.USERPROFILE || homedir19()) {
382015
- return join132(home, ".fusion", "agent");
382201
+ return join133(home, ".fusion", "agent");
382016
382202
  }
382017
382203
  function getLegacyAgentDir(home = process.env.HOME || process.env.USERPROFILE || homedir19()) {
382018
- return join132(home, ".pi", "agent");
382204
+ return join133(home, ".pi", "agent");
382019
382205
  }
382020
382206
  function getFusionModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir19()) {
382021
- return join132(getFusionAgentDir2(home), "models.json");
382207
+ return join133(getFusionAgentDir2(home), "models.json");
382022
382208
  }
382023
382209
  function getLegacyModelsPaths2(home = process.env.HOME || process.env.USERPROFILE || homedir19()) {
382024
382210
  return [
382025
- join132(home, ".pi", "agent", "models.json"),
382026
- join132(home, ".pi", "models.json")
382211
+ join133(home, ".pi", "agent", "models.json"),
382212
+ join133(home, ".pi", "models.json")
382027
382213
  ];
382028
382214
  }
382029
382215
  function getModelRegistryModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir19()) {
@@ -382050,8 +382236,8 @@ function hasPackageManagerSettings3(settings) {
382050
382236
  function getPackageManagerAgentDir2(home = process.env.HOME || process.env.USERPROFILE || homedir19()) {
382051
382237
  const fusionAgentDir = getFusionAgentDir2(home);
382052
382238
  const legacyAgentDir = getLegacyAgentDir(home);
382053
- const fusionSettings = readJsonObject5(join132(fusionAgentDir, "settings.json"));
382054
- const legacySettings = readJsonObject5(join132(legacyAgentDir, "settings.json"));
382239
+ const fusionSettings = readJsonObject5(join133(fusionAgentDir, "settings.json"));
382240
+ const legacySettings = readJsonObject5(join133(legacyAgentDir, "settings.json"));
382055
382241
  if (hasPackageManagerSettings3(fusionSettings) || !existsSync92(legacyAgentDir)) {
382056
382242
  return fusionAgentDir;
382057
382243
  }
@@ -382308,7 +382494,7 @@ import {
382308
382494
  symlinkSync as symlinkSync6,
382309
382495
  unlinkSync as unlinkSync7
382310
382496
  } from "node:fs";
382311
- import { dirname as dirname61, join as join133, resolve as resolve76 } from "node:path";
382497
+ import { dirname as dirname61, join as join134, resolve as resolve76 } from "node:path";
382312
382498
  import { fileURLToPath as fileURLToPath19 } from "node:url";
382313
382499
  function isPiClaudeCliConfigured(globalSettings) {
382314
382500
  if (!globalSettings || typeof globalSettings !== "object") {
@@ -382332,7 +382518,7 @@ function resolveFusionSkillSource() {
382332
382518
  return existsSync93(candidate) ? candidate : null;
382333
382519
  }
382334
382520
  function installFusionSkillIntoProject(projectPath, options = {}) {
382335
- const target = join133(projectPath, ".claude", "skills", FUSION_SKILL_NAME4);
382521
+ const target = join134(projectPath, ".claude", "skills", FUSION_SKILL_NAME4);
382336
382522
  if (options.enabled === false) {
382337
382523
  return { outcome: "skipped", target, reason: "pi-claude-cli not configured" };
382338
382524
  }
@@ -382357,7 +382543,7 @@ function installFusionSkillIntoProject(projectPath, options = {}) {
382357
382543
  unlinkSync7(target);
382358
382544
  replaced = true;
382359
382545
  } else {
382360
- const skillMd = join133(target, "SKILL.md");
382546
+ const skillMd = join134(target, "SKILL.md");
382361
382547
  if (!existsSync93(skillMd)) {
382362
382548
  return {
382363
382549
  outcome: "failed",
@@ -382404,7 +382590,7 @@ function ensureFusionSkillForProjects(projects2, options = { enabled: false }) {
382404
382590
  if (!options.enabled) {
382405
382591
  return projects2.map((p2) => ({
382406
382592
  outcome: "skipped",
382407
- target: join133(p2.path, ".claude", "skills", FUSION_SKILL_NAME4),
382593
+ target: join134(p2.path, ".claude", "skills", FUSION_SKILL_NAME4),
382408
382594
  reason: "pi-claude-cli not configured"
382409
382595
  }));
382410
382596
  }
@@ -382797,10 +382983,10 @@ var init_llama_cpp_extension = __esm({
382797
382983
 
382798
382984
  // src/update-cache.ts
382799
382985
  import { readFileSync as readFileSync38 } from "node:fs";
382800
- import { join as join134 } from "node:path";
382986
+ import { join as join135 } from "node:path";
382801
382987
  function getCachedUpdateStatus(currentVersion) {
382802
382988
  try {
382803
- const cachePath = join134(resolveGlobalDir(), "update-check.json");
382989
+ const cachePath = join135(resolveGlobalDir(), "update-check.json");
382804
382990
  const raw = readFileSync38(cachePath, "utf-8");
382805
382991
  const parsed = JSON.parse(raw);
382806
382992
  if (parsed.updateAvailable === true && typeof parsed.latestVersion === "string" && parsed.latestVersion.length > 0 && typeof parsed.currentVersion === "string" && parsed.currentVersion.length > 0) {
@@ -382906,7 +383092,7 @@ var init_self_extension = __esm({
382906
383092
  });
382907
383093
 
382908
383094
  // src/plugins/bundled-plugin-install.ts
382909
- import { dirname as dirname66, join as join135, resolve as resolve81 } from "node:path";
383095
+ import { dirname as dirname66, join as join136, resolve as resolve81 } from "node:path";
382910
383096
  import { fileURLToPath as fileURLToPath24 } from "node:url";
382911
383097
  function getCandidatePluginDirs(pluginId) {
382912
383098
  const moduleDir = dirname66(fileURLToPath24(import.meta.url));
@@ -382914,13 +383100,13 @@ function getCandidatePluginDirs(pluginId) {
382914
383100
  return [
382915
383101
  // Bundled/global runtime: moduleDir is typically <cli>/dist, and plugins are
382916
383102
  // staged under <cli>/dist/plugins/<id>. Keep first for the global-install regression.
382917
- join135(moduleDir, "plugins", pluginId),
383103
+ join136(moduleDir, "plugins", pluginId),
382918
383104
  // Source checkout: prefer the live workspace plugin (freshness-checked by
382919
383105
  // resolvePluginEntryPath) over the stale staged tsup bundle below.
382920
- join135(cliPackageRoot, "..", "..", "plugins", pluginId),
383106
+ join136(cliPackageRoot, "..", "..", "plugins", pluginId),
382921
383107
  // Source/dev fallbacks.
382922
- join135(cliPackageRoot, "dist", "plugins", pluginId),
382923
- join135(cliPackageRoot, "plugins", pluginId)
383108
+ join136(cliPackageRoot, "dist", "plugins", pluginId),
383109
+ join136(cliPackageRoot, "plugins", pluginId)
382924
383110
  ];
382925
383111
  }
382926
383112
  async function ensureBundledPluginInstalled2(pluginStore, pluginLoader, pluginId) {
@@ -386972,6 +387158,7 @@ var init_common2 = __esm({
386972
387158
  guardRejected: "This move is not allowed by the workflow.",
386973
387159
  mergeBlocked: "This task is blocked from completing until its merge step finishes.",
386974
387160
  unknownColumn: "That column doesn't exist in this task's workflow.",
387161
+ unplannedForExecution: "This task isn't ready for execution yet \u2014 planning or plan review is still outstanding.",
386975
387162
  workflowMismatch: "Drag can't move a card between workflows. Use the workflow switcher instead."
386976
387163
  }
386977
387164
  },
@@ -387463,6 +387650,7 @@ var init_common3 = __esm({
387463
387650
  guardRejected: "",
387464
387651
  mergeBlocked: "",
387465
387652
  unknownColumn: "",
387653
+ unplannedForExecution: "",
387466
387654
  workflowMismatch: ""
387467
387655
  }
387468
387656
  },
@@ -387954,6 +388142,7 @@ var init_common4 = __esm({
387954
388142
  guardRejected: "",
387955
388143
  mergeBlocked: "",
387956
388144
  unknownColumn: "",
388145
+ unplannedForExecution: "",
387957
388146
  workflowMismatch: ""
387958
388147
  }
387959
388148
  },
@@ -388445,6 +388634,7 @@ var init_common5 = __esm({
388445
388634
  guardRejected: "",
388446
388635
  mergeBlocked: "",
388447
388636
  unknownColumn: "",
388637
+ unplannedForExecution: "",
388448
388638
  workflowMismatch: ""
388449
388639
  }
388450
388640
  },
@@ -388936,6 +389126,7 @@ var init_common6 = __esm({
388936
389126
  guardRejected: "",
388937
389127
  mergeBlocked: "",
388938
389128
  unknownColumn: "",
389129
+ unplannedForExecution: "",
388939
389130
  workflowMismatch: ""
388940
389131
  }
388941
389132
  },
@@ -389427,6 +389618,7 @@ var init_common7 = __esm({
389427
389618
  guardRejected: "",
389428
389619
  mergeBlocked: "",
389429
389620
  unknownColumn: "",
389621
+ unplannedForExecution: "",
389430
389622
  workflowMismatch: ""
389431
389623
  }
389432
389624
  },
@@ -391344,7 +391536,7 @@ __export(dashboard_exports, {
391344
391536
  runDashboardSupervised: () => runDashboardSupervised,
391345
391537
  shouldSuperviseDashboard: () => shouldSuperviseDashboard
391346
391538
  });
391347
- import { join as join136, resolve as pathResolve2 } from "node:path";
391539
+ import { join as join137, resolve as pathResolve2 } from "node:path";
391348
391540
  import { execFile as execFileCb, spawn as spawn31 } from "node:child_process";
391349
391541
  import { promisify as promisify74 } from "node:util";
391350
391542
  import { stat as stat18, readdir as readdir16, readFile as fsReadFile4 } from "node:fs/promises";
@@ -391686,7 +391878,7 @@ async function buildFileListDirectory(projectPath, relativePath) {
391686
391878
  let size2 = 0;
391687
391879
  let modifiedAt = (/* @__PURE__ */ new Date(0)).toISOString();
391688
391880
  try {
391689
- const s3 = await stat18(join136(absDir, d.name));
391881
+ const s3 = await stat18(join137(absDir, d.name));
391690
391882
  size2 = d.isDirectory() ? 0 : s3.size;
391691
391883
  modifiedAt = s3.mtime.toISOString();
391692
391884
  } catch {
@@ -392374,7 +392566,7 @@ async function runDashboard(port, opts = {}) {
392374
392566
  ...llamaCppPaths
392375
392567
  ],
392376
392568
  cwd,
392377
- join136(cwd, ".fusion", "disabled-auto-extension-discovery")
392569
+ join137(cwd, ".fusion", "disabled-auto-extension-discovery")
392378
392570
  ), logPhase);
392379
392571
  for (const { path: path14, error: error3 } of extensionsResult.errors) {
392380
392572
  logSink.log(`Failed to load ${path14}: ${error3}`, "extensions");
@@ -393642,9 +393834,9 @@ function resolveFusionSourceWorkspaceRoot() {
393642
393834
  try {
393643
393835
  let dir2 = pathResolve2(fileURLToPath25(import.meta.url), "..");
393644
393836
  for (let i = 0; i < 10; i++) {
393645
- if (existsSync98(join136(dir2, "pnpm-workspace.yaml"))) {
393837
+ if (existsSync98(join137(dir2, "pnpm-workspace.yaml"))) {
393646
393838
  try {
393647
- const pkg = JSON.parse(readFileSync40(join136(dir2, "package.json"), "utf8"));
393839
+ const pkg = JSON.parse(readFileSync40(join137(dir2, "package.json"), "utf8"));
393648
393840
  return pkg?.name === "fusion-workspace" ? dir2 : void 0;
393649
393841
  } catch {
393650
393842
  return void 0;
@@ -394349,7 +394541,7 @@ var serve_exports = {};
394349
394541
  __export(serve_exports, {
394350
394542
  runServe: () => runServe
394351
394543
  });
394352
- import { join as join137, resolve as pathResolve3 } from "node:path";
394544
+ import { join as join138, resolve as pathResolve3 } from "node:path";
394353
394545
  import {
394354
394546
  DefaultPackageManager as DefaultPackageManager3,
394355
394547
  discoverAndLoadExtensions as discoverAndLoadExtensions3,
@@ -394809,7 +395001,7 @@ async function runServe(port, opts = {}) {
394809
395001
  ...llamaCppPaths
394810
395002
  ],
394811
395003
  primaryCwd,
394812
- join137(primaryCwd, ".fusion", "disabled-auto-extension-discovery")
395004
+ join138(primaryCwd, ".fusion", "disabled-auto-extension-discovery")
394813
395005
  );
394814
395006
  for (const { path: path14, error: error3 } of extensionsResult.errors) {
394815
395007
  console.log(`[extensions] Failed to load ${path14}: ${error3}`);
@@ -395234,7 +395426,7 @@ var daemon_exports = {};
395234
395426
  __export(daemon_exports, {
395235
395427
  runDaemon: () => runDaemon
395236
395428
  });
395237
- import { join as join138, resolve as pathResolve4 } from "node:path";
395429
+ import { join as join139, resolve as pathResolve4 } from "node:path";
395238
395430
  import {
395239
395431
  DefaultPackageManager as DefaultPackageManager4,
395240
395432
  discoverAndLoadExtensions as discoverAndLoadExtensions4,
@@ -395658,7 +395850,7 @@ async function runDaemon(opts = {}) {
395658
395850
  const extensionsResult = await discoverAndLoadExtensions4(
395659
395851
  [...reconciledExtensionPaths, ...droidCliPaths, ...llamaCppPaths],
395660
395852
  primaryCwd,
395661
- join138(primaryCwd, ".fusion", "disabled-auto-extension-discovery")
395853
+ join139(primaryCwd, ".fusion", "disabled-auto-extension-discovery")
395662
395854
  );
395663
395855
  for (const { path: path14, error: error3 } of extensionsResult.errors) {
395664
395856
  console.log(`[extensions] Failed to load ${path14}: ${error3}`);
@@ -396005,7 +396197,7 @@ __export(desktop_exports, {
396005
396197
  import { spawn as spawn32 } from "node:child_process";
396006
396198
  import { once as once2 } from "node:events";
396007
396199
  import { existsSync as existsSync99 } from "node:fs";
396008
- import { dirname as dirname67, isAbsolute as isAbsolute34, join as join139, resolve as resolve82 } from "node:path";
396200
+ import { dirname as dirname67, isAbsolute as isAbsolute34, join as join140, resolve as resolve82 } from "node:path";
396009
396201
  import { createRequire as createRequire13 } from "node:module";
396010
396202
  import { fileURLToPath as fileURLToPath26 } from "node:url";
396011
396203
  import * as os14 from "node:os";
@@ -396112,7 +396304,7 @@ function terminateProcess(child, signal = "SIGTERM") {
396112
396304
  child.kill(signal);
396113
396305
  }
396114
396306
  function resolveDevDesktopEntry(rootDir) {
396115
- const desktopEntry = join139(rootDir, "packages", "desktop", "dist", "main.js");
396307
+ const desktopEntry = join140(rootDir, "packages", "desktop", "dist", "main.js");
396116
396308
  if (existsSync99(desktopEntry)) {
396117
396309
  return desktopEntry;
396118
396310
  }
@@ -396749,7 +396941,7 @@ __export(task_exports, {
396749
396941
  });
396750
396942
  import { createInterface as createInterface3 } from "node:readline/promises";
396751
396943
  import { watchFile, unwatchFile, statSync as statSync17, existsSync as existsSync100, readFileSync as readFileSync41 } from "node:fs";
396752
- import { basename as basename41, join as join140 } from "node:path";
396944
+ import { basename as basename41, join as join141 } from "node:path";
396753
396945
  function columnLabel2(column) {
396754
396946
  return COLUMN_LABELS[column] ?? column;
396755
396947
  }
@@ -397107,7 +397299,7 @@ async function runTaskCreate(descriptionArg, attachFiles, depends, projectName,
397107
397299
  }
397108
397300
  console.log(` Path: .fusion/tasks/${resolvedTask.id}/`);
397109
397301
  if (attachFiles && attachFiles.length > 0) {
397110
- const { readFile: readFile63 } = await import("node:fs/promises");
397302
+ const { readFile: readFile64 } = await import("node:fs/promises");
397111
397303
  const { basename: basename46, extname: extname7, resolve: resolve103 } = await import("node:path");
397112
397304
  for (const filePath of attachFiles) {
397113
397305
  const resolvedPath = resolve103(filePath);
@@ -397120,7 +397312,7 @@ async function runTaskCreate(descriptionArg, attachFiles, depends, projectName,
397120
397312
  }
397121
397313
  let content;
397122
397314
  try {
397123
- content = await readFile63(resolvedPath);
397315
+ content = await readFile64(resolvedPath);
397124
397316
  } catch {
397125
397317
  console.error(` \u2717 Cannot read file: ${filePath}`);
397126
397318
  continue;
@@ -397291,7 +397483,7 @@ async function runTaskLogs(id, options = {}, projectName) {
397291
397483
  printEntries(filteredEntries);
397292
397484
  if (options.follow) {
397293
397485
  const projectPath = context.projectPath ?? process.cwd();
397294
- const logPath = join140(projectPath, ".fusion", "tasks", id, "agent.log");
397486
+ const logPath = join141(projectPath, ".fusion", "tasks", id, "agent.log");
397295
397487
  if (!existsSync100(logPath)) {
397296
397488
  console.log(`
397297
397489
  Waiting for log file to be created...`);
@@ -397496,7 +397688,7 @@ async function runTaskMerge(id, projectName) {
397496
397688
  }
397497
397689
  }
397498
397690
  async function runTaskAttach(id, filePath, projectName) {
397499
- const { readFile: readFile63 } = await import("node:fs/promises");
397691
+ const { readFile: readFile64 } = await import("node:fs/promises");
397500
397692
  const { basename: basename46, extname: extname7 } = await import("node:path");
397501
397693
  const { resolve: resolve103 } = await import("node:path");
397502
397694
  const resolvedPath = resolve103(filePath);
@@ -397510,7 +397702,7 @@ async function runTaskAttach(id, filePath, projectName) {
397510
397702
  }
397511
397703
  let content;
397512
397704
  try {
397513
- content = await readFile63(resolvedPath);
397705
+ content = await readFile64(resolvedPath);
397514
397706
  } catch {
397515
397707
  console.error(`Cannot read file: ${filePath}`);
397516
397708
  process.exit(1);
@@ -398882,7 +399074,7 @@ __export(settings_export_exports, {
398882
399074
  runSettingsExport: () => runSettingsExport
398883
399075
  });
398884
399076
  import { writeFile as writeFile41 } from "node:fs/promises";
398885
- import { resolve as resolve83, join as join141 } from "node:path";
399077
+ import { resolve as resolve83, join as join142 } from "node:path";
398886
399078
  async function runSettingsExport(options = {}) {
398887
399079
  const scope = options.scope ?? "both";
398888
399080
  let project;
@@ -398912,7 +399104,7 @@ async function runSettingsExport(options = {}) {
398912
399104
  targetPath = resolve83(outputPath);
398913
399105
  } else {
398914
399106
  const filename = generateExportFilename();
398915
- targetPath = join141(process.cwd(), filename);
399107
+ targetPath = join142(process.cwd(), filename);
398916
399108
  }
398917
399109
  const jsonContent = JSON.stringify(exportData, null, 2);
398918
399110
  await writeFile41(targetPath, jsonContent);
@@ -399086,7 +399278,7 @@ __export(mcp_exports, {
399086
399278
  runMcpValidate: () => runMcpValidate
399087
399279
  });
399088
399280
  import { existsSync as existsSync102 } from "node:fs";
399089
- import { readFile as readFile57, writeFile as writeFile42 } from "node:fs/promises";
399281
+ import { readFile as readFile58, writeFile as writeFile42 } from "node:fs/promises";
399090
399282
  import { resolve as resolve85 } from "node:path";
399091
399283
  async function createGlobalSettingsStore() {
399092
399284
  const store = new GlobalSettingsStore();
@@ -399424,7 +399616,7 @@ async function runMcpImport(filePath, opts = {}) {
399424
399616
  context = await loadContext(opts.projectName, scope === "project");
399425
399617
  const resolvedPath = resolve85(filePath);
399426
399618
  if (!existsSync102(resolvedPath)) throw new Error(`File not found: ${filePath}`);
399427
- const imported = importMcpServersJson(await readFile57(resolvedPath, "utf-8"), { scope });
399619
+ const imported = importMcpServersJson(await readFile58(resolvedPath, "utf-8"), { scope });
399428
399620
  if (imported.errors.length > 0) throw new Error(`Invalid MCP import file:
399429
399621
  ${imported.errors.map((error3) => ` - ${error3}`).join("\n")}`);
399430
399622
  console.log();
@@ -399541,7 +399733,7 @@ var init_mcp = __esm({
399541
399733
 
399542
399734
  // src/project-resolver.ts
399543
399735
  import { existsSync as existsSync103, statSync as statSync18 } from "node:fs";
399544
- import { basename as basename42, dirname as dirname68, join as join142, normalize as normalize9, resolve as resolve86 } from "node:path";
399736
+ import { basename as basename42, dirname as dirname68, join as join143, normalize as normalize9, resolve as resolve86 } from "node:path";
399545
399737
  import { createInterface as createInterface4 } from "node:readline/promises";
399546
399738
  async function getCentralCore() {
399547
399739
  if (!centralCoreInstance) {
@@ -399655,7 +399847,7 @@ Run \`fn project remove ` + match.name + "` to clean up the registry entry.",
399655
399847
  if (interactive) {
399656
399848
  console.log(`
399657
399849
  Found fn project at ${fusionDir} but it's not registered.`);
399658
- const projectFusionDir = join142(fusionDir, ".fusion");
399850
+ const projectFusionDir = join143(fusionDir, ".fusion");
399659
399851
  const identity = readProjectIdentity(projectFusionDir);
399660
399852
  if (identity) {
399661
399853
  const recover = await promptConfirm2(
@@ -399900,7 +400092,7 @@ var workflow_exports = {};
399900
400092
  __export(workflow_exports, {
399901
400093
  runWorkflowValidate: () => runWorkflowValidate
399902
400094
  });
399903
- import { readFile as readFile58 } from "node:fs/promises";
400095
+ import { readFile as readFile59 } from "node:fs/promises";
399904
400096
  import { resolve as resolve87 } from "node:path";
399905
400097
  async function resolveStore(projectName) {
399906
400098
  try {
@@ -399939,7 +400131,7 @@ async function runWorkflowValidate(opts) {
399939
400131
  if (opts.file) {
399940
400132
  const filePath = resolve87(opts.file);
399941
400133
  try {
399942
- ir2 = JSON.parse(await readFile58(filePath, "utf8"));
400134
+ ir2 = JSON.parse(await readFile59(filePath, "utf8"));
399943
400135
  } catch (error3) {
399944
400136
  const message = `Failed to read or parse workflow IR file '${opts.file}': ${error3 instanceof Error ? error3.message : String(error3)}`;
399945
400137
  if (opts.json) return await exitWithStore({ valid: false, error: message }, 2);
@@ -400759,7 +400951,7 @@ __export(db_exports, {
400759
400951
  });
400760
400952
  import { existsSync as existsSync104 } from "node:fs";
400761
400953
  import { copyFile as copyFile3, mkdir as mkdir41 } from "node:fs/promises";
400762
- import { join as join143 } from "node:path";
400954
+ import { join as join144 } from "node:path";
400763
400955
  function formatBytes9(bytes) {
400764
400956
  if (bytes <= 0) return "0 B";
400765
400957
  const units = ["B", "KB", "MB", "GB"];
@@ -400835,7 +401027,7 @@ async function runDbMigrate(projectName, opts = {}) {
400835
401027
  } catch {
400836
401028
  projectRoot = process.cwd();
400837
401029
  }
400838
- const fusionDir = join143(projectRoot, ".fusion");
401030
+ const fusionDir = join144(projectRoot, ".fusion");
400839
401031
  const globalDir = resolveGlobalDir();
400840
401032
  const sources = defaultMigrationSources(fusionDir, globalDir);
400841
401033
  const presentSources = sources.filter((s3) => existsSync104(s3.sqlitePath));
@@ -400962,11 +401154,11 @@ function describeBackendSafe(backend) {
400962
401154
  }
400963
401155
  async function createPreMigrationBackup(fusionDir, globalDir, sources) {
400964
401156
  const ts2 = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").replace("T", "_").slice(0, 19);
400965
- const backupDir = join143(globalDir, "migration-backups", `pre-migrate-${ts2}`);
401157
+ const backupDir = join144(globalDir, "migration-backups", `pre-migrate-${ts2}`);
400966
401158
  await mkdir41(backupDir, { recursive: true });
400967
401159
  for (const s3 of sources) {
400968
401160
  if (existsSync104(s3.sqlitePath)) {
400969
- const dest = join143(backupDir, s3.sqlitePath.split("/").pop() ?? "source.db");
401161
+ const dest = join144(backupDir, s3.sqlitePath.split("/").pop() ?? "source.db");
400970
401162
  await copyFile3(s3.sqlitePath, dest);
400971
401163
  }
400972
401164
  }
@@ -401860,7 +402052,7 @@ __export(project_exports2, {
401860
402052
  runProjectSetDefault: () => runProjectSetDefault,
401861
402053
  runProjectShow: () => runProjectShow
401862
402054
  });
401863
- import { resolve as resolve88, isAbsolute as isAbsolute35, relative as relative26, basename as basename43, join as join144 } from "node:path";
402055
+ import { resolve as resolve88, isAbsolute as isAbsolute35, relative as relative26, basename as basename43, join as join145 } from "node:path";
401864
402056
  import { existsSync as existsSync105, statSync as statSync19 } from "node:fs";
401865
402057
  import { createInterface as createInterface8 } from "node:readline/promises";
401866
402058
  function formatDisplayPath(projectPath) {
@@ -402105,7 +402297,7 @@ async function runProjectAdd(name2, path14, options = {}) {
402105
402297
  const project = ensured.project;
402106
402298
  await central.updateProject(project.id, { status: "active" });
402107
402299
  try {
402108
- writeProjectIdentity(join144(absolutePath, ".fusion"), {
402300
+ writeProjectIdentity(join145(absolutePath, ".fusion"), {
402109
402301
  id: project.id,
402110
402302
  createdAt: project.createdAt
402111
402303
  });
@@ -402348,13 +402540,13 @@ var init_project2 = __esm({
402348
402540
  // src/commands/skill-installation.ts
402349
402541
  import { cpSync as cpSync7, existsSync as existsSync106, mkdirSync as mkdirSync20 } from "node:fs";
402350
402542
  import { homedir as homedir20 } from "node:os";
402351
- import { dirname as dirname69, join as join145, resolve as resolve89 } from "node:path";
402543
+ import { dirname as dirname69, join as join146, resolve as resolve89 } from "node:path";
402352
402544
  import { fileURLToPath as fileURLToPath27 } from "node:url";
402353
402545
  function getSupportedSkillInstallTargets(homeDir = process.env.HOME || process.env.USERPROFILE || homedir20()) {
402354
402546
  return [
402355
- { client: "claude", targetDir: join145(homeDir, ".claude", "skills", FUSION_SKILL_NAME5) },
402356
- { client: "codex", targetDir: join145(homeDir, ".codex", "skills", FUSION_SKILL_NAME5) },
402357
- { client: "gemini", targetDir: join145(homeDir, ".gemini", "skills", FUSION_SKILL_NAME5) }
402547
+ { client: "claude", targetDir: join146(homeDir, ".claude", "skills", FUSION_SKILL_NAME5) },
402548
+ { client: "codex", targetDir: join146(homeDir, ".codex", "skills", FUSION_SKILL_NAME5) },
402549
+ { client: "gemini", targetDir: join146(homeDir, ".gemini", "skills", FUSION_SKILL_NAME5) }
402358
402550
  ];
402359
402551
  }
402360
402552
  function resolveBundledFusionSkillSource4() {
@@ -402418,13 +402610,13 @@ __export(init_exports, {
402418
402610
  runInit: () => runInit
402419
402611
  });
402420
402612
  import { existsSync as existsSync107, mkdirSync as mkdirSync21, writeFileSync as writeFileSync20, readFileSync as readFileSync42 } from "node:fs";
402421
- import { join as join146, resolve as resolve90, basename as basename44 } from "node:path";
402613
+ import { join as join147, resolve as resolve90, basename as basename44 } from "node:path";
402422
402614
  import { exec as exec50 } from "node:child_process";
402423
402615
  import { promisify as promisify76 } from "node:util";
402424
402616
  async function runInit(options = {}) {
402425
402617
  const cwd = options.path ? resolve90(options.path) : process.cwd();
402426
- const fusionDir = join146(cwd, ".fusion");
402427
- const dbPath = join146(fusionDir, "fusion.db");
402618
+ const fusionDir = join147(cwd, ".fusion");
402619
+ const dbPath = join147(fusionDir, "fusion.db");
402428
402620
  const hasDbPath = existsSync107(dbPath);
402429
402621
  const hasValidDb = hasDbPath && isValidSqliteDatabaseFile(dbPath);
402430
402622
  const hasIdentity = hasProjectIdentity(fusionDir);
@@ -402434,7 +402626,7 @@ async function runInit(options = {}) {
402434
402626
  const existing = await central2.getProjectByPath(cwd);
402435
402627
  if (existing) {
402436
402628
  try {
402437
- writeProjectIdentity(join146(cwd, ".fusion"), {
402629
+ writeProjectIdentity(join147(cwd, ".fusion"), {
402438
402630
  id: existing.id,
402439
402631
  createdAt: existing.createdAt
402440
402632
  });
@@ -402511,7 +402703,7 @@ async function runInit(options = {}) {
402511
402703
  const project = ensured.project;
402512
402704
  await central.updateProject(project.id, { status: "active" });
402513
402705
  try {
402514
- writeProjectIdentity(join146(cwd, ".fusion"), {
402706
+ writeProjectIdentity(join147(cwd, ".fusion"), {
402515
402707
  id: project.id,
402516
402708
  createdAt: project.createdAt
402517
402709
  });
@@ -402546,7 +402738,7 @@ async function runInit(options = {}) {
402546
402738
  }
402547
402739
  }
402548
402740
  async function detectProjectName2(dir2) {
402549
- if (!existsSync107(join146(dir2, ".git"))) {
402741
+ if (!existsSync107(join147(dir2, ".git"))) {
402550
402742
  return basename44(dir2) || "my-project";
402551
402743
  }
402552
402744
  try {
@@ -402566,7 +402758,7 @@ async function detectProjectName2(dir2) {
402566
402758
  return basename44(dir2) || "my-project";
402567
402759
  }
402568
402760
  async function addLocalStorageToGitignore(cwd) {
402569
- const gitignorePath = join146(cwd, ".gitignore");
402761
+ const gitignorePath = join147(cwd, ".gitignore");
402570
402762
  let content = "";
402571
402763
  if (existsSync107(gitignorePath)) {
402572
402764
  try {
@@ -402609,7 +402801,7 @@ async function initializeGitRepo(cwd) {
402609
402801
  }
402610
402802
  await ensureGitConfig(cwd, "user.name", "Fusion");
402611
402803
  await ensureGitConfig(cwd, "user.email", "noreply@runfusion.ai");
402612
- const gitkeepPath = join146(cwd, ".gitkeep");
402804
+ const gitkeepPath = join147(cwd, ".gitkeep");
402613
402805
  if (!existsSync107(gitkeepPath)) {
402614
402806
  writeFileSync20(gitkeepPath, "\n");
402615
402807
  }
@@ -403539,11 +403731,11 @@ var org_import_exports = {};
403539
403731
  __export(org_import_exports, {
403540
403732
  runOrgImport: () => runOrgImport
403541
403733
  });
403542
- import { readFile as readFile59 } from "node:fs/promises";
403734
+ import { readFile as readFile60 } from "node:fs/promises";
403543
403735
  import { resolve as resolve94 } from "node:path";
403544
403736
  async function runOrgImport(file, options = {}) {
403545
403737
  const rootDir = options.project ? await resolveProjectPathOnly(options.project) : process.cwd();
403546
- const bundle = JSON.parse(await readFile59(resolve94(file), "utf8"));
403738
+ const bundle = JSON.parse(await readFile60(resolve94(file), "utf8"));
403547
403739
  const boot = await createTaskStoreForBackend({ rootDir });
403548
403740
  const agents2 = new AgentStore({ rootDir: `${rootDir}/.fusion`, asyncLayer: boot.taskStore.asyncLayer });
403549
403741
  try {
@@ -404157,8 +404349,8 @@ __export(plugin_exports2, {
404157
404349
  runPluginUninstall: () => runPluginUninstall
404158
404350
  });
404159
404351
  import { existsSync as existsSync110 } from "node:fs";
404160
- import { dirname as dirname71, extname as extname6, join as join147, resolve as resolve95 } from "node:path";
404161
- import { readFile as readFile60, stat as stat19 } from "node:fs/promises";
404352
+ import { dirname as dirname71, extname as extname6, join as join148, resolve as resolve95 } from "node:path";
404353
+ import { readFile as readFile61, stat as stat19 } from "node:fs/promises";
404162
404354
  import * as readline from "node:readline";
404163
404355
  async function getProjectPath(projectName) {
404164
404356
  if (projectName) {
@@ -404249,10 +404441,10 @@ async function resolvePluginEntryFile(pluginDir) {
404249
404441
  }
404250
404442
  throw new Error(`Plugin entry file must end with .js, .mjs, or .cjs: ${absoluteInputPath}`);
404251
404443
  }
404252
- const packageJsonPath = join147(absoluteInputPath, "package.json");
404444
+ const packageJsonPath = join148(absoluteInputPath, "package.json");
404253
404445
  let selectedCandidate;
404254
404446
  if (existsSync110(packageJsonPath)) {
404255
- const packageJson = JSON.parse(await readFile60(packageJsonPath, "utf-8"));
404447
+ const packageJson = JSON.parse(await readFile61(packageJsonPath, "utf-8"));
404256
404448
  const exportsRecord = asRecord6(packageJson.exports);
404257
404449
  const dotExport = exportsRecord?.["."];
404258
404450
  const dotExportRecord = asRecord6(dotExport);
@@ -404299,11 +404491,11 @@ async function loadManifestFromPath(pluginPath) {
404299
404491
  const absoluteInputPath = resolve95(pluginPath);
404300
404492
  const inputStats = await statPath(absoluteInputPath);
404301
404493
  const manifestDir = inputStats?.isFile() ? dirname71(absoluteInputPath) : absoluteInputPath;
404302
- const manifestPath = join147(manifestDir, "manifest.json");
404494
+ const manifestPath = join148(manifestDir, "manifest.json");
404303
404495
  if (!existsSync110(manifestPath)) {
404304
404496
  throw new Error(`Plugin manifest not found at: ${manifestPath}`);
404305
404497
  }
404306
- const content = await readFile60(manifestPath, "utf-8");
404498
+ const content = await readFile61(manifestPath, "utf-8");
404307
404499
  const manifest = JSON.parse(content);
404308
404500
  const validation = validatePluginManifest(manifest);
404309
404501
  if (!validation.valid) {
@@ -404682,7 +404874,7 @@ __export(plugin_scaffold_exports, {
404682
404874
  runPluginNew: () => runPluginNew
404683
404875
  });
404684
404876
  import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, existsSync as existsSync111, readFileSync as readFileSync45 } from "node:fs";
404685
- import { join as join148, dirname as dirname72, resolve as resolve96 } from "node:path";
404877
+ import { join as join149, dirname as dirname72, resolve as resolve96 } from "node:path";
404686
404878
  import { fileURLToPath as fileURLToPath28 } from "node:url";
404687
404879
  function toTitleCase(str) {
404688
404880
  return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
@@ -405004,16 +405196,16 @@ async function runPluginCreate(name2, options) {
405004
405196
  ensureTargetPathAvailable(targetDir, targetPath);
405005
405197
  try {
405006
405198
  mkdirSync24(targetPath, { recursive: true });
405007
- mkdirSync24(join148(targetPath, "src", "__tests__"), { recursive: true });
405008
- writeFileSync23(join148(targetPath, "package.json"), generatePackageJson(name2));
405009
- writeFileSync23(join148(targetPath, "tsconfig.json"), generateTsconfig());
405010
- writeFileSync23(join148(targetPath, "vitest.config.ts"), generateVitestConfig());
405011
- writeFileSync23(join148(targetPath, "src", "index.ts"), generateIndexTs(name2));
405199
+ mkdirSync24(join149(targetPath, "src", "__tests__"), { recursive: true });
405200
+ writeFileSync23(join149(targetPath, "package.json"), generatePackageJson(name2));
405201
+ writeFileSync23(join149(targetPath, "tsconfig.json"), generateTsconfig());
405202
+ writeFileSync23(join149(targetPath, "vitest.config.ts"), generateVitestConfig());
405203
+ writeFileSync23(join149(targetPath, "src", "index.ts"), generateIndexTs(name2));
405012
405204
  writeFileSync23(
405013
- join148(targetPath, "src", "__tests__", "index.test.ts"),
405205
+ join149(targetPath, "src", "__tests__", "index.test.ts"),
405014
405206
  generateTestTs(name2)
405015
405207
  );
405016
- writeFileSync23(join148(targetPath, "README.md"), generateReadme(name2));
405208
+ writeFileSync23(join149(targetPath, "README.md"), generateReadme(name2));
405017
405209
  } catch (err) {
405018
405210
  console.error(
405019
405211
  `Error creating plugin files: ${err instanceof Error ? err.message : String(err)}`
@@ -405038,14 +405230,14 @@ async function runPluginNew(name2, options) {
405038
405230
  ensureTargetPathAvailable(targetDir, targetPath);
405039
405231
  try {
405040
405232
  mkdirSync24(targetPath, { recursive: true });
405041
- mkdirSync24(join148(targetPath, "src", "__tests__"), { recursive: true });
405042
- writeFileSync23(join148(targetPath, "package.json"), generateStandalonePackageJson(name2, options?.scope));
405043
- writeFileSync23(join148(targetPath, "tsconfig.json"), generateStandaloneTsconfig());
405044
- writeFileSync23(join148(targetPath, "vitest.config.ts"), generateVitestConfig());
405045
- writeFileSync23(join148(targetPath, "manifest.json"), generateManifest(name2));
405046
- writeFileSync23(join148(targetPath, "src", "index.ts"), generateStandaloneIndexTs(name2));
405047
- writeFileSync23(join148(targetPath, "src", "__tests__", "index.test.ts"), generateStandaloneTestTs(name2));
405048
- writeFileSync23(join148(targetPath, "README.md"), generateStandaloneReadme(name2));
405233
+ mkdirSync24(join149(targetPath, "src", "__tests__"), { recursive: true });
405234
+ writeFileSync23(join149(targetPath, "package.json"), generateStandalonePackageJson(name2, options?.scope));
405235
+ writeFileSync23(join149(targetPath, "tsconfig.json"), generateStandaloneTsconfig());
405236
+ writeFileSync23(join149(targetPath, "vitest.config.ts"), generateVitestConfig());
405237
+ writeFileSync23(join149(targetPath, "manifest.json"), generateManifest(name2));
405238
+ writeFileSync23(join149(targetPath, "src", "index.ts"), generateStandaloneIndexTs(name2));
405239
+ writeFileSync23(join149(targetPath, "src", "__tests__", "index.test.ts"), generateStandaloneTestTs(name2));
405240
+ writeFileSync23(join149(targetPath, "README.md"), generateStandaloneReadme(name2));
405049
405241
  } catch (err) {
405050
405242
  console.error(
405051
405243
  `Error creating plugin files: ${err instanceof Error ? err.message : String(err)}`
@@ -405080,7 +405272,7 @@ __export(plugin_dev_exports, {
405080
405272
  runPluginDev: () => runPluginDev
405081
405273
  });
405082
405274
  import { existsSync as existsSync112, watch as watch3 } from "node:fs";
405083
- import { join as join149, resolve as resolve97 } from "node:path";
405275
+ import { join as join150, resolve as resolve97 } from "node:path";
405084
405276
  async function runSupervisedCommand(command, cwd, timeoutMs = 12e4) {
405085
405277
  await new Promise((resolvePromise, rejectPromise) => {
405086
405278
  const child = superviseSpawn(command, [], {
@@ -405125,7 +405317,7 @@ async function defaultBuildFn(pluginDir) {
405125
405317
  await runSupervisedCommand("npm run build", pluginDir);
405126
405318
  }
405127
405319
  function defaultWatchFn(pluginDir, onChange) {
405128
- const watchPath = existsSync112(join149(pluginDir, "src")) ? join149(pluginDir, "src") : pluginDir;
405320
+ const watchPath = existsSync112(join150(pluginDir, "src")) ? join150(pluginDir, "src") : pluginDir;
405129
405321
  try {
405130
405322
  const watcher = watch3(watchPath, { recursive: true }, onChange);
405131
405323
  return { close: () => watcher.close() };
@@ -405262,8 +405454,8 @@ __export(plugin_publish_exports, {
405262
405454
  runPluginPublish: () => runPluginPublish
405263
405455
  });
405264
405456
  import { existsSync as existsSync113 } from "node:fs";
405265
- import { readFile as readFile61 } from "node:fs/promises";
405266
- import { join as join150, resolve as resolve98 } from "node:path";
405457
+ import { readFile as readFile62 } from "node:fs/promises";
405458
+ import { join as join151, resolve as resolve98 } from "node:path";
405267
405459
  import { pathToFileURL as pathToFileURL2 } from "node:url";
405268
405460
  function classifyVersionBump(previous, next) {
405269
405461
  const previousMatch = STRICT_SEMVER.exec(previous);
@@ -405288,8 +405480,8 @@ function asRecord7(value) {
405288
405480
  return value && typeof value === "object" ? value : void 0;
405289
405481
  }
405290
405482
  async function readPackageJsonVersion(pluginDir) {
405291
- const packageJsonPath = join150(pluginDir, "package.json");
405292
- const packageJson = JSON.parse(await readFile61(packageJsonPath, "utf-8"));
405483
+ const packageJsonPath = join151(pluginDir, "package.json");
405484
+ const packageJson = JSON.parse(await readFile62(packageJsonPath, "utf-8"));
405293
405485
  return typeof packageJson.version === "string" ? packageJson.version : void 0;
405294
405486
  }
405295
405487
  function collectDeclaredFunctionHooks(value, prefix, checks) {
@@ -405592,7 +405784,7 @@ __export(research_exports, {
405592
405784
  runResearchShow: () => runResearchShow
405593
405785
  });
405594
405786
  import { writeFile as writeFile43 } from "node:fs/promises";
405595
- import { join as join151, resolve as resolve99 } from "node:path";
405787
+ import { join as join152, resolve as resolve99 } from "node:path";
405596
405788
  async function withResolvedStore(projectName, fn2) {
405597
405789
  const owned = await getStore2(projectName);
405598
405790
  try {
@@ -405792,7 +405984,7 @@ async function runResearchExport(options) {
405792
405984
  }
405793
405985
  const content = format === "json" ? JSON.stringify(run2, null, 2) : renderMarkdown(run2);
405794
405986
  const ext = format === "json" ? "json" : "md";
405795
- const outputPath = options.output ? resolve99(options.output) : join151(process.cwd(), `research-${run2.id.toLowerCase()}.${ext}`);
405987
+ const outputPath = options.output ? resolve99(options.output) : join152(process.cwd(), `research-${run2.id.toLowerCase()}.${ext}`);
405796
405988
  await writeFile43(outputPath, content, "utf8");
405797
405989
  await retryOnLock(
405798
405990
  async () => store.getResearchStore().createExport(run2.id, format, content),
@@ -405870,7 +406062,7 @@ var experiment_finalize_exports = {};
405870
406062
  __export(experiment_finalize_exports, {
405871
406063
  runExperimentFinalize: () => runExperimentFinalize
405872
406064
  });
405873
- import { readFile as readFile62 } from "node:fs/promises";
406065
+ import { readFile as readFile63 } from "node:fs/promises";
405874
406066
  import { resolve as resolve100 } from "node:path";
405875
406067
  function printJson(payload) {
405876
406068
  result(JSON.stringify(payload, null, 2) + "\n");
@@ -405883,7 +406075,7 @@ function printPlan(plan) {
405883
406075
  }
405884
406076
  }
405885
406077
  async function parsePlanOverride(path14) {
405886
- const content = await readFile62(resolve100(path14), "utf8");
406078
+ const content = await readFile63(resolve100(path14), "utf8");
405887
406079
  return JSON.parse(content);
405888
406080
  }
405889
406081
  async function exitWithError(error3, shutdown) {
@@ -406336,7 +406528,7 @@ __export(onboard_autolaunch_exports, {
406336
406528
  shouldAutoLaunchOnboarding: () => shouldAutoLaunchOnboarding
406337
406529
  });
406338
406530
  import { existsSync as existsSync115 } from "node:fs";
406339
- import { join as join152 } from "node:path";
406531
+ import { join as join153 } from "node:path";
406340
406532
  function shouldAutoLaunchOnboarding(input) {
406341
406533
  const env = input.env ?? process.env;
406342
406534
  if (input.command === "serve" || input.command === "daemon") {
@@ -406403,8 +406595,8 @@ async function maybeAutoLaunchOnboarding(deps) {
406403
406595
  const pathExists4 = deps.pathExists ?? existsSync115;
406404
406596
  const centralDbPath = deps.centralDbPath ?? getDefaultCentralDbPath();
406405
406597
  const cwd = deps.cwd ?? process.cwd();
406406
- const projectMarkerPath = join152(cwd, ".fusion", "project.json");
406407
- const legacyProjectDbPath = join152(cwd, ".fusion", "fusion.db");
406598
+ const projectMarkerPath = join153(cwd, ".fusion", "project.json");
406599
+ const legacyProjectDbPath = join153(cwd, ".fusion", "fusion.db");
406408
406600
  centralDbExists = pathExists4(centralDbPath);
406409
406601
  projectInitialized = deps.projectInitialized ?? (pathExists4(projectMarkerPath) || pathExists4(legacyProjectDbPath));
406410
406602
  } catch (error3) {
@@ -406460,7 +406652,7 @@ __export(native_patch_exports, {
406460
406652
  isTerminalAvailable: () => isTerminalAvailable,
406461
406653
  setupNativeResolution: () => setupNativeResolution
406462
406654
  });
406463
- import { join as join153, basename as basename45, dirname as dirname74 } from "node:path";
406655
+ import { join as join154, basename as basename45, dirname as dirname74 } from "node:path";
406464
406656
  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";
406465
406657
  import { tmpdir as tmpdir22 } from "node:os";
406466
406658
  function findStagedNativeDir2() {
@@ -406468,13 +406660,13 @@ function findStagedNativeDir2() {
406468
406660
  const arch = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "x64" : "unknown";
406469
406661
  const prebuildName = `${platform6}-${arch}`;
406470
406662
  const execDir = dirname74(process.execPath);
406471
- const nextToBinary = join153(execDir, "runtime", prebuildName);
406472
- if (existsSync116(join153(nextToBinary, "pty.node"))) {
406663
+ const nextToBinary = join154(execDir, "runtime", prebuildName);
406664
+ if (existsSync116(join154(nextToBinary, "pty.node"))) {
406473
406665
  return nextToBinary;
406474
406666
  }
406475
406667
  if (process.env.FUSION_RUNTIME_DIR) {
406476
- const envPath = join153(process.env.FUSION_RUNTIME_DIR, prebuildName);
406477
- if (existsSync116(join153(envPath, "pty.node"))) {
406668
+ const envPath = join154(process.env.FUSION_RUNTIME_DIR, prebuildName);
406669
+ if (existsSync116(join154(envPath, "pty.node"))) {
406478
406670
  return envPath;
406479
406671
  }
406480
406672
  }
@@ -406507,17 +406699,17 @@ function setupNativeResolution() {
406507
406699
  process.env.NODE_PTY_SPAWN_HELPER_DIR = nativeDir;
406508
406700
  }
406509
406701
  process.env.FUSION_NATIVE_ASSETS_PATH = nativeDir;
406510
- const tmpRoot = join153(tmpdir22(), `fn-bunfs-${process.pid}`);
406511
- const fnDir = join153(tmpRoot, "fn");
406512
- const prebuildsDir = join153(fnDir, "prebuilds");
406513
- const platformDir = join153(prebuildsDir, basename45(nativeDir));
406702
+ const tmpRoot = join154(tmpdir22(), `fn-bunfs-${process.pid}`);
406703
+ const fnDir = join154(tmpRoot, "fn");
406704
+ const prebuildsDir = join154(fnDir, "prebuilds");
406705
+ const platformDir = join154(prebuildsDir, basename45(nativeDir));
406514
406706
  try {
406515
406707
  cleanupStaleBunfsLinks();
406516
406708
  mkdirSync25(platformDir, { recursive: true });
406517
- const ptyNodeDest = join153(platformDir, "pty.node");
406518
- copyFileSync2(join153(nativeDir, "pty.node"), ptyNodeDest);
406519
- if (existsSync116(join153(nativeDir, "spawn-helper"))) {
406520
- copyFileSync2(join153(nativeDir, "spawn-helper"), join153(platformDir, "spawn-helper"));
406709
+ const ptyNodeDest = join154(platformDir, "pty.node");
406710
+ copyFileSync2(join154(nativeDir, "pty.node"), ptyNodeDest);
406711
+ if (existsSync116(join154(nativeDir, "spawn-helper"))) {
406712
+ copyFileSync2(join154(nativeDir, "spawn-helper"), join154(platformDir, "spawn-helper"));
406521
406713
  }
406522
406714
  process.env.FUSION_FAKE_BUNFS_ROOT = tmpRoot;
406523
406715
  if (process.platform !== "win32") {
@@ -406595,7 +406787,7 @@ var init_native_patch = __esm({
406595
406787
  init_output();
406596
406788
  import { existsSync as existsSync117, mkdtempSync as mkdtempSync5, readFileSync as readFileSync47, symlinkSync as symlinkSync8, writeFileSync as writeFileSync24 } from "node:fs";
406597
406789
  import { createRequire as createRequire14 } from "node:module";
406598
- import { join as join154, dirname as dirname75, resolve as resolve102 } from "node:path";
406790
+ import { join as join155, dirname as dirname75, resolve as resolve102 } from "node:path";
406599
406791
  import { tmpdir as tmpdir23 } from "node:os";
406600
406792
  import { performance as performance4 } from "node:perf_hooks";
406601
406793
  import { Readable as Readable5 } from "node:stream";
@@ -406605,7 +406797,7 @@ function configurePiPackage() {
406605
406797
  if (process.env.PI_PACKAGE_DIR) {
406606
406798
  return;
406607
406799
  }
406608
- const tmp = mkdtempSync5(join154(tmpdir23(), "fn-pkg-"));
406800
+ const tmp = mkdtempSync5(join155(tmpdir23(), "fn-pkg-"));
406609
406801
  let packageJson = {
406610
406802
  name: "pi",
406611
406803
  version: "0.1.0",
@@ -406617,9 +406809,9 @@ function configurePiPackage() {
406617
406809
  const piPackageDir = dirname75(piPackagePath);
406618
406810
  packageJson = JSON.parse(readFileSync47(piPackagePath, "utf-8"));
406619
406811
  for (const entry of ["dist", "docs", "examples", "README.md", "CHANGELOG.md"]) {
406620
- const source = join154(piPackageDir, entry);
406812
+ const source = join155(piPackageDir, entry);
406621
406813
  if (existsSync117(source)) {
406622
- symlinkSync8(source, join154(tmp, entry));
406814
+ symlinkSync8(source, join155(tmp, entry));
406623
406815
  }
406624
406816
  }
406625
406817
  } catch {
@@ -406628,7 +406820,7 @@ function configurePiPackage() {
406628
406820
  ...packageJson.piConfig ?? {},
406629
406821
  configDir: ".fusion"
406630
406822
  };
406631
- writeFileSync24(join154(tmp, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
406823
+ writeFileSync24(join155(tmp, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
406632
406824
  process.env.PI_PACKAGE_DIR = tmp;
406633
406825
  }
406634
406826
  configurePiPackage();
@@ -406657,8 +406849,8 @@ function loadEnvFile(path14) {
406657
406849
  }
406658
406850
  function loadLocalEnv() {
406659
406851
  const cwd = process.cwd();
406660
- loadEnvFile(join154(cwd, ".env"));
406661
- loadEnvFile(join154(cwd, ".env.local"));
406852
+ loadEnvFile(join155(cwd, ".env"));
406853
+ loadEnvFile(join155(cwd, ".env.local"));
406662
406854
  }
406663
406855
  loadLocalEnv();
406664
406856
  async function loadCommandHandlers() {