@runfusion/fusion 0.8.0 → 0.8.1

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 (32) hide show
  1. package/dist/bin.js +809 -533
  2. package/dist/client/assets/{AgentDetailView-C3Xcrxnp.js → AgentDetailView-CLzxf6Z7.js} +1 -1
  3. package/dist/client/assets/{AgentsView-EjE4y4rM.js → AgentsView-CXaYJX_G.js} +3 -3
  4. package/dist/client/assets/{ChatView-DQLvKCYj.js → ChatView-iXxGAaN1.js} +1 -1
  5. package/dist/client/assets/{DevServerView-CX7paFRQ.js → DevServerView-BeXfFkF4.js} +1 -1
  6. package/dist/client/assets/{DirectoryPicker-_cBPx6Nx.js → DirectoryPicker-BMn5fjn9.js} +1 -1
  7. package/dist/client/assets/{DocumentsView-Wz33aYqp.js → DocumentsView-CjrtI3TX.js} +1 -1
  8. package/dist/client/assets/{InsightsView-C7YPnS92.js → InsightsView-BkfQ-TV1.js} +1 -1
  9. package/dist/client/assets/{MemoryView-DKQtFzFQ.js → MemoryView-1G0zWu1i.js} +1 -1
  10. package/dist/client/assets/{NodesView-CI4rUQC4.js → NodesView-Bn_1R73N.js} +1 -1
  11. package/dist/client/assets/{PiExtensionsManager-BFmdKgHZ.js → PiExtensionsManager-CqGOtQnR.js} +1 -1
  12. package/dist/client/assets/{PluginManager-BGQU1IIw.js → PluginManager-CM5QGvSG.js} +1 -1
  13. package/dist/client/assets/{RoadmapsView-Cts3hoIS.js → RoadmapsView-B4VnQP83.js} +1 -1
  14. package/dist/client/assets/{SettingsModal-DvRd0ZOE.js → SettingsModal-BiLA-BeG.js} +4 -4
  15. package/dist/client/assets/{SettingsModal-DXvBGZHf.js → SettingsModal-C3LckzfT.js} +1 -1
  16. package/dist/client/assets/SetupWizardModal-Bk_8HfLm.js +1 -0
  17. package/dist/client/assets/{SkillsView-BXvrHzEZ.js → SkillsView-CRvqF8P1.js} +1 -1
  18. package/dist/client/assets/{TodoView-NZHkv9YQ.js → TodoView-Vzui5Eha.js} +1 -1
  19. package/dist/client/assets/{folder-open-Kh0ScTc5.js → folder-open-CMF89prE.js} +1 -1
  20. package/dist/client/assets/{index-D1gavMG-.js → index-B8kH5y4Q.js} +3 -3
  21. package/dist/client/assets/{index-CWz44REw.css → index-D2fXOwWF.css} +1 -1
  22. package/dist/client/assets/{list-checks-CvoT0bwU.js → list-checks-M95d1uAy.js} +1 -1
  23. package/dist/client/assets/{star-BdfwSLBU.js → star-DHhJD6ow.js} +1 -1
  24. package/dist/client/assets/{upload-Bx8Yk_7Q.js → upload-CEq8jic8.js} +1 -1
  25. package/dist/client/assets/{users-DgVaFEsz.js → users-CUA8Tv-d.js} +1 -1
  26. package/dist/client/index.html +2 -2
  27. package/dist/client/version.json +1 -1
  28. package/dist/extension.js +187 -41
  29. package/dist/pi-claude-cli/package.json +4 -1
  30. package/dist/pi-claude-cli/src/process-manager.ts +1 -1
  31. package/package.json +1 -1
  32. package/dist/client/assets/SetupWizardModal-Y2ewEE8Y.js +0 -1
package/dist/bin.js CHANGED
@@ -2434,7 +2434,7 @@ var init_db = __esm({
2434
2434
  "use strict";
2435
2435
  init_sqlite_adapter();
2436
2436
  init_types();
2437
- SCHEMA_VERSION = 50;
2437
+ SCHEMA_VERSION = 51;
2438
2438
  SCHEMA_SQL = `
2439
2439
  -- Tasks table with JSON columns for nested data
2440
2440
  CREATE TABLE IF NOT EXISTS tasks (
@@ -3967,6 +3967,13 @@ CREATE INDEX IF NOT EXISTS idxTodoItemsSortOrder ON todo_items(listId, sortOrder
3967
3967
  this.addColumnIfMissing("tasks", "effectiveNodeSource", "TEXT");
3968
3968
  });
3969
3969
  }
3970
+ if (version < 51) {
3971
+ this.applyMigration(51, () => {
3972
+ if (this.hasTable("chat_messages")) {
3973
+ this.addColumnIfMissing("chat_messages", "attachments", "TEXT");
3974
+ }
3975
+ });
3976
+ }
3970
3977
  }
3971
3978
  /**
3972
3979
  * Run a single migration step inside a transaction and bump the version.
@@ -6479,9 +6486,9 @@ var init_global_settings = __esm({
6479
6486
  * Serialize operations via promise chain to prevent lost-update races.
6480
6487
  */
6481
6488
  withLock(fn) {
6482
- let resolve36;
6489
+ let resolve37;
6483
6490
  const next = new Promise((r) => {
6484
- resolve36 = r;
6491
+ resolve37 = r;
6485
6492
  });
6486
6493
  const prev = this.lock;
6487
6494
  this.lock = next;
@@ -6489,7 +6496,7 @@ var init_global_settings = __esm({
6489
6496
  try {
6490
6497
  return await fn();
6491
6498
  } finally {
6492
- resolve36();
6499
+ resolve37();
6493
6500
  }
6494
6501
  });
6495
6502
  }
@@ -27785,9 +27792,9 @@ var init_automation_store = __esm({
27785
27792
  */
27786
27793
  withScheduleLock(id, fn) {
27787
27794
  const prev = this.scheduleLocks.get(id) ?? Promise.resolve();
27788
- let resolve36;
27795
+ let resolve37;
27789
27796
  const next = new Promise((r) => {
27790
- resolve36 = r;
27797
+ resolve37 = r;
27791
27798
  });
27792
27799
  this.scheduleLocks.set(id, next);
27793
27800
  return prev.then(async () => {
@@ -27797,7 +27804,7 @@ var init_automation_store = __esm({
27797
27804
  if (this.scheduleLocks.get(id) === next) {
27798
27805
  this.scheduleLocks.delete(id);
27799
27806
  }
27800
- resolve36();
27807
+ resolve37();
27801
27808
  }
27802
27809
  });
27803
27810
  }
@@ -29585,7 +29592,7 @@ var init_project_memory = __esm({
29585
29592
  // ../core/src/run-command.ts
29586
29593
  import { spawn } from "node:child_process";
29587
29594
  function runCommandAsync(command, options = {}) {
29588
- return new Promise((resolve36) => {
29595
+ return new Promise((resolve37) => {
29589
29596
  const maxBuffer = options.maxBuffer ?? DEFAULT_MAX_BUFFER;
29590
29597
  let stdout = "";
29591
29598
  let stderr = "";
@@ -29644,7 +29651,7 @@ function runCommandAsync(command, options = {}) {
29644
29651
  clearTimeout(forceKillTimer);
29645
29652
  forceKillTimer = null;
29646
29653
  }
29647
- resolve36({
29654
+ resolve37({
29648
29655
  stdout,
29649
29656
  stderr,
29650
29657
  exitCode: null,
@@ -29662,7 +29669,7 @@ function runCommandAsync(command, options = {}) {
29662
29669
  }
29663
29670
  signalProcessGroup("SIGTERM");
29664
29671
  scheduleForceKill(NORMAL_CLEANUP_FORCE_KILL_DELAY_MS);
29665
- resolve36({
29672
+ resolve37({
29666
29673
  stdout,
29667
29674
  stderr,
29668
29675
  exitCode: code,
@@ -30812,9 +30819,9 @@ ${outcome}`;
30812
30819
  * lost-update races on the nextId counter.
30813
30820
  */
30814
30821
  withConfigLock(fn) {
30815
- let resolve36;
30822
+ let resolve37;
30816
30823
  const next = new Promise((r) => {
30817
- resolve36 = r;
30824
+ resolve37 = r;
30818
30825
  });
30819
30826
  const prev = this.configLock;
30820
30827
  this.configLock = next;
@@ -30822,7 +30829,7 @@ ${outcome}`;
30822
30829
  try {
30823
30830
  return await fn();
30824
30831
  } finally {
30825
- resolve36();
30832
+ resolve37();
30826
30833
  }
30827
30834
  });
30828
30835
  }
@@ -30832,9 +30839,9 @@ ${outcome}`;
30832
30839
  */
30833
30840
  withTaskLock(id, fn) {
30834
30841
  const prev = this.taskLocks.get(id) ?? Promise.resolve();
30835
- let resolve36;
30842
+ let resolve37;
30836
30843
  const next = new Promise((r) => {
30837
- resolve36 = r;
30844
+ resolve37 = r;
30838
30845
  });
30839
30846
  this.taskLocks.set(id, next);
30840
30847
  return prev.then(async () => {
@@ -30844,7 +30851,7 @@ ${outcome}`;
30844
30851
  if (this.taskLocks.get(id) === next) {
30845
30852
  this.taskLocks.delete(id);
30846
30853
  }
30847
- resolve36();
30854
+ resolve37();
30848
30855
  }
30849
30856
  });
30850
30857
  }
@@ -32502,8 +32509,8 @@ ${task.description}
32502
32509
  if (this.isWatching) this.taskCache.delete(id);
32503
32510
  const dir2 = this.taskDir(id);
32504
32511
  if (existsSync12(dir2)) {
32505
- const { rm: rm5 } = await import("node:fs/promises");
32506
- await rm5(dir2, { recursive: true });
32512
+ const { rm: rm6 } = await import("node:fs/promises");
32513
+ await rm6(dir2, { recursive: true });
32507
32514
  }
32508
32515
  for (const dependentTask of rewrittenDependents) {
32509
32516
  this.emit("task:updated", dependentTask);
@@ -32838,8 +32845,8 @@ ${task.description}
32838
32845
  this.archiveDb.upsert(entry);
32839
32846
  this.db.prepare("DELETE FROM tasks WHERE id = ?").run(id);
32840
32847
  this.db.bumpLastModified();
32841
- const { rm: rm5 } = await import("node:fs/promises");
32842
- await rm5(dir2, { recursive: true, force: true });
32848
+ const { rm: rm6 } = await import("node:fs/promises");
32849
+ await rm6(dir2, { recursive: true, force: true });
32843
32850
  if (this.isWatching) {
32844
32851
  this.taskCache.delete(id);
32845
32852
  }
@@ -32999,7 +33006,7 @@ ${task.description}
32999
33006
  }
33000
33007
  }
33001
33008
  }
33002
- await new Promise((resolve36) => setImmediate(resolve36));
33009
+ await new Promise((resolve37) => setImmediate(resolve37));
33003
33010
  const selectClause = this.getTaskSelectClause(true);
33004
33011
  const changedRows = this.lastPollTime ? this.db.prepare(`SELECT ${selectClause} FROM tasks WHERE updatedAt > ? OR columnMovedAt > ?`).all(this.lastPollTime, this.lastPollTime) : this.db.prepare(`SELECT ${selectClause} FROM tasks`).all();
33005
33012
  this.lastPollTime = (/* @__PURE__ */ new Date()).toISOString();
@@ -33019,7 +33026,7 @@ ${task.description}
33019
33026
  this.emit("task:updated", task);
33020
33027
  }
33021
33028
  if (i > 0 && i % 50 === 0) {
33022
- await new Promise((resolve36) => setImmediate(resolve36));
33029
+ await new Promise((resolve37) => setImmediate(resolve37));
33023
33030
  }
33024
33031
  }
33025
33032
  const elapsed = Date.now() - startTime;
@@ -33802,14 +33809,14 @@ ${task.description}
33802
33809
  if (rows.length === 0) {
33803
33810
  return;
33804
33811
  }
33805
- const { rm: rm5 } = await import("node:fs/promises");
33812
+ const { rm: rm6 } = await import("node:fs/promises");
33806
33813
  for (const row of rows) {
33807
33814
  const task = this.rowToTask(row);
33808
33815
  const archivedAt = task.columnMovedAt ?? task.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
33809
33816
  const entry = await this.taskToArchiveEntry(task, archivedAt);
33810
33817
  this.archiveDb.upsert(entry);
33811
33818
  this.db.prepare("DELETE FROM tasks WHERE id = ?").run(task.id);
33812
- await rm5(this.taskDir(task.id), { recursive: true, force: true });
33819
+ await rm6(this.taskDir(task.id), { recursive: true, force: true });
33813
33820
  if (this.isWatching) {
33814
33821
  this.taskCache.delete(task.id);
33815
33822
  }
@@ -33832,8 +33839,8 @@ ${task.description}
33832
33839
  this.archiveDb.upsert(entry);
33833
33840
  this.db.prepare("DELETE FROM tasks WHERE id = ?").run(task.id);
33834
33841
  this.db.bumpLastModified();
33835
- const { rm: rm5 } = await import("node:fs/promises");
33836
- await rm5(dir2, { recursive: true, force: true });
33842
+ const { rm: rm6 } = await import("node:fs/promises");
33843
+ await rm6(dir2, { recursive: true, force: true });
33837
33844
  if (this.isWatching) {
33838
33845
  this.taskCache.delete(task.id);
33839
33846
  }
@@ -34845,7 +34852,7 @@ function runGh(args, cwd) {
34845
34852
  }
34846
34853
  function runGhAsync(args, cwdOrOptions) {
34847
34854
  const { cwd, signal: externalSignal, timeoutMs = DEFAULT_GH_TIMEOUT_MS } = normalizeRunGhOptions(cwdOrOptions);
34848
- return new Promise((resolve36, reject2) => {
34855
+ return new Promise((resolve37, reject2) => {
34849
34856
  if (externalSignal?.aborted) {
34850
34857
  reject2(makeGhError(`gh command aborted: ${describeAbortReason(externalSignal.reason)}`, "ABORT_ERR"));
34851
34858
  return;
@@ -34896,7 +34903,7 @@ function runGhAsync(args, cwdOrOptions) {
34896
34903
  ghError.stderr = stderr ?? "";
34897
34904
  reject2(ghError);
34898
34905
  } else {
34899
- resolve36(stdout ?? "");
34906
+ resolve37(stdout ?? "");
34900
34907
  }
34901
34908
  }
34902
34909
  );
@@ -35184,9 +35191,9 @@ var init_routine_store = __esm({
35184
35191
  */
35185
35192
  withRoutineLock(id, fn) {
35186
35193
  const prev = this.routineLocks.get(id) ?? Promise.resolve();
35187
- let resolve36;
35194
+ let resolve37;
35188
35195
  const next = new Promise((r) => {
35189
- resolve36 = r;
35196
+ resolve37 = r;
35190
35197
  });
35191
35198
  this.routineLocks.set(id, next);
35192
35199
  return prev.then(async () => {
@@ -35196,7 +35203,7 @@ var init_routine_store = __esm({
35196
35203
  if (this.routineLocks.get(id) === next) {
35197
35204
  this.routineLocks.delete(id);
35198
35205
  }
35199
- resolve36();
35206
+ resolve37();
35200
35207
  }
35201
35208
  });
35202
35209
  }
@@ -35795,13 +35802,13 @@ var init_plugin_loader = __esm({
35795
35802
  * Execute a promise with a timeout.
35796
35803
  */
35797
35804
  withTimeout(promise, ms, timeoutMessage) {
35798
- return new Promise((resolve36, reject2) => {
35805
+ return new Promise((resolve37, reject2) => {
35799
35806
  const timer = setTimeout(() => {
35800
35807
  reject2(new Error(timeoutMessage));
35801
35808
  }, ms);
35802
35809
  promise.then((result) => {
35803
35810
  clearTimeout(timer);
35804
- resolve36(result);
35811
+ resolve37(result);
35805
35812
  }).catch((err) => {
35806
35813
  clearTimeout(timer);
35807
35814
  reject2(err);
@@ -39008,7 +39015,7 @@ var require_get_stream = __commonJS({
39008
39015
  };
39009
39016
  const { maxBuffer } = options;
39010
39017
  let stream;
39011
- await new Promise((resolve36, reject2) => {
39018
+ await new Promise((resolve37, reject2) => {
39012
39019
  const rejectPromise = (error) => {
39013
39020
  if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
39014
39021
  error.bufferedData = stream.getBufferedValue();
@@ -39020,7 +39027,7 @@ var require_get_stream = __commonJS({
39020
39027
  rejectPromise(error);
39021
39028
  return;
39022
39029
  }
39023
- resolve36();
39030
+ resolve37();
39024
39031
  });
39025
39032
  stream.on("data", () => {
39026
39033
  if (stream.getBufferedLength() > maxBuffer) {
@@ -40314,7 +40321,7 @@ var require_extract_zip = __commonJS({
40314
40321
  debug("opening", this.zipPath, "with opts", this.opts);
40315
40322
  this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
40316
40323
  this.canceled = false;
40317
- return new Promise((resolve36, reject2) => {
40324
+ return new Promise((resolve37, reject2) => {
40318
40325
  this.zipfile.on("error", (err) => {
40319
40326
  this.canceled = true;
40320
40327
  reject2(err);
@@ -40323,7 +40330,7 @@ var require_extract_zip = __commonJS({
40323
40330
  this.zipfile.on("close", () => {
40324
40331
  if (!this.canceled) {
40325
40332
  debug("zip extraction complete");
40326
- resolve36();
40333
+ resolve37();
40327
40334
  }
40328
40335
  });
40329
40336
  this.zipfile.on("entry", async (entry) => {
@@ -47773,10 +47780,10 @@ function pushAlias(aliases, value) {
47773
47780
  if (pathRef !== normalized && pathRef.length > 0) {
47774
47781
  aliases.add(pathRef);
47775
47782
  }
47776
- const basename16 = extractPathBasename(value);
47777
- if (basename16) {
47778
- aliases.add(basename16);
47779
- const basenameSlug = slugifyAgentReference(basename16);
47783
+ const basename17 = extractPathBasename(value);
47784
+ if (basename17) {
47785
+ aliases.add(basename17);
47786
+ const basenameSlug = slugifyAgentReference(basename17);
47780
47787
  if (basenameSlug.length > 0) {
47781
47788
  aliases.add(basenameSlug);
47782
47789
  }
@@ -48503,6 +48510,7 @@ var init_chat_store = __esm({
48503
48510
  content: row.content,
48504
48511
  thinkingOutput: row.thinkingOutput ?? null,
48505
48512
  metadata: fromJson(row.metadata) ?? null,
48513
+ attachments: fromJson(row.attachments) ?? void 0,
48506
48514
  createdAt: row.createdAt
48507
48515
  };
48508
48516
  }
@@ -48721,11 +48729,12 @@ var init_chat_store = __esm({
48721
48729
  content: input.content,
48722
48730
  thinkingOutput: input.thinkingOutput ?? null,
48723
48731
  metadata: input.metadata ?? null,
48732
+ attachments: input.attachments,
48724
48733
  createdAt: now
48725
48734
  };
48726
48735
  this.db.prepare(`
48727
- INSERT INTO chat_messages (id, sessionId, role, content, thinkingOutput, metadata, createdAt)
48728
- VALUES (?, ?, ?, ?, ?, ?, ?)
48736
+ INSERT INTO chat_messages (id, sessionId, role, content, thinkingOutput, metadata, attachments, createdAt)
48737
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
48729
48738
  `).run(
48730
48739
  message.id,
48731
48740
  message.sessionId,
@@ -48733,6 +48742,7 @@ var init_chat_store = __esm({
48733
48742
  message.content,
48734
48743
  message.thinkingOutput,
48735
48744
  toJsonNullable(message.metadata),
48745
+ toJsonNullable(message.attachments),
48736
48746
  message.createdAt
48737
48747
  );
48738
48748
  this.db.prepare("UPDATE chat_sessions SET updatedAt = ? WHERE id = ?").run(now, sessionId);
@@ -48740,6 +48750,28 @@ var init_chat_store = __esm({
48740
48750
  this.emit("chat:message:added", message);
48741
48751
  return message;
48742
48752
  }
48753
+ /**
48754
+ * Append a file attachment metadata record to an existing message.
48755
+ */
48756
+ addMessageAttachment(sessionId, messageId, attachment) {
48757
+ const message = this.getMessage(messageId);
48758
+ if (!message || message.sessionId !== sessionId) {
48759
+ throw new Error(`Message ${messageId} not found in session ${sessionId}`);
48760
+ }
48761
+ const updatedAttachments = [...message.attachments ?? [], attachment];
48762
+ this.db.prepare(`
48763
+ UPDATE chat_messages
48764
+ SET attachments = ?
48765
+ WHERE id = ?
48766
+ `).run(toJsonNullable(updatedAttachments), messageId);
48767
+ const updated = this.getMessage(messageId);
48768
+ if (!updated) {
48769
+ throw new Error(`Failed to update message ${messageId}`);
48770
+ }
48771
+ this.db.bumpLastModified();
48772
+ this.emit("chat:message:updated", updated);
48773
+ return updated;
48774
+ }
48743
48775
  /**
48744
48776
  * Get messages for a chat session with optional filtering.
48745
48777
  *
@@ -51040,12 +51072,12 @@ var init_concurrency = __esm({
51040
51072
  this._active++;
51041
51073
  return Promise.resolve();
51042
51074
  }
51043
- return new Promise((resolve36) => {
51075
+ return new Promise((resolve37) => {
51044
51076
  this._waiters.push({
51045
51077
  priority,
51046
51078
  resolve: () => {
51047
51079
  this._active++;
51048
- resolve36();
51080
+ resolve37();
51049
51081
  }
51050
51082
  });
51051
51083
  });
@@ -53466,20 +53498,20 @@ async function withRateLimitRetry(fn, options = {}) {
53466
53498
  throw lastError ?? new Error("withRateLimitRetry: unexpected state");
53467
53499
  }
53468
53500
  function sleep(ms, signal) {
53469
- return new Promise((resolve36, reject2) => {
53501
+ return new Promise((resolve37, reject2) => {
53470
53502
  if (signal?.aborted) {
53471
53503
  reject2(signal.reason ?? new Error("Aborted"));
53472
53504
  return;
53473
53505
  }
53474
- const timer = setTimeout(resolve36, ms);
53506
+ const timer = setTimeout(resolve37, ms);
53475
53507
  if (signal) {
53476
53508
  const onAbort = () => {
53477
53509
  clearTimeout(timer);
53478
53510
  reject2(signal.reason ?? new Error("Aborted"));
53479
53511
  };
53480
53512
  signal.addEventListener("abort", onAbort, { once: true });
53481
- const origResolve = resolve36;
53482
- resolve36 = () => {
53513
+ const origResolve = resolve37;
53514
+ resolve37 = () => {
53483
53515
  signal.removeEventListener("abort", onAbort);
53484
53516
  origResolve();
53485
53517
  };
@@ -53559,9 +53591,9 @@ async function readAttachmentContents(rootDir, taskId, attachments) {
53559
53591
  return { attachmentContents, imageContents };
53560
53592
  }
53561
53593
  const { readFile: readFile24 } = await import("node:fs/promises");
53562
- const { join: join65 } = await import("node:path");
53594
+ const { join: join66 } = await import("node:path");
53563
53595
  for (const att of attachments) {
53564
- const filePath = join65(
53596
+ const filePath = join66(
53565
53597
  rootDir,
53566
53598
  ".fusion",
53567
53599
  "tasks",
@@ -55075,9 +55107,9 @@ Remove or replace these ids and call fn_task_create again.`
55075
55107
  }
55076
55108
  try {
55077
55109
  const { readFile: readFile24 } = await import("node:fs/promises");
55078
- const { join: join65 } = await import("node:path");
55110
+ const { join: join66 } = await import("node:path");
55079
55111
  const promptContent = await readFile24(
55080
- join65(rootDir, promptPath),
55112
+ join66(rootDir, promptPath),
55081
55113
  "utf-8"
55082
55114
  ).catch((err) => {
55083
55115
  const msg = err instanceof Error ? err.message : String(err);
@@ -55446,7 +55478,7 @@ import { existsSync as existsSync21 } from "node:fs";
55446
55478
  import { join as join26 } from "node:path";
55447
55479
  import { Type as Type3 } from "typebox";
55448
55480
  async function execWithProcessGroup(command, options) {
55449
- return new Promise((resolve36, reject2) => {
55481
+ return new Promise((resolve37, reject2) => {
55450
55482
  if (options.signal?.aborted) {
55451
55483
  reject2(Object.assign(
55452
55484
  new Error(`Command aborted before start: ${command}`),
@@ -55539,7 +55571,7 @@ async function execWithProcessGroup(command, options) {
55539
55571
  return;
55540
55572
  }
55541
55573
  if (code === 0) {
55542
- resolve36({ stdout, stderr, bufferOverflow: stdoutOverflow || stderrOverflow });
55574
+ resolve37({ stdout, stderr, bufferOverflow: stdoutOverflow || stderrOverflow });
55543
55575
  return;
55544
55576
  }
55545
55577
  reject2(Object.assign(
@@ -56102,21 +56134,31 @@ ${failureContext.output.slice(0, VERIFICATION_LOG_MAX_CHARS)}
56102
56134
  return false;
56103
56135
  }
56104
56136
  }
56105
- async function amendMergeCommitWithFixes(rootDir, taskId, authorArg) {
56137
+ function resetMergeWithWarn(rootDir, taskId, label) {
56138
+ try {
56139
+ execSync("git reset --merge", { cwd: rootDir, stdio: "pipe" });
56140
+ } catch (err) {
56141
+ const msg = err instanceof Error ? err.message : String(err);
56142
+ mergerLog.warn(`${taskId}: git reset --merge cleanup failed during ${label}: ${msg}`);
56143
+ }
56144
+ }
56145
+ function buildDeterministicMergeMessage(params) {
56146
+ const { taskId, branch, commitLog, includeTaskId } = params;
56147
+ const prefix = includeTaskId ? `feat(${taskId})` : "feat";
56148
+ const subject = `${prefix}: merge ${branch}`;
56149
+ const body = commitLog && commitLog.trim().length > 0 ? commitLog.trim() : `- merge ${branch}`;
56150
+ const escape = (s) => s.replace(/(["\\$`])/g, "\\$1");
56151
+ return {
56152
+ subjectArg: `-m "${escape(subject)}"`,
56153
+ bodyArg: `-m "${escape(body)}"`
56154
+ };
56155
+ }
56156
+ async function commitOrAmendMergeWithFixes(rootDir, taskId, branch, commitLog, includeTaskId, preAttemptHeadSha, authorArg) {
56106
56157
  try {
56107
- const { stdout: stagedFiles } = await execAsync2("git diff --cached --name-only", {
56108
- cwd: rootDir,
56109
- encoding: "utf-8"
56110
- });
56111
56158
  const { stdout: unstagedFiles } = await execAsync2("git diff --name-only", {
56112
56159
  cwd: rootDir,
56113
56160
  encoding: "utf-8"
56114
56161
  });
56115
- const hasChanges = stagedFiles.trim().length > 0 || unstagedFiles.trim().length > 0;
56116
- if (!hasChanges) {
56117
- mergerLog.log(`${taskId}: no changes to amend after verification fix`);
56118
- return false;
56119
- }
56120
56162
  if (unstagedFiles.trim().length > 0) {
56121
56163
  await execAsync2("git add -A", { cwd: rootDir });
56122
56164
  }
@@ -56124,12 +56166,10 @@ async function amendMergeCommitWithFixes(rootDir, taskId, authorArg) {
56124
56166
  cwd: rootDir,
56125
56167
  encoding: "utf-8"
56126
56168
  });
56127
- const gitlinkPaths = [];
56128
56169
  for (const line of staged.split("\n")) {
56129
56170
  const match = line.match(/^:\d{6} 160000 [^\t]+\t(.+)$/);
56130
- if (match) gitlinkPaths.push(match[1]);
56131
- }
56132
- for (const path5 of gitlinkPaths) {
56171
+ if (!match) continue;
56172
+ const path5 = match[1];
56133
56173
  mergerLog.warn(`${taskId}: refusing to stage gitlink "${path5}" (project uses no submodules \u2014 likely a nested worktree). Unstaging.`);
56134
56174
  try {
56135
56175
  await execAsync2(`git reset HEAD -- "${path5}"`, { cwd: rootDir });
@@ -56142,15 +56182,43 @@ async function amendMergeCommitWithFixes(rootDir, taskId, authorArg) {
56142
56182
  cwd: rootDir,
56143
56183
  encoding: "utf-8"
56144
56184
  });
56145
- if (finalStaged.trim().length > 0) {
56146
- await execAsync2(`git commit --amend --no-edit${authorArg}`, { cwd: rootDir });
56147
- mergerLog.log(`${taskId}: amended merge commit with verification fixes`);
56185
+ const hasStaged = finalStaged.trim().length > 0;
56186
+ const { stdout: currentHeadOut } = await execAsync2("git rev-parse HEAD", {
56187
+ cwd: rootDir,
56188
+ encoding: "utf-8"
56189
+ });
56190
+ const currentHead = currentHeadOut.trim();
56191
+ const headMoved = currentHead !== preAttemptHeadSha;
56192
+ if (!hasStaged && !headMoved) {
56193
+ mergerLog.warn(
56194
+ `${taskId}: refusing to record merge \u2014 no commit was created and no changes are staged. This usually means the AI agent never ran git commit and the in-merge fix had nothing to add.`
56195
+ );
56196
+ return false;
56197
+ }
56198
+ const { subjectArg, bodyArg } = buildDeterministicMergeMessage({
56199
+ taskId,
56200
+ branch,
56201
+ commitLog,
56202
+ includeTaskId
56203
+ });
56204
+ const trailerArg = buildTaskIdTrailerArg(taskId);
56205
+ if (!headMoved) {
56206
+ await execAsync2(
56207
+ `git commit ${subjectArg} ${bodyArg}${trailerArg}${authorArg}`,
56208
+ { cwd: rootDir }
56209
+ );
56210
+ mergerLog.log(`${taskId}: created fresh merge commit after verification fix (no prior commit to amend)`);
56148
56211
  return true;
56149
56212
  }
56150
- return false;
56213
+ await execAsync2(
56214
+ `git commit --amend ${subjectArg} ${bodyArg}${trailerArg}${authorArg}`,
56215
+ { cwd: rootDir }
56216
+ );
56217
+ mergerLog.log(`${taskId}: amended merge commit with verification fixes (deterministic message)`);
56218
+ return true;
56151
56219
  } catch (err) {
56152
56220
  const errorMessage = err instanceof Error ? err.message : String(err);
56153
- mergerLog.warn(`${taskId}: failed to amend merge commit: ${errorMessage}`);
56221
+ mergerLog.warn(`${taskId}: failed to finalize merge commit: ${errorMessage}`);
56154
56222
  return false;
56155
56223
  }
56156
56224
  }
@@ -56401,6 +56469,11 @@ function getCommitAuthorArg(settings) {
56401
56469
  const email = settings.commitAuthorEmail || "noreply@runfusion.ai";
56402
56470
  return ` --author="${name} <${email}>"`;
56403
56471
  }
56472
+ function buildSourceIssueRef(sourceIssue) {
56473
+ if (!sourceIssue || sourceIssue.provider !== "github") return "";
56474
+ if (!sourceIssue.repository || !sourceIssue.issueNumber) return "";
56475
+ return `${sourceIssue.repository}#${sourceIssue.issueNumber}`;
56476
+ }
56404
56477
  function buildMergeSystemPrompt(includeTaskId, agentPrompts, authorArg) {
56405
56478
  const commitFormat = includeTaskId ? `\`\`\`
56406
56479
  git commit -m "<type>(<scope>): <summary>" -m "<body>"${authorArg || ""}
@@ -56411,6 +56484,7 @@ Message format:
56411
56484
  - **Scope:** the task ID (e.g., KB-001)
56412
56485
  - **Summary:** one line describing what the squash brings in (imperative mood)
56413
56486
  - **Body:** 2-5 bullet points summarizing the key changes, each starting with "- "
56487
+ - **GitHub reference:** when the prompt includes a source issue reference, add \`Ref: owner/repo#N\` to the commit body
56414
56488
  ${authorArg ? `- **Author:** Always include the --author flag as shown in the example above.` : ""}
56415
56489
 
56416
56490
  Example:
@@ -56428,6 +56502,7 @@ Message format:
56428
56502
  - **Type:** feat, fix, refactor, docs, test, chore
56429
56503
  - **Summary:** one line describing what the squash brings in (imperative mood)
56430
56504
  - **Body:** 2-5 bullet points summarizing the key changes, each starting with "- "
56505
+ - **GitHub reference:** when the prompt includes a source issue reference, add \`Ref: owner/repo#N\` to the commit body
56431
56506
  ${authorArg ? `- **Author:** Always include the --author flag as shown in the example above.` : ""}
56432
56507
  Do NOT include a scope in the commit message type.
56433
56508
 
@@ -56811,6 +56886,7 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
56811
56886
  throw new Error(`Cannot merge ${taskId}: ${mergeBlocker}`);
56812
56887
  }
56813
56888
  const branch = task.branch || `fusion/${taskId.toLowerCase()}`;
56889
+ const sourceIssueRef = buildSourceIssueRef(task.sourceIssue);
56814
56890
  const worktreePath = task.worktree;
56815
56891
  const result = {
56816
56892
  task,
@@ -57114,6 +57190,17 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
57114
57190
  void 0,
57115
57191
  "merger"
57116
57192
  );
57193
+ let preAttemptHeadSha = "";
57194
+ try {
57195
+ const { stdout } = await execAsync2("git rev-parse HEAD", {
57196
+ cwd: rootDir,
57197
+ encoding: "utf-8"
57198
+ });
57199
+ preAttemptHeadSha = stdout.trim();
57200
+ } catch (err) {
57201
+ const msg = err instanceof Error ? err.message : String(err);
57202
+ mergerLog.warn(`${taskId}: failed to capture pre-attempt HEAD (${msg}) \u2014 verification-fix finalizer will fall back to amend`);
57203
+ }
57117
57204
  try {
57118
57205
  const success = await executeMergeAttempt({
57119
57206
  store,
@@ -57123,6 +57210,7 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
57123
57210
  commitLog,
57124
57211
  diffStat,
57125
57212
  includeTaskId,
57213
+ sourceIssueRef,
57126
57214
  smartConflictResolution,
57127
57215
  mergeConflictStrategy,
57128
57216
  attemptNum,
@@ -57231,12 +57319,27 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
57231
57319
  }
57232
57320
  if (fixSuccess) {
57233
57321
  const authorArg = getCommitAuthorArg(settings);
57234
- await amendMergeCommitWithFixes(rootDir, taskId, authorArg);
57322
+ const finalized = await commitOrAmendMergeWithFixes(
57323
+ rootDir,
57324
+ taskId,
57325
+ branch,
57326
+ commitLog,
57327
+ includeTaskId,
57328
+ preAttemptHeadSha,
57329
+ authorArg
57330
+ );
57331
+ if (!finalized) {
57332
+ resetMergeWithWarn(rootDir, taskId, "verification-fix finalize");
57333
+ throw new Error(
57334
+ `${taskId}: verification fix succeeded but no merge commit could be created \u2014 refusing to mark merge complete.`
57335
+ );
57336
+ }
57235
57337
  return true;
57236
57338
  }
57237
57339
  }
57238
57340
  }
57239
57341
  mergerLog.error(`${taskId}: deterministic verification failed \u2014 aborting merge (in-merge fix exhausted or disabled)`);
57342
+ resetMergeWithWarn(rootDir, taskId, "deterministic-verification rollback");
57240
57343
  throw error;
57241
57344
  }
57242
57345
  if (error.message?.includes("Build verification failed")) {
@@ -57307,7 +57410,21 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
57307
57410
  }
57308
57411
  if (fixSuccess) {
57309
57412
  const authorArg = getCommitAuthorArg(settings);
57310
- await amendMergeCommitWithFixes(rootDir, taskId, authorArg);
57413
+ const finalized = await commitOrAmendMergeWithFixes(
57414
+ rootDir,
57415
+ taskId,
57416
+ branch,
57417
+ commitLog,
57418
+ includeTaskId,
57419
+ preAttemptHeadSha,
57420
+ authorArg
57421
+ );
57422
+ if (!finalized) {
57423
+ resetMergeWithWarn(rootDir, taskId, "build-verification fix finalize");
57424
+ throw new Error(
57425
+ `${taskId}: build verification fix succeeded but no merge commit could be created \u2014 refusing to mark merge complete.`
57426
+ );
57427
+ }
57311
57428
  return true;
57312
57429
  }
57313
57430
  }
@@ -57321,10 +57438,11 @@ async function aiMergeTask(store, rootDir, taskId, options = {}) {
57321
57438
  await audit.git({ type: "reset:hard", target: branch, metadata: { purpose: "build-retry" } });
57322
57439
  } catch (err) {
57323
57440
  const msg = err instanceof Error ? err.message : String(err);
57324
- mergerLog.warn(`${taskId}: git reset --merge cleanup failed (build-retry): ${msg}`);
57441
+ mergerLog.warn(`${taskId}: git reset --merge cleanup failed during build-verification rollback (build-retry): ${msg}`);
57325
57442
  }
57326
57443
  return false;
57327
57444
  }
57445
+ resetMergeWithWarn(rootDir, taskId, "build-verification rollback (no retries left)");
57328
57446
  throw error;
57329
57447
  }
57330
57448
  if (error.name === "MergeNonConflictError") {
@@ -57672,6 +57790,7 @@ async function executeMergeAttempt(params, aiTracker) {
57672
57790
  commitLog,
57673
57791
  diffStat,
57674
57792
  includeTaskId,
57793
+ sourceIssueRef,
57675
57794
  smartConflictResolution,
57676
57795
  attemptNum,
57677
57796
  options,
@@ -57862,19 +57981,12 @@ async function executeMergeAttempt(params, aiTracker) {
57862
57981
  simplifiedContext: attemptNum === 2,
57863
57982
  options,
57864
57983
  testCommand,
57865
- buildCommand: buildCommand2
57984
+ buildCommand: buildCommand2,
57985
+ sourceIssueRef
57866
57986
  });
57867
57987
  if (!agentResult.success) {
57868
57988
  const errorMessage = agentResult.error || "Build verification failed";
57869
57989
  await store.logEntry(taskId, "Build verification failed during merge", errorMessage);
57870
- try {
57871
- execSync("git reset --merge", { cwd: rootDir, stdio: "pipe" });
57872
- } catch (resetErr) {
57873
- const msg = resetErr instanceof Error ? resetErr.message : String(resetErr);
57874
- mergerLog.warn(
57875
- `${taskId}: git reset --merge cleanup failed during build-verification rollback (build-verification reset, build-retry): ${msg}`
57876
- );
57877
- }
57878
57990
  throw new Error(`Build verification failed for ${taskId}: ${errorMessage}`);
57879
57991
  }
57880
57992
  if (testCommand || buildCommand2) {
@@ -57890,6 +58002,24 @@ async function executeMergeAttempt(params, aiTracker) {
57890
58002
  options.signal
57891
58003
  );
57892
58004
  }
58005
+ try {
58006
+ const authorArg = getCommitAuthorArg(params.settings);
58007
+ const { subjectArg, bodyArg } = buildDeterministicMergeMessage({
58008
+ taskId,
58009
+ branch,
58010
+ commitLog,
58011
+ includeTaskId
58012
+ });
58013
+ const trailerArg = buildTaskIdTrailerArg(taskId);
58014
+ await execAsync2(
58015
+ `git commit --amend ${subjectArg} ${bodyArg}${trailerArg}${authorArg}`,
58016
+ { cwd: rootDir }
58017
+ );
58018
+ mergerLog.log(`${taskId}: rewrote AI-authored merge commit message with deterministic body`);
58019
+ } catch (err) {
58020
+ const msg = err instanceof Error ? err.message : String(err);
58021
+ mergerLog.warn(`${taskId}: failed to canonicalize merge commit message (${msg}) \u2014 keeping AI-written message`);
58022
+ }
57893
58023
  return true;
57894
58024
  } catch (error) {
57895
58025
  if (error instanceof Error && error.name === "MergeAbortedError") {
@@ -57912,7 +58042,7 @@ async function executeMergeAttempt(params, aiTracker) {
57912
58042
  }
57913
58043
  }
57914
58044
  async function attemptWithSideStrategy(params, side = "theirs", aiTracker) {
57915
- const { rootDir, branch, commitLog, includeTaskId, taskId, store, settings, testCommand, buildCommand: buildCommand2, testSource, buildSource } = params;
58045
+ const { rootDir, branch, commitLog, includeTaskId, sourceIssueRef, taskId, store, settings, testCommand, buildCommand: buildCommand2, testSource, buildSource } = params;
57916
58046
  mergerLog.log(`${taskId}: attempting merge with -X ${side} strategy`);
57917
58047
  try {
57918
58048
  throwIfAborted(params.options.signal, taskId);
@@ -57953,8 +58083,9 @@ async function attemptWithSideStrategy(params, side = "theirs", aiTracker) {
57953
58083
  const fallbackPrefix = includeTaskId ? `feat(${taskId})` : "feat";
57954
58084
  const authorArg = getCommitAuthorArg(settings);
57955
58085
  const trailerArg = buildTaskIdTrailerArg(taskId);
58086
+ const issueRefBodyArg = sourceIssueRef ? ` -m "Ref: ${sourceIssueRef}"` : "";
57956
58087
  await execAsync2(
57957
- `git commit -m "${fallbackPrefix}: merge ${branch} (auto-resolved)" -m "${escapedLog}"${trailerArg}${authorArg}`,
58088
+ `git commit -m "${fallbackPrefix}: merge ${branch} (auto-resolved)" -m "${escapedLog}"${issueRefBodyArg}${trailerArg}${authorArg}`,
57958
58089
  { cwd: rootDir }
57959
58090
  );
57960
58091
  mergerLog.log(`${taskId}: committed with -X ${side} auto-resolution`);
@@ -57991,6 +58122,7 @@ async function runAiAgentForCommit(params) {
57991
58122
  includeTaskId,
57992
58123
  hasConflicts,
57993
58124
  simplifiedContext,
58125
+ sourceIssueRef,
57994
58126
  options,
57995
58127
  testCommand,
57996
58128
  buildCommand: buildCommand2
@@ -58089,7 +58221,8 @@ async function runAiAgentForCommit(params) {
58089
58221
  simplifiedContext,
58090
58222
  testCommand,
58091
58223
  buildCommand: buildCommand2,
58092
- authorArg
58224
+ authorArg,
58225
+ sourceIssueRef
58093
58226
  });
58094
58227
  mergerLog.log(`${taskId}: starting fresh merge agent session`);
58095
58228
  try {
@@ -58121,7 +58254,8 @@ async function runAiAgentForCommit(params) {
58121
58254
  // Also skip detailed context
58122
58255
  testCommand,
58123
58256
  buildCommand: buildCommand2,
58124
- authorArg
58257
+ authorArg,
58258
+ sourceIssueRef
58125
58259
  });
58126
58260
  try {
58127
58261
  await withRateLimitRetry(async () => {
@@ -58163,8 +58297,9 @@ async function runAiAgentForCommit(params) {
58163
58297
  const fallbackPrefix = includeTaskId ? `feat(${taskId})` : "feat";
58164
58298
  const authorArg2 = getCommitAuthorArg(settings);
58165
58299
  const trailerArg = buildTaskIdTrailerArg(taskId);
58300
+ const issueRefBodyArg = sourceIssueRef ? ` -m "Ref: ${sourceIssueRef}"` : "";
58166
58301
  await execAsync2(
58167
- `git commit -m "${fallbackPrefix}: merge ${branch}" -m "${escapedLog}"${trailerArg}${authorArg2}`,
58302
+ `git commit -m "${fallbackPrefix}: merge ${branch}" -m "${escapedLog}"${issueRefBodyArg}${trailerArg}${authorArg2}`,
58168
58303
  { cwd: rootDir }
58169
58304
  );
58170
58305
  } else {
@@ -58187,7 +58322,7 @@ async function runAiAgentForCommit(params) {
58187
58322
  }
58188
58323
  }
58189
58324
  function buildMergePrompt(params) {
58190
- const { taskId, branch, commitLog, diffStat, hasConflicts, simplifiedContext, testCommand, buildCommand: buildCommand2, authorArg } = params;
58325
+ const { taskId, branch, commitLog, diffStat, hasConflicts, simplifiedContext, sourceIssueRef, testCommand, buildCommand: buildCommand2, authorArg } = params;
58191
58326
  const truncatedCommitLog = truncateWithEllipsis(commitLog, MERGE_COMMIT_LOG_MAX_CHARS);
58192
58327
  const truncatedDiffStat = truncateWithEllipsis(diffStat, MERGE_DIFF_STAT_MAX_CHARS);
58193
58328
  const parts = [
@@ -58223,6 +58358,13 @@ function buildMergePrompt(params) {
58223
58358
  `Write and run the \`git commit\` command with a good message summarizing the work.${authorArg ? ` Be sure to include \`${authorArg.trim()}\` in the commit command.` : ""}`
58224
58359
  );
58225
58360
  }
58361
+ if (sourceIssueRef) {
58362
+ parts.push(
58363
+ "",
58364
+ "Include this in the commit message body:",
58365
+ `- Ref: ${sourceIssueRef}`
58366
+ );
58367
+ }
58226
58368
  if (testCommand) {
58227
58369
  parts.push(
58228
58370
  "",
@@ -59398,7 +59540,7 @@ function resolveExecutorModelPair(taskModelProvider, taskModelId, settings) {
59398
59540
  return { provider: void 0, modelId: void 0 };
59399
59541
  }
59400
59542
  function sleep2(ms) {
59401
- return new Promise((resolve36) => setTimeout(resolve36, ms));
59543
+ return new Promise((resolve37) => setTimeout(resolve37, ms));
59402
59544
  }
59403
59545
  var execAsync4, stepExecLog, MAX_STEP_RETRIES, RETRY_DELAYS_MS, NOOP_TASK_STORE, StepSessionExecutor;
59404
59546
  var init_step_session_executor = __esm({
@@ -60146,6 +60288,7 @@ function buildExecutionPrompt(task, rootDir, settings, worktreePath) {
60146
60288
  const reviewMatch = prompt.match(/##\s*Review Level[:\s]*(\d)/);
60147
60289
  const reviewLevel = reviewMatch ? parseInt(reviewMatch[1], 10) : 0;
60148
60290
  const authorArg = settings?.commitAuthorEnabled !== false ? ` --author="${settings?.commitAuthorName || "Fusion"} <${settings?.commitAuthorEmail || "noreply@runfusion.ai"}>"` : "";
60291
+ const sourceIssueRef = task.sourceIssue?.provider === "github" && task.sourceIssue.repository && task.sourceIssue.issueNumber ? `${task.sourceIssue.repository}#${task.sourceIssue.issueNumber}` : "";
60149
60292
  const hasProgress = task.steps.length > 0 && task.steps.some((s) => s.status !== "pending");
60150
60293
  let progressSection = "";
60151
60294
  if (hasProgress) {
@@ -60248,7 +60391,7 @@ ${hasProgress ? `Resume from Step ${task.currentStep}. Do NOT redo completed ste
60248
60391
  Use \`fn_task_update\` to report progress on every step transition.
60249
60392
  Use \`fn_task_log\` for important actions and decisions.
60250
60393
  Use \`fn_task_create\` for truly separate follow-up work, not for fixes required to get tests, build, or typecheck back to green.
60251
- Commit at step boundaries: \`git commit -m "feat(${task.id}): complete Step N \u2014 description"${authorArg}\`
60394
+ Commit at step boundaries: \`git commit -m "feat(${task.id}): complete Step N \u2014 description"${sourceIssueRef ? ` -m "Ref: ${sourceIssueRef}"` : ""}${authorArg}\`
60252
60395
  When all steps are complete: call \`fn_task_done()\`
60253
60396
 
60254
60397
  If a build command is configured, run that exact command in this worktree before calling \`fn_task_done()\`.
@@ -60434,6 +60577,7 @@ If the task's PROMPT.md includes a "Documentation Requirements" section listing
60434
60577
  ## Git discipline
60435
60578
  - Commit after completing each step (not after every file change)
60436
60579
  - Use conventional commit messages prefixed with the task ID
60580
+ - When the task has a GitHub issue reference, include \`Ref: owner/repo#N\` in the commit body
60437
60581
  - Do NOT commit broken or half-implemented code
60438
60582
 
60439
60583
  ## Worktree Boundaries
@@ -63407,7 +63551,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
63407
63551
  );
63408
63552
  }
63409
63553
  const delay2 = this.WORKTREE_RETRY_DELAYS[attempt] || 1e3;
63410
- await new Promise((resolve36) => setTimeout(resolve36, delay2));
63554
+ await new Promise((resolve37) => setTimeout(resolve37, delay2));
63411
63555
  }
63412
63556
  }
63413
63557
  throw new Error("Unexpected exit from worktree creation retry loop");
@@ -72731,13 +72875,13 @@ var init_plugin_runner = __esm({
72731
72875
  * Returns the result on success, throws on timeout.
72732
72876
  */
72733
72877
  withTimeout(promise, ms, timeoutMessage) {
72734
- return new Promise((resolve36, reject2) => {
72878
+ return new Promise((resolve37, reject2) => {
72735
72879
  const timer = setTimeout(() => {
72736
72880
  reject2(new Error(timeoutMessage));
72737
72881
  }, ms);
72738
72882
  promise.then((result) => {
72739
72883
  clearTimeout(timer);
72740
- resolve36(result);
72884
+ resolve37(result);
72741
72885
  }).catch((err) => {
72742
72886
  clearTimeout(timer);
72743
72887
  reject2(err);
@@ -73406,7 +73550,7 @@ var init_in_process_runtime = __esm({
73406
73550
  runtimeLog.log(
73407
73551
  `Waiting for ${metrics.inFlightTasks} in-flight tasks to complete...`
73408
73552
  );
73409
- await new Promise((resolve36) => setTimeout(resolve36, 1e3));
73553
+ await new Promise((resolve37) => setTimeout(resolve37, 1e3));
73410
73554
  }
73411
73555
  const finalMetrics = this.getMetrics();
73412
73556
  if (finalMetrics.inFlightTasks > 0) {
@@ -73803,13 +73947,13 @@ var init_ipc_host = __esm({
73803
73947
  }
73804
73948
  const id = generateCorrelationId();
73805
73949
  const message = { type, id, payload };
73806
- return new Promise((resolve36, reject2) => {
73950
+ return new Promise((resolve37, reject2) => {
73807
73951
  const timeout2 = setTimeout(() => {
73808
73952
  this.pendingCommands.delete(id);
73809
73953
  reject2(new Error(`Command ${type} timed out after ${timeoutMs ?? this.commandTimeoutMs}ms`));
73810
73954
  }, timeoutMs ?? this.commandTimeoutMs);
73811
73955
  this.pendingCommands.set(id, {
73812
- resolve: resolve36,
73956
+ resolve: resolve37,
73813
73957
  reject: reject2,
73814
73958
  timeout: timeout2,
73815
73959
  type
@@ -74618,8 +74762,8 @@ var init_remote_node_client = __esm({
74618
74762
  return error instanceof TypeError;
74619
74763
  }
74620
74764
  async sleep(ms) {
74621
- await new Promise((resolve36) => {
74622
- setTimeout(resolve36, ms);
74765
+ await new Promise((resolve37) => {
74766
+ setTimeout(resolve37, ms);
74623
74767
  });
74624
74768
  }
74625
74769
  };
@@ -74883,14 +75027,14 @@ var init_remote_node_runtime = __esm({
74883
75027
  return error instanceof Error ? error : new Error(String(error));
74884
75028
  }
74885
75029
  async sleep(ms, signal) {
74886
- await new Promise((resolve36) => {
75030
+ await new Promise((resolve37) => {
74887
75031
  const timeout2 = setTimeout(() => {
74888
75032
  cleanup();
74889
- resolve36();
75033
+ resolve37();
74890
75034
  }, ms);
74891
75035
  const onAbort = () => {
74892
75036
  cleanup();
74893
- resolve36();
75037
+ resolve37();
74894
75038
  };
74895
75039
  const cleanup = () => {
74896
75040
  clearTimeout(timeout2);
@@ -75777,10 +75921,10 @@ var init_tunnel_process_manager = __esm({
75777
75921
  lastError: null
75778
75922
  });
75779
75923
  this.emitLog("info", "manager", `Stopping ${currentHandle.provider} tunnel (pid=${currentHandle.child.pid ?? "n/a"})`);
75780
- this.activeStopPromise = new Promise((resolve36) => {
75924
+ this.activeStopPromise = new Promise((resolve37) => {
75781
75925
  const onClose = () => {
75782
75926
  currentHandle.child.removeListener("close", onClose);
75783
- resolve36();
75927
+ resolve37();
75784
75928
  };
75785
75929
  currentHandle.child.once("close", onClose);
75786
75930
  killManagedProcess(currentHandle.child, "SIGTERM");
@@ -76336,12 +76480,12 @@ ${detail}`
76336
76480
  */
76337
76481
  async onMerge(taskId) {
76338
76482
  if (this.mergeActive.has(taskId)) {
76339
- return new Promise((resolve36, reject2) => {
76340
- this.manualMergeResolvers.set(taskId, { resolve: resolve36, reject: reject2 });
76483
+ return new Promise((resolve37, reject2) => {
76484
+ this.manualMergeResolvers.set(taskId, { resolve: resolve37, reject: reject2 });
76341
76485
  });
76342
76486
  }
76343
- return new Promise((resolve36, reject2) => {
76344
- this.manualMergeResolvers.set(taskId, { resolve: resolve36, reject: reject2 });
76487
+ return new Promise((resolve37, reject2) => {
76488
+ this.manualMergeResolvers.set(taskId, { resolve: resolve37, reject: reject2 });
76345
76489
  this.internalEnqueueMerge(taskId);
76346
76490
  });
76347
76491
  }
@@ -82211,7 +82355,7 @@ function hermesProfileHome(profileName) {
82211
82355
  async function listHermesProfiles(opts) {
82212
82356
  const binary = resolveBinaryForSpawn(opts?.binaryPath ?? "hermes");
82213
82357
  const timeoutMs = opts?.timeoutMs ?? 5e3;
82214
- return new Promise((resolve36, reject2) => {
82358
+ return new Promise((resolve37, reject2) => {
82215
82359
  let settled = false;
82216
82360
  const child = spawn4(binary, ["profile", "list"], {
82217
82361
  stdio: ["ignore", "pipe", "pipe"],
@@ -82254,7 +82398,7 @@ async function listHermesProfiles(opts) {
82254
82398
  ${combined}`));
82255
82399
  return;
82256
82400
  }
82257
- resolve36(parseProfileListOutput(stdout));
82401
+ resolve37(parseProfileListOutput(stdout));
82258
82402
  });
82259
82403
  });
82260
82404
  }
@@ -82331,7 +82475,7 @@ function buildHermesArgs(prompt, settings, resumeSessionId) {
82331
82475
  async function invokeHermesCli(prompt, settings, resumeSessionId, signal) {
82332
82476
  const args = buildHermesArgs(prompt, settings, resumeSessionId);
82333
82477
  const binary = resolveBinaryForSpawn(settings.binaryPath);
82334
- return new Promise((resolve36, reject2) => {
82478
+ return new Promise((resolve37, reject2) => {
82335
82479
  let settled = false;
82336
82480
  const spawnEnv = { ...process.env, PYTHONUNBUFFERED: "1" };
82337
82481
  if (settings.profile) {
@@ -82399,7 +82543,7 @@ ${combined}`));
82399
82543
  return;
82400
82544
  }
82401
82545
  try {
82402
- resolve36(parseHermesOutput(stdout, stderr));
82546
+ resolve37(parseHermesOutput(stdout, stderr));
82403
82547
  } catch (parseErr) {
82404
82548
  reject2(parseErr);
82405
82549
  }
@@ -82717,7 +82861,7 @@ async function promptCli(session, message, config, callbacks, signal) {
82717
82861
  const args = buildOpenClawArgs(config, session.sessionId, message);
82718
82862
  const cb = { ...session.callbacks, ...callbacks };
82719
82863
  cb.onToolStart?.("openclaw.agent", { sessionId: session.sessionId });
82720
- return new Promise((resolve36, reject2) => {
82864
+ return new Promise((resolve37, reject2) => {
82721
82865
  let settled = false;
82722
82866
  const child = spawn6(config.binaryPath, args, {
82723
82867
  stdio: ["ignore", "pipe", "pipe"]
@@ -82810,7 +82954,7 @@ async function promptCli(session, message, config, callbacks, signal) {
82810
82954
  ...metaError ? { error: metaError } : {},
82811
82955
  ...errorText.length > 0 ? { toolErrors: errorText } : {}
82812
82956
  });
82813
- resolve36();
82957
+ resolve37();
82814
82958
  });
82815
82959
  });
82816
82960
  }
@@ -83552,10 +83696,10 @@ function registerTaskWorkflowRoutes(ctx, deps) {
83552
83696
  nextRecoveryAt: null
83553
83697
  });
83554
83698
  if (retrySpecification) {
83555
- const { rm: rm5 } = await import("node:fs/promises");
83556
- const { join: join65 } = await import("node:path");
83557
- const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
83558
- await rm5(promptPath, { force: true });
83699
+ const { rm: rm6 } = await import("node:fs/promises");
83700
+ const { join: join66 } = await import("node:path");
83701
+ const promptPath = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
83702
+ await rm6(promptPath, { force: true });
83559
83703
  await scopedStore.logEntry(req.params.id, "Retry requested from dashboard (planning retry budget reset)");
83560
83704
  const updated2 = await scopedStore.getTask(req.params.id);
83561
83705
  res.json(updated2);
@@ -83975,10 +84119,10 @@ function registerTaskWorkflowRoutes(ctx, deps) {
83975
84119
  }
83976
84120
  await scopedStore.logEntry(task.id, "Plan rejected by user", "Specification will be regenerated");
83977
84121
  await scopedStore.updateTask(task.id, { status: void 0 });
83978
- const { rm: rm5 } = await import("node:fs/promises");
83979
- const { join: join65 } = await import("node:path");
83980
- const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
83981
- await rm5(promptPath, { force: true });
84122
+ const { rm: rm6 } = await import("node:fs/promises");
84123
+ const { join: join66 } = await import("node:path");
84124
+ const promptPath = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84125
+ await rm6(promptPath, { force: true });
83982
84126
  const updated = await scopedStore.getTask(task.id);
83983
84127
  res.json(updated);
83984
84128
  } catch (err) {
@@ -84246,10 +84390,10 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84246
84390
  const task = await scopedStore.getTask(req.params.id);
84247
84391
  if (task.column === "triage") {
84248
84392
  await scopedStore.logEntry(task.id, "AI spec revision requested", feedback);
84249
- const { rm: rm6 } = await import("node:fs/promises");
84250
- const { join: join66 } = await import("node:path");
84251
- const promptPath2 = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84252
- await rm6(promptPath2, { force: true });
84393
+ const { rm: rm7 } = await import("node:fs/promises");
84394
+ const { join: join67 } = await import("node:path");
84395
+ const promptPath2 = join67(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84396
+ await rm7(promptPath2, { force: true });
84253
84397
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84254
84398
  const updated2 = await scopedStore.getTask(task.id);
84255
84399
  res.json(updated2);
@@ -84263,10 +84407,10 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84263
84407
  }
84264
84408
  await scopedStore.logEntry(task.id, "AI spec revision requested", feedback);
84265
84409
  const updated = await scopedStore.moveTask(task.id, "triage");
84266
- const { rm: rm5 } = await import("node:fs/promises");
84267
- const { join: join65 } = await import("node:path");
84268
- const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84269
- await rm5(promptPath, { force: true });
84410
+ const { rm: rm6 } = await import("node:fs/promises");
84411
+ const { join: join66 } = await import("node:path");
84412
+ const promptPath = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84413
+ await rm6(promptPath, { force: true });
84270
84414
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84271
84415
  res.json(updated);
84272
84416
  } catch (err) {
@@ -84284,10 +84428,10 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84284
84428
  const task = await scopedStore.getTask(req.params.id);
84285
84429
  if (task.column === "triage") {
84286
84430
  await scopedStore.logEntry(task.id, "Specification rebuild requested by user");
84287
- const { rm: rm6 } = await import("node:fs/promises");
84288
- const { join: join66 } = await import("node:path");
84289
- const promptPath2 = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84290
- await rm6(promptPath2, { force: true });
84431
+ const { rm: rm7 } = await import("node:fs/promises");
84432
+ const { join: join67 } = await import("node:path");
84433
+ const promptPath2 = join67(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84434
+ await rm7(promptPath2, { force: true });
84291
84435
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84292
84436
  const updated2 = await scopedStore.getTask(task.id);
84293
84437
  res.json(updated2);
@@ -84299,10 +84443,10 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84299
84443
  }
84300
84444
  await scopedStore.logEntry(task.id, "Specification rebuild requested by user");
84301
84445
  const updated = await scopedStore.moveTask(task.id, "triage");
84302
- const { rm: rm5 } = await import("node:fs/promises");
84303
- const { join: join65 } = await import("node:path");
84304
- const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84305
- await rm5(promptPath, { force: true });
84446
+ const { rm: rm6 } = await import("node:fs/promises");
84447
+ const { join: join66 } = await import("node:path");
84448
+ const promptPath = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84449
+ await rm6(promptPath, { force: true });
84306
84450
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84307
84451
  res.json(updated);
84308
84452
  } catch (err) {
@@ -85582,6 +85726,11 @@ async function ensureEngineReady5() {
85582
85726
  } catch {
85583
85727
  }
85584
85728
  }
85729
+ function formatAttachmentSize(size) {
85730
+ if (size < 1024) return `${size}B`;
85731
+ if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)}KB`;
85732
+ return `${(size / (1024 * 1024)).toFixed(1)}MB`;
85733
+ }
85585
85734
  function validateFilePath(basePath, filePath) {
85586
85735
  if (filePath.includes("\0")) {
85587
85736
  throw new Error(`Access denied: Invalid characters in path`);
@@ -85911,7 +86060,7 @@ var init_chat = __esm({
85911
86060
  * @param modelProvider - Optional model provider override
85912
86061
  * @param modelId - Optional model ID override
85913
86062
  */
85914
- async sendMessage(sessionId, content, modelProvider, modelId) {
86063
+ async sendMessage(sessionId, content, modelProvider, modelId, attachments) {
85915
86064
  const abortController = new AbortController();
85916
86065
  this.activeGenerations.set(sessionId, { abortController });
85917
86066
  const session = this.chatStore.getSession(sessionId);
@@ -85935,7 +86084,8 @@ var init_chat = __esm({
85935
86084
  this.chatStore.addMessage(sessionId, {
85936
86085
  role: "user",
85937
86086
  content,
85938
- metadata: mentions.length > 0 ? { mentions } : void 0
86087
+ metadata: mentions.length > 0 ? { mentions } : void 0,
86088
+ attachments
85939
86089
  });
85940
86090
  } catch (err) {
85941
86091
  chatStreamManager.broadcast(sessionId, {
@@ -86012,6 +86162,7 @@ ${mentionContext}`;
86012
86162
  (message) => message.role === "user" || message.role === "assistant"
86013
86163
  );
86014
86164
  const resolvedContent = await resolveFileReferences(content, this.rootDir);
86165
+ const attachmentSummary = attachments && attachments.length > 0 ? `[User attached: ${attachments.map((attachment) => `${attachment.originalName} (${attachment.mimeType}, ${formatAttachmentSize(attachment.size)})`).join(", ")}]` : "";
86015
86166
  const promptContent = conversationMessages.length > 0 ? [
86016
86167
  "## Previous Conversation",
86017
86168
  "",
@@ -86022,8 +86173,9 @@ ${mentionContext}`;
86022
86173
  "",
86023
86174
  "## Current Message",
86024
86175
  "",
86176
+ attachmentSummary,
86025
86177
  resolvedContent
86026
- ].join("\n") : resolvedContent;
86178
+ ].filter(Boolean).join("\n") : [attachmentSummary, resolvedContent].filter(Boolean).join("\n\n");
86027
86179
  agentResult = await createFnAgent8({
86028
86180
  cwd: this.rootDir,
86029
86181
  systemPrompt,
@@ -86100,7 +86252,7 @@ ${mentionContext}`;
86100
86252
  });
86101
86253
  chatStreamManager.broadcast(sessionId, {
86102
86254
  type: "done",
86103
- data: { messageId: assistantMessage.id }
86255
+ data: { messageId: assistantMessage.id, attachments }
86104
86256
  });
86105
86257
  } catch (err) {
86106
86258
  if (abortController.signal.aborted) {
@@ -86166,9 +86318,36 @@ ${mentionContext}`;
86166
86318
  });
86167
86319
 
86168
86320
  // ../dashboard/src/routes/register-chat-routes.ts
86321
+ import { randomUUID as randomUUID15 } from "node:crypto";
86322
+ import { createReadStream as createReadStream2 } from "node:fs";
86323
+ import { mkdir as mkdir12, rm as rm2, writeFile as writeFile12 } from "node:fs/promises";
86324
+ import { basename as basename9, join as join37, resolve as resolve17 } from "node:path";
86325
+ function resolveAttachmentPath(rootDir, sessionId, filename) {
86326
+ const sessionDir = resolve17(rootDir, ".fusion", "chat-attachments", sessionId);
86327
+ const safeName = basename9(filename);
86328
+ const filePath = resolve17(sessionDir, safeName);
86329
+ if (!filePath.startsWith(`${sessionDir}/`) && filePath !== sessionDir) {
86330
+ throw badRequest("Invalid attachment path");
86331
+ }
86332
+ return { sessionDir, filePath };
86333
+ }
86169
86334
  function registerChatRoutes(ctx, deps) {
86170
86335
  const { router, options, getProjectContext: getProjectContext3, chatLogger, rethrowAsApiError: rethrowAsApiError7 } = ctx;
86171
- const { parseLastEventId: parseLastEventId3, validateOptionalModelField: validateOptionalModelField2 } = deps;
86336
+ const { parseLastEventId: parseLastEventId3, validateOptionalModelField: validateOptionalModelField2, upload: upload2 } = deps;
86337
+ const uploadChatAttachment = (req, res, next) => {
86338
+ upload2.single("file")(req, res, (err) => {
86339
+ if (!err) {
86340
+ next();
86341
+ return;
86342
+ }
86343
+ const multerError = err;
86344
+ if (multerError?.code === "LIMIT_FILE_SIZE") {
86345
+ next(badRequest(`File too large. Maximum: ${CHAT_MAX_ATTACHMENT_SIZE} bytes (5MB)`));
86346
+ return;
86347
+ }
86348
+ next(err);
86349
+ });
86350
+ };
86172
86351
  router.get("/chat/sessions", rateLimit(RATE_LIMITS.api), async (req, res) => {
86173
86352
  try {
86174
86353
  const chatStore = options?.chatStore;
@@ -86368,6 +86547,84 @@ function registerChatRoutes(ctx, deps) {
86368
86547
  rethrowAsApiError7(err, "Failed to get chat messages");
86369
86548
  }
86370
86549
  });
86550
+ router.post("/chat/sessions/:id/attachments", rateLimit(RATE_LIMITS.mutation), uploadChatAttachment, async (req, res) => {
86551
+ try {
86552
+ const chatStore = options?.chatStore;
86553
+ if (!chatStore) {
86554
+ throw internalError("Chat store not available");
86555
+ }
86556
+ const sessionId = String(req.params.id);
86557
+ const session = chatStore.getSession(sessionId);
86558
+ if (!session) {
86559
+ throw notFound(`Chat session ${sessionId} not found`);
86560
+ }
86561
+ const file = req.file;
86562
+ if (!file) {
86563
+ throw badRequest("file is required");
86564
+ }
86565
+ if (!CHAT_ALLOWED_MIME_TYPES.has(file.mimetype)) {
86566
+ throw badRequest(`Invalid mime type '${file.mimetype}'`);
86567
+ }
86568
+ if (file.size > CHAT_MAX_ATTACHMENT_SIZE) {
86569
+ throw badRequest(`File too large (${file.size} bytes). Maximum: ${CHAT_MAX_ATTACHMENT_SIZE} bytes (5MB)`);
86570
+ }
86571
+ const { store: scopedStore } = await getProjectContext3(req);
86572
+ const rootDir = scopedStore.getRootDir();
86573
+ const sessionDir = resolve17(rootDir, ".fusion", "chat-attachments", sessionId);
86574
+ await mkdir12(sessionDir, { recursive: true });
86575
+ const sanitizedFilename = (file.originalname || "attachment").replace(/[^a-zA-Z0-9._-]/g, "_");
86576
+ const filename = `${Date.now()}-${sanitizedFilename}`;
86577
+ const filePath = join37(sessionDir, filename);
86578
+ await writeFile12(filePath, file.buffer);
86579
+ const attachment = {
86580
+ id: `att-${randomUUID15().slice(0, 8)}`,
86581
+ filename,
86582
+ originalName: file.originalname,
86583
+ mimeType: file.mimetype,
86584
+ size: file.size,
86585
+ createdAt: (/* @__PURE__ */ new Date()).toISOString()
86586
+ };
86587
+ res.status(201).json({ attachment });
86588
+ } catch (err) {
86589
+ if (err instanceof ApiError) throw err;
86590
+ rethrowAsApiError7(err, "Failed to upload chat attachment");
86591
+ }
86592
+ });
86593
+ router.get("/chat/sessions/:id/attachments/:filename", async (req, res) => {
86594
+ try {
86595
+ const { store: scopedStore } = await getProjectContext3(req);
86596
+ const rootDir = scopedStore.getRootDir();
86597
+ const { filePath } = resolveAttachmentPath(rootDir, String(req.params.id), String(req.params.filename));
86598
+ const stream = createReadStream2(filePath);
86599
+ stream.on("error", () => {
86600
+ if (!res.headersSent) {
86601
+ res.status(404).json({ error: "Attachment not found" });
86602
+ } else {
86603
+ res.end();
86604
+ }
86605
+ });
86606
+ res.setHeader("Content-Type", "application/octet-stream");
86607
+ stream.pipe(res);
86608
+ } catch (err) {
86609
+ if (err instanceof ApiError) throw err;
86610
+ rethrowAsApiError7(err, "Failed to fetch chat attachment");
86611
+ }
86612
+ });
86613
+ router.delete("/chat/sessions/:id/attachments/:filename", rateLimit(RATE_LIMITS.mutation), async (req, res) => {
86614
+ try {
86615
+ const { store: scopedStore } = await getProjectContext3(req);
86616
+ const rootDir = scopedStore.getRootDir();
86617
+ const { filePath } = resolveAttachmentPath(rootDir, String(req.params.id), String(req.params.filename));
86618
+ await rm2(filePath);
86619
+ res.json({ success: true });
86620
+ } catch (err) {
86621
+ if (err?.code === "ENOENT") {
86622
+ throw notFound("Attachment not found");
86623
+ }
86624
+ if (err instanceof ApiError) throw err;
86625
+ rethrowAsApiError7(err, "Failed to delete chat attachment");
86626
+ }
86627
+ });
86371
86628
  router.post("/chat/sessions/:id/messages", rateLimit(RATE_LIMITS.sse), async (req, res) => {
86372
86629
  try {
86373
86630
  const chatStore = options?.chatStore;
@@ -86375,7 +86632,7 @@ function registerChatRoutes(ctx, deps) {
86375
86632
  if (!chatStore || !chatManager) {
86376
86633
  throw internalError("Chat store or manager not available");
86377
86634
  }
86378
- const { content, modelProvider, modelId } = req.body;
86635
+ const { content, modelProvider, modelId, attachments } = req.body;
86379
86636
  const sessionId = String(req.params.id);
86380
86637
  if (!content || typeof content !== "string" || !content.trim()) {
86381
86638
  throw badRequest("content is required and must be a non-empty string");
@@ -86449,7 +86706,8 @@ function registerChatRoutes(ctx, deps) {
86449
86706
  sessionId,
86450
86707
  content.trim(),
86451
86708
  normalizedProvider,
86452
- normalizedModelId
86709
+ normalizedModelId,
86710
+ Array.isArray(attachments) ? attachments : void 0
86453
86711
  ).catch((err) => {
86454
86712
  chatLogger.error("Error in sendMessage", {
86455
86713
  error: err.message
@@ -86518,6 +86776,9 @@ function registerChatRoutes(ctx, deps) {
86518
86776
  "PATCH /chat/sessions/:id",
86519
86777
  "DELETE /chat/sessions/:id",
86520
86778
  "GET /chat/sessions/:id/messages",
86779
+ "POST /chat/sessions/:id/attachments",
86780
+ "GET /chat/sessions/:id/attachments/:filename",
86781
+ "DELETE /chat/sessions/:id/attachments/:filename",
86521
86782
  "POST /chat/sessions/:id/messages",
86522
86783
  "POST /chat/sessions/:id/cancel",
86523
86784
  "DELETE /chat/sessions/:id/messages/:messageId"
@@ -86525,12 +86786,26 @@ function registerChatRoutes(ctx, deps) {
86525
86786
  chatLogger.info("routes registered", { chatRoutes });
86526
86787
  }
86527
86788
  }
86789
+ var CHAT_ALLOWED_MIME_TYPES, CHAT_MAX_ATTACHMENT_SIZE;
86528
86790
  var init_register_chat_routes = __esm({
86529
86791
  "../dashboard/src/routes/register-chat-routes.ts"() {
86530
86792
  "use strict";
86531
86793
  init_api_error();
86532
86794
  init_rate_limit();
86533
86795
  init_sse_buffer();
86796
+ CHAT_ALLOWED_MIME_TYPES = /* @__PURE__ */ new Set([
86797
+ "image/png",
86798
+ "image/jpeg",
86799
+ "image/gif",
86800
+ "image/webp",
86801
+ "text/plain",
86802
+ "application/json",
86803
+ "text/yaml",
86804
+ "text/x-toml",
86805
+ "text/csv",
86806
+ "application/xml"
86807
+ ]);
86808
+ CHAT_MAX_ATTACHMENT_SIZE = 5 * 1024 * 1024;
86534
86809
  }
86535
86810
  });
86536
86811
 
@@ -87879,7 +88154,7 @@ import * as os3 from "os";
87879
88154
  import * as path2 from "path";
87880
88155
  import * as fs from "node:fs";
87881
88156
  import { createRequire as createRequire3 } from "node:module";
87882
- import { join as join37, dirname as dirname10 } from "node:path";
88157
+ import { join as join38, dirname as dirname10 } from "node:path";
87883
88158
  function getNativePrebuildName() {
87884
88159
  const platform3 = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : process.platform === "win32" ? "win32" : "unknown";
87885
88160
  const arch = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "x64" : "unknown";
@@ -87889,12 +88164,12 @@ function findInstalledNodePtyNativeDir() {
87889
88164
  try {
87890
88165
  const packageJsonPath = require2.resolve("node-pty/package.json");
87891
88166
  const pkgRoot = dirname10(packageJsonPath);
87892
- const releaseDir = join37(pkgRoot, "build", "Release");
87893
- if (fs.existsSync(join37(releaseDir, "pty.node"))) {
88167
+ const releaseDir = join38(pkgRoot, "build", "Release");
88168
+ if (fs.existsSync(join38(releaseDir, "pty.node"))) {
87894
88169
  return releaseDir;
87895
88170
  }
87896
- const prebuildDir = join37(pkgRoot, "prebuilds", getNativePrebuildName());
87897
- if (fs.existsSync(join37(prebuildDir, "pty.node"))) {
88171
+ const prebuildDir = join38(pkgRoot, "prebuilds", getNativePrebuildName());
88172
+ if (fs.existsSync(join38(prebuildDir, "pty.node"))) {
87898
88173
  return prebuildDir;
87899
88174
  }
87900
88175
  return null;
@@ -87920,8 +88195,8 @@ function ensureNodePtyNativePermissions() {
87920
88195
  candidateDirs.add(installedNativeDir);
87921
88196
  }
87922
88197
  for (const nativeDir of candidateDirs) {
87923
- const helperPath = join37(nativeDir, "spawn-helper");
87924
- const nativeModulePath = join37(nativeDir, "pty.node");
88198
+ const helperPath = join38(nativeDir, "spawn-helper");
88199
+ const nativeModulePath = join38(nativeDir, "pty.node");
87925
88200
  try {
87926
88201
  fs.chmodSync(helperPath, 493);
87927
88202
  } catch {
@@ -87939,14 +88214,14 @@ function ensureNodePtyNativePermissions() {
87939
88214
  function findStagedNativeDir() {
87940
88215
  const prebuildName = getNativePrebuildName();
87941
88216
  if (process.env.FUSION_RUNTIME_DIR) {
87942
- const envPath = join37(process.env.FUSION_RUNTIME_DIR, prebuildName);
87943
- if (fs.existsSync(join37(envPath, "pty.node"))) {
88217
+ const envPath = join38(process.env.FUSION_RUNTIME_DIR, prebuildName);
88218
+ if (fs.existsSync(join38(envPath, "pty.node"))) {
87944
88219
  return envPath;
87945
88220
  }
87946
88221
  }
87947
88222
  const execDir = dirname10(process.execPath);
87948
- const nextToBinary = join37(execDir, "runtime", prebuildName);
87949
- if (fs.existsSync(join37(nextToBinary, "pty.node"))) {
88223
+ const nextToBinary = join38(execDir, "runtime", prebuildName);
88224
+ if (fs.existsSync(join38(nextToBinary, "pty.node"))) {
87950
88225
  return nextToBinary;
87951
88226
  }
87952
88227
  return null;
@@ -87966,7 +88241,7 @@ async function loadPtyModule() {
87966
88241
  process.env.NODE_PTY_SPAWN_HELPER_DIR = nativeDir;
87967
88242
  }
87968
88243
  process.env.FUSION_NATIVE_ASSETS_PATH = nativeDir;
87969
- const nativePath = join37(nativeDir, "pty.node");
88244
+ const nativePath = join38(nativeDir, "pty.node");
87970
88245
  if (fs.existsSync(nativePath)) {
87971
88246
  try {
87972
88247
  const nativeModule = { exports: {} };
@@ -88943,7 +89218,7 @@ var init_register_messaging_scripts = __esm({
88943
89218
 
88944
89219
  // ../dashboard/src/github.ts
88945
89220
  function delay(ms) {
88946
- return new Promise((resolve36) => setTimeout(resolve36, ms));
89221
+ return new Promise((resolve37) => setTimeout(resolve37, ms));
88947
89222
  }
88948
89223
  function normalizeCheckState(state) {
88949
89224
  switch ((state ?? "").toLowerCase()) {
@@ -93302,7 +93577,7 @@ var init_register_git_github = __esm({
93302
93577
 
93303
93578
  // ../dashboard/src/terminal.ts
93304
93579
  import { spawn as spawn8 } from "node:child_process";
93305
- import { randomUUID as randomUUID15 } from "node:crypto";
93580
+ import { randomUUID as randomUUID16 } from "node:crypto";
93306
93581
  import { EventEmitter as EventEmitter31 } from "node:events";
93307
93582
  function extractBaseCommand(command) {
93308
93583
  let trimmed = command.trim();
@@ -93462,7 +93737,7 @@ var init_terminal = __esm({
93462
93737
  if (!validation.valid) {
93463
93738
  return { sessionId: "", error: validation.error };
93464
93739
  }
93465
- const sessionId = randomUUID15();
93740
+ const sessionId = randomUUID16();
93466
93741
  const childProcess = spawn8(command, [], {
93467
93742
  cwd,
93468
93743
  shell: true,
@@ -93587,20 +93862,20 @@ var init_terminal = __esm({
93587
93862
  });
93588
93863
 
93589
93864
  // ../dashboard/src/file-service.ts
93590
- import { join as join38, resolve as resolve18, relative as relative9, dirname as dirname11, basename as basename10 } from "node:path";
93591
- import { readdir as readdir8, readFile as fsReadFile, writeFile as fsWriteFile, stat as stat7, copyFile as fsCopyFile, rename as fsRename, rm as fsRm, mkdir as mkdir12, access as access4 } from "node:fs/promises";
93865
+ import { join as join39, resolve as resolve19, relative as relative9, dirname as dirname11, basename as basename11 } from "node:path";
93866
+ import { readdir as readdir8, readFile as fsReadFile, writeFile as fsWriteFile, stat as stat7, copyFile as fsCopyFile, rename as fsRename, rm as fsRm, mkdir as mkdir13, access as access4 } from "node:fs/promises";
93592
93867
  async function getTaskBasePath(store, taskId) {
93593
93868
  try {
93594
93869
  const task = await store.getTask(taskId);
93595
93870
  if (task.worktree) {
93596
93871
  try {
93597
93872
  await access4(task.worktree);
93598
- return resolve18(task.worktree);
93873
+ return resolve19(task.worktree);
93599
93874
  } catch {
93600
93875
  }
93601
93876
  }
93602
93877
  const rootDir = store.getRootDir();
93603
- return resolve18(join38(rootDir, ".fusion", "tasks", taskId));
93878
+ return resolve19(join39(rootDir, ".fusion", "tasks", taskId));
93604
93879
  } catch (err) {
93605
93880
  const error = err;
93606
93881
  if (error.code === "ENOENT" || error.message && error.message.includes("not found")) {
@@ -93610,7 +93885,7 @@ async function getTaskBasePath(store, taskId) {
93610
93885
  }
93611
93886
  }
93612
93887
  function getProjectBasePath(store) {
93613
- return resolve18(store.getRootDir());
93888
+ return resolve19(store.getRootDir());
93614
93889
  }
93615
93890
  async function getWorkspaceBasePath(store, workspace) {
93616
93891
  if (workspace === "project") {
@@ -93626,8 +93901,8 @@ function validatePath(basePath, filePath) {
93626
93901
  if (decodedPath.startsWith("/") || decodedPath.match(/^[a-zA-Z]:/)) {
93627
93902
  throw new FileServiceError(`Access denied: Absolute paths not allowed`, "EINVAL");
93628
93903
  }
93629
- const resolvedBase = resolve18(basePath);
93630
- const resolvedPath = resolve18(join38(resolvedBase, decodedPath));
93904
+ const resolvedBase = resolve19(basePath);
93905
+ const resolvedPath = resolve19(join39(resolvedBase, decodedPath));
93631
93906
  const relativePath = relative9(resolvedBase, resolvedPath);
93632
93907
  if (relativePath.startsWith("..") || relativePath.startsWith("../") || relativePath === "..") {
93633
93908
  throw new FileServiceError(`Access denied: Path traversal detected`, "EINVAL");
@@ -93656,7 +93931,7 @@ async function listFilesForBasePath(basePath, subPath) {
93656
93931
  const entries = await readdir8(targetPath, { withFileTypes: true });
93657
93932
  const fileNodes = [];
93658
93933
  for (const entry of entries) {
93659
- const entryPath = join38(targetPath, entry.name);
93934
+ const entryPath = join39(targetPath, entry.name);
93660
93935
  const entryStats = await stat7(entryPath);
93661
93936
  fileNodes.push({
93662
93937
  name: entry.name,
@@ -93786,7 +94061,7 @@ async function readFile18(store, taskId, filePath) {
93786
94061
  const taskBase = await getTaskBasePath(store, taskId);
93787
94062
  return readFileForBasePath(taskBase, filePath);
93788
94063
  }
93789
- async function writeFile12(store, taskId, filePath, content) {
94064
+ async function writeFile13(store, taskId, filePath, content) {
93790
94065
  const taskBase = await getTaskBasePath(store, taskId);
93791
94066
  return writeFileForBasePath(taskBase, filePath, content);
93792
94067
  }
@@ -93805,7 +94080,7 @@ async function writeWorkspaceFile(store, workspace, filePath, content) {
93805
94080
  function validateSourceAndDestination(basePath, sourcePath, destinationPath) {
93806
94081
  const resolvedSource = validatePath(basePath, sourcePath);
93807
94082
  const resolvedDest = validatePath(basePath, destinationPath);
93808
- const sourceRelative = relative9(resolve18(basePath), resolvedSource);
94083
+ const sourceRelative = relative9(resolve19(basePath), resolvedSource);
93809
94084
  if (!sourceRelative || sourceRelative === "." || sourceRelative === "") {
93810
94085
  throw new FileServiceError("Cannot operate on workspace root directory", "EINVAL");
93811
94086
  }
@@ -93929,7 +94204,7 @@ async function deleteWorkspaceFile(store, workspace, filePath) {
93929
94204
  }
93930
94205
  const workspaceBase = await getWorkspaceBasePath(store, workspace);
93931
94206
  const resolvedPath = validatePath(workspaceBase, filePath);
93932
- const relativePath = relative9(resolve18(workspaceBase), resolvedPath);
94207
+ const relativePath = relative9(resolve19(workspaceBase), resolvedPath);
93933
94208
  if (!relativePath || relativePath === "." || relativePath === "") {
93934
94209
  throw new FileServiceError("Cannot delete workspace root directory", "EINVAL");
93935
94210
  }
@@ -93970,7 +94245,7 @@ async function renameWorkspaceFile(store, workspace, filePath, newName) {
93970
94245
  }
93971
94246
  const workspaceBase = await getWorkspaceBasePath(store, workspace);
93972
94247
  const resolvedPath = validatePath(workspaceBase, filePath);
93973
- const relativePath = relative9(resolve18(workspaceBase), resolvedPath);
94248
+ const relativePath = relative9(resolve19(workspaceBase), resolvedPath);
93974
94249
  if (!relativePath || relativePath === "." || relativePath === "") {
93975
94250
  throw new FileServiceError("Cannot rename workspace root directory", "EINVAL");
93976
94251
  }
@@ -93983,12 +94258,12 @@ async function renameWorkspaceFile(store, workspace, filePath, newName) {
93983
94258
  }
93984
94259
  throw err;
93985
94260
  }
93986
- const destPath = join38(dirname11(resolvedPath), newName);
93987
- const destRelative = relative9(resolve18(workspaceBase), destPath);
94261
+ const destPath = join39(dirname11(resolvedPath), newName);
94262
+ const destRelative = relative9(resolve19(workspaceBase), destPath);
93988
94263
  if (destRelative.startsWith("..") || destRelative.startsWith("../") || destRelative === "..") {
93989
94264
  throw new FileServiceError("Destination would be outside workspace", "EINVAL");
93990
94265
  }
93991
- if (!destPath.startsWith(resolve18(workspaceBase))) {
94266
+ if (!destPath.startsWith(resolve19(workspaceBase))) {
93992
94267
  throw new FileServiceError("Destination would be outside workspace", "EINVAL");
93993
94268
  }
93994
94269
  try {
@@ -94017,7 +94292,7 @@ async function getWorkspaceFileForDownload(store, workspace, filePath) {
94017
94292
  }
94018
94293
  const workspaceBase = await getWorkspaceBasePath(store, workspace);
94019
94294
  const resolvedPath = validatePath(workspaceBase, filePath);
94020
- const relativePath = relative9(resolve18(workspaceBase), resolvedPath);
94295
+ const relativePath = relative9(resolve19(workspaceBase), resolvedPath);
94021
94296
  if (!relativePath || relativePath === "." || relativePath === "") {
94022
94297
  throw new FileServiceError("Cannot download workspace root", "EINVAL");
94023
94298
  }
@@ -94041,7 +94316,7 @@ async function getWorkspaceFileForDownload(store, workspace, filePath) {
94041
94316
  mtime: stats.mtime,
94042
94317
  isFile: true
94043
94318
  },
94044
- fileName: basename10(resolvedPath)
94319
+ fileName: basename11(resolvedPath)
94045
94320
  };
94046
94321
  }
94047
94322
  async function getWorkspaceFolderForZip(store, workspace, dirPath) {
@@ -94050,7 +94325,7 @@ async function getWorkspaceFolderForZip(store, workspace, dirPath) {
94050
94325
  }
94051
94326
  const workspaceBase = await getWorkspaceBasePath(store, workspace);
94052
94327
  const resolvedPath = validatePath(workspaceBase, dirPath);
94053
- const relativePath = relative9(resolve18(workspaceBase), resolvedPath);
94328
+ const relativePath = relative9(resolve19(workspaceBase), resolvedPath);
94054
94329
  if (!relativePath || relativePath === "." || relativePath === "") {
94055
94330
  throw new FileServiceError("Cannot download workspace root as ZIP", "EINVAL");
94056
94331
  }
@@ -94069,14 +94344,14 @@ async function getWorkspaceFolderForZip(store, workspace, dirPath) {
94069
94344
  }
94070
94345
  return {
94071
94346
  absolutePath: resolvedPath,
94072
- dirName: basename10(resolvedPath)
94347
+ dirName: basename11(resolvedPath)
94073
94348
  };
94074
94349
  }
94075
94350
  function isHiddenPathSegment(name) {
94076
94351
  return name.startsWith(".");
94077
94352
  }
94078
94353
  async function walkDirForMarkdown(basePath, currentRelative, results, options) {
94079
- const currentPath = currentRelative ? join38(basePath, currentRelative) : basePath;
94354
+ const currentPath = currentRelative ? join39(basePath, currentRelative) : basePath;
94080
94355
  let entries;
94081
94356
  try {
94082
94357
  entries = await readdir8(currentPath, { withFileTypes: true });
@@ -94084,7 +94359,7 @@ async function walkDirForMarkdown(basePath, currentRelative, results, options) {
94084
94359
  return;
94085
94360
  }
94086
94361
  for (const entry of entries) {
94087
- const entryRelativePath = currentRelative ? join38(currentRelative, entry.name) : entry.name;
94362
+ const entryRelativePath = currentRelative ? join39(currentRelative, entry.name) : entry.name;
94088
94363
  if (entry.isDirectory()) {
94089
94364
  if (MARKDOWN_SCAN_EXCLUDED_DIRS.has(entry.name)) {
94090
94365
  continue;
@@ -94101,7 +94376,7 @@ async function walkDirForMarkdown(basePath, currentRelative, results, options) {
94101
94376
  if (!options.showHidden && isHiddenPathSegment(entry.name)) {
94102
94377
  continue;
94103
94378
  }
94104
- const fullPath = join38(basePath, entryRelativePath);
94379
+ const fullPath = join39(basePath, entryRelativePath);
94105
94380
  let fileStats;
94106
94381
  try {
94107
94382
  fileStats = await stat7(fullPath);
@@ -94151,7 +94426,7 @@ async function scanMarkdownFiles(store, options) {
94151
94426
  return;
94152
94427
  }
94153
94428
  for (const entry of entries) {
94154
- const entryRelativePath = relativeDir ? join38(relativeDir, entry.name) : entry.name;
94429
+ const entryRelativePath = relativeDir ? join39(relativeDir, entry.name) : entry.name;
94155
94430
  let shouldRecurse = entry.isDirectory();
94156
94431
  if (!shouldRecurse && typeof entry.isSymbolicLink === "function" && entry.isSymbolicLink()) {
94157
94432
  let symlinkPath;
@@ -94241,8 +94516,8 @@ async function searchWorkspaceFiles(store, workspace, query) {
94241
94516
  if (entry.isDirectory() && EXCLUDED_DIRS.has(entry.name)) {
94242
94517
  continue;
94243
94518
  }
94244
- const fullPath = join38(dir2, entry.name);
94245
- const relPath = join38(relativeDir, entry.name);
94519
+ const fullPath = join39(dir2, entry.name);
94520
+ const relPath = join39(relativeDir, entry.name);
94246
94521
  if (entry.isFile()) {
94247
94522
  if (entry.name.toLowerCase().includes(lowerQuery)) {
94248
94523
  results.push({
@@ -94260,11 +94535,11 @@ async function searchWorkspaceFiles(store, workspace, query) {
94260
94535
  return { files: results };
94261
94536
  }
94262
94537
  async function copyDirectoryRecursive(source, destination) {
94263
- await mkdir12(destination, { recursive: true });
94538
+ await mkdir13(destination, { recursive: true });
94264
94539
  const entries = await readdir8(source, { withFileTypes: true });
94265
94540
  for (const entry of entries) {
94266
- const sourcePath = join38(source, entry.name);
94267
- const destPath = join38(destination, entry.name);
94541
+ const sourcePath = join39(source, entry.name);
94542
+ const destPath = join39(destination, entry.name);
94268
94543
  if (entry.isDirectory()) {
94269
94544
  await copyDirectoryRecursive(sourcePath, destPath);
94270
94545
  } else {
@@ -95181,9 +95456,9 @@ var require_readdir_glob = __commonJS({
95181
95456
  var fs2 = __require("fs");
95182
95457
  var { EventEmitter: EventEmitter35 } = __require("events");
95183
95458
  var { Minimatch } = require_minimatch();
95184
- var { resolve: resolve36 } = __require("path");
95459
+ var { resolve: resolve37 } = __require("path");
95185
95460
  function readdir12(dir2, strict) {
95186
- return new Promise((resolve37, reject2) => {
95461
+ return new Promise((resolve38, reject2) => {
95187
95462
  fs2.readdir(dir2, { withFileTypes: true }, (err, files) => {
95188
95463
  if (err) {
95189
95464
  switch (err.code) {
@@ -95191,7 +95466,7 @@ var require_readdir_glob = __commonJS({
95191
95466
  if (strict) {
95192
95467
  reject2(err);
95193
95468
  } else {
95194
- resolve37([]);
95469
+ resolve38([]);
95195
95470
  }
95196
95471
  break;
95197
95472
  case "ENOTSUP":
@@ -95201,7 +95476,7 @@ var require_readdir_glob = __commonJS({
95201
95476
  case "ENAMETOOLONG":
95202
95477
  // Filename too long
95203
95478
  case "UNKNOWN":
95204
- resolve37([]);
95479
+ resolve38([]);
95205
95480
  break;
95206
95481
  case "ELOOP":
95207
95482
  // Too many levels of symbolic links
@@ -95210,30 +95485,30 @@ var require_readdir_glob = __commonJS({
95210
95485
  break;
95211
95486
  }
95212
95487
  } else {
95213
- resolve37(files);
95488
+ resolve38(files);
95214
95489
  }
95215
95490
  });
95216
95491
  });
95217
95492
  }
95218
95493
  function stat12(file, followSymlinks) {
95219
- return new Promise((resolve37, reject2) => {
95494
+ return new Promise((resolve38, reject2) => {
95220
95495
  const statFunc = followSymlinks ? fs2.stat : fs2.lstat;
95221
95496
  statFunc(file, (err, stats) => {
95222
95497
  if (err) {
95223
95498
  switch (err.code) {
95224
95499
  case "ENOENT":
95225
95500
  if (followSymlinks) {
95226
- resolve37(stat12(file, false));
95501
+ resolve38(stat12(file, false));
95227
95502
  } else {
95228
- resolve37(null);
95503
+ resolve38(null);
95229
95504
  }
95230
95505
  break;
95231
95506
  default:
95232
- resolve37(null);
95507
+ resolve38(null);
95233
95508
  break;
95234
95509
  }
95235
95510
  } else {
95236
- resolve37(stats);
95511
+ resolve38(stats);
95237
95512
  }
95238
95513
  });
95239
95514
  });
@@ -95323,7 +95598,7 @@ var require_readdir_glob = __commonJS({
95323
95598
  (skip) => new Minimatch(skip, { dot: true })
95324
95599
  );
95325
95600
  }
95326
- this.iterator = explore(resolve36(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
95601
+ this.iterator = explore(resolve37(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
95327
95602
  this.paused = false;
95328
95603
  this.inactive = false;
95329
95604
  this.aborted = false;
@@ -95577,10 +95852,10 @@ function awaitify(asyncFn, arity) {
95577
95852
  if (typeof args[arity - 1] === "function") {
95578
95853
  return asyncFn.apply(this, args);
95579
95854
  }
95580
- return new Promise((resolve36, reject2) => {
95855
+ return new Promise((resolve37, reject2) => {
95581
95856
  args[arity - 1] = (err, ...cbArgs) => {
95582
95857
  if (err) return reject2(err);
95583
- resolve36(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
95858
+ resolve37(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
95584
95859
  };
95585
95860
  asyncFn.apply(this, args);
95586
95861
  });
@@ -95762,13 +96037,13 @@ function mapSeries(coll, iteratee, callback) {
95762
96037
  return _asyncMap(eachOfSeries$1, coll, iteratee, callback);
95763
96038
  }
95764
96039
  function promiseCallback() {
95765
- let resolve36, reject2;
96040
+ let resolve37, reject2;
95766
96041
  function callback(err, ...args) {
95767
96042
  if (err) return reject2(err);
95768
- resolve36(args.length > 1 ? args : args[0]);
96043
+ resolve37(args.length > 1 ? args : args[0]);
95769
96044
  }
95770
96045
  callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
95771
- resolve36 = res, reject2 = rej;
96046
+ resolve37 = res, reject2 = rej;
95772
96047
  });
95773
96048
  return callback;
95774
96049
  }
@@ -96041,8 +96316,8 @@ function queue$1(worker, concurrency, payload) {
96041
96316
  });
96042
96317
  }
96043
96318
  if (rejectOnError || !callback) {
96044
- return new Promise((resolve36, reject2) => {
96045
- res = resolve36;
96319
+ return new Promise((resolve37, reject2) => {
96320
+ res = resolve37;
96046
96321
  rej = reject2;
96047
96322
  });
96048
96323
  }
@@ -96081,10 +96356,10 @@ function queue$1(worker, concurrency, payload) {
96081
96356
  }
96082
96357
  const eventMethod = (name) => (handler) => {
96083
96358
  if (!handler) {
96084
- return new Promise((resolve36, reject2) => {
96359
+ return new Promise((resolve37, reject2) => {
96085
96360
  once3(name, (err, data) => {
96086
96361
  if (err) return reject2(err);
96087
- resolve36(data);
96362
+ resolve37(data);
96088
96363
  });
96089
96364
  });
96090
96365
  }
@@ -97745,7 +98020,7 @@ var require_graceful_fs = __commonJS({
97745
98020
  function patch(fs3) {
97746
98021
  polyfills(fs3);
97747
98022
  fs3.gracefulify = patch;
97748
- fs3.createReadStream = createReadStream3;
98023
+ fs3.createReadStream = createReadStream4;
97749
98024
  fs3.createWriteStream = createWriteStream2;
97750
98025
  var fs$readFile = fs3.readFile;
97751
98026
  fs3.readFile = readFile24;
@@ -97765,8 +98040,8 @@ var require_graceful_fs = __commonJS({
97765
98040
  }
97766
98041
  }
97767
98042
  var fs$writeFile = fs3.writeFile;
97768
- fs3.writeFile = writeFile17;
97769
- function writeFile17(path5, data, options, cb) {
98043
+ fs3.writeFile = writeFile18;
98044
+ function writeFile18(path5, data, options, cb) {
97770
98045
  if (typeof options === "function")
97771
98046
  cb = options, options = null;
97772
98047
  return go$writeFile(path5, data, options, cb);
@@ -97955,7 +98230,7 @@ var require_graceful_fs = __commonJS({
97955
98230
  }
97956
98231
  });
97957
98232
  }
97958
- function createReadStream3(path5, options) {
98233
+ function createReadStream4(path5, options) {
97959
98234
  return new fs3.ReadStream(path5, options);
97960
98235
  }
97961
98236
  function createWriteStream2(path5, options) {
@@ -98333,7 +98608,7 @@ var require_BufferList = __commonJS({
98333
98608
  this.head = this.tail = null;
98334
98609
  this.length = 0;
98335
98610
  };
98336
- BufferList.prototype.join = function join65(s) {
98611
+ BufferList.prototype.join = function join66(s) {
98337
98612
  if (this.length === 0) return "";
98338
98613
  var p = this.head;
98339
98614
  var ret = "" + p.data;
@@ -102090,25 +102365,25 @@ var require_util2 = __commonJS({
102090
102365
  };
102091
102366
  },
102092
102367
  createDeferredPromise: function() {
102093
- let resolve36;
102368
+ let resolve37;
102094
102369
  let reject2;
102095
102370
  const promise = new Promise((res, rej) => {
102096
- resolve36 = res;
102371
+ resolve37 = res;
102097
102372
  reject2 = rej;
102098
102373
  });
102099
102374
  return {
102100
102375
  promise,
102101
- resolve: resolve36,
102376
+ resolve: resolve37,
102102
102377
  reject: reject2
102103
102378
  };
102104
102379
  },
102105
102380
  promisify(fn) {
102106
- return new Promise((resolve36, reject2) => {
102381
+ return new Promise((resolve37, reject2) => {
102107
102382
  fn((err, ...args) => {
102108
102383
  if (err) {
102109
102384
  return reject2(err);
102110
102385
  }
102111
- return resolve36(...args);
102386
+ return resolve37(...args);
102112
102387
  });
102113
102388
  });
102114
102389
  },
@@ -102900,7 +103175,7 @@ var require_end_of_stream2 = __commonJS({
102900
103175
  validateBoolean3(opts.cleanup, "cleanup");
102901
103176
  autoCleanup = opts.cleanup;
102902
103177
  }
102903
- return new Promise2((resolve36, reject2) => {
103178
+ return new Promise2((resolve37, reject2) => {
102904
103179
  const cleanup = eos(stream, opts, (err) => {
102905
103180
  if (autoCleanup) {
102906
103181
  cleanup();
@@ -102908,7 +103183,7 @@ var require_end_of_stream2 = __commonJS({
102908
103183
  if (err) {
102909
103184
  reject2(err);
102910
103185
  } else {
102911
- resolve36();
103186
+ resolve37();
102912
103187
  }
102913
103188
  });
102914
103189
  });
@@ -104075,7 +104350,7 @@ var require_readable2 = __commonJS({
104075
104350
  error = this.readableEnded ? null : new AbortError();
104076
104351
  this.destroy(error);
104077
104352
  }
104078
- return new Promise2((resolve36, reject2) => eos(this, (err) => err && err !== error ? reject2(err) : resolve36(null)));
104353
+ return new Promise2((resolve37, reject2) => eos(this, (err) => err && err !== error ? reject2(err) : resolve37(null)));
104079
104354
  };
104080
104355
  Readable2.prototype.push = function(chunk, encoding) {
104081
104356
  return readableAddChunk(this, chunk, encoding, false);
@@ -104619,12 +104894,12 @@ var require_readable2 = __commonJS({
104619
104894
  }
104620
104895
  async function* createAsyncIterator(stream, options) {
104621
104896
  let callback = nop;
104622
- function next(resolve36) {
104897
+ function next(resolve37) {
104623
104898
  if (this === stream) {
104624
104899
  callback();
104625
104900
  callback = nop;
104626
104901
  } else {
104627
- callback = resolve36;
104902
+ callback = resolve37;
104628
104903
  }
104629
104904
  }
104630
104905
  stream.on("readable", next);
@@ -105677,7 +105952,7 @@ var require_duplexify = __commonJS({
105677
105952
  );
105678
105953
  };
105679
105954
  function fromAsyncGen(fn) {
105680
- let { promise, resolve: resolve36 } = createDeferredPromise();
105955
+ let { promise, resolve: resolve37 } = createDeferredPromise();
105681
105956
  const ac = new AbortController2();
105682
105957
  const signal = ac.signal;
105683
105958
  const value = fn(
@@ -105692,7 +105967,7 @@ var require_duplexify = __commonJS({
105692
105967
  throw new AbortError(void 0, {
105693
105968
  cause: signal.reason
105694
105969
  });
105695
- ({ promise, resolve: resolve36 } = createDeferredPromise());
105970
+ ({ promise, resolve: resolve37 } = createDeferredPromise());
105696
105971
  yield chunk;
105697
105972
  }
105698
105973
  })(),
@@ -105703,8 +105978,8 @@ var require_duplexify = __commonJS({
105703
105978
  return {
105704
105979
  value,
105705
105980
  write(chunk, encoding, cb) {
105706
- const _resolve = resolve36;
105707
- resolve36 = null;
105981
+ const _resolve = resolve37;
105982
+ resolve37 = null;
105708
105983
  _resolve({
105709
105984
  chunk,
105710
105985
  done: false,
@@ -105712,8 +105987,8 @@ var require_duplexify = __commonJS({
105712
105987
  });
105713
105988
  },
105714
105989
  final(cb) {
105715
- const _resolve = resolve36;
105716
- resolve36 = null;
105990
+ const _resolve = resolve37;
105991
+ resolve37 = null;
105717
105992
  _resolve({
105718
105993
  done: true,
105719
105994
  cb
@@ -106165,7 +106440,7 @@ var require_pipeline = __commonJS({
106165
106440
  callback();
106166
106441
  }
106167
106442
  };
106168
- const wait = () => new Promise2((resolve36, reject2) => {
106443
+ const wait = () => new Promise2((resolve37, reject2) => {
106169
106444
  if (error) {
106170
106445
  reject2(error);
106171
106446
  } else {
@@ -106173,7 +106448,7 @@ var require_pipeline = __commonJS({
106173
106448
  if (error) {
106174
106449
  reject2(error);
106175
106450
  } else {
106176
- resolve36();
106451
+ resolve37();
106177
106452
  }
106178
106453
  };
106179
106454
  }
@@ -106817,8 +107092,8 @@ var require_operators = __commonJS({
106817
107092
  next = null;
106818
107093
  }
106819
107094
  if (!done && (queue2.length >= highWaterMark2 || cnt >= concurrency)) {
106820
- await new Promise2((resolve36) => {
106821
- resume = resolve36;
107095
+ await new Promise2((resolve37) => {
107096
+ resume = resolve37;
106822
107097
  });
106823
107098
  }
106824
107099
  }
@@ -106852,8 +107127,8 @@ var require_operators = __commonJS({
106852
107127
  queue2.shift();
106853
107128
  maybeResume();
106854
107129
  }
106855
- await new Promise2((resolve36) => {
106856
- next = resolve36;
107130
+ await new Promise2((resolve37) => {
107131
+ next = resolve37;
106857
107132
  });
106858
107133
  }
106859
107134
  } finally {
@@ -107111,7 +107386,7 @@ var require_promises = __commonJS({
107111
107386
  var { finished } = require_end_of_stream2();
107112
107387
  require_stream2();
107113
107388
  function pipeline(...streams) {
107114
- return new Promise2((resolve36, reject2) => {
107389
+ return new Promise2((resolve37, reject2) => {
107115
107390
  let signal;
107116
107391
  let end;
107117
107392
  const lastArg = streams[streams.length - 1];
@@ -107126,7 +107401,7 @@ var require_promises = __commonJS({
107126
107401
  if (err) {
107127
107402
  reject2(err);
107128
107403
  } else {
107129
- resolve36(value);
107404
+ resolve37(value);
107130
107405
  }
107131
107406
  },
107132
107407
  {
@@ -111899,10 +112174,10 @@ var require_commonjs3 = __commonJS({
111899
112174
  * Return a void Promise that resolves once the stream ends.
111900
112175
  */
111901
112176
  async promise() {
111902
- return new Promise((resolve36, reject2) => {
112177
+ return new Promise((resolve37, reject2) => {
111903
112178
  this.on(DESTROYED, () => reject2(new Error("stream destroyed")));
111904
112179
  this.on("error", (er) => reject2(er));
111905
- this.on("end", () => resolve36());
112180
+ this.on("end", () => resolve37());
111906
112181
  });
111907
112182
  }
111908
112183
  /**
@@ -111926,7 +112201,7 @@ var require_commonjs3 = __commonJS({
111926
112201
  return Promise.resolve({ done: false, value: res });
111927
112202
  if (this[EOF])
111928
112203
  return stop();
111929
- let resolve36;
112204
+ let resolve37;
111930
112205
  let reject2;
111931
112206
  const onerr = (er) => {
111932
112207
  this.off("data", ondata);
@@ -111940,19 +112215,19 @@ var require_commonjs3 = __commonJS({
111940
112215
  this.off("end", onend);
111941
112216
  this.off(DESTROYED, ondestroy);
111942
112217
  this.pause();
111943
- resolve36({ value, done: !!this[EOF] });
112218
+ resolve37({ value, done: !!this[EOF] });
111944
112219
  };
111945
112220
  const onend = () => {
111946
112221
  this.off("error", onerr);
111947
112222
  this.off("data", ondata);
111948
112223
  this.off(DESTROYED, ondestroy);
111949
112224
  stop();
111950
- resolve36({ done: true, value: void 0 });
112225
+ resolve37({ done: true, value: void 0 });
111951
112226
  };
111952
112227
  const ondestroy = () => onerr(new Error("stream destroyed"));
111953
112228
  return new Promise((res2, rej) => {
111954
112229
  reject2 = rej;
111955
- resolve36 = res2;
112230
+ resolve37 = res2;
111956
112231
  this.once(DESTROYED, ondestroy);
111957
112232
  this.once("error", onerr);
111958
112233
  this.once("end", onend);
@@ -112968,9 +113243,9 @@ var require_commonjs4 = __commonJS({
112968
113243
  if (this.#asyncReaddirInFlight) {
112969
113244
  await this.#asyncReaddirInFlight;
112970
113245
  } else {
112971
- let resolve36 = () => {
113246
+ let resolve37 = () => {
112972
113247
  };
112973
- this.#asyncReaddirInFlight = new Promise((res) => resolve36 = res);
113248
+ this.#asyncReaddirInFlight = new Promise((res) => resolve37 = res);
112974
113249
  try {
112975
113250
  for (const e of await this.#fs.promises.readdir(fullpath, {
112976
113251
  withFileTypes: true
@@ -112983,7 +113258,7 @@ var require_commonjs4 = __commonJS({
112983
113258
  children.provisional = 0;
112984
113259
  }
112985
113260
  this.#asyncReaddirInFlight = void 0;
112986
- resolve36();
113261
+ resolve37();
112987
113262
  }
112988
113263
  return children.slice(0, children.provisional);
112989
113264
  }
@@ -115756,11 +116031,11 @@ var require_core = __commonJS({
115756
116031
  this._finalize();
115757
116032
  }
115758
116033
  var self2 = this;
115759
- return new Promise(function(resolve36, reject2) {
116034
+ return new Promise(function(resolve37, reject2) {
115760
116035
  var errored;
115761
116036
  self2._module.on("end", function() {
115762
116037
  if (!errored) {
115763
- resolve36();
116038
+ resolve37();
115764
116039
  }
115765
116040
  });
115766
116041
  self2._module.on("error", function(err) {
@@ -118200,8 +118475,8 @@ var require_streamx = __commonJS({
118200
118475
  return this;
118201
118476
  },
118202
118477
  next() {
118203
- return new Promise(function(resolve36, reject2) {
118204
- promiseResolve = resolve36;
118478
+ return new Promise(function(resolve37, reject2) {
118479
+ promiseResolve = resolve37;
118205
118480
  promiseReject = reject2;
118206
118481
  const data = stream.read();
118207
118482
  if (data !== null) ondata(data);
@@ -118231,11 +118506,11 @@ var require_streamx = __commonJS({
118231
118506
  }
118232
118507
  function destroy(err) {
118233
118508
  stream.destroy(err);
118234
- return new Promise((resolve36, reject2) => {
118235
- if (stream._duplexState & DESTROYED) return resolve36({ value: void 0, done: true });
118509
+ return new Promise((resolve37, reject2) => {
118510
+ if (stream._duplexState & DESTROYED) return resolve37({ value: void 0, done: true });
118236
118511
  stream.once("close", function() {
118237
118512
  if (err) reject2(err);
118238
- else resolve36({ value: void 0, done: true });
118513
+ else resolve37({ value: void 0, done: true });
118239
118514
  });
118240
118515
  });
118241
118516
  }
@@ -118279,8 +118554,8 @@ var require_streamx = __commonJS({
118279
118554
  const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
118280
118555
  if (writes === 0) return Promise.resolve(true);
118281
118556
  if (state.drains === null) state.drains = [];
118282
- return new Promise((resolve36) => {
118283
- state.drains.push({ writes, resolve: resolve36 });
118557
+ return new Promise((resolve37) => {
118558
+ state.drains.push({ writes, resolve: resolve37 });
118284
118559
  });
118285
118560
  }
118286
118561
  write(data) {
@@ -118385,10 +118660,10 @@ var require_streamx = __commonJS({
118385
118660
  cb(null);
118386
118661
  }
118387
118662
  function pipelinePromise(...streams) {
118388
- return new Promise((resolve36, reject2) => {
118663
+ return new Promise((resolve37, reject2) => {
118389
118664
  return pipeline(...streams, (err) => {
118390
118665
  if (err) return reject2(err);
118391
- resolve36();
118666
+ resolve37();
118392
118667
  });
118393
118668
  });
118394
118669
  }
@@ -119045,16 +119320,16 @@ var require_extract = __commonJS({
119045
119320
  entryCallback = null;
119046
119321
  cb(err);
119047
119322
  }
119048
- function onnext(resolve36, reject2) {
119323
+ function onnext(resolve37, reject2) {
119049
119324
  if (error) {
119050
119325
  return reject2(error);
119051
119326
  }
119052
119327
  if (entryStream) {
119053
- resolve36({ value: entryStream, done: false });
119328
+ resolve37({ value: entryStream, done: false });
119054
119329
  entryStream = null;
119055
119330
  return;
119056
119331
  }
119057
- promiseResolve = resolve36;
119332
+ promiseResolve = resolve37;
119058
119333
  promiseReject = reject2;
119059
119334
  consumeCallback(null);
119060
119335
  if (extract._finished && promiseResolve) {
@@ -119082,11 +119357,11 @@ var require_extract = __commonJS({
119082
119357
  function destroy(err) {
119083
119358
  extract.destroy(err);
119084
119359
  consumeCallback(err);
119085
- return new Promise((resolve36, reject2) => {
119086
- if (extract.destroyed) return resolve36({ value: void 0, done: true });
119360
+ return new Promise((resolve37, reject2) => {
119361
+ if (extract.destroyed) return resolve37({ value: void 0, done: true });
119087
119362
  extract.once("close", function() {
119088
119363
  if (err) reject2(err);
119089
- else resolve36({ value: void 0, done: true });
119364
+ else resolve37({ value: void 0, done: true });
119090
119365
  });
119091
119366
  });
119092
119367
  }
@@ -119857,7 +120132,7 @@ var require_archiver = __commonJS({
119857
120132
 
119858
120133
  // ../dashboard/src/routes/register-file-workspace-routes.ts
119859
120134
  import { access as access5 } from "node:fs/promises";
119860
- import { createReadStream as createReadStream2 } from "node:fs";
120135
+ import { createReadStream as createReadStream3 } from "node:fs";
119861
120136
  function extractFileParams(req) {
119862
120137
  const filePath = Array.isArray(req.params.filepath) ? req.params.filepath[0] : req.params.filepath ?? "";
119863
120138
  const workspace = typeof req.query.workspace === "string" && req.query.workspace.length > 0 ? req.query.workspace : "project";
@@ -119908,7 +120183,7 @@ function registerFileWorkspaceRoutes(ctx) {
119908
120183
  if (typeof content !== "string") {
119909
120184
  throw badRequest("content is required and must be a string");
119910
120185
  }
119911
- const result = await writeFile12(scopedStore, req.params.id, filePath, content);
120186
+ const result = await writeFile13(scopedStore, req.params.id, filePath, content);
119912
120187
  res.json(result);
119913
120188
  } catch (err) {
119914
120189
  if (err instanceof ApiError) {
@@ -120119,7 +120394,7 @@ function registerFileWorkspaceRoutes(ctx) {
120119
120394
  res.setHeader("Content-Disposition", `attachment; filename="${fileName}"`);
120120
120395
  res.setHeader("Content-Length", stats.size);
120121
120396
  res.setHeader("Last-Modified", stats.mtime.toUTCString());
120122
- const stream = createReadStream2(absolutePath);
120397
+ const stream = createReadStream3(absolutePath);
120123
120398
  stream.pipe(res);
120124
120399
  } catch (err) {
120125
120400
  if (err instanceof ApiError) {
@@ -120866,8 +121141,8 @@ var init_exec_file = __esm({
120866
121141
 
120867
121142
  // ../dashboard/src/routes/register-project-routes.ts
120868
121143
  import * as fsPromises from "node:fs/promises";
120869
- import { dirname as dirname12, isAbsolute as isAbsolute14, join as join39 } from "node:path";
120870
- var access7, stat8, mkdir13, readdir9, rm2, registerProjectRoutes;
121144
+ import { dirname as dirname12, isAbsolute as isAbsolute14, join as join40 } from "node:path";
121145
+ var access7, stat8, mkdir14, readdir9, rm3, registerProjectRoutes;
120871
121146
  var init_register_project_routes = __esm({
120872
121147
  "../dashboard/src/routes/register-project-routes.ts"() {
120873
121148
  "use strict";
@@ -120878,9 +121153,9 @@ var init_register_project_routes = __esm({
120878
121153
  ({
120879
121154
  access: access7,
120880
121155
  stat: stat8,
120881
- mkdir: mkdir13,
121156
+ mkdir: mkdir14,
120882
121157
  readdir: readdir9,
120883
- rm: rm2
121158
+ rm: rm3
120884
121159
  } = fsPromises);
120885
121160
  registerProjectRoutes = (ctx) => {
120886
121161
  const { router, options, runtimeLogger, prioritizeProjectsForCurrentDirectory, rethrowAsApiError: rethrowAsApiError7 } = ctx;
@@ -121031,7 +121306,7 @@ var init_register_project_routes = __esm({
121031
121306
  throw badRequest("Clone destination must be empty");
121032
121307
  }
121033
121308
  } else {
121034
- await mkdir13(normalizedPath, { recursive: false });
121309
+ await mkdir14(normalizedPath, { recursive: false });
121035
121310
  destinationCreatedForClone = true;
121036
121311
  }
121037
121312
  const cloneSource = normalizedCloneUrl;
@@ -121047,7 +121322,7 @@ var init_register_project_routes = __esm({
121047
121322
  } catch (cloneError) {
121048
121323
  if (destinationCreatedForClone) {
121049
121324
  try {
121050
- await rm2(normalizedPath, { recursive: true, force: true });
121325
+ await rm3(normalizedPath, { recursive: true, force: true });
121051
121326
  } catch {
121052
121327
  }
121053
121328
  }
@@ -121057,7 +121332,7 @@ var init_register_project_routes = __esm({
121057
121332
  }
121058
121333
  }
121059
121334
  let hasFusionDir = false;
121060
- const fusionDirPath = join39(normalizedPath, ".fusion");
121335
+ const fusionDirPath = join40(normalizedPath, ".fusion");
121061
121336
  try {
121062
121337
  await access7(fusionDirPath);
121063
121338
  hasFusionDir = true;
@@ -121119,18 +121394,18 @@ var init_register_project_routes = __esm({
121119
121394
  const entries = await readdir9(searchPath, { withFileTypes: true });
121120
121395
  for (const entry of entries) {
121121
121396
  if (!entry.isDirectory()) continue;
121122
- const dirPath = join39(searchPath, entry.name);
121397
+ const dirPath = join40(searchPath, entry.name);
121123
121398
  let hasKbDb = false;
121124
121399
  let hasFusionDir = false;
121125
121400
  try {
121126
- await access7(join39(dirPath, ".fusion", "fusion.db"));
121401
+ await access7(join40(dirPath, ".fusion", "fusion.db"));
121127
121402
  hasKbDb = true;
121128
121403
  } catch {
121129
121404
  hasKbDb = false;
121130
121405
  }
121131
121406
  if (!hasKbDb) {
121132
121407
  try {
121133
- await access7(join39(dirPath, ".fusion"));
121408
+ await access7(join40(dirPath, ".fusion"));
121134
121409
  hasFusionDir = true;
121135
121410
  } catch {
121136
121411
  hasFusionDir = false;
@@ -124134,7 +124409,7 @@ var init_register_agent_reflection_rating_routes = __esm({
124134
124409
  });
124135
124410
 
124136
124411
  // ../dashboard/src/agent-generation.ts
124137
- import { randomUUID as randomUUID16 } from "node:crypto";
124412
+ import { randomUUID as randomUUID17 } from "node:crypto";
124138
124413
  async function initPromptCatalog() {
124139
124414
  if (promptCatalogReady) return;
124140
124415
  try {
@@ -124340,7 +124615,7 @@ async function startAgentGeneration(ip, roleDescription) {
124340
124615
  `Rate limit exceeded. Maximum ${MAX_SESSIONS_PER_IP_PER_HOUR4} generation sessions per hour. Reset at ${resetTime?.toISOString() || "unknown"}`
124341
124616
  );
124342
124617
  }
124343
- const sessionId = randomUUID16();
124618
+ const sessionId = randomUUID17();
124344
124619
  const session = {
124345
124620
  id: sessionId,
124346
124621
  ip,
@@ -124518,7 +124793,7 @@ You MUST respond with ONLY valid JSON (no markdown, no explanation):
124518
124793
  import { createWriteStream } from "node:fs";
124519
124794
  import * as fsPromises2 from "node:fs/promises";
124520
124795
  import { tmpdir as tmpdir3 } from "node:os";
124521
- import { join as join40, resolve as resolve19 } from "node:path";
124796
+ import { join as join41, resolve as resolve20 } from "node:path";
124522
124797
  import { Readable } from "node:stream";
124523
124798
  import { pipeline as streamPipeline } from "node:stream/promises";
124524
124799
  function registerAgentImportExportRoutes(ctx) {
@@ -124555,11 +124830,11 @@ function registerAgentImportExportRoutes(ctx) {
124555
124830
  }
124556
124831
  let resolvedOutputDir;
124557
124832
  if (typeof outputDir === "string" && outputDir.trim().length > 0) {
124558
- resolvedOutputDir = resolve19(outputDir.trim());
124833
+ resolvedOutputDir = resolve20(outputDir.trim());
124559
124834
  } else if (typeof outputDir === "string") {
124560
124835
  throw badRequest("outputDir cannot be empty");
124561
124836
  } else {
124562
- resolvedOutputDir = await mkdtemp(join40(tmpdir3(), "fusion-agent-export-"));
124837
+ resolvedOutputDir = await mkdtemp(join41(tmpdir3(), "fusion-agent-export-"));
124563
124838
  }
124564
124839
  const result = await exportAgentsToDirectory2(agentsToExport, resolvedOutputDir, {
124565
124840
  companyName: typeof companyName === "string" ? companyName : void 0,
@@ -124686,7 +124961,7 @@ ${body}`;
124686
124961
  return result;
124687
124962
  }
124688
124963
  const safeCompanySlug = companySlug ? slugifyPathSegment2(companySlug, "unknown-company") : "unknown-company";
124689
- const skillsBaseDir = join40(projectRoot, "skills", "imported", safeCompanySlug);
124964
+ const skillsBaseDir = join41(projectRoot, "skills", "imported", safeCompanySlug);
124690
124965
  const usedSlugs = /* @__PURE__ */ new Set();
124691
124966
  for (const skill of skills) {
124692
124967
  const name = typeof skill.name === "string" && skill.name.trim().length > 0 ? skill.name.trim() : null;
@@ -124703,8 +124978,8 @@ ${body}`;
124703
124978
  skillSlug = `${skillSlug}-${counter}`;
124704
124979
  }
124705
124980
  usedSlugs.add(skillSlug);
124706
- const skillDir = join40(skillsBaseDir, skillSlug);
124707
- const skillPath = join40(skillDir, "SKILL.md");
124981
+ const skillDir = join41(skillsBaseDir, skillSlug);
124982
+ const skillPath = join41(skillDir, "SKILL.md");
124708
124983
  try {
124709
124984
  await access8(skillPath);
124710
124985
  result.skipped.push(name);
@@ -124740,7 +125015,7 @@ ${body}`;
124740
125015
 
124741
125016
  <!-- Add skill instructions here. -->`;
124742
125017
  try {
124743
- await mkdir14(skillDir, { recursive: true });
125018
+ await mkdir15(skillDir, { recursive: true });
124744
125019
  const content = toSkillMarkdown2(frontmatter, body);
124745
125020
  await fsWriteFile2(skillPath, content, "utf-8");
124746
125021
  result.imported.push({ name, path: `skills/imported/${safeCompanySlug}/${skillSlug}/SKILL.md` });
@@ -124790,7 +125065,7 @@ ${body}`;
124790
125065
  tasks: []
124791
125066
  };
124792
125067
  } else if (typeof source === "string" && source.trim()) {
124793
- const sourcePath = resolve19(source);
125068
+ const sourcePath = resolve20(source);
124794
125069
  const isArchive = sourcePath.endsWith(".tar.gz") || sourcePath.endsWith(".tgz") || sourcePath.endsWith(".zip");
124795
125070
  if (isArchive) {
124796
125071
  try {
@@ -124874,8 +125149,8 @@ ${body}`;
124874
125149
  const archiveUrl = `https://github.com/${repoOwner}/${repoName}/archive/refs/heads/main.tar.gz`;
124875
125150
  let tempDir = null;
124876
125151
  try {
124877
- tempDir = await mkdtemp(join40(tmpdir3(), `fn-agent-import-${importCompanySlug}-`));
124878
- const archivePath = join40(tempDir, "archive.tar.gz");
125152
+ tempDir = await mkdtemp(join41(tmpdir3(), `fn-agent-import-${importCompanySlug}-`));
125153
+ const archivePath = join41(tempDir, "archive.tar.gz");
124879
125154
  const downloadController = new AbortController();
124880
125155
  const downloadTimeout = setTimeout(() => downloadController.abort(), 3e4);
124881
125156
  let archiveResponse;
@@ -124919,7 +125194,7 @@ ${body}`;
124919
125194
  } finally {
124920
125195
  if (tempDir) {
124921
125196
  try {
124922
- await rm3(tempDir, { recursive: true, force: true });
125197
+ await rm4(tempDir, { recursive: true, force: true });
124923
125198
  } catch {
124924
125199
  }
124925
125200
  }
@@ -125127,14 +125402,14 @@ function registerAgentGenerationRoutes(ctx) {
125127
125402
  }
125128
125403
  });
125129
125404
  }
125130
- var mkdtemp, access8, stat9, mkdir14, rm3, fsWriteFile2;
125405
+ var mkdtemp, access8, stat9, mkdir15, rm4, fsWriteFile2;
125131
125406
  var init_register_agent_import_export_generation_routes = __esm({
125132
125407
  "../dashboard/src/routes/register-agent-import-export-generation-routes.ts"() {
125133
125408
  "use strict";
125134
125409
  init_api_error();
125135
125410
  init_ai_session_diagnostics();
125136
125411
  init_agent_generation();
125137
- ({ mkdtemp, access: access8, stat: stat9, mkdir: mkdir14, rm: rm3, writeFile: fsWriteFile2 } = fsPromises2);
125412
+ ({ mkdtemp, access: access8, stat: stat9, mkdir: mkdir15, rm: rm4, writeFile: fsWriteFile2 } = fsPromises2);
125138
125413
  }
125139
125414
  });
125140
125415
 
@@ -125591,9 +125866,9 @@ function registerProxyRoutes(router, deps) {
125591
125866
  if (req.rawBody && req.rawBody.length > 0) {
125592
125867
  body = req.rawBody;
125593
125868
  } else {
125594
- await new Promise((resolve36, reject2) => {
125869
+ await new Promise((resolve37, reject2) => {
125595
125870
  req.on("data", (chunk) => chunks.push(chunk));
125596
- req.on("end", resolve36);
125871
+ req.on("end", resolve37);
125597
125872
  req.on("error", reject2);
125598
125873
  });
125599
125874
  if (chunks.length > 0) {
@@ -125789,13 +126064,13 @@ import { readFile as readFile19 } from "node:fs/promises";
125789
126064
  import * as https from "node:https";
125790
126065
  import * as child_process from "node:child_process";
125791
126066
  function execFileAsync4(file, args, options) {
125792
- return new Promise((resolve36, reject2) => {
126067
+ return new Promise((resolve37, reject2) => {
125793
126068
  child_process.execFile(file, args, options, (error, stdout, stderr) => {
125794
126069
  if (error) {
125795
126070
  reject2(error);
125796
126071
  return;
125797
126072
  }
125798
- resolve36({ stdout: String(stdout), stderr: String(stderr) });
126073
+ resolve37({ stdout: String(stdout), stderr: String(stderr) });
125799
126074
  });
125800
126075
  });
125801
126076
  }
@@ -125854,7 +126129,7 @@ function formatDuration(ms) {
125854
126129
  return remHours > 0 ? `${days}d ${remHours}h` : `${days}d`;
125855
126130
  }
125856
126131
  function httpsRequest(url, options) {
125857
- return new Promise((resolve36, reject2) => {
126132
+ return new Promise((resolve37, reject2) => {
125858
126133
  const parsed = new URL(url);
125859
126134
  const req = https.request(
125860
126135
  {
@@ -125874,7 +126149,7 @@ function httpsRequest(url, options) {
125874
126149
  if (typeof v === "string") hdrs[k.toLowerCase()] = v;
125875
126150
  else if (Array.isArray(v)) hdrs[k.toLowerCase()] = v.join(", ");
125876
126151
  }
125877
- resolve36({
126152
+ resolve37({
125878
126153
  status: res.statusCode || 0,
125879
126154
  headers: hdrs,
125880
126155
  body: Buffer.concat(chunks).toString("utf-8")
@@ -126121,7 +126396,7 @@ async function fetchClaudeUsageViaCli() {
126121
126396
  env: { ...process.env, TERM: "xterm-256color" }
126122
126397
  };
126123
126398
  if (isWindows) ptyOptions.useConpty = false;
126124
- const output = await new Promise((resolve36, reject2) => {
126399
+ const output = await new Promise((resolve37, reject2) => {
126125
126400
  let buf = "";
126126
126401
  let settled = false;
126127
126402
  let sentCommand = false;
@@ -126137,7 +126412,7 @@ async function fetchClaudeUsageViaCli() {
126137
126412
  }
126138
126413
  const clean = _stripClaudeAnsi(buf);
126139
126414
  if (clean.includes("Current session") || clean.includes("% left") || clean.includes("% used")) {
126140
- resolve36(buf);
126415
+ resolve37(buf);
126141
126416
  } else {
126142
126417
  reject2(new Error("Claude CLI timed out after 60s \u2014 got output but no usage data. Try running `claude /usage` manually."));
126143
126418
  }
@@ -126188,7 +126463,7 @@ async function fetchClaudeUsageViaCli() {
126188
126463
  ptyProcess.kill();
126189
126464
  } catch {
126190
126465
  }
126191
- resolve36(buf);
126466
+ resolve37(buf);
126192
126467
  }
126193
126468
  }, 2e3);
126194
126469
  }
@@ -126199,7 +126474,7 @@ async function fetchClaudeUsageViaCli() {
126199
126474
  if (settled) return;
126200
126475
  settled = true;
126201
126476
  clearTimeout(timeout2);
126202
- resolve36(buf);
126477
+ resolve37(buf);
126203
126478
  });
126204
126479
  });
126205
126480
  const cleanOutput = _stripClaudeAnsi(output);
@@ -126867,9 +127142,9 @@ async function fetchGitHubCopilotUsage() {
126867
127142
  return usage;
126868
127143
  }
126869
127144
  function withTimeout(providerPromise, providerName, timeoutMs = PROVIDER_FETCH_TIMEOUT_MS) {
126870
- return new Promise((resolve36) => {
127145
+ return new Promise((resolve37) => {
126871
127146
  const timer = setTimeout(() => {
126872
- resolve36({
127147
+ resolve37({
126873
127148
  name: providerName,
126874
127149
  icon: "\u23F1\uFE0F",
126875
127150
  status: "error",
@@ -126879,10 +127154,10 @@ function withTimeout(providerPromise, providerName, timeoutMs = PROVIDER_FETCH_T
126879
127154
  }, timeoutMs);
126880
127155
  providerPromise.then((result) => {
126881
127156
  clearTimeout(timer);
126882
- resolve36(result);
127157
+ resolve37(result);
126883
127158
  }).catch((err) => {
126884
127159
  clearTimeout(timer);
126885
- resolve36({
127160
+ resolve37({
126886
127161
  name: providerName,
126887
127162
  icon: "\u23F1\uFE0F",
126888
127163
  status: "error",
@@ -126937,7 +127212,7 @@ var init_usage = __esm({
126937
127212
  ANTHROPIC_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
126938
127213
  ANTHROPIC_OAUTH_BETA = "oauth-2025-04-20";
126939
127214
  CLAUDE_USAGE_USER_AGENT = "claude-code-fusion-dashboard";
126940
- _sleep = (ms) => new Promise((resolve36) => setTimeout(resolve36, ms));
127215
+ _sleep = (ms) => new Promise((resolve37) => setTimeout(resolve37, ms));
126941
127216
  sleepFn = _sleep;
126942
127217
  PROVIDER_FETCH_TIMEOUT_MS = 1e4;
126943
127218
  CLAUDE_FETCH_TIMEOUT_MS = 75e3;
@@ -127251,8 +127526,8 @@ var init_register_auth_routes = __esm({
127251
127526
  loginInProgress.set(provider, abortController);
127252
127527
  let authResolve;
127253
127528
  let authReject;
127254
- const authUrlPromise = new Promise((resolve36, reject2) => {
127255
- authResolve = resolve36;
127529
+ const authUrlPromise = new Promise((resolve37, reject2) => {
127530
+ authResolve = resolve37;
127256
127531
  authReject = reject2;
127257
127532
  });
127258
127533
  const loginPromise = storage.login(provider, {
@@ -127678,7 +127953,7 @@ async function mintAgentApiKeyViaCli(opts) {
127678
127953
  args.push("--data-dir", opts.dataDir);
127679
127954
  }
127680
127955
  const timeoutMs = opts.cliTimeoutMs ?? 3e4;
127681
- return new Promise((resolve36, reject2) => {
127956
+ return new Promise((resolve37, reject2) => {
127682
127957
  let child;
127683
127958
  try {
127684
127959
  child = spawn15(bin, args, { stdio: ["ignore", "pipe", "pipe"] });
@@ -127752,7 +128027,7 @@ async function mintAgentApiKeyViaCli(opts) {
127752
128027
  const apiBase = (typeof r.apiBase === "string" ? r.apiBase : void 0) ?? (typeof r.api_base === "string" ? r.api_base : void 0);
127753
128028
  const agentId = (typeof r.agentId === "string" ? r.agentId : void 0) ?? (typeof r.id === "string" ? r.id : void 0);
127754
128029
  const companyId = typeof r.companyId === "string" ? r.companyId : void 0;
127755
- resolve36({ apiKey, apiBase, agentId, companyId, raw: parsed });
128030
+ resolve37({ apiKey, apiBase, agentId, companyId, raw: parsed });
127756
128031
  });
127757
128032
  });
127758
128033
  }
@@ -127772,7 +128047,7 @@ async function spawnPaperclipCliJson(args, opts) {
127772
128047
  }
127773
128048
  const timeoutMs = opts.cliTimeoutMs ?? 15e3;
127774
128049
  const label = ["paperclipai", ...args].join(" ");
127775
- return new Promise((resolve36, reject2) => {
128050
+ return new Promise((resolve37, reject2) => {
127776
128051
  let child;
127777
128052
  try {
127778
128053
  child = spawn15(bin, fullArgs, { stdio: ["ignore", "pipe", "pipe"] });
@@ -127818,7 +128093,7 @@ async function spawnPaperclipCliJson(args, opts) {
127818
128093
  return;
127819
128094
  }
127820
128095
  try {
127821
- resolve36(JSON.parse(cleaned));
128096
+ resolve37(JSON.parse(cleaned));
127822
128097
  } catch {
127823
128098
  reject2(new Error(`${label} returned non-JSON output: ${cleaned.slice(0, 200)}`));
127824
128099
  }
@@ -127945,9 +128220,9 @@ var init_paperclip_client = __esm({
127945
128220
  });
127946
128221
 
127947
128222
  // ../../plugins/fusion-plugin-paperclip-runtime/dist/runtime-adapter.js
127948
- import { randomUUID as randomUUID17 } from "node:crypto";
128223
+ import { randomUUID as randomUUID18 } from "node:crypto";
127949
128224
  function sleep3(ms) {
127950
- return new Promise((resolve36) => setTimeout(resolve36, ms));
128225
+ return new Promise((resolve37) => setTimeout(resolve37, ms));
127951
128226
  }
127952
128227
  function asString2(value) {
127953
128228
  return typeof value === "string" ? value : void 0;
@@ -128064,7 +128339,7 @@ var init_runtime_adapter3 = __esm({
128064
128339
  apiKey: effectiveApiKey,
128065
128340
  agentId,
128066
128341
  companyId,
128067
- sessionId: randomUUID17(),
128342
+ sessionId: randomUUID18(),
128068
128343
  systemPrompt: options.systemPrompt,
128069
128344
  cwd: options.cwd,
128070
128345
  mode: normalizeMode(this.config.mode),
@@ -128590,8 +128865,8 @@ var init_register_runtime_provider_routes = __esm({
128590
128865
 
128591
128866
  // ../dashboard/src/update-check.ts
128592
128867
  import { readFileSync as readFileSync8 } from "node:fs";
128593
- import { mkdir as mkdir15, rm as rm4, writeFile as writeFile13 } from "node:fs/promises";
128594
- import { join as join42 } from "node:path";
128868
+ import { mkdir as mkdir16, rm as rm5, writeFile as writeFile14 } from "node:fs/promises";
128869
+ import { join as join43 } from "node:path";
128595
128870
  function ttlForFrequency(frequency) {
128596
128871
  switch (frequency) {
128597
128872
  case "manual":
@@ -128605,7 +128880,7 @@ function ttlForFrequency(frequency) {
128605
128880
  }
128606
128881
  }
128607
128882
  function getCachePath(fusionDir) {
128608
- return join42(fusionDir, CACHE_FILENAME);
128883
+ return join43(fusionDir, CACHE_FILENAME);
128609
128884
  }
128610
128885
  function parseVersion(version) {
128611
128886
  return version.split(".").slice(0, 3).map((part) => Number.parseInt(part, 10)).map((value) => Number.isFinite(value) ? value : 0);
@@ -128637,7 +128912,7 @@ function readCachedUpdateCheck(fusionDir) {
128637
128912
  }
128638
128913
  }
128639
128914
  async function clearUpdateCheckCache(fusionDir) {
128640
- await rm4(getCachePath(fusionDir), { force: true });
128915
+ await rm5(getCachePath(fusionDir), { force: true });
128641
128916
  }
128642
128917
  async function performUpdateCheck(fusionDir, currentVersion, options = {}) {
128643
128918
  const now = Date.now();
@@ -128669,8 +128944,8 @@ async function performUpdateCheck(fusionDir, currentVersion, options = {}) {
128669
128944
  updateAvailable,
128670
128945
  lastChecked: now
128671
128946
  };
128672
- await mkdir15(fusionDir, { recursive: true });
128673
- await writeFile13(getCachePath(fusionDir), JSON.stringify(result, null, 2), "utf-8");
128947
+ await mkdir16(fusionDir, { recursive: true });
128948
+ await writeFile14(getCachePath(fusionDir), JSON.stringify(result, null, 2), "utf-8");
128674
128949
  hasRefreshedThisProcess = true;
128675
128950
  return result;
128676
128951
  } catch (error) {
@@ -128697,7 +128972,7 @@ var init_update_check = __esm({
128697
128972
 
128698
128973
  // ../dashboard/src/routes/register-update-check-routes.ts
128699
128974
  import { readFileSync as readFileSync9 } from "node:fs";
128700
- import { dirname as dirname13, join as join43 } from "node:path";
128975
+ import { dirname as dirname13, join as join44 } from "node:path";
128701
128976
  import { fileURLToPath as fileURLToPath3 } from "node:url";
128702
128977
  var __dirname, CLI_PACKAGE_VERSION, registerUpdateCheckRoutes;
128703
128978
  var init_register_update_check_routes = __esm({
@@ -128708,7 +128983,7 @@ var init_register_update_check_routes = __esm({
128708
128983
  __dirname = dirname13(fileURLToPath3(import.meta.url));
128709
128984
  CLI_PACKAGE_VERSION = (() => {
128710
128985
  try {
128711
- const packageJsonPath = join43(__dirname, "..", "..", "..", "cli", "package.json");
128986
+ const packageJsonPath = join44(__dirname, "..", "..", "..", "cli", "package.json");
128712
128987
  const packageJson = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
128713
128988
  if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
128714
128989
  return packageJson.version;
@@ -132693,7 +132968,7 @@ var init_todo_routes = __esm({
132693
132968
 
132694
132969
  // ../dashboard/src/dev-server-detect.ts
132695
132970
  import { glob, readFile as readFile20 } from "node:fs/promises";
132696
- import { dirname as dirname14, join as join44, relative as relative10, resolve as resolve20 } from "node:path";
132971
+ import { dirname as dirname14, join as join45, relative as relative10, resolve as resolve21 } from "node:path";
132697
132972
  async function readPackageJson(filePath) {
132698
132973
  try {
132699
132974
  const raw = await readFile20(filePath, "utf-8");
@@ -132736,14 +133011,14 @@ function scoreCandidate(scriptName, pkg) {
132736
133011
  async function collectWorkspacePackageJsons(projectRoot) {
132737
133012
  const discovered = /* @__PURE__ */ new Set();
132738
133013
  try {
132739
- await readFile20(join44(projectRoot, "pnpm-workspace.yaml"), "utf-8");
133014
+ await readFile20(join45(projectRoot, "pnpm-workspace.yaml"), "utf-8");
132740
133015
  } catch {
132741
133016
  }
132742
133017
  for (const pattern of ["packages/*/package.json", "apps/*/package.json"]) {
132743
133018
  try {
132744
133019
  for await (const match of glob(pattern, { cwd: projectRoot })) {
132745
133020
  if (typeof match === "string") {
132746
- discovered.add(resolve20(projectRoot, match));
133021
+ discovered.add(resolve21(projectRoot, match));
132747
133022
  }
132748
133023
  }
132749
133024
  } catch {
@@ -132768,9 +133043,9 @@ function toSource(projectRoot, packageJsonPath) {
132768
133043
  return rel.length > 0 ? rel : "root";
132769
133044
  }
132770
133045
  async function detectDevServerScripts(projectRoot) {
132771
- const root = resolve20(projectRoot);
133046
+ const root = resolve21(projectRoot);
132772
133047
  const candidates = [];
132773
- const rootPackagePath = join44(root, "package.json");
133048
+ const rootPackagePath = join45(root, "package.json");
132774
133049
  const rootPackage = await readPackageJson(rootPackagePath);
132775
133050
  if (rootPackage) {
132776
133051
  for (const script of extractScripts(rootPackage)) {
@@ -132836,10 +133111,10 @@ var init_dev_server_detect = __esm({
132836
133111
  });
132837
133112
 
132838
133113
  // ../dashboard/src/dev-server-store.ts
132839
- import { mkdir as mkdir16, readFile as readFile21, writeFile as writeFile14 } from "node:fs/promises";
132840
- import { dirname as dirname15, join as join45, resolve as resolve21 } from "node:path";
133114
+ import { mkdir as mkdir17, readFile as readFile21, writeFile as writeFile15 } from "node:fs/promises";
133115
+ import { dirname as dirname15, join as join46, resolve as resolve22 } from "node:path";
132841
133116
  function devServerFilePath(projectDir) {
132842
- return join45(resolve21(projectDir), ".fusion", "dev-server.json");
133117
+ return join46(resolve22(projectDir), ".fusion", "dev-server.json");
132843
133118
  }
132844
133119
  function normalizeState(candidate) {
132845
133120
  const defaults = DEV_SERVER_DEFAULT_STATE();
@@ -132874,7 +133149,7 @@ function normalizeConfig(candidate) {
132874
133149
  };
132875
133150
  }
132876
133151
  async function loadDevServerStore(projectDir) {
132877
- const storeKey = resolve21(projectDir);
133152
+ const storeKey = resolve22(projectDir);
132878
133153
  let store = storeInstances.get(storeKey);
132879
133154
  if (!store) {
132880
133155
  store = new DevServerStore(projectDir);
@@ -132933,7 +133208,7 @@ var init_dev_server_store = __esm({
132933
133208
  return error.code === "ENOENT";
132934
133209
  };
132935
133210
  try {
132936
- await mkdir16(dir2, { recursive: true });
133211
+ await mkdir17(dir2, { recursive: true });
132937
133212
  } catch (error) {
132938
133213
  if (isMissingPathError(error)) {
132939
133214
  return;
@@ -132941,13 +133216,13 @@ var init_dev_server_store = __esm({
132941
133216
  throw error;
132942
133217
  }
132943
133218
  try {
132944
- await writeFile14(this.filePath, serializedPayload, "utf-8");
133219
+ await writeFile15(this.filePath, serializedPayload, "utf-8");
132945
133220
  } catch (error) {
132946
133221
  if (!isMissingPathError(error)) {
132947
133222
  throw error;
132948
133223
  }
132949
133224
  try {
132950
- await mkdir16(dir2, { recursive: true });
133225
+ await mkdir17(dir2, { recursive: true });
132951
133226
  } catch (retryMkdirError) {
132952
133227
  if (isMissingPathError(retryMkdirError)) {
132953
133228
  return;
@@ -132955,7 +133230,7 @@ var init_dev_server_store = __esm({
132955
133230
  throw retryMkdirError;
132956
133231
  }
132957
133232
  try {
132958
- await writeFile14(this.filePath, serializedPayload, "utf-8");
133233
+ await writeFile15(this.filePath, serializedPayload, "utf-8");
132959
133234
  } catch (retryWriteError) {
132960
133235
  if (isMissingPathError(retryWriteError)) {
132961
133236
  return;
@@ -133152,7 +133427,7 @@ function detectPortFromLogLine(line) {
133152
133427
  return detectViteLine(cleanLine) ?? detectNextLine(cleanLine) ?? detectStorybookLine(cleanLine) ?? detectAngularLine(cleanLine) ?? detectGenericUrl(cleanLine) ?? detectGenericPortLine(cleanLine);
133153
133428
  }
133154
133429
  function probePort(host, port, timeoutMs) {
133155
- return new Promise((resolve36) => {
133430
+ return new Promise((resolve37) => {
133156
133431
  let settled = false;
133157
133432
  const socket = createConnection({ host, port });
133158
133433
  const settle = (isOpen) => {
@@ -133166,7 +133441,7 @@ function probePort(host, port, timeoutMs) {
133166
133441
  } else {
133167
133442
  socket.destroy();
133168
133443
  }
133169
- resolve36(isOpen);
133444
+ resolve37(isOpen);
133170
133445
  };
133171
133446
  socket.setTimeout(timeoutMs);
133172
133447
  socket.once("connect", () => settle(true));
@@ -133293,8 +133568,8 @@ var init_dev_server_process = __esm({
133293
133568
  stdio: ["pipe", "pipe", "pipe"]
133294
133569
  });
133295
133570
  this.childProcess = child;
133296
- this.closePromise = new Promise((resolve36) => {
133297
- this.resolveClosePromise = resolve36;
133571
+ this.closePromise = new Promise((resolve37) => {
133572
+ this.resolveClosePromise = resolve37;
133298
133573
  });
133299
133574
  const runningState = await this.store.updateState({
133300
133575
  pid: child.pid,
@@ -134091,7 +134366,7 @@ Your job is to refine task descriptions based on the user's selected refinement
134091
134366
 
134092
134367
  // ../dashboard/src/routes.ts
134093
134368
  import multer from "multer";
134094
- import { resolve as resolve22, sep as sep6, join as join46, isAbsolute as isAbsolute15 } from "node:path";
134369
+ import { resolve as resolve23, sep as sep6, join as join47, isAbsolute as isAbsolute15 } from "node:path";
134095
134370
  import * as nodeFs from "node:fs";
134096
134371
  import os5 from "node:os";
134097
134372
  import v8 from "node:v8";
@@ -134112,8 +134387,8 @@ function hasPackageManagerSettings2(settings) {
134112
134387
  function getPiPackageManagerAgentDir() {
134113
134388
  const fusionAgentDir = getFusionAgentDir();
134114
134389
  const legacyAgentDir = getLegacyPiAgentDir();
134115
- const fusionSettings = readJsonObject3(join46(fusionAgentDir, "settings.json"));
134116
- const legacySettings = readJsonObject3(join46(legacyAgentDir, "settings.json"));
134390
+ const fusionSettings = readJsonObject3(join47(fusionAgentDir, "settings.json"));
134391
+ const legacySettings = readJsonObject3(join47(legacyAgentDir, "settings.json"));
134117
134392
  if (hasPackageManagerSettings2(fusionSettings) || !nodeFs.existsSync(legacyAgentDir)) {
134118
134393
  return fusionAgentDir;
134119
134394
  }
@@ -134123,7 +134398,7 @@ function getPiPackageManagerAgentDir() {
134123
134398
  return nodeFs.existsSync(fusionAgentDir) ? fusionAgentDir : legacyAgentDir;
134124
134399
  }
134125
134400
  function packageExtensionName(extensionPath, source) {
134126
- const base = resolve22(extensionPath).split(sep6).pop()?.replace(/\.(ts|js)$/i, "") || source;
134401
+ const base = resolve23(extensionPath).split(sep6).pop()?.replace(/\.(ts|js)$/i, "") || source;
134127
134402
  if (base !== "index") {
134128
134403
  return base;
134129
134404
  }
@@ -134131,15 +134406,15 @@ function packageExtensionName(extensionPath, source) {
134131
134406
  }
134132
134407
  async function discoverDashboardPiExtensions(cwd) {
134133
134408
  const settings = discoverPiExtensions(cwd);
134134
- const disabled = new Set(settings.disabledIds.map((id) => resolve22(id)));
134409
+ const disabled = new Set(settings.disabledIds.map((id) => resolve23(id)));
134135
134410
  const byPath = new Map(settings.extensions.map((entry) => [entry.id, entry]));
134136
134411
  try {
134137
134412
  const { DefaultPackageManager: DefaultPackageManager5 } = await import("@mariozechner/pi-coding-agent");
134138
134413
  const agentDir = getPiPackageManagerAgentDir();
134139
- const legacyGlobalSettings = readJsonObject3(join46(getLegacyPiAgentDir(), "settings.json"));
134140
- const fusionGlobalSettings = readJsonObject3(join46(getFusionAgentDir(), "settings.json"));
134414
+ const legacyGlobalSettings = readJsonObject3(join47(getLegacyPiAgentDir(), "settings.json"));
134415
+ const fusionGlobalSettings = readJsonObject3(join47(getFusionAgentDir(), "settings.json"));
134141
134416
  const globalSettings = { ...legacyGlobalSettings, ...fusionGlobalSettings };
134142
- const projectSettings = readJsonObject3(join46(cwd, ".fusion", "settings.json"));
134417
+ const projectSettings = readJsonObject3(join47(cwd, ".fusion", "settings.json"));
134143
134418
  const mergedSettings = { ...globalSettings, ...projectSettings };
134144
134419
  const packageManager = new DefaultPackageManager5({
134145
134420
  cwd,
@@ -134153,7 +134428,7 @@ async function discoverDashboardPiExtensions(cwd) {
134153
134428
  });
134154
134429
  const resolved = await packageManager.resolve(async () => "skip");
134155
134430
  for (const extension2 of resolved.extensions) {
134156
- const id = resolve22(extension2.path);
134431
+ const id = resolve23(extension2.path);
134157
134432
  const source = extension2.metadata?.source || "package";
134158
134433
  byPath.set(id, {
134159
134434
  id,
@@ -134543,7 +134818,8 @@ function createApiRoutes(store, options) {
134543
134818
  });
134544
134819
  registerChatRoutes(routeContext, {
134545
134820
  parseLastEventId: parseLastEventId2,
134546
- validateOptionalModelField
134821
+ validateOptionalModelField,
134822
+ upload
134547
134823
  });
134548
134824
  registerMessagingScriptRoutes(routeContext);
134549
134825
  registerGitGitHubRoutes(routeContext);
@@ -134555,8 +134831,8 @@ function createApiRoutes(store, options) {
134555
134831
  function isHeartbeatMonitorForProject(scopedStore) {
134556
134832
  if (!heartbeatMonitor?.rootDir) return true;
134557
134833
  try {
134558
- const monitorRoot = resolve22(heartbeatMonitor.rootDir);
134559
- const storeRoot = resolve22(scopedStore.getRootDir());
134834
+ const monitorRoot = resolve23(heartbeatMonitor.rootDir);
134835
+ const storeRoot = resolve23(scopedStore.getRootDir());
134560
134836
  return monitorRoot === storeRoot;
134561
134837
  } catch {
134562
134838
  return true;
@@ -136478,15 +136754,15 @@ Description: ${step.description}`
136478
136754
  return;
136479
136755
  }
136480
136756
  }
136481
- const { resolve: resolve36, dirname: dirname28, join: join65 } = await import("node:path");
136757
+ const { resolve: resolve37, dirname: dirname28, join: join66 } = await import("node:path");
136482
136758
  const { readdir: readdir12, stat: stat12 } = await import("node:fs/promises");
136483
136759
  const rawPath = req.query.path || process.env.HOME || process.env.USERPROFILE || "/";
136484
136760
  const showHidden = req.query.showHidden === "true";
136485
- const resolvedPath = resolve36(rawPath);
136761
+ const resolvedPath = resolve37(rawPath);
136486
136762
  if (rawPath.includes("..")) {
136487
136763
  throw badRequest("Path must not contain '..' traversal");
136488
136764
  }
136489
- if (resolvedPath !== resolve36(resolvedPath)) {
136765
+ if (resolvedPath !== resolve37(resolvedPath)) {
136490
136766
  throw badRequest("Path must be absolute");
136491
136767
  }
136492
136768
  let pathStat;
@@ -136503,7 +136779,7 @@ Description: ${step.description}`
136503
136779
  for (const entry of dirEntries) {
136504
136780
  if (!entry.isDirectory()) continue;
136505
136781
  if (!showHidden && entry.name.startsWith(".")) continue;
136506
- const entryPath = join65(resolvedPath, entry.name);
136782
+ const entryPath = join66(resolvedPath, entry.name);
136507
136783
  let hasChildren = false;
136508
136784
  try {
136509
136785
  const subEntries = await readdir12(entryPath, { withFileTypes: true });
@@ -141813,7 +142089,7 @@ var init_badge_pubsub = __esm({
141813
142089
  });
141814
142090
 
141815
142091
  // ../dashboard/src/terminal-websocket-diagnostics.ts
141816
- import { basename as basename11, normalize as normalize4, sep as sep7 } from "node:path";
142092
+ import { basename as basename12, normalize as normalize4, sep as sep7 } from "node:path";
141817
142093
  function toSessionTag(sessionId) {
141818
142094
  const normalized = sessionId.trim();
141819
142095
  if (normalized.length <= 8) {
@@ -141860,8 +142136,8 @@ function createTerminalWebSocketDiagnostics(runtimeLogger) {
141860
142136
  projectId,
141861
142137
  sessionCwdHint: toRedactedPathHint(sessionCwd),
141862
142138
  scopedRootHint: toRedactedPathHint(scopedRootDir),
141863
- sessionCwdBase: basename11(sessionCwd),
141864
- scopedRootBase: basename11(scopedRootDir)
142139
+ sessionCwdBase: basename12(sessionCwd),
142140
+ scopedRootBase: basename12(scopedRootDir)
141865
142141
  });
141866
142142
  },
141867
142143
  staleReconnect({ sessionId, idleMs, staleThresholdMs }) {
@@ -142003,8 +142279,8 @@ var init_auth_middleware = __esm({
142003
142279
 
142004
142280
  // ../dashboard/src/server.ts
142005
142281
  import express from "express";
142006
- import { randomUUID as randomUUID18 } from "node:crypto";
142007
- import { join as join47, dirname as dirname16 } from "node:path";
142282
+ import { randomUUID as randomUUID19 } from "node:crypto";
142283
+ import { join as join48, dirname as dirname16 } from "node:path";
142008
142284
  import { existsSync as existsSync30, readFileSync as readFileSync11 } from "node:fs";
142009
142285
  import { fileURLToPath as fileURLToPath4 } from "node:url";
142010
142286
  import { createSecureServer as createHttp2SecureServer } from "node:http2";
@@ -142186,11 +142462,11 @@ function createServer(store, options) {
142186
142462
  getTerminalService(store.getRootDir());
142187
142463
  const isHeadless = options?.headless === true;
142188
142464
  const execDir = dirname16(process.execPath);
142189
- const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync30(join47(execDir, "client", "index.html")) ? join47(execDir, "client") : existsSync30(join47(__dirname2, "..", "dist", "client")) ? join47(__dirname2, "..", "dist", "client") : join47(__dirname2, "..", "client");
142465
+ const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync30(join48(execDir, "client", "index.html")) ? join48(execDir, "client") : existsSync30(join48(__dirname2, "..", "dist", "client")) ? join48(__dirname2, "..", "dist", "client") : join48(__dirname2, "..", "client");
142190
142466
  if (!isHeadless) {
142191
142467
  app.get("/version.json", (_req, res) => {
142192
142468
  res.setHeader("Cache-Control", "no-store, max-age=0");
142193
- res.sendFile(join47(clientDir, "version.json"), (err) => {
142469
+ res.sendFile(join48(clientDir, "version.json"), (err) => {
142194
142470
  if (err) {
142195
142471
  res.status(404).json({ version: null });
142196
142472
  }
@@ -142610,7 +142886,7 @@ data: ${JSON.stringify({ type: event.type, data: event.data })}
142610
142886
  });
142611
142887
  if (!isHeadless) {
142612
142888
  app.get("/{*splat}", (_req, res) => {
142613
- res.sendFile(join47(clientDir, "index.html"));
142889
+ res.sendFile(join48(clientDir, "index.html"));
142614
142890
  });
142615
142891
  }
142616
142892
  const dashboardApp = app;
@@ -142849,7 +143125,7 @@ function setupBadgeWebSocket(app, server, store, options) {
142849
143125
  const dashboardApp = app;
142850
143126
  const wsManager = new WebSocketManager();
142851
143127
  const badgeSnapshots = /* @__PURE__ */ new Map();
142852
- const serverId = randomUUID18();
143128
+ const serverId = randomUUID19();
142853
143129
  const badgePubSub = options?.badgePubSub ?? createBadgePubSub({ sourceId: serverId });
142854
143130
  void badgePubSub.start();
142855
143131
  const scopedStores = /* @__PURE__ */ new Map();
@@ -142983,7 +143259,7 @@ function setupBadgeWebSocket(app, server, store, options) {
142983
143259
  const url = new URL(req.url || "", `http://${req.headers.host}`);
142984
143260
  const projectId = url.searchParams.get("projectId") ?? "default";
142985
143261
  void ensureScopedListeners(projectId);
142986
- wsManager.addClient(ws, randomUUID18(), projectId);
143262
+ wsManager.addClient(ws, randomUUID19(), projectId);
142987
143263
  });
142988
143264
  server.once("close", () => {
142989
143265
  for (const cleanup of scopedCleanups.values()) {
@@ -143052,7 +143328,7 @@ var init_server = __esm({
143052
143328
  __dirname2 = dirname16(fileURLToPath4(import.meta.url));
143053
143329
  PACKAGE_VERSION = (() => {
143054
143330
  try {
143055
- const packageJsonPath = join47(__dirname2, "..", "package.json");
143331
+ const packageJsonPath = join48(__dirname2, "..", "package.json");
143056
143332
  const packageJson = JSON.parse(readFileSync11(packageJsonPath, "utf-8"));
143057
143333
  if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
143058
143334
  return packageJson.version;
@@ -143063,7 +143339,7 @@ var init_server = __esm({
143063
143339
  })();
143064
143340
  CLI_PACKAGE_VERSION2 = (() => {
143065
143341
  try {
143066
- const packageJsonPath = join47(__dirname2, "..", "..", "cli", "package.json");
143342
+ const packageJsonPath = join48(__dirname2, "..", "..", "cli", "package.json");
143067
143343
  const packageJson = JSON.parse(readFileSync11(packageJsonPath, "utf-8"));
143068
143344
  if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
143069
143345
  return packageJson.version;
@@ -143085,8 +143361,8 @@ var init_server = __esm({
143085
143361
  });
143086
143362
 
143087
143363
  // ../dashboard/src/skills-adapter.ts
143088
- import { access as access9, readFile as readFile22, writeFile as writeFile15, mkdir as mkdir17, readdir as readdir10, stat as stat10 } from "node:fs/promises";
143089
- import { join as join48, relative as relative11, dirname as dirname17 } from "node:path";
143364
+ import { access as access9, readFile as readFile22, writeFile as writeFile16, mkdir as mkdir18, readdir as readdir10, stat as stat10 } from "node:fs/promises";
143365
+ import { join as join49, relative as relative11, dirname as dirname17 } from "node:path";
143090
143366
  async function pathExists(path5) {
143091
143367
  try {
143092
143368
  await access9(path5);
@@ -143184,7 +143460,7 @@ function createSkillsAdapter(options) {
143184
143460
  const settingsPath = options.getSettingsPath(rootDir);
143185
143461
  const settingsDir = dirname17(settingsPath);
143186
143462
  if (!await pathExists(settingsDir)) {
143187
- await mkdir17(settingsDir, { recursive: true });
143463
+ await mkdir18(settingsDir, { recursive: true });
143188
143464
  }
143189
143465
  let settings = {};
143190
143466
  if (await pathExists(settingsPath)) {
@@ -143213,7 +143489,7 @@ function createSkillsAdapter(options) {
143213
143489
  }
143214
143490
  skills.push(`${prefix}${skillPath}`);
143215
143491
  settings.skills = skills;
143216
- await writeFile15(settingsPath, JSON.stringify(settings, null, 2));
143492
+ await writeFile16(settingsPath, JSON.stringify(settings, null, 2));
143217
143493
  return {
143218
143494
  settingsPath: "skills",
143219
143495
  pattern: `${prefix}${skillPath}`,
@@ -143250,7 +143526,7 @@ function createSkillsAdapter(options) {
143250
143526
  }
143251
143527
  pkgEntry.skills.push(`${prefix}${skillPath}`);
143252
143528
  settings.packages = packages;
143253
- await writeFile15(settingsPath, JSON.stringify(settings, null, 2));
143529
+ await writeFile16(settingsPath, JSON.stringify(settings, null, 2));
143254
143530
  return {
143255
143531
  settingsPath: "packages[].skills",
143256
143532
  pattern: `${prefix}${skillPath}`,
@@ -143342,7 +143618,7 @@ function createSkillsAdapter(options) {
143342
143618
  } catch {
143343
143619
  skillDir = dirname17(skill.path);
143344
143620
  }
143345
- const skillMdPath = join48(skillDir, "SKILL.md");
143621
+ const skillMdPath = join49(skillDir, "SKILL.md");
143346
143622
  let skillMd = "";
143347
143623
  try {
143348
143624
  skillMd = await readFile22(skillMdPath, "utf-8");
@@ -143550,7 +143826,7 @@ function normalizeEntry(entry) {
143550
143826
  };
143551
143827
  }
143552
143828
  function getProjectSettingsPath(rootDir) {
143553
- return join48(rootDir, ".fusion", "settings.json");
143829
+ return join49(rootDir, ".fusion", "settings.json");
143554
143830
  }
143555
143831
  var MIN_PUBLIC_SEARCH_QUERY_LENGTH;
143556
143832
  var init_skills_adapter = __esm({
@@ -143725,7 +144001,7 @@ var init_task_lifecycle = __esm({
143725
144001
  // src/commands/port-prompt.ts
143726
144002
  import { createInterface } from "node:readline";
143727
144003
  function promptForPort(defaultPort = 4040, input = process.stdin) {
143728
- return new Promise((resolve36, reject2) => {
144004
+ return new Promise((resolve37, reject2) => {
143729
144005
  const rl = createInterface({
143730
144006
  input,
143731
144007
  output: process.stdout
@@ -143742,7 +144018,7 @@ function promptForPort(defaultPort = 4040, input = process.stdin) {
143742
144018
  if (trimmed === "") {
143743
144019
  process.removeListener("SIGINT", sigintHandler);
143744
144020
  rl.close();
143745
- resolve36(defaultPort);
144021
+ resolve37(defaultPort);
143746
144022
  return;
143747
144023
  }
143748
144024
  const port = parseInt(trimmed, 10);
@@ -143758,7 +144034,7 @@ function promptForPort(defaultPort = 4040, input = process.stdin) {
143758
144034
  }
143759
144035
  process.removeListener("SIGINT", sigintHandler);
143760
144036
  rl.close();
143761
- resolve36(port);
144037
+ resolve37(port);
143762
144038
  });
143763
144039
  };
143764
144040
  ask();
@@ -143772,12 +144048,12 @@ var init_port_prompt = __esm({
143772
144048
 
143773
144049
  // src/commands/provider-settings.ts
143774
144050
  import { existsSync as existsSync31, readFileSync as readFileSync12, writeFileSync as writeFileSync2, mkdirSync as mkdirSync6 } from "node:fs";
143775
- import { join as join49, dirname as dirname18, basename as basename12 } from "node:path";
144051
+ import { join as join50, dirname as dirname18, basename as basename13 } from "node:path";
143776
144052
  function siblingAgentDir2(agentDir, siblingRoot) {
143777
- if (basename12(agentDir) !== "agent") {
144053
+ if (basename13(agentDir) !== "agent") {
143778
144054
  return void 0;
143779
144055
  }
143780
- return join49(dirname18(dirname18(agentDir)), siblingRoot, "agent");
144056
+ return join50(dirname18(dirname18(agentDir)), siblingRoot, "agent");
143781
144057
  }
143782
144058
  function readJsonObject4(path5) {
143783
144059
  if (!existsSync31(path5)) {
@@ -143791,13 +144067,13 @@ function readJsonObject4(path5) {
143791
144067
  }
143792
144068
  }
143793
144069
  function createReadOnlyProviderSettingsView(cwd, agentDir) {
143794
- const fusionAgentDir = agentDir.includes(`${join49(".fusion", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".fusion");
143795
- const legacyAgentDir = agentDir.includes(`${join49(".pi", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".pi");
143796
- const legacyGlobalSettings = legacyAgentDir ? readJsonObject4(join49(legacyAgentDir, "settings.json")) : {};
143797
- const fusionGlobalSettings = fusionAgentDir ? readJsonObject4(join49(fusionAgentDir, "settings.json")) : {};
143798
- const directGlobalSettings = readJsonObject4(join49(agentDir, "settings.json"));
144070
+ const fusionAgentDir = agentDir.includes(`${join50(".fusion", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".fusion");
144071
+ const legacyAgentDir = agentDir.includes(`${join50(".pi", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".pi");
144072
+ const legacyGlobalSettings = legacyAgentDir ? readJsonObject4(join50(legacyAgentDir, "settings.json")) : {};
144073
+ const fusionGlobalSettings = fusionAgentDir ? readJsonObject4(join50(fusionAgentDir, "settings.json")) : {};
144074
+ const directGlobalSettings = readJsonObject4(join50(agentDir, "settings.json"));
143799
144075
  const globalSettings = { ...legacyGlobalSettings, ...directGlobalSettings, ...fusionGlobalSettings };
143800
- const fusionProjectSettings = readJsonObject4(join49(cwd, ".fusion", "settings.json"));
144076
+ const fusionProjectSettings = readJsonObject4(join50(cwd, ".fusion", "settings.json"));
143801
144077
  const mergedSettings = { ...globalSettings, ...fusionProjectSettings };
143802
144078
  return {
143803
144079
  getGlobalSettings: () => structuredClone(globalSettings),
@@ -143983,29 +144259,29 @@ var init_provider_auth = __esm({
143983
144259
  // src/commands/auth-paths.ts
143984
144260
  import { homedir as homedir7 } from "node:os";
143985
144261
  import { existsSync as existsSync33, readFileSync as readFileSync14 } from "node:fs";
143986
- import { join as join50 } from "node:path";
144262
+ import { join as join51 } from "node:path";
143987
144263
  function getFusionAgentDir3(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
143988
- return join50(home, ".fusion", "agent");
144264
+ return join51(home, ".fusion", "agent");
143989
144265
  }
143990
144266
  function getLegacyAgentDir(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
143991
- return join50(home, ".pi", "agent");
144267
+ return join51(home, ".pi", "agent");
143992
144268
  }
143993
144269
  function getFusionAuthPath3(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
143994
- return join50(getFusionAgentDir3(home), "auth.json");
144270
+ return join51(getFusionAgentDir3(home), "auth.json");
143995
144271
  }
143996
144272
  function getLegacyAuthPaths2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
143997
144273
  return [
143998
- join50(home, ".pi", "agent", "auth.json"),
143999
- join50(home, ".pi", "auth.json")
144274
+ join51(home, ".pi", "agent", "auth.json"),
144275
+ join51(home, ".pi", "auth.json")
144000
144276
  ];
144001
144277
  }
144002
144278
  function getFusionModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144003
- return join50(getFusionAgentDir3(home), "models.json");
144279
+ return join51(getFusionAgentDir3(home), "models.json");
144004
144280
  }
144005
144281
  function getLegacyModelsPaths2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144006
144282
  return [
144007
- join50(home, ".pi", "agent", "models.json"),
144008
- join50(home, ".pi", "models.json")
144283
+ join51(home, ".pi", "agent", "models.json"),
144284
+ join51(home, ".pi", "models.json")
144009
144285
  ];
144010
144286
  }
144011
144287
  function getModelRegistryModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
@@ -144032,8 +144308,8 @@ function hasPackageManagerSettings3(settings) {
144032
144308
  function getPackageManagerAgentDir2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144033
144309
  const fusionAgentDir = getFusionAgentDir3(home);
144034
144310
  const legacyAgentDir = getLegacyAgentDir(home);
144035
- const fusionSettings = readJsonObject5(join50(fusionAgentDir, "settings.json"));
144036
- const legacySettings = readJsonObject5(join50(legacyAgentDir, "settings.json"));
144311
+ const fusionSettings = readJsonObject5(join51(fusionAgentDir, "settings.json"));
144312
+ const legacySettings = readJsonObject5(join51(legacyAgentDir, "settings.json"));
144037
144313
  if (hasPackageManagerSettings3(fusionSettings) || !existsSync33(legacyAgentDir)) {
144038
144314
  return fusionAgentDir;
144039
144315
  }
@@ -144049,7 +144325,7 @@ var init_auth_paths2 = __esm({
144049
144325
  });
144050
144326
 
144051
144327
  // src/project-context.ts
144052
- import { resolve as resolve23, dirname as dirname19 } from "node:path";
144328
+ import { resolve as resolve24, dirname as dirname19 } from "node:path";
144053
144329
  import { existsSync as existsSync34 } from "node:fs";
144054
144330
  async function resolveProject(projectNameFlag, cwd = process.cwd(), globalDir) {
144055
144331
  const central = new CentralCore(globalDir);
@@ -144141,9 +144417,9 @@ async function clearDefaultProject(globalDir) {
144141
144417
  await globalStore.updateSettings(rest);
144142
144418
  }
144143
144419
  async function detectProjectFromCwd(cwd, central) {
144144
- let currentDir = resolve23(cwd);
144420
+ let currentDir = resolve24(cwd);
144145
144421
  while (true) {
144146
- const kbPath = resolve23(currentDir, ".fusion", "fusion.db");
144422
+ const kbPath = resolve24(currentDir, ".fusion", "fusion.db");
144147
144423
  if (existsSync34(kbPath)) {
144148
144424
  const project = await central.getProjectByPath(currentDir);
144149
144425
  if (project) {
@@ -144207,7 +144483,7 @@ import {
144207
144483
  symlinkSync,
144208
144484
  unlinkSync
144209
144485
  } from "node:fs";
144210
- import { dirname as dirname20, join as join51, resolve as resolve24 } from "node:path";
144486
+ import { dirname as dirname20, join as join52, resolve as resolve25 } from "node:path";
144211
144487
  import { fileURLToPath as fileURLToPath5 } from "node:url";
144212
144488
  function isPiClaudeCliConfigured(globalSettings) {
144213
144489
  if (!globalSettings || typeof globalSettings !== "object") {
@@ -144227,11 +144503,11 @@ function isPiClaudeCliConfigured(globalSettings) {
144227
144503
  }
144228
144504
  function resolveFusionSkillSource() {
144229
144505
  const here = fileURLToPath5(import.meta.url);
144230
- const candidate = resolve24(dirname20(here), "..", "..", "skill", FUSION_SKILL_NAME);
144506
+ const candidate = resolve25(dirname20(here), "..", "..", "skill", FUSION_SKILL_NAME);
144231
144507
  return existsSync35(candidate) ? candidate : null;
144232
144508
  }
144233
144509
  function installFusionSkillIntoProject(projectPath, options = {}) {
144234
- const target = join51(projectPath, ".claude", "skills", FUSION_SKILL_NAME);
144510
+ const target = join52(projectPath, ".claude", "skills", FUSION_SKILL_NAME);
144235
144511
  if (options.enabled === false) {
144236
144512
  return { outcome: "skipped", target, reason: "pi-claude-cli not configured" };
144237
144513
  }
@@ -144250,13 +144526,13 @@ function installFusionSkillIntoProject(projectPath, options = {}) {
144250
144526
  const stat12 = lstatSync2(target);
144251
144527
  if (stat12.isSymbolicLink()) {
144252
144528
  const current = safeReadlink(target);
144253
- if (current && resolve24(dirname20(target), current) === resolve24(source)) {
144529
+ if (current && resolve25(dirname20(target), current) === resolve25(source)) {
144254
144530
  return { outcome: "already-installed", target, source };
144255
144531
  }
144256
144532
  unlinkSync(target);
144257
144533
  replaced = true;
144258
144534
  } else {
144259
- const skillMd = join51(target, "SKILL.md");
144535
+ const skillMd = join52(target, "SKILL.md");
144260
144536
  if (!existsSync35(skillMd)) {
144261
144537
  return {
144262
144538
  outcome: "failed",
@@ -144303,7 +144579,7 @@ function ensureFusionSkillForProjects(projects, options = { enabled: false }) {
144303
144579
  if (!options.enabled) {
144304
144580
  return projects.map((p) => ({
144305
144581
  outcome: "skipped",
144306
- target: join51(p.path, ".claude", "skills", FUSION_SKILL_NAME),
144582
+ target: join52(p.path, ".claude", "skills", FUSION_SKILL_NAME),
144307
144583
  reason: "pi-claude-cli not configured"
144308
144584
  }));
144309
144585
  }
@@ -144415,13 +144691,13 @@ var init_claude_skills_runner = __esm({
144415
144691
  // src/commands/claude-cli-extension.ts
144416
144692
  import { existsSync as existsSync36, readFileSync as readFileSync15 } from "node:fs";
144417
144693
  import { createRequire as createRequire4 } from "node:module";
144418
- import { dirname as dirname21, resolve as resolve25 } from "node:path";
144694
+ import { dirname as dirname21, resolve as resolve26 } from "node:path";
144419
144695
  import { fileURLToPath as fileURLToPath6 } from "node:url";
144420
144696
  function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
144421
144697
  let pkgJsonPath;
144422
144698
  const here = dirname21(fileURLToPath6(moduleUrl));
144423
144699
  for (const rel of ["pi-claude-cli", "../pi-claude-cli", "../../pi-claude-cli"]) {
144424
- const candidate = resolve25(here, rel, "package.json");
144700
+ const candidate = resolve26(here, rel, "package.json");
144425
144701
  if (existsSync36(candidate)) {
144426
144702
  pkgJsonPath = candidate;
144427
144703
  break;
@@ -144457,7 +144733,7 @@ function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
144457
144733
  reason: "@fusion/pi-claude-cli pi.extensions[0] is not a valid path string"
144458
144734
  };
144459
144735
  }
144460
- const entryPath = resolve25(dirname21(pkgJsonPath), rawEntry);
144736
+ const entryPath = resolve26(dirname21(pkgJsonPath), rawEntry);
144461
144737
  if (!existsSync36(entryPath)) {
144462
144738
  return {
144463
144739
  status: "missing-entry",
@@ -144510,10 +144786,10 @@ var init_claude_cli_extension = __esm({
144510
144786
 
144511
144787
  // src/update-cache.ts
144512
144788
  import { readFileSync as readFileSync16 } from "node:fs";
144513
- import { join as join52 } from "node:path";
144789
+ import { join as join53 } from "node:path";
144514
144790
  function getCachedUpdateStatus() {
144515
144791
  try {
144516
- const cachePath = join52(resolveGlobalDir(), "update-check.json");
144792
+ const cachePath = join53(resolveGlobalDir(), "update-check.json");
144517
144793
  const raw = readFileSync16(cachePath, "utf-8");
144518
144794
  const parsed = JSON.parse(raw);
144519
144795
  if (parsed.updateAvailable === true && typeof parsed.latestVersion === "string" && parsed.latestVersion.length > 0 && typeof parsed.currentVersion === "string" && parsed.currentVersion.length > 0) {
@@ -144543,16 +144819,16 @@ var init_update_cache = __esm({
144543
144819
 
144544
144820
  // src/commands/self-extension.ts
144545
144821
  import { existsSync as existsSync37, readFileSync as readFileSync17 } from "node:fs";
144546
- import { dirname as dirname22, resolve as resolve26 } from "node:path";
144822
+ import { dirname as dirname22, resolve as resolve27 } from "node:path";
144547
144823
  import { fileURLToPath as fileURLToPath7 } from "node:url";
144548
144824
  function resolveSelfExtension() {
144549
144825
  const here = dirname22(fileURLToPath7(import.meta.url));
144550
144826
  let pkgDir;
144551
144827
  let cur = here;
144552
144828
  for (let i = 0; i < 5; i++) {
144553
- if (existsSync37(resolve26(cur, "package.json"))) {
144829
+ if (existsSync37(resolve27(cur, "package.json"))) {
144554
144830
  try {
144555
- const parsed = JSON.parse(readFileSync17(resolve26(cur, "package.json"), "utf-8"));
144831
+ const parsed = JSON.parse(readFileSync17(resolve27(cur, "package.json"), "utf-8"));
144556
144832
  if (parsed.name === "@runfusion/fusion") {
144557
144833
  pkgDir = cur;
144558
144834
  break;
@@ -144560,7 +144836,7 @@ function resolveSelfExtension() {
144560
144836
  } catch {
144561
144837
  }
144562
144838
  }
144563
- const parent2 = resolve26(cur, "..");
144839
+ const parent2 = resolve27(cur, "..");
144564
144840
  if (parent2 === cur) break;
144565
144841
  cur = parent2;
144566
144842
  }
@@ -144569,11 +144845,11 @@ function resolveSelfExtension() {
144569
144845
  }
144570
144846
  let pkgJson;
144571
144847
  try {
144572
- pkgJson = JSON.parse(readFileSync17(resolve26(pkgDir, "package.json"), "utf-8"));
144848
+ pkgJson = JSON.parse(readFileSync17(resolve27(pkgDir, "package.json"), "utf-8"));
144573
144849
  } catch (err) {
144574
144850
  return { status: "missing", reason: `Failed to read @runfusion/fusion package.json: ${err instanceof Error ? err.message : String(err)}` };
144575
144851
  }
144576
- const srcEntry = resolve26(pkgDir, "src", "extension.ts");
144852
+ const srcEntry = resolve27(pkgDir, "src", "extension.ts");
144577
144853
  if (existsSync37(srcEntry)) {
144578
144854
  return { status: "ok", path: srcEntry, packageVersion: pkgJson.version ?? "unknown" };
144579
144855
  }
@@ -144585,7 +144861,7 @@ function resolveSelfExtension() {
144585
144861
  if (typeof rawEntry !== "string" || rawEntry.length === 0) {
144586
144862
  return { status: "missing", reason: "@runfusion/fusion pi.extensions[0] is not a valid path string" };
144587
144863
  }
144588
- const entryPath = resolve26(pkgDir, rawEntry);
144864
+ const entryPath = resolve27(pkgDir, rawEntry);
144589
144865
  if (!existsSync37(entryPath)) {
144590
144866
  return { status: "missing", reason: `@runfusion/fusion extension file not found at ${entryPath}` };
144591
144867
  }
@@ -144646,20 +144922,20 @@ var init_state = __esm({
144646
144922
 
144647
144923
  // src/commands/dashboard-tui/logo.ts
144648
144924
  import { existsSync as existsSync38, readFileSync as readFileSync18 } from "node:fs";
144649
- import { dirname as dirname23, resolve as resolve27 } from "node:path";
144925
+ import { dirname as dirname23, resolve as resolve28 } from "node:path";
144650
144926
  import { fileURLToPath as fileURLToPath8 } from "node:url";
144651
144927
  function readFusionVersion() {
144652
144928
  try {
144653
144929
  let cur = dirname23(fileURLToPath8(import.meta.url));
144654
144930
  for (let i = 0; i < 6; i++) {
144655
- const pkgPath = resolve27(cur, "package.json");
144931
+ const pkgPath = resolve28(cur, "package.json");
144656
144932
  if (existsSync38(pkgPath)) {
144657
144933
  const parsed = JSON.parse(readFileSync18(pkgPath, "utf-8"));
144658
144934
  if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
144659
144935
  return parsed.version;
144660
144936
  }
144661
144937
  }
144662
- const parent2 = resolve27(cur, "..");
144938
+ const parent2 = resolve28(cur, "..");
144663
144939
  if (parent2 === cur) break;
144664
144940
  cur = parent2;
144665
144941
  }
@@ -144764,14 +145040,14 @@ async function copyToClipboard(text) {
144764
145040
  { cmd: "xsel", args: ["--clipboard", "--input"] }
144765
145041
  ];
144766
145042
  for (const { cmd, args } of candidates) {
144767
- const ok = await new Promise((resolve36) => {
145043
+ const ok = await new Promise((resolve37) => {
144768
145044
  try {
144769
145045
  const child = spawn11(cmd, args, { stdio: ["pipe", "ignore", "ignore"] });
144770
- child.once("error", () => resolve36(false));
144771
- child.once("close", (code) => resolve36(code === 0));
145046
+ child.once("error", () => resolve37(false));
145047
+ child.once("close", (code) => resolve37(code === 0));
144772
145048
  child.stdin.end(text);
144773
145049
  } catch {
144774
- resolve36(false);
145050
+ resolve37(false);
144775
145051
  }
144776
145052
  });
144777
145053
  if (ok) return true;
@@ -148687,7 +148963,7 @@ __export(dashboard_exports, {
148687
148963
  promptForPort: () => promptForPort,
148688
148964
  runDashboard: () => runDashboard
148689
148965
  });
148690
- import { join as join53, resolve as pathResolve } from "node:path";
148966
+ import { join as join54, resolve as pathResolve } from "node:path";
148691
148967
  import { execFile as execFileCb } from "node:child_process";
148692
148968
  import { promisify as promisify14 } from "node:util";
148693
148969
  import { stat as stat11, readdir as readdir11, readFile as fsReadFile3 } from "node:fs/promises";
@@ -148994,7 +149270,7 @@ async function buildFileListDirectory(projectPath, relativePath) {
148994
149270
  let size = 0;
148995
149271
  let modifiedAt = (/* @__PURE__ */ new Date(0)).toISOString();
148996
149272
  try {
148997
- const s = await stat11(join53(absDir, d.name));
149273
+ const s = await stat11(join54(absDir, d.name));
148998
149274
  size = d.isDirectory() ? 0 : s.size;
148999
149275
  modifiedAt = s.mtime.toISOString();
149000
149276
  } catch {
@@ -149423,7 +149699,7 @@ async function runDashboard(port, opts = {}) {
149423
149699
  ...claudeCliPaths
149424
149700
  ],
149425
149701
  cwd,
149426
- join53(cwd, ".fusion", "disabled-auto-extension-discovery")
149702
+ join54(cwd, ".fusion", "disabled-auto-extension-discovery")
149427
149703
  );
149428
149704
  for (const { path: path5, error } of extensionsResult.errors) {
149429
149705
  logSink.log(`Failed to load ${path5}: ${error}`, "extensions");
@@ -149904,8 +150180,8 @@ async function runDashboard(port, opts = {}) {
149904
150180
  try {
149905
150181
  const updateCheckEnabled = await Promise.race([
149906
150182
  isUpdateCheckEnabled(),
149907
- new Promise((resolve36) => {
149908
- setTimeout(() => resolve36(false), 3e3);
150183
+ new Promise((resolve37) => {
150184
+ setTimeout(() => resolve37(false), 3e3);
149909
150185
  })
149910
150186
  ]);
149911
150187
  if (!updateCheckEnabled) {
@@ -150874,7 +151150,7 @@ var serve_exports = {};
150874
151150
  __export(serve_exports, {
150875
151151
  runServe: () => runServe
150876
151152
  });
150877
- import { join as join54 } from "node:path";
151153
+ import { join as join55 } from "node:path";
150878
151154
  import {
150879
151155
  AuthStorage as AuthStorage3,
150880
151156
  DefaultPackageManager as DefaultPackageManager3,
@@ -151146,7 +151422,7 @@ async function runServe(port, opts = {}) {
151146
151422
  ...claudeCliPaths
151147
151423
  ],
151148
151424
  cwd,
151149
- join54(cwd, ".fusion", "disabled-auto-extension-discovery")
151425
+ join55(cwd, ".fusion", "disabled-auto-extension-discovery")
151150
151426
  );
151151
151427
  for (const { path: path5, error } of extensionsResult.errors) {
151152
151428
  console.log(`[extensions] Failed to load ${path5}: ${error}`);
@@ -151300,8 +151576,8 @@ async function runServe(port, opts = {}) {
151300
151576
  https: loadTlsCredentialsFromEnv()
151301
151577
  });
151302
151578
  const server = app.listen(selectedPort, selectedHost);
151303
- await new Promise((resolve36, reject2) => {
151304
- server.once("listening", resolve36);
151579
+ await new Promise((resolve37, reject2) => {
151580
+ server.once("listening", resolve37);
151305
151581
  server.once("error", reject2);
151306
151582
  });
151307
151583
  const actualPort = server.address().port;
@@ -151458,7 +151734,7 @@ var daemon_exports = {};
151458
151734
  __export(daemon_exports, {
151459
151735
  runDaemon: () => runDaemon
151460
151736
  });
151461
- import { join as join55 } from "node:path";
151737
+ import { join as join56 } from "node:path";
151462
151738
  import {
151463
151739
  AuthStorage as AuthStorage4,
151464
151740
  DefaultPackageManager as DefaultPackageManager4,
@@ -151728,7 +152004,7 @@ async function runDaemon(opts = {}) {
151728
152004
  const extensionsResult = await discoverAndLoadExtensions4(
151729
152005
  reconciledExtensionPaths,
151730
152006
  cwd,
151731
- join55(cwd, ".fusion", "disabled-auto-extension-discovery")
152007
+ join56(cwd, ".fusion", "disabled-auto-extension-discovery")
151732
152008
  );
151733
152009
  for (const { path: path5, error } of extensionsResult.errors) {
151734
152010
  console.log(`[extensions] Failed to load ${path5}: ${error}`);
@@ -151819,8 +152095,8 @@ async function runDaemon(opts = {}) {
151819
152095
  https: loadTlsCredentialsFromEnv()
151820
152096
  });
151821
152097
  const server = app.listen(selectedPort, selectedHost);
151822
- await new Promise((resolve36, reject2) => {
151823
- server.once("listening", resolve36);
152098
+ await new Promise((resolve37, reject2) => {
152099
+ server.once("listening", resolve37);
151824
152100
  server.once("error", reject2);
151825
152101
  });
151826
152102
  const actualPort = server.address().port;
@@ -151931,10 +152207,10 @@ __export(desktop_exports, {
151931
152207
  });
151932
152208
  import { spawn as spawn13 } from "node:child_process";
151933
152209
  import { once as once2 } from "node:events";
151934
- import { join as join56 } from "node:path";
152210
+ import { join as join57 } from "node:path";
151935
152211
  import { createRequire as createRequire5 } from "node:module";
151936
152212
  function runCommand(command, args, cwd) {
151937
- return new Promise((resolve36, reject2) => {
152213
+ return new Promise((resolve37, reject2) => {
151938
152214
  const child = spawn13(command, args, {
151939
152215
  cwd,
151940
152216
  stdio: "inherit",
@@ -151943,7 +152219,7 @@ function runCommand(command, args, cwd) {
151943
152219
  child.on("error", (error) => reject2(error));
151944
152220
  child.on("exit", (code) => {
151945
152221
  if (code === 0) {
151946
- resolve36();
152222
+ resolve37();
151947
152223
  return;
151948
152224
  }
151949
152225
  reject2(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}`));
@@ -151986,8 +152262,8 @@ async function startDashboardRuntime(rootDir, paused) {
151986
152262
  };
151987
152263
  }
151988
152264
  async function closeDashboardRuntime(runtime) {
151989
- await new Promise((resolve36) => {
151990
- runtime.server.close(() => resolve36());
152265
+ await new Promise((resolve37) => {
152266
+ runtime.server.close(() => resolve37());
151991
152267
  });
151992
152268
  runtime.store.close();
151993
152269
  }
@@ -152010,7 +152286,7 @@ async function runDesktop(options = {}) {
152010
152286
  }
152011
152287
  const runtime = await startDashboardRuntime(rootDir, Boolean(options.paused));
152012
152288
  const electronBinary = resolveElectronBinary();
152013
- const desktopEntry = join56(rootDir, "packages", "desktop", "dist", "main.js");
152289
+ const desktopEntry = join57(rootDir, "packages", "desktop", "dist", "main.js");
152014
152290
  const electronArgs = ["--enable-source-maps", desktopEntry, ...options.dev ? ["--dev"] : []];
152015
152291
  const electronEnv = {
152016
152292
  ...process.env,
@@ -152096,7 +152372,7 @@ __export(task_exports, {
152096
152372
  });
152097
152373
  import { createInterface as createInterface3 } from "node:readline/promises";
152098
152374
  import { watchFile, unwatchFile, statSync as statSync6, existsSync as existsSync39, readFileSync as readFileSync19 } from "node:fs";
152099
- import { join as join57 } from "node:path";
152375
+ import { join as join58 } from "node:path";
152100
152376
  function asLocalProjectContext(store) {
152101
152377
  const cwd = process.cwd();
152102
152378
  return {
@@ -152216,10 +152492,10 @@ async function runTaskCreate(descriptionArg, attachFiles, depends, projectName,
152216
152492
  console.log(` Path: .fusion/tasks/${task.id}/`);
152217
152493
  if (attachFiles && attachFiles.length > 0) {
152218
152494
  const { readFile: readFile24 } = await import("node:fs/promises");
152219
- const { basename: basename16, extname: extname2, resolve: resolve36 } = await import("node:path");
152495
+ const { basename: basename17, extname: extname2, resolve: resolve37 } = await import("node:path");
152220
152496
  for (const filePath of attachFiles) {
152221
- const resolvedPath = resolve36(filePath);
152222
- const filename = basename16(resolvedPath);
152497
+ const resolvedPath = resolve37(filePath);
152498
+ const filename = basename17(resolvedPath);
152223
152499
  const ext = extname2(filename).toLowerCase();
152224
152500
  const mimeType = MIME_TYPES[ext];
152225
152501
  if (!mimeType) {
@@ -152352,7 +152628,7 @@ async function runTaskLogs(id, options = {}, projectName) {
152352
152628
  printEntries(filteredEntries);
152353
152629
  if (options.follow) {
152354
152630
  const projectPath = projectContext?.projectPath ?? process.cwd();
152355
- const logPath = join57(projectPath, ".fusion", "tasks", id, "agent.log");
152631
+ const logPath = join58(projectPath, ".fusion", "tasks", id, "agent.log");
152356
152632
  if (!existsSync39(logPath)) {
152357
152633
  console.log(`
152358
152634
  Waiting for log file to be created...`);
@@ -152511,10 +152787,10 @@ async function runTaskMerge(id, projectName) {
152511
152787
  }
152512
152788
  async function runTaskAttach(id, filePath, projectName) {
152513
152789
  const { readFile: readFile24 } = await import("node:fs/promises");
152514
- const { basename: basename16, extname: extname2 } = await import("node:path");
152515
- const { resolve: resolve36 } = await import("node:path");
152516
- const resolvedPath = resolve36(filePath);
152517
- const filename = basename16(resolvedPath);
152790
+ const { basename: basename17, extname: extname2 } = await import("node:path");
152791
+ const { resolve: resolve37 } = await import("node:path");
152792
+ const resolvedPath = resolve37(filePath);
152793
+ const filename = basename17(resolvedPath);
152518
152794
  const ext = extname2(filename).toLowerCase();
152519
152795
  const mimeType = MIME_TYPES[ext];
152520
152796
  if (!mimeType) {
@@ -153044,12 +153320,12 @@ async function promptText(question) {
153044
153320
  console.log(" (Enter your response. Type DONE on its own line when finished):\n");
153045
153321
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
153046
153322
  const lines = [];
153047
- return new Promise((resolve36) => {
153323
+ return new Promise((resolve37) => {
153048
153324
  const askLine = () => {
153049
153325
  rl.question(" ").then((line) => {
153050
153326
  if (line.trim() === "DONE") {
153051
153327
  rl.close();
153052
- resolve36(lines.join("\n"));
153328
+ resolve37(lines.join("\n"));
153053
153329
  } else {
153054
153330
  lines.push(line);
153055
153331
  askLine();
@@ -153616,8 +153892,8 @@ var settings_export_exports = {};
153616
153892
  __export(settings_export_exports, {
153617
153893
  runSettingsExport: () => runSettingsExport
153618
153894
  });
153619
- import { writeFile as writeFile16 } from "node:fs/promises";
153620
- import { resolve as resolve28, join as join58 } from "node:path";
153895
+ import { writeFile as writeFile17 } from "node:fs/promises";
153896
+ import { resolve as resolve29, join as join59 } from "node:path";
153621
153897
  async function runSettingsExport(options = {}) {
153622
153898
  const scope = options.scope ?? "both";
153623
153899
  const project = options.projectName ? await resolveProject(options.projectName) : void 0;
@@ -153628,13 +153904,13 @@ async function runSettingsExport(options = {}) {
153628
153904
  const exportData = await exportSettings(store, { scope });
153629
153905
  let targetPath;
153630
153906
  if (outputPath) {
153631
- targetPath = resolve28(outputPath);
153907
+ targetPath = resolve29(outputPath);
153632
153908
  } else {
153633
153909
  const filename = generateExportFilename();
153634
- targetPath = join58(process.cwd(), filename);
153910
+ targetPath = join59(process.cwd(), filename);
153635
153911
  }
153636
153912
  const jsonContent = JSON.stringify(exportData, null, 2);
153637
- await writeFile16(targetPath, jsonContent);
153913
+ await writeFile17(targetPath, jsonContent);
153638
153914
  console.log();
153639
153915
  console.log(` \u2713 Settings exported to ${targetPath}`);
153640
153916
  const parts = [];
@@ -153678,7 +153954,7 @@ __export(settings_import_exports, {
153678
153954
  runSettingsImport: () => runSettingsImport
153679
153955
  });
153680
153956
  import { existsSync as existsSync40 } from "node:fs";
153681
- import { resolve as resolve29 } from "node:path";
153957
+ import { resolve as resolve30 } from "node:path";
153682
153958
  async function runSettingsImport(filePath, options = {}) {
153683
153959
  const scope = options.scope ?? "both";
153684
153960
  const project = options.projectName ? await resolveProject(options.projectName) : void 0;
@@ -153687,7 +153963,7 @@ async function runSettingsImport(filePath, options = {}) {
153687
153963
  const merge = options.merge ?? true;
153688
153964
  const skipConfirm = options.yes ?? false;
153689
153965
  try {
153690
- const resolvedPath = resolve29(filePath);
153966
+ const resolvedPath = resolve30(filePath);
153691
153967
  if (!existsSync40(resolvedPath)) {
153692
153968
  console.error(`Error: File not found: ${filePath}`);
153693
153969
  process.exit(1);
@@ -154162,7 +154438,7 @@ var init_backup2 = __esm({
154162
154438
 
154163
154439
  // src/project-resolver.ts
154164
154440
  import { existsSync as existsSync41, statSync as statSync7 } from "node:fs";
154165
- import { dirname as dirname24, resolve as resolve30, normalize as normalize5 } from "node:path";
154441
+ import { dirname as dirname24, resolve as resolve31, normalize as normalize5 } from "node:path";
154166
154442
  import { createInterface as createInterface5 } from "node:readline/promises";
154167
154443
  async function getCentralCore() {
154168
154444
  if (!centralCoreInstance) {
@@ -154179,9 +154455,9 @@ async function getProjectManager() {
154179
154455
  return projectManagerInstance;
154180
154456
  }
154181
154457
  function findKbDir(startPath) {
154182
- let current = resolve30(startPath);
154458
+ let current = resolve31(startPath);
154183
154459
  for (let i = 0; i < 100; i++) {
154184
- const kbPath = resolve30(current, ".fusion");
154460
+ const kbPath = resolve31(current, ".fusion");
154185
154461
  if (existsSync41(kbPath) && statSync7(kbPath).isDirectory()) {
154186
154462
  return current;
154187
154463
  }
@@ -154248,7 +154524,7 @@ Run \`fn project remove ` + match.name + "` to clean up the registry entry.",
154248
154524
  }
154249
154525
  return createResolvedProject(match);
154250
154526
  }
154251
- const cwd = options.cwd ? resolve30(options.cwd) : process.cwd();
154527
+ const cwd = options.cwd ? resolve31(options.cwd) : process.cwd();
154252
154528
  const fusionDir = findKbDir(cwd);
154253
154529
  if (fusionDir) {
154254
154530
  const allProjects2 = await central.listProjects();
@@ -154760,7 +155036,7 @@ __export(project_exports, {
154760
155036
  runProjectSetDefault: () => runProjectSetDefault,
154761
155037
  runProjectShow: () => runProjectShow
154762
155038
  });
154763
- import { resolve as resolve31, isAbsolute as isAbsolute16, relative as relative12, basename as basename13 } from "node:path";
155039
+ import { resolve as resolve32, isAbsolute as isAbsolute16, relative as relative12, basename as basename14 } from "node:path";
154764
155040
  import { existsSync as existsSync42, statSync as statSync8 } from "node:fs";
154765
155041
  import { createInterface as createInterface7 } from "node:readline/promises";
154766
155042
  function formatDisplayPath(projectPath) {
@@ -154768,7 +155044,7 @@ function formatDisplayPath(projectPath) {
154768
155044
  if (rel && !rel.startsWith("..") && rel !== "") {
154769
155045
  return rel;
154770
155046
  }
154771
- return basename13(projectPath) || ".";
155047
+ return basename14(projectPath) || ".";
154772
155048
  }
154773
155049
  function formatLastActivity2(timestamp) {
154774
155050
  if (!timestamp) return "never";
@@ -154889,7 +155165,7 @@ async function runProjectAdd(name, path5, options = {}) {
154889
155165
  const pathInput = await rl.question(` Project path [${defaultPath}]: `);
154890
155166
  projectPath = pathInput.trim() || defaultPath;
154891
155167
  }
154892
- const absolutePath2 = isAbsolute16(projectPath) ? projectPath : resolve31(process.cwd(), projectPath);
155168
+ const absolutePath2 = isAbsolute16(projectPath) ? projectPath : resolve32(process.cwd(), projectPath);
154893
155169
  if (!existsSync42(absolutePath2)) {
154894
155170
  console.error(`
154895
155171
  \u2717 Path does not exist: ${projectPath}`);
@@ -154902,7 +155178,7 @@ async function runProjectAdd(name, path5, options = {}) {
154902
155178
  rl.close();
154903
155179
  process.exit(1);
154904
155180
  }
154905
- const kbDbPath2 = resolve31(absolutePath2, ".fusion", "fusion.db");
155181
+ const kbDbPath2 = resolve32(absolutePath2, ".fusion", "fusion.db");
154906
155182
  if (!existsSync42(kbDbPath2) && !options.force) {
154907
155183
  console.log(`
154908
155184
  No fn project found at ${formatDisplayPath(absolutePath2)}`);
@@ -154918,7 +155194,7 @@ async function runProjectAdd(name, path5, options = {}) {
154918
155194
  }
154919
155195
  }
154920
155196
  if (!projectName) {
154921
- const suggested = basename13(absolutePath2);
155197
+ const suggested = basename14(absolutePath2);
154922
155198
  projectName = await rl.question(` Project name [${suggested}]: `);
154923
155199
  projectName = projectName.trim() || suggested;
154924
155200
  }
@@ -154934,7 +155210,7 @@ async function runProjectAdd(name, path5, options = {}) {
154934
155210
  console.error(" Name must be 1-64 characters and contain only: a-z, A-Z, 0-9, _, -\n");
154935
155211
  process.exit(1);
154936
155212
  }
154937
- const absolutePath = isAbsolute16(projectPath) ? projectPath : resolve31(process.cwd(), projectPath);
155213
+ const absolutePath = isAbsolute16(projectPath) ? projectPath : resolve32(process.cwd(), projectPath);
154938
155214
  if (!existsSync42(absolutePath)) {
154939
155215
  console.error(`
154940
155216
  \u2717 Path does not exist: ${projectPath}
@@ -154947,7 +155223,7 @@ async function runProjectAdd(name, path5, options = {}) {
154947
155223
  `);
154948
155224
  process.exit(1);
154949
155225
  }
154950
- const kbDbPath = resolve31(absolutePath, ".fusion", "fusion.db");
155226
+ const kbDbPath = resolve32(absolutePath, ".fusion", "fusion.db");
154951
155227
  if (!existsSync42(kbDbPath) && !options.force) {
154952
155228
  console.error(`
154953
155229
  \u2717 No fn project found at ${formatDisplayPath(absolutePath)}`);
@@ -155206,18 +155482,18 @@ var init_project = __esm({
155206
155482
  // src/commands/skill-installation.ts
155207
155483
  import { cpSync as cpSync2, existsSync as existsSync43, mkdirSync as mkdirSync8 } from "node:fs";
155208
155484
  import { homedir as homedir8 } from "node:os";
155209
- import { dirname as dirname25, join as join59, resolve as resolve32 } from "node:path";
155485
+ import { dirname as dirname25, join as join60, resolve as resolve33 } from "node:path";
155210
155486
  import { fileURLToPath as fileURLToPath9 } from "node:url";
155211
155487
  function getSupportedSkillInstallTargets(homeDir = process.env.HOME || process.env.USERPROFILE || homedir8()) {
155212
155488
  return [
155213
- { client: "claude", targetDir: join59(homeDir, ".claude", "skills", FUSION_SKILL_NAME2) },
155214
- { client: "codex", targetDir: join59(homeDir, ".codex", "skills", FUSION_SKILL_NAME2) },
155215
- { client: "gemini", targetDir: join59(homeDir, ".gemini", "skills", FUSION_SKILL_NAME2) }
155489
+ { client: "claude", targetDir: join60(homeDir, ".claude", "skills", FUSION_SKILL_NAME2) },
155490
+ { client: "codex", targetDir: join60(homeDir, ".codex", "skills", FUSION_SKILL_NAME2) },
155491
+ { client: "gemini", targetDir: join60(homeDir, ".gemini", "skills", FUSION_SKILL_NAME2) }
155216
155492
  ];
155217
155493
  }
155218
155494
  function resolveBundledFusionSkillSource() {
155219
155495
  const here = fileURLToPath9(import.meta.url);
155220
- const source = resolve32(dirname25(here), "..", "..", "skill", FUSION_SKILL_NAME2);
155496
+ const source = resolve33(dirname25(here), "..", "..", "skill", FUSION_SKILL_NAME2);
155221
155497
  return existsSync43(source) ? source : null;
155222
155498
  }
155223
155499
  function installBundledFusionSkill(options = {}) {
@@ -155276,13 +155552,13 @@ __export(init_exports, {
155276
155552
  runInit: () => runInit
155277
155553
  });
155278
155554
  import { existsSync as existsSync44, mkdirSync as mkdirSync9, writeFileSync as writeFileSync3, readFileSync as readFileSync20 } from "node:fs";
155279
- import { join as join60, resolve as resolve33, basename as basename14 } from "node:path";
155555
+ import { join as join61, resolve as resolve34, basename as basename15 } from "node:path";
155280
155556
  import { exec as exec11 } from "node:child_process";
155281
155557
  import { promisify as promisify16 } from "node:util";
155282
155558
  async function runInit(options = {}) {
155283
- const cwd = options.path ? resolve33(options.path) : process.cwd();
155284
- const fusionDir = join60(cwd, ".fusion");
155285
- const dbPath = join60(fusionDir, "fusion.db");
155559
+ const cwd = options.path ? resolve34(options.path) : process.cwd();
155560
+ const fusionDir = join61(cwd, ".fusion");
155561
+ const dbPath = join61(fusionDir, "fusion.db");
155286
155562
  if (existsSync44(fusionDir) && existsSync44(dbPath)) {
155287
155563
  const central2 = new CentralCore();
155288
155564
  await central2.init();
@@ -155389,8 +155665,8 @@ async function runInit(options = {}) {
155389
155665
  }
155390
155666
  }
155391
155667
  async function detectProjectName(dir2) {
155392
- if (!existsSync44(join60(dir2, ".git"))) {
155393
- return basename14(dir2) || "my-project";
155668
+ if (!existsSync44(join61(dir2, ".git"))) {
155669
+ return basename15(dir2) || "my-project";
155394
155670
  }
155395
155671
  try {
155396
155672
  const { stdout: remoteUrl } = await execAsync11("git remote get-url origin", {
@@ -155406,10 +155682,10 @@ async function detectProjectName(dir2) {
155406
155682
  }
155407
155683
  } catch {
155408
155684
  }
155409
- return basename14(dir2) || "my-project";
155685
+ return basename15(dir2) || "my-project";
155410
155686
  }
155411
155687
  async function addLocalStorageToGitignore(cwd) {
155412
- const gitignorePath = join60(cwd, ".gitignore");
155688
+ const gitignorePath = join61(cwd, ".gitignore");
155413
155689
  let content = "";
155414
155690
  if (existsSync44(gitignorePath)) {
155415
155691
  try {
@@ -155452,7 +155728,7 @@ async function initializeGitRepo(cwd) {
155452
155728
  }
155453
155729
  await ensureGitConfig(cwd, "user.name", "Fusion");
155454
155730
  await ensureGitConfig(cwd, "user.email", "noreply@runfusion.ai");
155455
- const gitkeepPath = join60(cwd, ".gitkeep");
155731
+ const gitkeepPath = join61(cwd, ".gitkeep");
155456
155732
  if (!existsSync44(gitkeepPath)) {
155457
155733
  writeFileSync3(gitkeepPath, "\n");
155458
155734
  }
@@ -155592,7 +155868,7 @@ __export(agent_import_exports, {
155592
155868
  runAgentImport: () => runAgentImport
155593
155869
  });
155594
155870
  import { existsSync as existsSync45, mkdirSync as mkdirSync10, readFileSync as readFileSync21, statSync as statSync9, writeFileSync as writeFileSync4 } from "node:fs";
155595
- import { resolve as resolve34 } from "node:path";
155871
+ import { resolve as resolve35 } from "node:path";
155596
155872
  function slugifyPathSegment(input) {
155597
155873
  if (!input || typeof input !== "string") {
155598
155874
  return "unnamed";
@@ -155641,15 +155917,15 @@ async function importSkillsToProject(projectPath, skills, companySlug, dryRun) {
155641
155917
  errors: []
155642
155918
  };
155643
155919
  const companyDir = slugifyPathSegment(companySlug ?? "unknown-company");
155644
- const baseSkillsDir = resolve34(projectPath, "skills", "imported", companyDir);
155920
+ const baseSkillsDir = resolve35(projectPath, "skills", "imported", companyDir);
155645
155921
  for (const skill of skills) {
155646
155922
  if (!skill.name || typeof skill.name !== "string" || skill.name.trim().length === 0) {
155647
155923
  result.errors.push({ name: "(unnamed)", error: "Skill is missing required 'name' field" });
155648
155924
  continue;
155649
155925
  }
155650
155926
  const skillSlug = slugifyPathSegment(skill.name);
155651
- const skillDir = resolve34(baseSkillsDir, skillSlug);
155652
- const skillPath = resolve34(skillDir, "SKILL.md");
155927
+ const skillDir = resolve35(baseSkillsDir, skillSlug);
155928
+ const skillPath = resolve35(skillDir, "SKILL.md");
155653
155929
  if (existsSync45(skillPath)) {
155654
155930
  result.skipped.push(skill.name);
155655
155931
  continue;
@@ -155722,7 +155998,7 @@ function isArchivePath(path5) {
155722
155998
  async function runAgentImport(source, options) {
155723
155999
  const dryRun = options?.dryRun ?? false;
155724
156000
  const skipExisting = options?.skipExisting ?? false;
155725
- const sourcePath = resolve34(source);
156001
+ const sourcePath = resolve35(source);
155726
156002
  if (!existsSync45(sourcePath)) {
155727
156003
  console.error(`Path not found: ${sourcePath}`);
155728
156004
  process.exit(1);
@@ -155861,7 +156137,7 @@ var agent_export_exports = {};
155861
156137
  __export(agent_export_exports, {
155862
156138
  runAgentExport: () => runAgentExport
155863
156139
  });
155864
- import { resolve as resolve35 } from "node:path";
156140
+ import { resolve as resolve36 } from "node:path";
155865
156141
  async function getProjectPath4(projectName) {
155866
156142
  if (projectName) {
155867
156143
  const context = await resolveProject(projectName);
@@ -155899,7 +156175,7 @@ async function runAgentExport(outputDir, options) {
155899
156175
  console.error("No agents found to export");
155900
156176
  process.exit(1);
155901
156177
  }
155902
- const result = await exportAgentsToDirectory(agents, resolve35(outputDir), {
156178
+ const result = await exportAgentsToDirectory(agents, resolve36(outputDir), {
155903
156179
  companyName: options?.companyName,
155904
156180
  companySlug: options?.companySlug
155905
156181
  });
@@ -156119,7 +156395,7 @@ __export(plugin_exports, {
156119
156395
  runPluginUninstall: () => runPluginUninstall
156120
156396
  });
156121
156397
  import { existsSync as existsSync46 } from "node:fs";
156122
- import { join as join61 } from "node:path";
156398
+ import { join as join62 } from "node:path";
156123
156399
  import { readFile as readFile23 } from "node:fs/promises";
156124
156400
  import * as readline from "node:readline";
156125
156401
  async function getProjectPath6(projectName) {
@@ -156157,7 +156433,7 @@ async function createPluginLoader(pluginStore, projectName) {
156157
156433
  return { store: pluginStore, loader };
156158
156434
  }
156159
156435
  async function loadManifestFromPath(pluginPath) {
156160
- const manifestPath = join61(pluginPath, "manifest.json");
156436
+ const manifestPath = join62(pluginPath, "manifest.json");
156161
156437
  if (!existsSync46(manifestPath)) {
156162
156438
  throw new Error(`Plugin manifest not found at: ${manifestPath}`);
156163
156439
  }
@@ -156261,14 +156537,14 @@ async function runPluginUninstall(id, options) {
156261
156537
  console.log(` Uninstall "${plugin4.name}"?`);
156262
156538
  console.log(` This will stop and remove the plugin.`);
156263
156539
  console.log();
156264
- const response = await new Promise((resolve36) => {
156540
+ const response = await new Promise((resolve37) => {
156265
156541
  const rl = readline.createInterface({
156266
156542
  input: process.stdin,
156267
156543
  output: process.stdout
156268
156544
  });
156269
156545
  rl.question(" Continue? [y/N] ", (answer) => {
156270
156546
  rl.close();
156271
- resolve36(answer.toLowerCase());
156547
+ resolve37(answer.toLowerCase());
156272
156548
  });
156273
156549
  });
156274
156550
  if (response !== "y" && response !== "yes") {
@@ -156349,7 +156625,7 @@ __export(plugin_scaffold_exports, {
156349
156625
  runPluginCreate: () => runPluginCreate
156350
156626
  });
156351
156627
  import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync5, existsSync as existsSync47 } from "node:fs";
156352
- import { join as join62 } from "node:path";
156628
+ import { join as join63 } from "node:path";
156353
156629
  function toTitleCase(str) {
156354
156630
  return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
156355
156631
  }
@@ -156482,7 +156758,7 @@ async function runPluginCreate(name, options) {
156482
156758
  process.exit(1);
156483
156759
  }
156484
156760
  const targetDir = options?.output ?? name;
156485
- const targetPath = join62(process.cwd(), targetDir);
156761
+ const targetPath = join63(process.cwd(), targetDir);
156486
156762
  if (existsSync47(targetPath)) {
156487
156763
  console.error(`Error: Directory '${targetDir}' already exists.`);
156488
156764
  console.error("Please choose a different name or remove the existing directory.");
@@ -156490,16 +156766,16 @@ async function runPluginCreate(name, options) {
156490
156766
  }
156491
156767
  try {
156492
156768
  mkdirSync11(targetPath, { recursive: true });
156493
- mkdirSync11(join62(targetPath, "src", "__tests__"), { recursive: true });
156494
- writeFileSync5(join62(targetPath, "package.json"), generatePackageJson(name));
156495
- writeFileSync5(join62(targetPath, "tsconfig.json"), generateTsconfig());
156496
- writeFileSync5(join62(targetPath, "vitest.config.ts"), generateVitestConfig());
156497
- writeFileSync5(join62(targetPath, "src", "index.ts"), generateIndexTs(name));
156769
+ mkdirSync11(join63(targetPath, "src", "__tests__"), { recursive: true });
156770
+ writeFileSync5(join63(targetPath, "package.json"), generatePackageJson(name));
156771
+ writeFileSync5(join63(targetPath, "tsconfig.json"), generateTsconfig());
156772
+ writeFileSync5(join63(targetPath, "vitest.config.ts"), generateVitestConfig());
156773
+ writeFileSync5(join63(targetPath, "src", "index.ts"), generateIndexTs(name));
156498
156774
  writeFileSync5(
156499
- join62(targetPath, "src", "__tests__", "index.test.ts"),
156775
+ join63(targetPath, "src", "__tests__", "index.test.ts"),
156500
156776
  generateTestTs(name)
156501
156777
  );
156502
- writeFileSync5(join62(targetPath, "README.md"), generateReadme(name));
156778
+ writeFileSync5(join63(targetPath, "README.md"), generateReadme(name));
156503
156779
  } catch (err) {
156504
156780
  console.error(
156505
156781
  `Error creating plugin files: ${err instanceof Error ? err.message : String(err)}`
@@ -156616,9 +156892,9 @@ async function runSkillsInstall(args, options) {
156616
156892
  stdio: "inherit",
156617
156893
  shell: true
156618
156894
  });
156619
- const exitCode = await new Promise((resolve36, reject2) => {
156895
+ const exitCode = await new Promise((resolve37, reject2) => {
156620
156896
  child.on("exit", (code) => {
156621
- resolve36(code ?? 1);
156897
+ resolve37(code ?? 1);
156622
156898
  });
156623
156899
  child.on("error", (err) => {
156624
156900
  reject2(err);
@@ -156649,7 +156925,7 @@ __export(native_patch_exports, {
156649
156925
  isTerminalAvailable: () => isTerminalAvailable,
156650
156926
  setupNativeResolution: () => setupNativeResolution
156651
156927
  });
156652
- import { join as join63, basename as basename15, dirname as dirname26 } from "node:path";
156928
+ import { join as join64, basename as basename16, dirname as dirname26 } from "node:path";
156653
156929
  import { existsSync as existsSync48, copyFileSync, mkdirSync as mkdirSync12, symlinkSync as symlinkSync2, rmSync as rmSync5, lstatSync as lstatSync3, readlinkSync as readlinkSync2 } from "node:fs";
156654
156930
  import { tmpdir as tmpdir4 } from "node:os";
156655
156931
  function findStagedNativeDir2() {
@@ -156657,13 +156933,13 @@ function findStagedNativeDir2() {
156657
156933
  const arch = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "x64" : "unknown";
156658
156934
  const prebuildName = `${platform3}-${arch}`;
156659
156935
  const execDir = dirname26(process.execPath);
156660
- const nextToBinary = join63(execDir, "runtime", prebuildName);
156661
- if (existsSync48(join63(nextToBinary, "pty.node"))) {
156936
+ const nextToBinary = join64(execDir, "runtime", prebuildName);
156937
+ if (existsSync48(join64(nextToBinary, "pty.node"))) {
156662
156938
  return nextToBinary;
156663
156939
  }
156664
156940
  if (process.env.FUSION_RUNTIME_DIR) {
156665
- const envPath = join63(process.env.FUSION_RUNTIME_DIR, prebuildName);
156666
- if (existsSync48(join63(envPath, "pty.node"))) {
156941
+ const envPath = join64(process.env.FUSION_RUNTIME_DIR, prebuildName);
156942
+ if (existsSync48(join64(envPath, "pty.node"))) {
156667
156943
  return envPath;
156668
156944
  }
156669
156945
  }
@@ -156696,17 +156972,17 @@ function setupNativeResolution() {
156696
156972
  process.env.NODE_PTY_SPAWN_HELPER_DIR = nativeDir;
156697
156973
  }
156698
156974
  process.env.FUSION_NATIVE_ASSETS_PATH = nativeDir;
156699
- const tmpRoot = join63(tmpdir4(), `fn-bunfs-${process.pid}`);
156700
- const fnDir = join63(tmpRoot, "fn");
156701
- const prebuildsDir = join63(fnDir, "prebuilds");
156702
- const platformDir = join63(prebuildsDir, basename15(nativeDir));
156975
+ const tmpRoot = join64(tmpdir4(), `fn-bunfs-${process.pid}`);
156976
+ const fnDir = join64(tmpRoot, "fn");
156977
+ const prebuildsDir = join64(fnDir, "prebuilds");
156978
+ const platformDir = join64(prebuildsDir, basename16(nativeDir));
156703
156979
  try {
156704
156980
  cleanupStaleBunfsLinks();
156705
156981
  mkdirSync12(platformDir, { recursive: true });
156706
- const ptyNodeDest = join63(platformDir, "pty.node");
156707
- copyFileSync(join63(nativeDir, "pty.node"), ptyNodeDest);
156708
- if (existsSync48(join63(nativeDir, "spawn-helper"))) {
156709
- copyFileSync(join63(nativeDir, "spawn-helper"), join63(platformDir, "spawn-helper"));
156982
+ const ptyNodeDest = join64(platformDir, "pty.node");
156983
+ copyFileSync(join64(nativeDir, "pty.node"), ptyNodeDest);
156984
+ if (existsSync48(join64(nativeDir, "spawn-helper"))) {
156985
+ copyFileSync(join64(nativeDir, "spawn-helper"), join64(platformDir, "spawn-helper"));
156710
156986
  }
156711
156987
  process.env.FUSION_FAKE_BUNFS_ROOT = tmpRoot;
156712
156988
  if (process.platform !== "win32") {
@@ -156783,7 +157059,7 @@ var init_native_patch = __esm({
156783
157059
  // src/bin.ts
156784
157060
  import { existsSync as existsSync49, mkdtempSync as mkdtempSync2, readFileSync as readFileSync22, symlinkSync as symlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
156785
157061
  import { createRequire as createRequire6 } from "node:module";
156786
- import { join as join64, dirname as dirname27 } from "node:path";
157062
+ import { join as join65, dirname as dirname27 } from "node:path";
156787
157063
  import { tmpdir as tmpdir5 } from "node:os";
156788
157064
  import { performance as performance3 } from "node:perf_hooks";
156789
157065
  var isBunBinary3 = typeof Bun !== "undefined" && !!Bun.embeddedFiles;
@@ -156791,7 +157067,7 @@ function configurePiPackage() {
156791
157067
  if (process.env.PI_PACKAGE_DIR) {
156792
157068
  return;
156793
157069
  }
156794
- const tmp = mkdtempSync2(join64(tmpdir5(), "fn-pkg-"));
157070
+ const tmp = mkdtempSync2(join65(tmpdir5(), "fn-pkg-"));
156795
157071
  let packageJson = {
156796
157072
  name: "pi",
156797
157073
  version: "0.1.0",
@@ -156803,9 +157079,9 @@ function configurePiPackage() {
156803
157079
  const piPackageDir = dirname27(piPackagePath);
156804
157080
  packageJson = JSON.parse(readFileSync22(piPackagePath, "utf-8"));
156805
157081
  for (const entry of ["dist", "docs", "examples", "README.md", "CHANGELOG.md"]) {
156806
- const source = join64(piPackageDir, entry);
157082
+ const source = join65(piPackageDir, entry);
156807
157083
  if (existsSync49(source)) {
156808
- symlinkSync3(source, join64(tmp, entry));
157084
+ symlinkSync3(source, join65(tmp, entry));
156809
157085
  }
156810
157086
  }
156811
157087
  } catch {
@@ -156814,7 +157090,7 @@ function configurePiPackage() {
156814
157090
  ...packageJson.piConfig ?? {},
156815
157091
  configDir: ".fusion"
156816
157092
  };
156817
- writeFileSync6(join64(tmp, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
157093
+ writeFileSync6(join65(tmp, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
156818
157094
  process.env.PI_PACKAGE_DIR = tmp;
156819
157095
  }
156820
157096
  configurePiPackage();
@@ -156842,8 +157118,8 @@ function loadEnvFile(path5) {
156842
157118
  }
156843
157119
  function loadLocalEnv() {
156844
157120
  const cwd = process.cwd();
156845
- loadEnvFile(join64(cwd, ".env"));
156846
- loadEnvFile(join64(cwd, ".env.local"));
157121
+ loadEnvFile(join65(cwd, ".env"));
157122
+ loadEnvFile(join65(cwd, ".env.local"));
156847
157123
  }
156848
157124
  loadLocalEnv();
156849
157125
  async function loadCommandHandlers() {