@runfusion/fusion 0.8.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/bin.js +625 -491
  2. package/dist/client/assets/{AgentDetailView-CLzxf6Z7.js → AgentDetailView-O2adxiKD.js} +1 -1
  3. package/dist/client/assets/{AgentsView-CXaYJX_G.js → AgentsView-CMsJN9J0.js} +3 -3
  4. package/dist/client/assets/{ChatView-iXxGAaN1.js → ChatView-DoqdjDGh.js} +1 -1
  5. package/dist/client/assets/{DevServerView-BeXfFkF4.js → DevServerView-C-CMoxz2.js} +1 -1
  6. package/dist/client/assets/{DirectoryPicker-BMn5fjn9.js → DirectoryPicker-tAfuzQl7.js} +1 -1
  7. package/dist/client/assets/{DocumentsView-CjrtI3TX.js → DocumentsView-B_co_BXz.js} +1 -1
  8. package/dist/client/assets/{InsightsView-BkfQ-TV1.js → InsightsView-CI-TP1Lp.js} +1 -1
  9. package/dist/client/assets/{MemoryView-1G0zWu1i.js → MemoryView-BcDbZcBz.js} +1 -1
  10. package/dist/client/assets/{NodesView-Bn_1R73N.js → NodesView-DCfW16N1.js} +1 -1
  11. package/dist/client/assets/{PiExtensionsManager-CqGOtQnR.js → PiExtensionsManager-BIhPGruz.js} +1 -1
  12. package/dist/client/assets/{PluginManager-CM5QGvSG.js → PluginManager-DOuZY2ZA.js} +1 -1
  13. package/dist/client/assets/{RoadmapsView-B4VnQP83.js → RoadmapsView-CkEjJ6G3.js} +1 -1
  14. package/dist/client/assets/{SettingsModal-C3LckzfT.js → SettingsModal-Cwjchghd.js} +1 -1
  15. package/dist/client/assets/{SettingsModal-BiLA-BeG.js → SettingsModal-a6UiOZ_3.js} +3 -3
  16. package/dist/client/assets/{SetupWizardModal-Bk_8HfLm.js → SetupWizardModal-DPtyqkGN.js} +1 -1
  17. package/dist/client/assets/{SkillsView-CRvqF8P1.js → SkillsView-utmyFduT.js} +1 -1
  18. package/dist/client/assets/{TodoView-Vzui5Eha.js → TodoView-DyiPO0Fc.js} +1 -1
  19. package/dist/client/assets/{folder-open-CMF89prE.js → folder-open-mD33kGzX.js} +1 -1
  20. package/dist/client/assets/{index-B8kH5y4Q.js → index-DZBqmGBj.js} +3 -3
  21. package/dist/client/assets/{list-checks-M95d1uAy.js → list-checks-NQXhquQA.js} +1 -1
  22. package/dist/client/assets/{star-DHhJD6ow.js → star-Bai3dakq.js} +1 -1
  23. package/dist/client/assets/{upload-CEq8jic8.js → upload-Bhl-n_mv.js} +1 -1
  24. package/dist/client/assets/{users-CUA8Tv-d.js → users-tZ6VJnpO.js} +1 -1
  25. package/dist/client/index.html +1 -1
  26. package/dist/client/version.json +1 -1
  27. package/dist/extension.js +313 -155
  28. package/dist/pi-claude-cli/package.json +1 -4
  29. package/package.json +1 -1
  30. package/dist/pi-claude-cli/src/types/cross-spawn.d.ts +0 -7
package/dist/bin.js CHANGED
@@ -6486,9 +6486,9 @@ var init_global_settings = __esm({
6486
6486
  * Serialize operations via promise chain to prevent lost-update races.
6487
6487
  */
6488
6488
  withLock(fn) {
6489
- let resolve37;
6489
+ let resolve39;
6490
6490
  const next = new Promise((r) => {
6491
- resolve37 = r;
6491
+ resolve39 = r;
6492
6492
  });
6493
6493
  const prev = this.lock;
6494
6494
  this.lock = next;
@@ -6496,7 +6496,7 @@ var init_global_settings = __esm({
6496
6496
  try {
6497
6497
  return await fn();
6498
6498
  } finally {
6499
- resolve37();
6499
+ resolve39();
6500
6500
  }
6501
6501
  });
6502
6502
  }
@@ -11806,8 +11806,8 @@ import { join as join8, dirname as dirname2 } from "node:path";
11806
11806
  import { fileURLToPath } from "node:url";
11807
11807
  function getAppVersion() {
11808
11808
  if (cachedVersion !== null) return cachedVersion;
11809
- const __dirname3 = dirname2(fileURLToPath(import.meta.url));
11810
- let currentDir = __dirname3;
11809
+ const __dirname2 = dirname2(fileURLToPath(import.meta.url));
11810
+ let currentDir = __dirname2;
11811
11811
  for (let i = 0; i < 10; i++) {
11812
11812
  try {
11813
11813
  const pkgPath = join8(currentDir, "package.json");
@@ -27792,9 +27792,9 @@ var init_automation_store = __esm({
27792
27792
  */
27793
27793
  withScheduleLock(id, fn) {
27794
27794
  const prev = this.scheduleLocks.get(id) ?? Promise.resolve();
27795
- let resolve37;
27795
+ let resolve39;
27796
27796
  const next = new Promise((r) => {
27797
- resolve37 = r;
27797
+ resolve39 = r;
27798
27798
  });
27799
27799
  this.scheduleLocks.set(id, next);
27800
27800
  return prev.then(async () => {
@@ -27804,7 +27804,7 @@ var init_automation_store = __esm({
27804
27804
  if (this.scheduleLocks.get(id) === next) {
27805
27805
  this.scheduleLocks.delete(id);
27806
27806
  }
27807
- resolve37();
27807
+ resolve39();
27808
27808
  }
27809
27809
  });
27810
27810
  }
@@ -29592,7 +29592,7 @@ var init_project_memory = __esm({
29592
29592
  // ../core/src/run-command.ts
29593
29593
  import { spawn } from "node:child_process";
29594
29594
  function runCommandAsync(command, options = {}) {
29595
- return new Promise((resolve37) => {
29595
+ return new Promise((resolve39) => {
29596
29596
  const maxBuffer = options.maxBuffer ?? DEFAULT_MAX_BUFFER;
29597
29597
  let stdout = "";
29598
29598
  let stderr = "";
@@ -29651,7 +29651,7 @@ function runCommandAsync(command, options = {}) {
29651
29651
  clearTimeout(forceKillTimer);
29652
29652
  forceKillTimer = null;
29653
29653
  }
29654
- resolve37({
29654
+ resolve39({
29655
29655
  stdout,
29656
29656
  stderr,
29657
29657
  exitCode: null,
@@ -29669,7 +29669,7 @@ function runCommandAsync(command, options = {}) {
29669
29669
  }
29670
29670
  signalProcessGroup("SIGTERM");
29671
29671
  scheduleForceKill(NORMAL_CLEANUP_FORCE_KILL_DELAY_MS);
29672
- resolve37({
29672
+ resolve39({
29673
29673
  stdout,
29674
29674
  stderr,
29675
29675
  exitCode: code,
@@ -30819,9 +30819,9 @@ ${outcome}`;
30819
30819
  * lost-update races on the nextId counter.
30820
30820
  */
30821
30821
  withConfigLock(fn) {
30822
- let resolve37;
30822
+ let resolve39;
30823
30823
  const next = new Promise((r) => {
30824
- resolve37 = r;
30824
+ resolve39 = r;
30825
30825
  });
30826
30826
  const prev = this.configLock;
30827
30827
  this.configLock = next;
@@ -30829,7 +30829,7 @@ ${outcome}`;
30829
30829
  try {
30830
30830
  return await fn();
30831
30831
  } finally {
30832
- resolve37();
30832
+ resolve39();
30833
30833
  }
30834
30834
  });
30835
30835
  }
@@ -30839,9 +30839,9 @@ ${outcome}`;
30839
30839
  */
30840
30840
  withTaskLock(id, fn) {
30841
30841
  const prev = this.taskLocks.get(id) ?? Promise.resolve();
30842
- let resolve37;
30842
+ let resolve39;
30843
30843
  const next = new Promise((r) => {
30844
- resolve37 = r;
30844
+ resolve39 = r;
30845
30845
  });
30846
30846
  this.taskLocks.set(id, next);
30847
30847
  return prev.then(async () => {
@@ -30851,7 +30851,7 @@ ${outcome}`;
30851
30851
  if (this.taskLocks.get(id) === next) {
30852
30852
  this.taskLocks.delete(id);
30853
30853
  }
30854
- resolve37();
30854
+ resolve39();
30855
30855
  }
30856
30856
  });
30857
30857
  }
@@ -33006,7 +33006,7 @@ ${task.description}
33006
33006
  }
33007
33007
  }
33008
33008
  }
33009
- await new Promise((resolve37) => setImmediate(resolve37));
33009
+ await new Promise((resolve39) => setImmediate(resolve39));
33010
33010
  const selectClause = this.getTaskSelectClause(true);
33011
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();
33012
33012
  this.lastPollTime = (/* @__PURE__ */ new Date()).toISOString();
@@ -33026,7 +33026,7 @@ ${task.description}
33026
33026
  this.emit("task:updated", task);
33027
33027
  }
33028
33028
  if (i > 0 && i % 50 === 0) {
33029
- await new Promise((resolve37) => setImmediate(resolve37));
33029
+ await new Promise((resolve39) => setImmediate(resolve39));
33030
33030
  }
33031
33031
  }
33032
33032
  const elapsed = Date.now() - startTime;
@@ -34852,7 +34852,7 @@ function runGh(args, cwd) {
34852
34852
  }
34853
34853
  function runGhAsync(args, cwdOrOptions) {
34854
34854
  const { cwd, signal: externalSignal, timeoutMs = DEFAULT_GH_TIMEOUT_MS } = normalizeRunGhOptions(cwdOrOptions);
34855
- return new Promise((resolve37, reject2) => {
34855
+ return new Promise((resolve39, reject2) => {
34856
34856
  if (externalSignal?.aborted) {
34857
34857
  reject2(makeGhError(`gh command aborted: ${describeAbortReason(externalSignal.reason)}`, "ABORT_ERR"));
34858
34858
  return;
@@ -34903,7 +34903,7 @@ function runGhAsync(args, cwdOrOptions) {
34903
34903
  ghError.stderr = stderr ?? "";
34904
34904
  reject2(ghError);
34905
34905
  } else {
34906
- resolve37(stdout ?? "");
34906
+ resolve39(stdout ?? "");
34907
34907
  }
34908
34908
  }
34909
34909
  );
@@ -35191,9 +35191,9 @@ var init_routine_store = __esm({
35191
35191
  */
35192
35192
  withRoutineLock(id, fn) {
35193
35193
  const prev = this.routineLocks.get(id) ?? Promise.resolve();
35194
- let resolve37;
35194
+ let resolve39;
35195
35195
  const next = new Promise((r) => {
35196
- resolve37 = r;
35196
+ resolve39 = r;
35197
35197
  });
35198
35198
  this.routineLocks.set(id, next);
35199
35199
  return prev.then(async () => {
@@ -35203,7 +35203,7 @@ var init_routine_store = __esm({
35203
35203
  if (this.routineLocks.get(id) === next) {
35204
35204
  this.routineLocks.delete(id);
35205
35205
  }
35206
- resolve37();
35206
+ resolve39();
35207
35207
  }
35208
35208
  });
35209
35209
  }
@@ -35802,13 +35802,13 @@ var init_plugin_loader = __esm({
35802
35802
  * Execute a promise with a timeout.
35803
35803
  */
35804
35804
  withTimeout(promise, ms, timeoutMessage) {
35805
- return new Promise((resolve37, reject2) => {
35805
+ return new Promise((resolve39, reject2) => {
35806
35806
  const timer = setTimeout(() => {
35807
35807
  reject2(new Error(timeoutMessage));
35808
35808
  }, ms);
35809
35809
  promise.then((result) => {
35810
35810
  clearTimeout(timer);
35811
- resolve37(result);
35811
+ resolve39(result);
35812
35812
  }).catch((err) => {
35813
35813
  clearTimeout(timer);
35814
35814
  reject2(err);
@@ -39015,7 +39015,7 @@ var require_get_stream = __commonJS({
39015
39015
  };
39016
39016
  const { maxBuffer } = options;
39017
39017
  let stream;
39018
- await new Promise((resolve37, reject2) => {
39018
+ await new Promise((resolve39, reject2) => {
39019
39019
  const rejectPromise = (error) => {
39020
39020
  if (error && stream.getBufferedLength() <= BufferConstants.MAX_LENGTH) {
39021
39021
  error.bufferedData = stream.getBufferedValue();
@@ -39027,7 +39027,7 @@ var require_get_stream = __commonJS({
39027
39027
  rejectPromise(error);
39028
39028
  return;
39029
39029
  }
39030
- resolve37();
39030
+ resolve39();
39031
39031
  });
39032
39032
  stream.on("data", () => {
39033
39033
  if (stream.getBufferedLength() > maxBuffer) {
@@ -40321,7 +40321,7 @@ var require_extract_zip = __commonJS({
40321
40321
  debug("opening", this.zipPath, "with opts", this.opts);
40322
40322
  this.zipfile = await openZip(this.zipPath, { lazyEntries: true });
40323
40323
  this.canceled = false;
40324
- return new Promise((resolve37, reject2) => {
40324
+ return new Promise((resolve39, reject2) => {
40325
40325
  this.zipfile.on("error", (err) => {
40326
40326
  this.canceled = true;
40327
40327
  reject2(err);
@@ -40330,7 +40330,7 @@ var require_extract_zip = __commonJS({
40330
40330
  this.zipfile.on("close", () => {
40331
40331
  if (!this.canceled) {
40332
40332
  debug("zip extraction complete");
40333
- resolve37();
40333
+ resolve39();
40334
40334
  }
40335
40335
  });
40336
40336
  this.zipfile.on("entry", async (entry) => {
@@ -51072,12 +51072,12 @@ var init_concurrency = __esm({
51072
51072
  this._active++;
51073
51073
  return Promise.resolve();
51074
51074
  }
51075
- return new Promise((resolve37) => {
51075
+ return new Promise((resolve39) => {
51076
51076
  this._waiters.push({
51077
51077
  priority,
51078
51078
  resolve: () => {
51079
51079
  this._active++;
51080
- resolve37();
51080
+ resolve39();
51081
51081
  }
51082
51082
  });
51083
51083
  });
@@ -53498,20 +53498,20 @@ async function withRateLimitRetry(fn, options = {}) {
53498
53498
  throw lastError ?? new Error("withRateLimitRetry: unexpected state");
53499
53499
  }
53500
53500
  function sleep(ms, signal) {
53501
- return new Promise((resolve37, reject2) => {
53501
+ return new Promise((resolve39, reject2) => {
53502
53502
  if (signal?.aborted) {
53503
53503
  reject2(signal.reason ?? new Error("Aborted"));
53504
53504
  return;
53505
53505
  }
53506
- const timer = setTimeout(resolve37, ms);
53506
+ const timer = setTimeout(resolve39, ms);
53507
53507
  if (signal) {
53508
53508
  const onAbort = () => {
53509
53509
  clearTimeout(timer);
53510
53510
  reject2(signal.reason ?? new Error("Aborted"));
53511
53511
  };
53512
53512
  signal.addEventListener("abort", onAbort, { once: true });
53513
- const origResolve = resolve37;
53514
- resolve37 = () => {
53513
+ const origResolve = resolve39;
53514
+ resolve39 = () => {
53515
53515
  signal.removeEventListener("abort", onAbort);
53516
53516
  origResolve();
53517
53517
  };
@@ -53591,9 +53591,9 @@ async function readAttachmentContents(rootDir, taskId, attachments) {
53591
53591
  return { attachmentContents, imageContents };
53592
53592
  }
53593
53593
  const { readFile: readFile24 } = await import("node:fs/promises");
53594
- const { join: join66 } = await import("node:path");
53594
+ const { join: join65 } = await import("node:path");
53595
53595
  for (const att of attachments) {
53596
- const filePath = join66(
53596
+ const filePath = join65(
53597
53597
  rootDir,
53598
53598
  ".fusion",
53599
53599
  "tasks",
@@ -55107,9 +55107,9 @@ Remove or replace these ids and call fn_task_create again.`
55107
55107
  }
55108
55108
  try {
55109
55109
  const { readFile: readFile24 } = await import("node:fs/promises");
55110
- const { join: join66 } = await import("node:path");
55110
+ const { join: join65 } = await import("node:path");
55111
55111
  const promptContent = await readFile24(
55112
- join66(rootDir, promptPath),
55112
+ join65(rootDir, promptPath),
55113
55113
  "utf-8"
55114
55114
  ).catch((err) => {
55115
55115
  const msg = err instanceof Error ? err.message : String(err);
@@ -55478,7 +55478,7 @@ import { existsSync as existsSync21 } from "node:fs";
55478
55478
  import { join as join26 } from "node:path";
55479
55479
  import { Type as Type3 } from "typebox";
55480
55480
  async function execWithProcessGroup(command, options) {
55481
- return new Promise((resolve37, reject2) => {
55481
+ return new Promise((resolve39, reject2) => {
55482
55482
  if (options.signal?.aborted) {
55483
55483
  reject2(Object.assign(
55484
55484
  new Error(`Command aborted before start: ${command}`),
@@ -55571,7 +55571,7 @@ async function execWithProcessGroup(command, options) {
55571
55571
  return;
55572
55572
  }
55573
55573
  if (code === 0) {
55574
- resolve37({ stdout, stderr, bufferOverflow: stdoutOverflow || stderrOverflow });
55574
+ resolve39({ stdout, stderr, bufferOverflow: stdoutOverflow || stderrOverflow });
55575
55575
  return;
55576
55576
  }
55577
55577
  reject2(Object.assign(
@@ -59540,7 +59540,7 @@ function resolveExecutorModelPair(taskModelProvider, taskModelId, settings) {
59540
59540
  return { provider: void 0, modelId: void 0 };
59541
59541
  }
59542
59542
  function sleep2(ms) {
59543
- return new Promise((resolve37) => setTimeout(resolve37, ms));
59543
+ return new Promise((resolve39) => setTimeout(resolve39, ms));
59544
59544
  }
59545
59545
  var execAsync4, stepExecLog, MAX_STEP_RETRIES, RETRY_DELAYS_MS, NOOP_TASK_STORE, StepSessionExecutor;
59546
59546
  var init_step_session_executor = __esm({
@@ -60424,7 +60424,7 @@ function detectReviewHandoffIntent(commentText) {
60424
60424
  ];
60425
60425
  return handoffPhrases.some((phrase) => text.includes(phrase));
60426
60426
  }
60427
- var execAsync5, STEP_STATUSES, MAX_WORKFLOW_STEP_RETRIES, MAX_TASK_DONE_SESSION_RETRIES, MAX_TASK_DONE_REQUEUE_RETRIES, WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS2, NonRetryableWorktreeError, taskUpdateParams, taskAddDepParams, spawnAgentParams, reviewStepParams, EXECUTOR_SYSTEM_PROMPT, TaskExecutor;
60427
+ var execAsync5, STEP_STATUSES, MAX_WORKFLOW_STEP_RETRIES, MAX_TASK_DONE_SESSION_RETRIES, MAX_TASK_DONE_REQUEUE_RETRIES, COMPLETED_TASK_WATCHDOG_MS, WORKFLOW_RERUN_WATCHDOG_MS, WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS2, NonRetryableWorktreeError, taskUpdateParams, taskAddDepParams, spawnAgentParams, reviewStepParams, EXECUTOR_SYSTEM_PROMPT, TaskExecutor;
60428
60428
  var init_executor = __esm({
60429
60429
  "../engine/src/executor.ts"() {
60430
60430
  "use strict";
@@ -60460,6 +60460,8 @@ var init_executor = __esm({
60460
60460
  MAX_WORKFLOW_STEP_RETRIES = 3;
60461
60461
  MAX_TASK_DONE_SESSION_RETRIES = 3;
60462
60462
  MAX_TASK_DONE_REQUEUE_RETRIES = 3;
60463
+ COMPLETED_TASK_WATCHDOG_MS = 6e4;
60464
+ WORKFLOW_RERUN_WATCHDOG_MS = 15e3;
60463
60465
  WORKFLOW_SCRIPT_OUTPUT_MAX_CHARS2 = 4e3;
60464
60466
  NonRetryableWorktreeError = class extends Error {
60465
60467
  };
@@ -60670,6 +60672,7 @@ Lint, tests, and typecheck are also hard quality gates:
60670
60672
  store.on("task:moved", ({ task, from, to }) => {
60671
60673
  executorLog.log(`[event:task:moved] ${task.id}: ${from} \u2192 ${to}`);
60672
60674
  if (to === "in-progress") {
60675
+ this.clearWorkflowRerunWatchdog(task.id);
60673
60676
  executorLog.log(`[event:task:moved] Initiating execute() for ${task.id}`);
60674
60677
  void (async () => {
60675
60678
  const taskForExecution = await this.resetMergeStateIfNeeded(task, from);
@@ -60678,6 +60681,7 @@ Lint, tests, and typecheck are also hard quality gates:
60678
60681
  (err) => executorLog.error(`Failed to start ${task.id}:`, err)
60679
60682
  );
60680
60683
  } else if (from === "in-progress") {
60684
+ this.clearCompletedTaskWatchdog(task.id);
60681
60685
  if (this.activeSessions.has(task.id)) {
60682
60686
  executorLog.log(`${task.id} moved from in-progress to ${to} \u2014 terminating agent session`);
60683
60687
  this.pausedAborted.add(task.id);
@@ -60869,6 +60873,10 @@ Lint, tests, and typecheck are also hard quality gates:
60869
60873
  spawnedAgents = /* @__PURE__ */ new Map();
60870
60874
  /** Per-task baseline of session stats used for delta persistence across repeated updates. */
60871
60875
  tokenUsageBaselines = /* @__PURE__ */ new Map();
60876
+ /** One-shot watchdogs for completed tasks that should have transitioned to in-review. */
60877
+ completedTaskWatchdogs = /* @__PURE__ */ new Map();
60878
+ /** One-shot watchdogs for workflow reruns that should have bounced back to in-progress. */
60879
+ workflowRerunWatchdogs = /* @__PURE__ */ new Map();
60872
60880
  async finalizeAlreadyReviewedTask(taskId) {
60873
60881
  const latestTask = await this.store.getTask(taskId);
60874
60882
  if (!latestTask || latestTask.column !== "in-review") {
@@ -61024,6 +61032,120 @@ Lint, tests, and typecheck are also hard quality gates:
61024
61032
  await this.store.updateTask(task.id, updates);
61025
61033
  }
61026
61034
  }
61035
+ clearCompletedTaskWatchdog(taskId) {
61036
+ const handle = this.completedTaskWatchdogs.get(taskId);
61037
+ if (!handle) return;
61038
+ clearTimeout(handle);
61039
+ this.completedTaskWatchdogs.delete(taskId);
61040
+ }
61041
+ clearWorkflowRerunWatchdog(taskId) {
61042
+ const handle = this.workflowRerunWatchdogs.get(taskId);
61043
+ if (!handle) return;
61044
+ clearTimeout(handle);
61045
+ this.workflowRerunWatchdogs.delete(taskId);
61046
+ }
61047
+ scheduleCompletedTaskWatchdog(taskId, trigger) {
61048
+ this.clearCompletedTaskWatchdog(taskId);
61049
+ const handle = setTimeout(async () => {
61050
+ this.completedTaskWatchdogs.delete(taskId);
61051
+ let currentTask = null;
61052
+ try {
61053
+ currentTask = await this.store.getTask(taskId);
61054
+ } catch (err) {
61055
+ const errorMessage = err instanceof Error ? err.message : String(err);
61056
+ executorLog.warn(`${taskId}: completed-task watchdog could not read latest task state: ${errorMessage}`);
61057
+ return;
61058
+ }
61059
+ if (!currentTask || currentTask.column !== "in-progress" || currentTask.paused) {
61060
+ return;
61061
+ }
61062
+ if (this.activeSessions.has(taskId) || this.activeStepExecutors.has(taskId) || this.recoveringCompleted.has(taskId)) {
61063
+ return;
61064
+ }
61065
+ if (!this.isTaskWorkComplete(currentTask)) {
61066
+ return;
61067
+ }
61068
+ executorLog.warn(
61069
+ `${taskId}: completed-task watchdog fired after ${COMPLETED_TASK_WATCHDOG_MS / 1e3}s (${trigger}) \u2014 attempting direct recovery to in-review`
61070
+ );
61071
+ await this.store.logEntry(
61072
+ taskId,
61073
+ `Watchdog: task remained in-progress ${COMPLETED_TASK_WATCHDOG_MS / 1e3}s after ${trigger} \u2014 attempting direct recovery to in-review`
61074
+ ).catch(() => void 0);
61075
+ this.recoveringCompleted.add(taskId);
61076
+ try {
61077
+ const recovered = await this.recoverCompletedTask(currentTask);
61078
+ if (!recovered) {
61079
+ await this.store.logEntry(
61080
+ taskId,
61081
+ "Watchdog recovery attempt could not finalize completed task \u2014 leaving for follow-up recovery"
61082
+ ).catch(() => void 0);
61083
+ }
61084
+ } finally {
61085
+ this.recoveringCompleted.delete(taskId);
61086
+ }
61087
+ }, COMPLETED_TASK_WATCHDOG_MS);
61088
+ this.completedTaskWatchdogs.set(taskId, handle);
61089
+ }
61090
+ async performWorkflowRerunBounce(taskId, worktreePath) {
61091
+ const latestTask = await this.store.getTask(taskId);
61092
+ if (!latestTask) {
61093
+ throw new Error("task missing during workflow rerun bounce");
61094
+ }
61095
+ if (latestTask.column === "in-progress") {
61096
+ await this.store.moveTask(taskId, "todo");
61097
+ await this.store.updateTask(taskId, { worktree: worktreePath });
61098
+ await this.store.moveTask(taskId, "in-progress");
61099
+ return;
61100
+ }
61101
+ if (latestTask.column === "todo") {
61102
+ await this.store.updateTask(taskId, { worktree: worktreePath });
61103
+ await this.store.moveTask(taskId, "in-progress");
61104
+ return;
61105
+ }
61106
+ throw new Error(`task is in '${latestTask.column}', cannot bounce to in-progress`);
61107
+ }
61108
+ scheduleWorkflowRerun(taskId, worktreePath, successMessage) {
61109
+ this.clearWorkflowRerunWatchdog(taskId);
61110
+ setTimeout(async () => {
61111
+ try {
61112
+ await this.performWorkflowRerunBounce(taskId, worktreePath);
61113
+ executorLog.log(successMessage);
61114
+ } catch (err) {
61115
+ const errorMessage = err instanceof Error ? err.message : String(err);
61116
+ executorLog.error(`${taskId}: failed to schedule rerun bounce: ${errorMessage}`);
61117
+ }
61118
+ }, 0);
61119
+ const watchdog = setTimeout(async () => {
61120
+ this.workflowRerunWatchdogs.delete(taskId);
61121
+ let currentTask = null;
61122
+ try {
61123
+ currentTask = await this.store.getTask(taskId);
61124
+ } catch (err) {
61125
+ const errorMessage = err instanceof Error ? err.message : String(err);
61126
+ executorLog.warn(`${taskId}: workflow rerun watchdog could not read latest task state: ${errorMessage}`);
61127
+ return;
61128
+ }
61129
+ if (!currentTask || currentTask.paused || currentTask.column === "in-progress") {
61130
+ return;
61131
+ }
61132
+ executorLog.warn(
61133
+ `${taskId}: workflow rerun watchdog fired after ${WORKFLOW_RERUN_WATCHDOG_MS / 1e3}s \u2014 task is still ${currentTask.column}; retrying handoff once`
61134
+ );
61135
+ await this.store.logEntry(
61136
+ taskId,
61137
+ `Watchdog: workflow rerun handoff stalled for ${WORKFLOW_RERUN_WATCHDOG_MS / 1e3}s (still ${currentTask.column}) \u2014 retrying once`
61138
+ ).catch(() => void 0);
61139
+ try {
61140
+ await this.performWorkflowRerunBounce(taskId, worktreePath);
61141
+ executorLog.warn(`${taskId}: workflow rerun watchdog retry succeeded`);
61142
+ } catch (err) {
61143
+ const errorMessage = err instanceof Error ? err.message : String(err);
61144
+ executorLog.error(`${taskId}: workflow rerun watchdog retry failed: ${errorMessage}`);
61145
+ }
61146
+ }, WORKFLOW_RERUN_WATCHDOG_MS);
61147
+ this.workflowRerunWatchdogs.set(taskId, watchdog);
61148
+ }
61027
61149
  async shouldFinalizeCompletedTask(taskId, taskDone) {
61028
61150
  const task = await this.store.getTask(taskId);
61029
61151
  const completionBlocker = await this.getTaskCompletionBlocker(task);
@@ -61157,6 +61279,7 @@ Lint, tests, and typecheck are also hard quality gates:
61157
61279
  }
61158
61280
  await this.persistTokenUsage(task.id);
61159
61281
  await this.store.moveTask(task.id, "in-review");
61282
+ this.clearCompletedTaskWatchdog(task.id);
61160
61283
  await this.store.logEntry(task.id, "Auto-recovered: task work was complete but stuck in in-progress \u2014 moved to in-review");
61161
61284
  executorLog.log(`\u2713 ${task.id} auto-recovered completed task \u2192 in-review`);
61162
61285
  this.options.onComplete?.(task);
@@ -61653,6 +61776,7 @@ Lint, tests, and typecheck are also hard quality gates:
61653
61776
  executorLog.log(`${task.id}: captured ${modifiedFiles.length} modified files`);
61654
61777
  await audit.filesystem({ type: "file:capture-modified", target: task.id, metadata: { files: modifiedFiles } });
61655
61778
  }
61779
+ this.scheduleCompletedTaskWatchdog(task.id, "step-session completion");
61656
61780
  if (executionMode !== "fast") {
61657
61781
  const workflowResult = await this.runWorkflowSteps(task, worktreePath, settings);
61658
61782
  if (!workflowResult.allPassed) {
@@ -61673,6 +61797,7 @@ Lint, tests, and typecheck are also hard quality gates:
61673
61797
  }
61674
61798
  await this.store.updateTask(task.id, { workflowStepRetries: void 0, taskDoneRetryCount: null });
61675
61799
  await this.store.moveTask(task.id, "in-review");
61800
+ this.clearCompletedTaskWatchdog(task.id);
61676
61801
  await audit.database({ type: "task:move", target: task.id, metadata: { to: "in-review" } });
61677
61802
  executorLog.log(`\u2713 ${task.id} completed (step-session) \u2192 in-review`);
61678
61803
  this.options.onComplete?.(task);
@@ -62009,6 +62134,7 @@ Lint, tests, and typecheck are also hard quality gates:
62009
62134
  await this.store.logEntry(task.id, "Execution paused after completion \u2014 finalizing to in-review");
62010
62135
  await this.persistTokenUsage(task.id);
62011
62136
  await this.store.moveTask(task.id, "in-review");
62137
+ this.clearCompletedTaskWatchdog(task.id);
62012
62138
  this.options.onComplete?.(task);
62013
62139
  } else {
62014
62140
  executorLog.log(`${task.id} paused (graceful session exit) \u2014 moving to todo`);
@@ -62029,6 +62155,7 @@ Lint, tests, and typecheck are also hard quality gates:
62029
62155
  taskDone = true;
62030
62156
  executorLog.log(`${task.id} all steps done \u2014 treating as implicit fn_task_done`);
62031
62157
  await this.store.logEntry(task.id, "All steps complete \u2014 implicit fn_task_done (agent did not call tool explicitly)", void 0, this.currentRunContext);
62158
+ this.scheduleCompletedTaskWatchdog(task.id, "implicit fn_task_done");
62032
62159
  }
62033
62160
  }
62034
62161
  if (taskDone) {
@@ -62038,6 +62165,7 @@ Lint, tests, and typecheck are also hard quality gates:
62038
62165
  await this.store.updateTask(task.id, { modifiedFiles });
62039
62166
  executorLog.log(`${task.id}: captured ${modifiedFiles.length} modified files`);
62040
62167
  }
62168
+ this.scheduleCompletedTaskWatchdog(task.id, "task completion");
62041
62169
  if (executionMode !== "fast") {
62042
62170
  const workflowResult = await this.runWorkflowSteps(task, worktreePath, settings);
62043
62171
  if (!workflowResult.allPassed) {
@@ -62059,6 +62187,7 @@ Lint, tests, and typecheck are also hard quality gates:
62059
62187
  await this.store.updateTask(task.id, { workflowStepRetries: void 0, taskDoneRetryCount: null });
62060
62188
  await this.persistTokenUsage(task.id);
62061
62189
  await this.store.moveTask(task.id, "in-review");
62190
+ this.clearCompletedTaskWatchdog(task.id);
62062
62191
  executorLog.log(`\u2713 ${task.id} completed \u2192 in-review`);
62063
62192
  this.options.onComplete?.(task);
62064
62193
  } else {
@@ -62132,6 +62261,7 @@ Lint, tests, and typecheck are also hard quality gates:
62132
62261
  taskDone = true;
62133
62262
  executorLog.log(`${task.id} all steps done \u2014 treating as implicit fn_task_done`);
62134
62263
  await this.store.logEntry(task.id, "All steps complete \u2014 implicit fn_task_done (agent did not call tool explicitly)", void 0, this.currentRunContext);
62264
+ this.scheduleCompletedTaskWatchdog(task.id, "implicit fn_task_done");
62135
62265
  }
62136
62266
  }
62137
62267
  }
@@ -62142,6 +62272,7 @@ Lint, tests, and typecheck are also hard quality gates:
62142
62272
  await this.store.updateTask(task.id, { modifiedFiles });
62143
62273
  executorLog.log(`${task.id}: captured ${modifiedFiles.length} modified files`);
62144
62274
  }
62275
+ this.scheduleCompletedTaskWatchdog(task.id, "task completion retry");
62145
62276
  if (executionMode !== "fast") {
62146
62277
  const workflowResult = await this.runWorkflowSteps(task, worktreePath, settings);
62147
62278
  if (!workflowResult.allPassed) {
@@ -62159,6 +62290,7 @@ Lint, tests, and typecheck are also hard quality gates:
62159
62290
  await this.store.updateTask(task.id, { workflowStepRetries: void 0, taskDoneRetryCount: null });
62160
62291
  await this.persistTokenUsage(task.id);
62161
62292
  await this.store.moveTask(task.id, "in-review");
62293
+ this.clearCompletedTaskWatchdog(task.id);
62162
62294
  executorLog.log(`\u2713 ${task.id} completed on retry \u2192 in-review`);
62163
62295
  this.options.onComplete?.(task);
62164
62296
  } else {
@@ -62586,6 +62718,7 @@ Lint, tests, and typecheck are also hard quality gates:
62586
62718
  await store.updateTask(taskId, { summary: params.summary });
62587
62719
  }
62588
62720
  await store.logEntry(taskId, "Task marked done by agent");
62721
+ this.scheduleCompletedTaskWatchdog(taskId, "fn_task_done");
62589
62722
  const successMessage = params.summary ? "Task marked complete with summary. All steps done. Moving to in-review." : "Task marked complete. All steps done. Moving to in-review.";
62590
62723
  return {
62591
62724
  content: [{ type: "text", text: successMessage }],
@@ -62812,6 +62945,7 @@ Take a different approach. Do NOT repeat the rejected strategy. Re-read the step
62812
62945
  */
62813
62946
  async handleWorkflowRevisionRequest(task, worktreePath, feedback, stepName) {
62814
62947
  executorLog.log(`${task.id}: workflow revision requested by step "${stepName}"`);
62948
+ this.clearCompletedTaskWatchdog(task.id);
62815
62949
  const updatedTask = await this.store.getTask(task.id);
62816
62950
  const reopen = await this.reopenLastStepForRevision(task.id, updatedTask);
62817
62951
  const reopenSummary = reopen ? `re-opening Step ${reopen.index + 1} ("${reopen.name}") for in-place fix` : "no step to re-open (none were completed)";
@@ -62826,21 +62960,11 @@ Take a different approach. Do NOT repeat the rejected strategy. Re-read the step
62826
62960
  sessionFile: null
62827
62961
  });
62828
62962
  executorLog.log(`${task.id}: scheduling fresh execution after revision request`);
62829
- setTimeout(async () => {
62830
- try {
62831
- await this.store.moveTask(task.id, "todo");
62832
- await this.store.updateTask(task.id, { worktree: worktreePath });
62833
- await this.store.moveTask(task.id, "in-progress");
62834
- executorLog.log(`${task.id}: revision rerun scheduled \u2014 moved to todo then in-progress`);
62835
- } catch (err) {
62836
- const errorMessage = err instanceof Error ? err.message : String(err);
62837
- executorLog.error(`${task.id}: failed to schedule revision rerun: ${errorMessage}`);
62838
- await this.store.logEntry(
62839
- task.id,
62840
- "Workflow revision requested \u2014 executor ready for fresh execution"
62841
- );
62842
- }
62843
- }, 0);
62963
+ this.scheduleWorkflowRerun(
62964
+ task.id,
62965
+ worktreePath,
62966
+ `${task.id}: revision rerun scheduled \u2014 moved to todo then in-progress`
62967
+ );
62844
62968
  }
62845
62969
  /**
62846
62970
  * Re-open the last non-pending step so a revision/failure handler gives the
@@ -62927,6 +63051,7 @@ ${feedback}
62927
63051
  * @returns true if a retry was scheduled, false if retries are exhausted
62928
63052
  */
62929
63053
  async handleWorkflowStepFailure(task, worktreePath, failureFeedback, stepName) {
63054
+ this.clearCompletedTaskWatchdog(task.id);
62930
63055
  const currentRetries = task.workflowStepRetries ?? 0;
62931
63056
  if (currentRetries >= MAX_WORKFLOW_STEP_RETRIES) {
62932
63057
  executorLog.warn(`${task.id}: workflow step "${stepName}" failed \u2014 retries exhausted (${MAX_WORKFLOW_STEP_RETRIES}/${MAX_WORKFLOW_STEP_RETRIES})`);
@@ -62945,21 +63070,11 @@ ${feedback}
62945
63070
  sessionFile: null
62946
63071
  });
62947
63072
  executorLog.log(`${task.id}: scheduling fresh execution after workflow step failure (retry ${retryCount}/${MAX_WORKFLOW_STEP_RETRIES})`);
62948
- setTimeout(async () => {
62949
- try {
62950
- await this.store.moveTask(task.id, "todo");
62951
- await this.store.updateTask(task.id, { worktree: worktreePath });
62952
- await this.store.moveTask(task.id, "in-progress");
62953
- executorLog.log(`${task.id}: workflow step retry scheduled \u2014 moved to todo then in-progress`);
62954
- } catch (err) {
62955
- const errorMessage = err instanceof Error ? err.message : String(err);
62956
- executorLog.error(`${task.id}: failed to schedule workflow step retry: ${errorMessage}`);
62957
- await this.store.logEntry(
62958
- task.id,
62959
- "Workflow step failed \u2014 executor ready for fresh execution"
62960
- );
62961
- }
62962
- }, 0);
63073
+ this.scheduleWorkflowRerun(
63074
+ task.id,
63075
+ worktreePath,
63076
+ `${task.id}: workflow step retry scheduled \u2014 moved to todo then in-progress`
63077
+ );
62963
63078
  return true;
62964
63079
  }
62965
63080
  /**
@@ -62969,6 +63084,7 @@ ${feedback}
62969
63084
  */
62970
63085
  async sendTaskBackForFix(task, worktreePath, failureFeedback, stepName, reason) {
62971
63086
  const taskId = task.id;
63087
+ this.clearCompletedTaskWatchdog(taskId);
62972
63088
  await this.store.addTaskComment(
62973
63089
  taskId,
62974
63090
  `${reason}. The failing workflow step was "${stepName}". Feedback:
@@ -62990,17 +63106,11 @@ Please fix the issues so the verification can pass on the next attempt.`,
62990
63106
  sessionFile: null,
62991
63107
  workflowStepRetries: 0
62992
63108
  });
62993
- setTimeout(async () => {
62994
- try {
62995
- await this.store.moveTask(taskId, "todo");
62996
- await this.store.updateTask(taskId, { worktree: worktreePath });
62997
- await this.store.moveTask(taskId, "in-progress");
62998
- executorLog.log(`${taskId}: sent back to in-progress for remediation`);
62999
- } catch (err) {
63000
- const errorMessage = err instanceof Error ? err.message : String(err);
63001
- executorLog.error(`${taskId}: failed to move back to in-progress: ${errorMessage}`);
63002
- }
63003
- }, 0);
63109
+ this.scheduleWorkflowRerun(
63110
+ taskId,
63111
+ worktreePath,
63112
+ `${taskId}: sent back to in-progress for remediation`
63113
+ );
63004
63114
  }
63005
63115
  /**
63006
63116
  * Inject or update the "Workflow Step Failure" section in PROMPT.md.
@@ -63551,7 +63661,7 @@ Review the work done in this worktree and evaluate it against the criteria in yo
63551
63661
  );
63552
63662
  }
63553
63663
  const delay2 = this.WORKTREE_RETRY_DELAYS[attempt] || 1e3;
63554
- await new Promise((resolve37) => setTimeout(resolve37, delay2));
63664
+ await new Promise((resolve39) => setTimeout(resolve39, delay2));
63555
63665
  }
63556
63666
  }
63557
63667
  throw new Error("Unexpected exit from worktree creation retry loop");
@@ -72875,13 +72985,13 @@ var init_plugin_runner = __esm({
72875
72985
  * Returns the result on success, throws on timeout.
72876
72986
  */
72877
72987
  withTimeout(promise, ms, timeoutMessage) {
72878
- return new Promise((resolve37, reject2) => {
72988
+ return new Promise((resolve39, reject2) => {
72879
72989
  const timer = setTimeout(() => {
72880
72990
  reject2(new Error(timeoutMessage));
72881
72991
  }, ms);
72882
72992
  promise.then((result) => {
72883
72993
  clearTimeout(timer);
72884
- resolve37(result);
72994
+ resolve39(result);
72885
72995
  }).catch((err) => {
72886
72996
  clearTimeout(timer);
72887
72997
  reject2(err);
@@ -73550,7 +73660,7 @@ var init_in_process_runtime = __esm({
73550
73660
  runtimeLog.log(
73551
73661
  `Waiting for ${metrics.inFlightTasks} in-flight tasks to complete...`
73552
73662
  );
73553
- await new Promise((resolve37) => setTimeout(resolve37, 1e3));
73663
+ await new Promise((resolve39) => setTimeout(resolve39, 1e3));
73554
73664
  }
73555
73665
  const finalMetrics = this.getMetrics();
73556
73666
  if (finalMetrics.inFlightTasks > 0) {
@@ -73947,13 +74057,13 @@ var init_ipc_host = __esm({
73947
74057
  }
73948
74058
  const id = generateCorrelationId();
73949
74059
  const message = { type, id, payload };
73950
- return new Promise((resolve37, reject2) => {
74060
+ return new Promise((resolve39, reject2) => {
73951
74061
  const timeout2 = setTimeout(() => {
73952
74062
  this.pendingCommands.delete(id);
73953
74063
  reject2(new Error(`Command ${type} timed out after ${timeoutMs ?? this.commandTimeoutMs}ms`));
73954
74064
  }, timeoutMs ?? this.commandTimeoutMs);
73955
74065
  this.pendingCommands.set(id, {
73956
- resolve: resolve37,
74066
+ resolve: resolve39,
73957
74067
  reject: reject2,
73958
74068
  timeout: timeout2,
73959
74069
  type
@@ -74762,8 +74872,8 @@ var init_remote_node_client = __esm({
74762
74872
  return error instanceof TypeError;
74763
74873
  }
74764
74874
  async sleep(ms) {
74765
- await new Promise((resolve37) => {
74766
- setTimeout(resolve37, ms);
74875
+ await new Promise((resolve39) => {
74876
+ setTimeout(resolve39, ms);
74767
74877
  });
74768
74878
  }
74769
74879
  };
@@ -75027,14 +75137,14 @@ var init_remote_node_runtime = __esm({
75027
75137
  return error instanceof Error ? error : new Error(String(error));
75028
75138
  }
75029
75139
  async sleep(ms, signal) {
75030
- await new Promise((resolve37) => {
75140
+ await new Promise((resolve39) => {
75031
75141
  const timeout2 = setTimeout(() => {
75032
75142
  cleanup();
75033
- resolve37();
75143
+ resolve39();
75034
75144
  }, ms);
75035
75145
  const onAbort = () => {
75036
75146
  cleanup();
75037
- resolve37();
75147
+ resolve39();
75038
75148
  };
75039
75149
  const cleanup = () => {
75040
75150
  clearTimeout(timeout2);
@@ -75921,10 +76031,10 @@ var init_tunnel_process_manager = __esm({
75921
76031
  lastError: null
75922
76032
  });
75923
76033
  this.emitLog("info", "manager", `Stopping ${currentHandle.provider} tunnel (pid=${currentHandle.child.pid ?? "n/a"})`);
75924
- this.activeStopPromise = new Promise((resolve37) => {
76034
+ this.activeStopPromise = new Promise((resolve39) => {
75925
76035
  const onClose = () => {
75926
76036
  currentHandle.child.removeListener("close", onClose);
75927
- resolve37();
76037
+ resolve39();
75928
76038
  };
75929
76039
  currentHandle.child.once("close", onClose);
75930
76040
  killManagedProcess(currentHandle.child, "SIGTERM");
@@ -76480,12 +76590,12 @@ ${detail}`
76480
76590
  */
76481
76591
  async onMerge(taskId) {
76482
76592
  if (this.mergeActive.has(taskId)) {
76483
- return new Promise((resolve37, reject2) => {
76484
- this.manualMergeResolvers.set(taskId, { resolve: resolve37, reject: reject2 });
76593
+ return new Promise((resolve39, reject2) => {
76594
+ this.manualMergeResolvers.set(taskId, { resolve: resolve39, reject: reject2 });
76485
76595
  });
76486
76596
  }
76487
- return new Promise((resolve37, reject2) => {
76488
- this.manualMergeResolvers.set(taskId, { resolve: resolve37, reject: reject2 });
76597
+ return new Promise((resolve39, reject2) => {
76598
+ this.manualMergeResolvers.set(taskId, { resolve: resolve39, reject: reject2 });
76489
76599
  this.internalEnqueueMerge(taskId);
76490
76600
  });
76491
76601
  }
@@ -82355,7 +82465,7 @@ function hermesProfileHome(profileName) {
82355
82465
  async function listHermesProfiles(opts) {
82356
82466
  const binary = resolveBinaryForSpawn(opts?.binaryPath ?? "hermes");
82357
82467
  const timeoutMs = opts?.timeoutMs ?? 5e3;
82358
- return new Promise((resolve37, reject2) => {
82468
+ return new Promise((resolve39, reject2) => {
82359
82469
  let settled = false;
82360
82470
  const child = spawn4(binary, ["profile", "list"], {
82361
82471
  stdio: ["ignore", "pipe", "pipe"],
@@ -82398,7 +82508,7 @@ async function listHermesProfiles(opts) {
82398
82508
  ${combined}`));
82399
82509
  return;
82400
82510
  }
82401
- resolve37(parseProfileListOutput(stdout));
82511
+ resolve39(parseProfileListOutput(stdout));
82402
82512
  });
82403
82513
  });
82404
82514
  }
@@ -82475,7 +82585,7 @@ function buildHermesArgs(prompt, settings, resumeSessionId) {
82475
82585
  async function invokeHermesCli(prompt, settings, resumeSessionId, signal) {
82476
82586
  const args = buildHermesArgs(prompt, settings, resumeSessionId);
82477
82587
  const binary = resolveBinaryForSpawn(settings.binaryPath);
82478
- return new Promise((resolve37, reject2) => {
82588
+ return new Promise((resolve39, reject2) => {
82479
82589
  let settled = false;
82480
82590
  const spawnEnv = { ...process.env, PYTHONUNBUFFERED: "1" };
82481
82591
  if (settings.profile) {
@@ -82543,7 +82653,7 @@ ${combined}`));
82543
82653
  return;
82544
82654
  }
82545
82655
  try {
82546
- resolve37(parseHermesOutput(stdout, stderr));
82656
+ resolve39(parseHermesOutput(stdout, stderr));
82547
82657
  } catch (parseErr) {
82548
82658
  reject2(parseErr);
82549
82659
  }
@@ -82861,7 +82971,7 @@ async function promptCli(session, message, config, callbacks, signal) {
82861
82971
  const args = buildOpenClawArgs(config, session.sessionId, message);
82862
82972
  const cb = { ...session.callbacks, ...callbacks };
82863
82973
  cb.onToolStart?.("openclaw.agent", { sessionId: session.sessionId });
82864
- return new Promise((resolve37, reject2) => {
82974
+ return new Promise((resolve39, reject2) => {
82865
82975
  let settled = false;
82866
82976
  const child = spawn6(config.binaryPath, args, {
82867
82977
  stdio: ["ignore", "pipe", "pipe"]
@@ -82954,7 +83064,7 @@ async function promptCli(session, message, config, callbacks, signal) {
82954
83064
  ...metaError ? { error: metaError } : {},
82955
83065
  ...errorText.length > 0 ? { toolErrors: errorText } : {}
82956
83066
  });
82957
- resolve37();
83067
+ resolve39();
82958
83068
  });
82959
83069
  });
82960
83070
  }
@@ -83697,8 +83807,8 @@ function registerTaskWorkflowRoutes(ctx, deps) {
83697
83807
  });
83698
83808
  if (retrySpecification) {
83699
83809
  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");
83810
+ const { join: join65 } = await import("node:path");
83811
+ const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
83702
83812
  await rm6(promptPath, { force: true });
83703
83813
  await scopedStore.logEntry(req.params.id, "Retry requested from dashboard (planning retry budget reset)");
83704
83814
  const updated2 = await scopedStore.getTask(req.params.id);
@@ -84120,8 +84230,8 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84120
84230
  await scopedStore.logEntry(task.id, "Plan rejected by user", "Specification will be regenerated");
84121
84231
  await scopedStore.updateTask(task.id, { status: void 0 });
84122
84232
  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");
84233
+ const { join: join65 } = await import("node:path");
84234
+ const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84125
84235
  await rm6(promptPath, { force: true });
84126
84236
  const updated = await scopedStore.getTask(task.id);
84127
84237
  res.json(updated);
@@ -84391,8 +84501,8 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84391
84501
  if (task.column === "triage") {
84392
84502
  await scopedStore.logEntry(task.id, "AI spec revision requested", feedback);
84393
84503
  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");
84504
+ const { join: join66 } = await import("node:path");
84505
+ const promptPath2 = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84396
84506
  await rm7(promptPath2, { force: true });
84397
84507
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84398
84508
  const updated2 = await scopedStore.getTask(task.id);
@@ -84408,8 +84518,8 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84408
84518
  await scopedStore.logEntry(task.id, "AI spec revision requested", feedback);
84409
84519
  const updated = await scopedStore.moveTask(task.id, "triage");
84410
84520
  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");
84521
+ const { join: join65 } = await import("node:path");
84522
+ const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84413
84523
  await rm6(promptPath, { force: true });
84414
84524
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84415
84525
  res.json(updated);
@@ -84429,8 +84539,8 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84429
84539
  if (task.column === "triage") {
84430
84540
  await scopedStore.logEntry(task.id, "Specification rebuild requested by user");
84431
84541
  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");
84542
+ const { join: join66 } = await import("node:path");
84543
+ const promptPath2 = join66(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84434
84544
  await rm7(promptPath2, { force: true });
84435
84545
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84436
84546
  const updated2 = await scopedStore.getTask(task.id);
@@ -84444,8 +84554,8 @@ function registerTaskWorkflowRoutes(ctx, deps) {
84444
84554
  await scopedStore.logEntry(task.id, "Specification rebuild requested by user");
84445
84555
  const updated = await scopedStore.moveTask(task.id, "triage");
84446
84556
  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");
84557
+ const { join: join65 } = await import("node:path");
84558
+ const promptPath = join65(scopedStore.getRootDir(), ".fusion", "tasks", task.id, "PROMPT.md");
84449
84559
  await rm6(promptPath, { force: true });
84450
84560
  await scopedStore.updateTask(task.id, { status: "needs-replan" });
84451
84561
  res.json(updated);
@@ -89218,7 +89328,7 @@ var init_register_messaging_scripts = __esm({
89218
89328
 
89219
89329
  // ../dashboard/src/github.ts
89220
89330
  function delay(ms) {
89221
- return new Promise((resolve37) => setTimeout(resolve37, ms));
89331
+ return new Promise((resolve39) => setTimeout(resolve39, ms));
89222
89332
  }
89223
89333
  function normalizeCheckState(state) {
89224
89334
  switch ((state ?? "").toLowerCase()) {
@@ -95456,9 +95566,9 @@ var require_readdir_glob = __commonJS({
95456
95566
  var fs2 = __require("fs");
95457
95567
  var { EventEmitter: EventEmitter35 } = __require("events");
95458
95568
  var { Minimatch } = require_minimatch();
95459
- var { resolve: resolve37 } = __require("path");
95569
+ var { resolve: resolve39 } = __require("path");
95460
95570
  function readdir12(dir2, strict) {
95461
- return new Promise((resolve38, reject2) => {
95571
+ return new Promise((resolve40, reject2) => {
95462
95572
  fs2.readdir(dir2, { withFileTypes: true }, (err, files) => {
95463
95573
  if (err) {
95464
95574
  switch (err.code) {
@@ -95466,7 +95576,7 @@ var require_readdir_glob = __commonJS({
95466
95576
  if (strict) {
95467
95577
  reject2(err);
95468
95578
  } else {
95469
- resolve38([]);
95579
+ resolve40([]);
95470
95580
  }
95471
95581
  break;
95472
95582
  case "ENOTSUP":
@@ -95476,7 +95586,7 @@ var require_readdir_glob = __commonJS({
95476
95586
  case "ENAMETOOLONG":
95477
95587
  // Filename too long
95478
95588
  case "UNKNOWN":
95479
- resolve38([]);
95589
+ resolve40([]);
95480
95590
  break;
95481
95591
  case "ELOOP":
95482
95592
  // Too many levels of symbolic links
@@ -95485,30 +95595,30 @@ var require_readdir_glob = __commonJS({
95485
95595
  break;
95486
95596
  }
95487
95597
  } else {
95488
- resolve38(files);
95598
+ resolve40(files);
95489
95599
  }
95490
95600
  });
95491
95601
  });
95492
95602
  }
95493
95603
  function stat12(file, followSymlinks) {
95494
- return new Promise((resolve38, reject2) => {
95604
+ return new Promise((resolve40, reject2) => {
95495
95605
  const statFunc = followSymlinks ? fs2.stat : fs2.lstat;
95496
95606
  statFunc(file, (err, stats) => {
95497
95607
  if (err) {
95498
95608
  switch (err.code) {
95499
95609
  case "ENOENT":
95500
95610
  if (followSymlinks) {
95501
- resolve38(stat12(file, false));
95611
+ resolve40(stat12(file, false));
95502
95612
  } else {
95503
- resolve38(null);
95613
+ resolve40(null);
95504
95614
  }
95505
95615
  break;
95506
95616
  default:
95507
- resolve38(null);
95617
+ resolve40(null);
95508
95618
  break;
95509
95619
  }
95510
95620
  } else {
95511
- resolve38(stats);
95621
+ resolve40(stats);
95512
95622
  }
95513
95623
  });
95514
95624
  });
@@ -95598,7 +95708,7 @@ var require_readdir_glob = __commonJS({
95598
95708
  (skip) => new Minimatch(skip, { dot: true })
95599
95709
  );
95600
95710
  }
95601
- this.iterator = explore(resolve37(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
95711
+ this.iterator = explore(resolve39(cwd || "."), this.options.follow, this.options.stat, this._shouldSkipDirectory.bind(this));
95602
95712
  this.paused = false;
95603
95713
  this.inactive = false;
95604
95714
  this.aborted = false;
@@ -95852,10 +95962,10 @@ function awaitify(asyncFn, arity) {
95852
95962
  if (typeof args[arity - 1] === "function") {
95853
95963
  return asyncFn.apply(this, args);
95854
95964
  }
95855
- return new Promise((resolve37, reject2) => {
95965
+ return new Promise((resolve39, reject2) => {
95856
95966
  args[arity - 1] = (err, ...cbArgs) => {
95857
95967
  if (err) return reject2(err);
95858
- resolve37(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
95968
+ resolve39(cbArgs.length > 1 ? cbArgs : cbArgs[0]);
95859
95969
  };
95860
95970
  asyncFn.apply(this, args);
95861
95971
  });
@@ -96037,13 +96147,13 @@ function mapSeries(coll, iteratee, callback) {
96037
96147
  return _asyncMap(eachOfSeries$1, coll, iteratee, callback);
96038
96148
  }
96039
96149
  function promiseCallback() {
96040
- let resolve37, reject2;
96150
+ let resolve39, reject2;
96041
96151
  function callback(err, ...args) {
96042
96152
  if (err) return reject2(err);
96043
- resolve37(args.length > 1 ? args : args[0]);
96153
+ resolve39(args.length > 1 ? args : args[0]);
96044
96154
  }
96045
96155
  callback[PROMISE_SYMBOL] = new Promise((res, rej) => {
96046
- resolve37 = res, reject2 = rej;
96156
+ resolve39 = res, reject2 = rej;
96047
96157
  });
96048
96158
  return callback;
96049
96159
  }
@@ -96316,8 +96426,8 @@ function queue$1(worker, concurrency, payload) {
96316
96426
  });
96317
96427
  }
96318
96428
  if (rejectOnError || !callback) {
96319
- return new Promise((resolve37, reject2) => {
96320
- res = resolve37;
96429
+ return new Promise((resolve39, reject2) => {
96430
+ res = resolve39;
96321
96431
  rej = reject2;
96322
96432
  });
96323
96433
  }
@@ -96356,10 +96466,10 @@ function queue$1(worker, concurrency, payload) {
96356
96466
  }
96357
96467
  const eventMethod = (name) => (handler) => {
96358
96468
  if (!handler) {
96359
- return new Promise((resolve37, reject2) => {
96469
+ return new Promise((resolve39, reject2) => {
96360
96470
  once3(name, (err, data) => {
96361
96471
  if (err) return reject2(err);
96362
- resolve37(data);
96472
+ resolve39(data);
96363
96473
  });
96364
96474
  });
96365
96475
  }
@@ -98608,7 +98718,7 @@ var require_BufferList = __commonJS({
98608
98718
  this.head = this.tail = null;
98609
98719
  this.length = 0;
98610
98720
  };
98611
- BufferList.prototype.join = function join66(s) {
98721
+ BufferList.prototype.join = function join65(s) {
98612
98722
  if (this.length === 0) return "";
98613
98723
  var p = this.head;
98614
98724
  var ret = "" + p.data;
@@ -102365,25 +102475,25 @@ var require_util2 = __commonJS({
102365
102475
  };
102366
102476
  },
102367
102477
  createDeferredPromise: function() {
102368
- let resolve37;
102478
+ let resolve39;
102369
102479
  let reject2;
102370
102480
  const promise = new Promise((res, rej) => {
102371
- resolve37 = res;
102481
+ resolve39 = res;
102372
102482
  reject2 = rej;
102373
102483
  });
102374
102484
  return {
102375
102485
  promise,
102376
- resolve: resolve37,
102486
+ resolve: resolve39,
102377
102487
  reject: reject2
102378
102488
  };
102379
102489
  },
102380
102490
  promisify(fn) {
102381
- return new Promise((resolve37, reject2) => {
102491
+ return new Promise((resolve39, reject2) => {
102382
102492
  fn((err, ...args) => {
102383
102493
  if (err) {
102384
102494
  return reject2(err);
102385
102495
  }
102386
- return resolve37(...args);
102496
+ return resolve39(...args);
102387
102497
  });
102388
102498
  });
102389
102499
  },
@@ -103175,7 +103285,7 @@ var require_end_of_stream2 = __commonJS({
103175
103285
  validateBoolean3(opts.cleanup, "cleanup");
103176
103286
  autoCleanup = opts.cleanup;
103177
103287
  }
103178
- return new Promise2((resolve37, reject2) => {
103288
+ return new Promise2((resolve39, reject2) => {
103179
103289
  const cleanup = eos(stream, opts, (err) => {
103180
103290
  if (autoCleanup) {
103181
103291
  cleanup();
@@ -103183,7 +103293,7 @@ var require_end_of_stream2 = __commonJS({
103183
103293
  if (err) {
103184
103294
  reject2(err);
103185
103295
  } else {
103186
- resolve37();
103296
+ resolve39();
103187
103297
  }
103188
103298
  });
103189
103299
  });
@@ -104350,7 +104460,7 @@ var require_readable2 = __commonJS({
104350
104460
  error = this.readableEnded ? null : new AbortError();
104351
104461
  this.destroy(error);
104352
104462
  }
104353
- return new Promise2((resolve37, reject2) => eos(this, (err) => err && err !== error ? reject2(err) : resolve37(null)));
104463
+ return new Promise2((resolve39, reject2) => eos(this, (err) => err && err !== error ? reject2(err) : resolve39(null)));
104354
104464
  };
104355
104465
  Readable2.prototype.push = function(chunk, encoding) {
104356
104466
  return readableAddChunk(this, chunk, encoding, false);
@@ -104894,12 +105004,12 @@ var require_readable2 = __commonJS({
104894
105004
  }
104895
105005
  async function* createAsyncIterator(stream, options) {
104896
105006
  let callback = nop;
104897
- function next(resolve37) {
105007
+ function next(resolve39) {
104898
105008
  if (this === stream) {
104899
105009
  callback();
104900
105010
  callback = nop;
104901
105011
  } else {
104902
- callback = resolve37;
105012
+ callback = resolve39;
104903
105013
  }
104904
105014
  }
104905
105015
  stream.on("readable", next);
@@ -105952,7 +106062,7 @@ var require_duplexify = __commonJS({
105952
106062
  );
105953
106063
  };
105954
106064
  function fromAsyncGen(fn) {
105955
- let { promise, resolve: resolve37 } = createDeferredPromise();
106065
+ let { promise, resolve: resolve39 } = createDeferredPromise();
105956
106066
  const ac = new AbortController2();
105957
106067
  const signal = ac.signal;
105958
106068
  const value = fn(
@@ -105967,7 +106077,7 @@ var require_duplexify = __commonJS({
105967
106077
  throw new AbortError(void 0, {
105968
106078
  cause: signal.reason
105969
106079
  });
105970
- ({ promise, resolve: resolve37 } = createDeferredPromise());
106080
+ ({ promise, resolve: resolve39 } = createDeferredPromise());
105971
106081
  yield chunk;
105972
106082
  }
105973
106083
  })(),
@@ -105978,8 +106088,8 @@ var require_duplexify = __commonJS({
105978
106088
  return {
105979
106089
  value,
105980
106090
  write(chunk, encoding, cb) {
105981
- const _resolve = resolve37;
105982
- resolve37 = null;
106091
+ const _resolve = resolve39;
106092
+ resolve39 = null;
105983
106093
  _resolve({
105984
106094
  chunk,
105985
106095
  done: false,
@@ -105987,8 +106097,8 @@ var require_duplexify = __commonJS({
105987
106097
  });
105988
106098
  },
105989
106099
  final(cb) {
105990
- const _resolve = resolve37;
105991
- resolve37 = null;
106100
+ const _resolve = resolve39;
106101
+ resolve39 = null;
105992
106102
  _resolve({
105993
106103
  done: true,
105994
106104
  cb
@@ -106440,7 +106550,7 @@ var require_pipeline = __commonJS({
106440
106550
  callback();
106441
106551
  }
106442
106552
  };
106443
- const wait = () => new Promise2((resolve37, reject2) => {
106553
+ const wait = () => new Promise2((resolve39, reject2) => {
106444
106554
  if (error) {
106445
106555
  reject2(error);
106446
106556
  } else {
@@ -106448,7 +106558,7 @@ var require_pipeline = __commonJS({
106448
106558
  if (error) {
106449
106559
  reject2(error);
106450
106560
  } else {
106451
- resolve37();
106561
+ resolve39();
106452
106562
  }
106453
106563
  };
106454
106564
  }
@@ -107092,8 +107202,8 @@ var require_operators = __commonJS({
107092
107202
  next = null;
107093
107203
  }
107094
107204
  if (!done && (queue2.length >= highWaterMark2 || cnt >= concurrency)) {
107095
- await new Promise2((resolve37) => {
107096
- resume = resolve37;
107205
+ await new Promise2((resolve39) => {
107206
+ resume = resolve39;
107097
107207
  });
107098
107208
  }
107099
107209
  }
@@ -107127,8 +107237,8 @@ var require_operators = __commonJS({
107127
107237
  queue2.shift();
107128
107238
  maybeResume();
107129
107239
  }
107130
- await new Promise2((resolve37) => {
107131
- next = resolve37;
107240
+ await new Promise2((resolve39) => {
107241
+ next = resolve39;
107132
107242
  });
107133
107243
  }
107134
107244
  } finally {
@@ -107386,7 +107496,7 @@ var require_promises = __commonJS({
107386
107496
  var { finished } = require_end_of_stream2();
107387
107497
  require_stream2();
107388
107498
  function pipeline(...streams) {
107389
- return new Promise2((resolve37, reject2) => {
107499
+ return new Promise2((resolve39, reject2) => {
107390
107500
  let signal;
107391
107501
  let end;
107392
107502
  const lastArg = streams[streams.length - 1];
@@ -107401,7 +107511,7 @@ var require_promises = __commonJS({
107401
107511
  if (err) {
107402
107512
  reject2(err);
107403
107513
  } else {
107404
- resolve37(value);
107514
+ resolve39(value);
107405
107515
  }
107406
107516
  },
107407
107517
  {
@@ -112174,10 +112284,10 @@ var require_commonjs3 = __commonJS({
112174
112284
  * Return a void Promise that resolves once the stream ends.
112175
112285
  */
112176
112286
  async promise() {
112177
- return new Promise((resolve37, reject2) => {
112287
+ return new Promise((resolve39, reject2) => {
112178
112288
  this.on(DESTROYED, () => reject2(new Error("stream destroyed")));
112179
112289
  this.on("error", (er) => reject2(er));
112180
- this.on("end", () => resolve37());
112290
+ this.on("end", () => resolve39());
112181
112291
  });
112182
112292
  }
112183
112293
  /**
@@ -112201,7 +112311,7 @@ var require_commonjs3 = __commonJS({
112201
112311
  return Promise.resolve({ done: false, value: res });
112202
112312
  if (this[EOF])
112203
112313
  return stop();
112204
- let resolve37;
112314
+ let resolve39;
112205
112315
  let reject2;
112206
112316
  const onerr = (er) => {
112207
112317
  this.off("data", ondata);
@@ -112215,19 +112325,19 @@ var require_commonjs3 = __commonJS({
112215
112325
  this.off("end", onend);
112216
112326
  this.off(DESTROYED, ondestroy);
112217
112327
  this.pause();
112218
- resolve37({ value, done: !!this[EOF] });
112328
+ resolve39({ value, done: !!this[EOF] });
112219
112329
  };
112220
112330
  const onend = () => {
112221
112331
  this.off("error", onerr);
112222
112332
  this.off("data", ondata);
112223
112333
  this.off(DESTROYED, ondestroy);
112224
112334
  stop();
112225
- resolve37({ done: true, value: void 0 });
112335
+ resolve39({ done: true, value: void 0 });
112226
112336
  };
112227
112337
  const ondestroy = () => onerr(new Error("stream destroyed"));
112228
112338
  return new Promise((res2, rej) => {
112229
112339
  reject2 = rej;
112230
- resolve37 = res2;
112340
+ resolve39 = res2;
112231
112341
  this.once(DESTROYED, ondestroy);
112232
112342
  this.once("error", onerr);
112233
112343
  this.once("end", onend);
@@ -113243,9 +113353,9 @@ var require_commonjs4 = __commonJS({
113243
113353
  if (this.#asyncReaddirInFlight) {
113244
113354
  await this.#asyncReaddirInFlight;
113245
113355
  } else {
113246
- let resolve37 = () => {
113356
+ let resolve39 = () => {
113247
113357
  };
113248
- this.#asyncReaddirInFlight = new Promise((res) => resolve37 = res);
113358
+ this.#asyncReaddirInFlight = new Promise((res) => resolve39 = res);
113249
113359
  try {
113250
113360
  for (const e of await this.#fs.promises.readdir(fullpath, {
113251
113361
  withFileTypes: true
@@ -113258,7 +113368,7 @@ var require_commonjs4 = __commonJS({
113258
113368
  children.provisional = 0;
113259
113369
  }
113260
113370
  this.#asyncReaddirInFlight = void 0;
113261
- resolve37();
113371
+ resolve39();
113262
113372
  }
113263
113373
  return children.slice(0, children.provisional);
113264
113374
  }
@@ -116031,11 +116141,11 @@ var require_core = __commonJS({
116031
116141
  this._finalize();
116032
116142
  }
116033
116143
  var self2 = this;
116034
- return new Promise(function(resolve37, reject2) {
116144
+ return new Promise(function(resolve39, reject2) {
116035
116145
  var errored;
116036
116146
  self2._module.on("end", function() {
116037
116147
  if (!errored) {
116038
- resolve37();
116148
+ resolve39();
116039
116149
  }
116040
116150
  });
116041
116151
  self2._module.on("error", function(err) {
@@ -118475,8 +118585,8 @@ var require_streamx = __commonJS({
118475
118585
  return this;
118476
118586
  },
118477
118587
  next() {
118478
- return new Promise(function(resolve37, reject2) {
118479
- promiseResolve = resolve37;
118588
+ return new Promise(function(resolve39, reject2) {
118589
+ promiseResolve = resolve39;
118480
118590
  promiseReject = reject2;
118481
118591
  const data = stream.read();
118482
118592
  if (data !== null) ondata(data);
@@ -118506,11 +118616,11 @@ var require_streamx = __commonJS({
118506
118616
  }
118507
118617
  function destroy(err) {
118508
118618
  stream.destroy(err);
118509
- return new Promise((resolve37, reject2) => {
118510
- if (stream._duplexState & DESTROYED) return resolve37({ value: void 0, done: true });
118619
+ return new Promise((resolve39, reject2) => {
118620
+ if (stream._duplexState & DESTROYED) return resolve39({ value: void 0, done: true });
118511
118621
  stream.once("close", function() {
118512
118622
  if (err) reject2(err);
118513
- else resolve37({ value: void 0, done: true });
118623
+ else resolve39({ value: void 0, done: true });
118514
118624
  });
118515
118625
  });
118516
118626
  }
@@ -118554,8 +118664,8 @@ var require_streamx = __commonJS({
118554
118664
  const writes = pending + (ws._duplexState & WRITE_WRITING ? 1 : 0);
118555
118665
  if (writes === 0) return Promise.resolve(true);
118556
118666
  if (state.drains === null) state.drains = [];
118557
- return new Promise((resolve37) => {
118558
- state.drains.push({ writes, resolve: resolve37 });
118667
+ return new Promise((resolve39) => {
118668
+ state.drains.push({ writes, resolve: resolve39 });
118559
118669
  });
118560
118670
  }
118561
118671
  write(data) {
@@ -118660,10 +118770,10 @@ var require_streamx = __commonJS({
118660
118770
  cb(null);
118661
118771
  }
118662
118772
  function pipelinePromise(...streams) {
118663
- return new Promise((resolve37, reject2) => {
118773
+ return new Promise((resolve39, reject2) => {
118664
118774
  return pipeline(...streams, (err) => {
118665
118775
  if (err) return reject2(err);
118666
- resolve37();
118776
+ resolve39();
118667
118777
  });
118668
118778
  });
118669
118779
  }
@@ -119320,16 +119430,16 @@ var require_extract = __commonJS({
119320
119430
  entryCallback = null;
119321
119431
  cb(err);
119322
119432
  }
119323
- function onnext(resolve37, reject2) {
119433
+ function onnext(resolve39, reject2) {
119324
119434
  if (error) {
119325
119435
  return reject2(error);
119326
119436
  }
119327
119437
  if (entryStream) {
119328
- resolve37({ value: entryStream, done: false });
119438
+ resolve39({ value: entryStream, done: false });
119329
119439
  entryStream = null;
119330
119440
  return;
119331
119441
  }
119332
- promiseResolve = resolve37;
119442
+ promiseResolve = resolve39;
119333
119443
  promiseReject = reject2;
119334
119444
  consumeCallback(null);
119335
119445
  if (extract._finished && promiseResolve) {
@@ -119357,11 +119467,11 @@ var require_extract = __commonJS({
119357
119467
  function destroy(err) {
119358
119468
  extract.destroy(err);
119359
119469
  consumeCallback(err);
119360
- return new Promise((resolve37, reject2) => {
119361
- if (extract.destroyed) return resolve37({ value: void 0, done: true });
119470
+ return new Promise((resolve39, reject2) => {
119471
+ if (extract.destroyed) return resolve39({ value: void 0, done: true });
119362
119472
  extract.once("close", function() {
119363
119473
  if (err) reject2(err);
119364
- else resolve37({ value: void 0, done: true });
119474
+ else resolve39({ value: void 0, done: true });
119365
119475
  });
119366
119476
  });
119367
119477
  }
@@ -125866,9 +125976,9 @@ function registerProxyRoutes(router, deps) {
125866
125976
  if (req.rawBody && req.rawBody.length > 0) {
125867
125977
  body = req.rawBody;
125868
125978
  } else {
125869
- await new Promise((resolve37, reject2) => {
125979
+ await new Promise((resolve39, reject2) => {
125870
125980
  req.on("data", (chunk) => chunks.push(chunk));
125871
- req.on("end", resolve37);
125981
+ req.on("end", resolve39);
125872
125982
  req.on("error", reject2);
125873
125983
  });
125874
125984
  if (chunks.length > 0) {
@@ -126064,13 +126174,13 @@ import { readFile as readFile19 } from "node:fs/promises";
126064
126174
  import * as https from "node:https";
126065
126175
  import * as child_process from "node:child_process";
126066
126176
  function execFileAsync4(file, args, options) {
126067
- return new Promise((resolve37, reject2) => {
126177
+ return new Promise((resolve39, reject2) => {
126068
126178
  child_process.execFile(file, args, options, (error, stdout, stderr) => {
126069
126179
  if (error) {
126070
126180
  reject2(error);
126071
126181
  return;
126072
126182
  }
126073
- resolve37({ stdout: String(stdout), stderr: String(stderr) });
126183
+ resolve39({ stdout: String(stdout), stderr: String(stderr) });
126074
126184
  });
126075
126185
  });
126076
126186
  }
@@ -126129,7 +126239,7 @@ function formatDuration(ms) {
126129
126239
  return remHours > 0 ? `${days}d ${remHours}h` : `${days}d`;
126130
126240
  }
126131
126241
  function httpsRequest(url, options) {
126132
- return new Promise((resolve37, reject2) => {
126242
+ return new Promise((resolve39, reject2) => {
126133
126243
  const parsed = new URL(url);
126134
126244
  const req = https.request(
126135
126245
  {
@@ -126149,7 +126259,7 @@ function httpsRequest(url, options) {
126149
126259
  if (typeof v === "string") hdrs[k.toLowerCase()] = v;
126150
126260
  else if (Array.isArray(v)) hdrs[k.toLowerCase()] = v.join(", ");
126151
126261
  }
126152
- resolve37({
126262
+ resolve39({
126153
126263
  status: res.statusCode || 0,
126154
126264
  headers: hdrs,
126155
126265
  body: Buffer.concat(chunks).toString("utf-8")
@@ -126396,7 +126506,7 @@ async function fetchClaudeUsageViaCli() {
126396
126506
  env: { ...process.env, TERM: "xterm-256color" }
126397
126507
  };
126398
126508
  if (isWindows) ptyOptions.useConpty = false;
126399
- const output = await new Promise((resolve37, reject2) => {
126509
+ const output = await new Promise((resolve39, reject2) => {
126400
126510
  let buf = "";
126401
126511
  let settled = false;
126402
126512
  let sentCommand = false;
@@ -126412,7 +126522,7 @@ async function fetchClaudeUsageViaCli() {
126412
126522
  }
126413
126523
  const clean = _stripClaudeAnsi(buf);
126414
126524
  if (clean.includes("Current session") || clean.includes("% left") || clean.includes("% used")) {
126415
- resolve37(buf);
126525
+ resolve39(buf);
126416
126526
  } else {
126417
126527
  reject2(new Error("Claude CLI timed out after 60s \u2014 got output but no usage data. Try running `claude /usage` manually."));
126418
126528
  }
@@ -126463,7 +126573,7 @@ async function fetchClaudeUsageViaCli() {
126463
126573
  ptyProcess.kill();
126464
126574
  } catch {
126465
126575
  }
126466
- resolve37(buf);
126576
+ resolve39(buf);
126467
126577
  }
126468
126578
  }, 2e3);
126469
126579
  }
@@ -126474,7 +126584,7 @@ async function fetchClaudeUsageViaCli() {
126474
126584
  if (settled) return;
126475
126585
  settled = true;
126476
126586
  clearTimeout(timeout2);
126477
- resolve37(buf);
126587
+ resolve39(buf);
126478
126588
  });
126479
126589
  });
126480
126590
  const cleanOutput = _stripClaudeAnsi(output);
@@ -127142,9 +127252,9 @@ async function fetchGitHubCopilotUsage() {
127142
127252
  return usage;
127143
127253
  }
127144
127254
  function withTimeout(providerPromise, providerName, timeoutMs = PROVIDER_FETCH_TIMEOUT_MS) {
127145
- return new Promise((resolve37) => {
127255
+ return new Promise((resolve39) => {
127146
127256
  const timer = setTimeout(() => {
127147
- resolve37({
127257
+ resolve39({
127148
127258
  name: providerName,
127149
127259
  icon: "\u23F1\uFE0F",
127150
127260
  status: "error",
@@ -127154,10 +127264,10 @@ function withTimeout(providerPromise, providerName, timeoutMs = PROVIDER_FETCH_T
127154
127264
  }, timeoutMs);
127155
127265
  providerPromise.then((result) => {
127156
127266
  clearTimeout(timer);
127157
- resolve37(result);
127267
+ resolve39(result);
127158
127268
  }).catch((err) => {
127159
127269
  clearTimeout(timer);
127160
- resolve37({
127270
+ resolve39({
127161
127271
  name: providerName,
127162
127272
  icon: "\u23F1\uFE0F",
127163
127273
  status: "error",
@@ -127212,7 +127322,7 @@ var init_usage = __esm({
127212
127322
  ANTHROPIC_OAUTH_CLIENT_ID = "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
127213
127323
  ANTHROPIC_OAUTH_BETA = "oauth-2025-04-20";
127214
127324
  CLAUDE_USAGE_USER_AGENT = "claude-code-fusion-dashboard";
127215
- _sleep = (ms) => new Promise((resolve37) => setTimeout(resolve37, ms));
127325
+ _sleep = (ms) => new Promise((resolve39) => setTimeout(resolve39, ms));
127216
127326
  sleepFn = _sleep;
127217
127327
  PROVIDER_FETCH_TIMEOUT_MS = 1e4;
127218
127328
  CLAUDE_FETCH_TIMEOUT_MS = 75e3;
@@ -127526,8 +127636,8 @@ var init_register_auth_routes = __esm({
127526
127636
  loginInProgress.set(provider, abortController);
127527
127637
  let authResolve;
127528
127638
  let authReject;
127529
- const authUrlPromise = new Promise((resolve37, reject2) => {
127530
- authResolve = resolve37;
127639
+ const authUrlPromise = new Promise((resolve39, reject2) => {
127640
+ authResolve = resolve39;
127531
127641
  authReject = reject2;
127532
127642
  });
127533
127643
  const loginPromise = storage.login(provider, {
@@ -127953,7 +128063,7 @@ async function mintAgentApiKeyViaCli(opts) {
127953
128063
  args.push("--data-dir", opts.dataDir);
127954
128064
  }
127955
128065
  const timeoutMs = opts.cliTimeoutMs ?? 3e4;
127956
- return new Promise((resolve37, reject2) => {
128066
+ return new Promise((resolve39, reject2) => {
127957
128067
  let child;
127958
128068
  try {
127959
128069
  child = spawn15(bin, args, { stdio: ["ignore", "pipe", "pipe"] });
@@ -128027,7 +128137,7 @@ async function mintAgentApiKeyViaCli(opts) {
128027
128137
  const apiBase = (typeof r.apiBase === "string" ? r.apiBase : void 0) ?? (typeof r.api_base === "string" ? r.api_base : void 0);
128028
128138
  const agentId = (typeof r.agentId === "string" ? r.agentId : void 0) ?? (typeof r.id === "string" ? r.id : void 0);
128029
128139
  const companyId = typeof r.companyId === "string" ? r.companyId : void 0;
128030
- resolve37({ apiKey, apiBase, agentId, companyId, raw: parsed });
128140
+ resolve39({ apiKey, apiBase, agentId, companyId, raw: parsed });
128031
128141
  });
128032
128142
  });
128033
128143
  }
@@ -128047,7 +128157,7 @@ async function spawnPaperclipCliJson(args, opts) {
128047
128157
  }
128048
128158
  const timeoutMs = opts.cliTimeoutMs ?? 15e3;
128049
128159
  const label = ["paperclipai", ...args].join(" ");
128050
- return new Promise((resolve37, reject2) => {
128160
+ return new Promise((resolve39, reject2) => {
128051
128161
  let child;
128052
128162
  try {
128053
128163
  child = spawn15(bin, fullArgs, { stdio: ["ignore", "pipe", "pipe"] });
@@ -128093,7 +128203,7 @@ async function spawnPaperclipCliJson(args, opts) {
128093
128203
  return;
128094
128204
  }
128095
128205
  try {
128096
- resolve37(JSON.parse(cleaned));
128206
+ resolve39(JSON.parse(cleaned));
128097
128207
  } catch {
128098
128208
  reject2(new Error(`${label} returned non-JSON output: ${cleaned.slice(0, 200)}`));
128099
128209
  }
@@ -128222,7 +128332,7 @@ var init_paperclip_client = __esm({
128222
128332
  // ../../plugins/fusion-plugin-paperclip-runtime/dist/runtime-adapter.js
128223
128333
  import { randomUUID as randomUUID18 } from "node:crypto";
128224
128334
  function sleep3(ms) {
128225
- return new Promise((resolve37) => setTimeout(resolve37, ms));
128335
+ return new Promise((resolve39) => setTimeout(resolve39, ms));
128226
128336
  }
128227
128337
  function asString2(value) {
128228
128338
  return typeof value === "string" ? value : void 0;
@@ -128971,22 +129081,29 @@ var init_update_check = __esm({
128971
129081
  });
128972
129082
 
128973
129083
  // ../dashboard/src/routes/register-update-check-routes.ts
128974
- import { readFileSync as readFileSync9 } from "node:fs";
128975
- import { dirname as dirname13, join as join44 } from "node:path";
129084
+ import { existsSync as existsSync29, readFileSync as readFileSync9 } from "node:fs";
129085
+ import { dirname as dirname13, resolve as resolve21 } from "node:path";
128976
129086
  import { fileURLToPath as fileURLToPath3 } from "node:url";
128977
- var __dirname, CLI_PACKAGE_VERSION, registerUpdateCheckRoutes;
129087
+ var CLI_PACKAGE_VERSION, registerUpdateCheckRoutes;
128978
129088
  var init_register_update_check_routes = __esm({
128979
129089
  "../dashboard/src/routes/register-update-check-routes.ts"() {
128980
129090
  "use strict";
128981
129091
  init_src();
128982
129092
  init_update_check();
128983
- __dirname = dirname13(fileURLToPath3(import.meta.url));
128984
129093
  CLI_PACKAGE_VERSION = (() => {
128985
129094
  try {
128986
- const packageJsonPath = join44(__dirname, "..", "..", "..", "cli", "package.json");
128987
- const packageJson = JSON.parse(readFileSync9(packageJsonPath, "utf-8"));
128988
- if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
128989
- return packageJson.version;
129095
+ let cur = dirname13(fileURLToPath3(import.meta.url));
129096
+ for (let i = 0; i < 8; i++) {
129097
+ const pkgPath = resolve21(cur, "package.json");
129098
+ if (existsSync29(pkgPath)) {
129099
+ const parsed = JSON.parse(readFileSync9(pkgPath, "utf-8"));
129100
+ if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string" && parsed.version.length > 0) {
129101
+ return parsed.version;
129102
+ }
129103
+ }
129104
+ const parent2 = resolve21(cur, "..");
129105
+ if (parent2 === cur) break;
129106
+ cur = parent2;
128990
129107
  }
128991
129108
  } catch {
128992
129109
  }
@@ -132968,7 +133085,7 @@ var init_todo_routes = __esm({
132968
133085
 
132969
133086
  // ../dashboard/src/dev-server-detect.ts
132970
133087
  import { glob, readFile as readFile20 } from "node:fs/promises";
132971
- import { dirname as dirname14, join as join45, relative as relative10, resolve as resolve21 } from "node:path";
133088
+ import { dirname as dirname14, join as join44, relative as relative10, resolve as resolve22 } from "node:path";
132972
133089
  async function readPackageJson(filePath) {
132973
133090
  try {
132974
133091
  const raw = await readFile20(filePath, "utf-8");
@@ -133011,14 +133128,14 @@ function scoreCandidate(scriptName, pkg) {
133011
133128
  async function collectWorkspacePackageJsons(projectRoot) {
133012
133129
  const discovered = /* @__PURE__ */ new Set();
133013
133130
  try {
133014
- await readFile20(join45(projectRoot, "pnpm-workspace.yaml"), "utf-8");
133131
+ await readFile20(join44(projectRoot, "pnpm-workspace.yaml"), "utf-8");
133015
133132
  } catch {
133016
133133
  }
133017
133134
  for (const pattern of ["packages/*/package.json", "apps/*/package.json"]) {
133018
133135
  try {
133019
133136
  for await (const match of glob(pattern, { cwd: projectRoot })) {
133020
133137
  if (typeof match === "string") {
133021
- discovered.add(resolve21(projectRoot, match));
133138
+ discovered.add(resolve22(projectRoot, match));
133022
133139
  }
133023
133140
  }
133024
133141
  } catch {
@@ -133043,9 +133160,9 @@ function toSource(projectRoot, packageJsonPath) {
133043
133160
  return rel.length > 0 ? rel : "root";
133044
133161
  }
133045
133162
  async function detectDevServerScripts(projectRoot) {
133046
- const root = resolve21(projectRoot);
133163
+ const root = resolve22(projectRoot);
133047
133164
  const candidates = [];
133048
- const rootPackagePath = join45(root, "package.json");
133165
+ const rootPackagePath = join44(root, "package.json");
133049
133166
  const rootPackage = await readPackageJson(rootPackagePath);
133050
133167
  if (rootPackage) {
133051
133168
  for (const script of extractScripts(rootPackage)) {
@@ -133112,9 +133229,9 @@ var init_dev_server_detect = __esm({
133112
133229
 
133113
133230
  // ../dashboard/src/dev-server-store.ts
133114
133231
  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";
133232
+ import { dirname as dirname15, join as join45, resolve as resolve23 } from "node:path";
133116
133233
  function devServerFilePath(projectDir) {
133117
- return join46(resolve22(projectDir), ".fusion", "dev-server.json");
133234
+ return join45(resolve23(projectDir), ".fusion", "dev-server.json");
133118
133235
  }
133119
133236
  function normalizeState(candidate) {
133120
133237
  const defaults = DEV_SERVER_DEFAULT_STATE();
@@ -133149,7 +133266,7 @@ function normalizeConfig(candidate) {
133149
133266
  };
133150
133267
  }
133151
133268
  async function loadDevServerStore(projectDir) {
133152
- const storeKey = resolve22(projectDir);
133269
+ const storeKey = resolve23(projectDir);
133153
133270
  let store = storeInstances.get(storeKey);
133154
133271
  if (!store) {
133155
133272
  store = new DevServerStore(projectDir);
@@ -133427,7 +133544,7 @@ function detectPortFromLogLine(line) {
133427
133544
  return detectViteLine(cleanLine) ?? detectNextLine(cleanLine) ?? detectStorybookLine(cleanLine) ?? detectAngularLine(cleanLine) ?? detectGenericUrl(cleanLine) ?? detectGenericPortLine(cleanLine);
133428
133545
  }
133429
133546
  function probePort(host, port, timeoutMs) {
133430
- return new Promise((resolve37) => {
133547
+ return new Promise((resolve39) => {
133431
133548
  let settled = false;
133432
133549
  const socket = createConnection({ host, port });
133433
133550
  const settle = (isOpen) => {
@@ -133441,7 +133558,7 @@ function probePort(host, port, timeoutMs) {
133441
133558
  } else {
133442
133559
  socket.destroy();
133443
133560
  }
133444
- resolve37(isOpen);
133561
+ resolve39(isOpen);
133445
133562
  };
133446
133563
  socket.setTimeout(timeoutMs);
133447
133564
  socket.once("connect", () => settle(true));
@@ -133568,8 +133685,8 @@ var init_dev_server_process = __esm({
133568
133685
  stdio: ["pipe", "pipe", "pipe"]
133569
133686
  });
133570
133687
  this.childProcess = child;
133571
- this.closePromise = new Promise((resolve37) => {
133572
- this.resolveClosePromise = resolve37;
133688
+ this.closePromise = new Promise((resolve39) => {
133689
+ this.resolveClosePromise = resolve39;
133573
133690
  });
133574
133691
  const runningState = await this.store.updateState({
133575
133692
  pid: child.pid,
@@ -134366,7 +134483,7 @@ Your job is to refine task descriptions based on the user's selected refinement
134366
134483
 
134367
134484
  // ../dashboard/src/routes.ts
134368
134485
  import multer from "multer";
134369
- import { resolve as resolve23, sep as sep6, join as join47, isAbsolute as isAbsolute15 } from "node:path";
134486
+ import { resolve as resolve24, sep as sep6, join as join46, isAbsolute as isAbsolute15 } from "node:path";
134370
134487
  import * as nodeFs from "node:fs";
134371
134488
  import os5 from "node:os";
134372
134489
  import v8 from "node:v8";
@@ -134387,8 +134504,8 @@ function hasPackageManagerSettings2(settings) {
134387
134504
  function getPiPackageManagerAgentDir() {
134388
134505
  const fusionAgentDir = getFusionAgentDir();
134389
134506
  const legacyAgentDir = getLegacyPiAgentDir();
134390
- const fusionSettings = readJsonObject3(join47(fusionAgentDir, "settings.json"));
134391
- const legacySettings = readJsonObject3(join47(legacyAgentDir, "settings.json"));
134507
+ const fusionSettings = readJsonObject3(join46(fusionAgentDir, "settings.json"));
134508
+ const legacySettings = readJsonObject3(join46(legacyAgentDir, "settings.json"));
134392
134509
  if (hasPackageManagerSettings2(fusionSettings) || !nodeFs.existsSync(legacyAgentDir)) {
134393
134510
  return fusionAgentDir;
134394
134511
  }
@@ -134398,7 +134515,7 @@ function getPiPackageManagerAgentDir() {
134398
134515
  return nodeFs.existsSync(fusionAgentDir) ? fusionAgentDir : legacyAgentDir;
134399
134516
  }
134400
134517
  function packageExtensionName(extensionPath, source) {
134401
- const base = resolve23(extensionPath).split(sep6).pop()?.replace(/\.(ts|js)$/i, "") || source;
134518
+ const base = resolve24(extensionPath).split(sep6).pop()?.replace(/\.(ts|js)$/i, "") || source;
134402
134519
  if (base !== "index") {
134403
134520
  return base;
134404
134521
  }
@@ -134406,15 +134523,15 @@ function packageExtensionName(extensionPath, source) {
134406
134523
  }
134407
134524
  async function discoverDashboardPiExtensions(cwd) {
134408
134525
  const settings = discoverPiExtensions(cwd);
134409
- const disabled = new Set(settings.disabledIds.map((id) => resolve23(id)));
134526
+ const disabled = new Set(settings.disabledIds.map((id) => resolve24(id)));
134410
134527
  const byPath = new Map(settings.extensions.map((entry) => [entry.id, entry]));
134411
134528
  try {
134412
134529
  const { DefaultPackageManager: DefaultPackageManager5 } = await import("@mariozechner/pi-coding-agent");
134413
134530
  const agentDir = getPiPackageManagerAgentDir();
134414
- const legacyGlobalSettings = readJsonObject3(join47(getLegacyPiAgentDir(), "settings.json"));
134415
- const fusionGlobalSettings = readJsonObject3(join47(getFusionAgentDir(), "settings.json"));
134531
+ const legacyGlobalSettings = readJsonObject3(join46(getLegacyPiAgentDir(), "settings.json"));
134532
+ const fusionGlobalSettings = readJsonObject3(join46(getFusionAgentDir(), "settings.json"));
134416
134533
  const globalSettings = { ...legacyGlobalSettings, ...fusionGlobalSettings };
134417
- const projectSettings = readJsonObject3(join47(cwd, ".fusion", "settings.json"));
134534
+ const projectSettings = readJsonObject3(join46(cwd, ".fusion", "settings.json"));
134418
134535
  const mergedSettings = { ...globalSettings, ...projectSettings };
134419
134536
  const packageManager = new DefaultPackageManager5({
134420
134537
  cwd,
@@ -134428,7 +134545,7 @@ async function discoverDashboardPiExtensions(cwd) {
134428
134545
  });
134429
134546
  const resolved = await packageManager.resolve(async () => "skip");
134430
134547
  for (const extension2 of resolved.extensions) {
134431
- const id = resolve23(extension2.path);
134548
+ const id = resolve24(extension2.path);
134432
134549
  const source = extension2.metadata?.source || "package";
134433
134550
  byPath.set(id, {
134434
134551
  id,
@@ -134831,8 +134948,8 @@ function createApiRoutes(store, options) {
134831
134948
  function isHeartbeatMonitorForProject(scopedStore) {
134832
134949
  if (!heartbeatMonitor?.rootDir) return true;
134833
134950
  try {
134834
- const monitorRoot = resolve23(heartbeatMonitor.rootDir);
134835
- const storeRoot = resolve23(scopedStore.getRootDir());
134951
+ const monitorRoot = resolve24(heartbeatMonitor.rootDir);
134952
+ const storeRoot = resolve24(scopedStore.getRootDir());
134836
134953
  return monitorRoot === storeRoot;
134837
134954
  } catch {
134838
134955
  return true;
@@ -136754,15 +136871,15 @@ Description: ${step.description}`
136754
136871
  return;
136755
136872
  }
136756
136873
  }
136757
- const { resolve: resolve37, dirname: dirname28, join: join66 } = await import("node:path");
136874
+ const { resolve: resolve39, dirname: dirname28, join: join65 } = await import("node:path");
136758
136875
  const { readdir: readdir12, stat: stat12 } = await import("node:fs/promises");
136759
136876
  const rawPath = req.query.path || process.env.HOME || process.env.USERPROFILE || "/";
136760
136877
  const showHidden = req.query.showHidden === "true";
136761
- const resolvedPath = resolve37(rawPath);
136878
+ const resolvedPath = resolve39(rawPath);
136762
136879
  if (rawPath.includes("..")) {
136763
136880
  throw badRequest("Path must not contain '..' traversal");
136764
136881
  }
136765
- if (resolvedPath !== resolve37(resolvedPath)) {
136882
+ if (resolvedPath !== resolve39(resolvedPath)) {
136766
136883
  throw badRequest("Path must be absolute");
136767
136884
  }
136768
136885
  let pathStat;
@@ -136779,7 +136896,7 @@ Description: ${step.description}`
136779
136896
  for (const entry of dirEntries) {
136780
136897
  if (!entry.isDirectory()) continue;
136781
136898
  if (!showHidden && entry.name.startsWith(".")) continue;
136782
- const entryPath = join66(resolvedPath, entry.name);
136899
+ const entryPath = join65(resolvedPath, entry.name);
136783
136900
  let hasChildren = false;
136784
136901
  try {
136785
136902
  const subEntries = await readdir12(entryPath, { withFileTypes: true });
@@ -142280,8 +142397,8 @@ var init_auth_middleware = __esm({
142280
142397
  // ../dashboard/src/server.ts
142281
142398
  import express from "express";
142282
142399
  import { randomUUID as randomUUID19 } from "node:crypto";
142283
- import { join as join48, dirname as dirname16 } from "node:path";
142284
- import { existsSync as existsSync30, readFileSync as readFileSync11 } from "node:fs";
142400
+ import { join as join47, dirname as dirname16, resolve as resolve25 } from "node:path";
142401
+ import { existsSync as existsSync31, readFileSync as readFileSync11 } from "node:fs";
142285
142402
  import { fileURLToPath as fileURLToPath4 } from "node:url";
142286
142403
  import { createSecureServer as createHttp2SecureServer } from "node:http2";
142287
142404
  function parseVersion2(version) {
@@ -142462,11 +142579,11 @@ function createServer(store, options) {
142462
142579
  getTerminalService(store.getRootDir());
142463
142580
  const isHeadless = options?.headless === true;
142464
142581
  const execDir = dirname16(process.execPath);
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");
142582
+ const clientDir = process.env.FUSION_CLIENT_DIR ? process.env.FUSION_CLIENT_DIR : existsSync31(join47(execDir, "client", "index.html")) ? join47(execDir, "client") : existsSync31(join47(__dirname, "..", "dist", "client")) ? join47(__dirname, "..", "dist", "client") : join47(__dirname, "..", "client");
142466
142583
  if (!isHeadless) {
142467
142584
  app.get("/version.json", (_req, res) => {
142468
142585
  res.setHeader("Cache-Control", "no-store, max-age=0");
142469
- res.sendFile(join48(clientDir, "version.json"), (err) => {
142586
+ res.sendFile(join47(clientDir, "version.json"), (err) => {
142470
142587
  if (err) {
142471
142588
  res.status(404).json({ version: null });
142472
142589
  }
@@ -142886,7 +143003,7 @@ data: ${JSON.stringify({ type: event.type, data: event.data })}
142886
143003
  });
142887
143004
  if (!isHeadless) {
142888
143005
  app.get("/{*splat}", (_req, res) => {
142889
- res.sendFile(join48(clientDir, "index.html"));
143006
+ res.sendFile(join47(clientDir, "index.html"));
142890
143007
  });
142891
143008
  }
142892
143009
  const dashboardApp = app;
@@ -143299,7 +143416,7 @@ function snapshotsEqual(a, b) {
143299
143416
  if (a.issueInfo?.title !== b.issueInfo?.title) return false;
143300
143417
  return true;
143301
143418
  }
143302
- var __dirname2, PACKAGE_VERSION, CLI_PACKAGE_VERSION2, DEFAULT_AI_SESSION_TTL_MS, MIN_AI_SESSION_TTL_MS, MAX_AI_SESSION_TTL_MS, DEFAULT_AI_SESSION_CLEANUP_INTERVAL_MS, MIN_AI_SESSION_CLEANUP_INTERVAL_MS, MAX_AI_SESSION_CLEANUP_INTERVAL_MS, aiSessionCleanupIntervalHandle;
143419
+ var __dirname, PACKAGE_VERSION, CLI_PACKAGE_VERSION2, DEFAULT_AI_SESSION_TTL_MS, MIN_AI_SESSION_TTL_MS, MAX_AI_SESSION_TTL_MS, DEFAULT_AI_SESSION_CLEANUP_INTERVAL_MS, MIN_AI_SESSION_CLEANUP_INTERVAL_MS, MAX_AI_SESSION_CLEANUP_INTERVAL_MS, aiSessionCleanupIntervalHandle;
143303
143420
  var init_server = __esm({
143304
143421
  "../dashboard/src/server.ts"() {
143305
143422
  "use strict";
@@ -143325,10 +143442,10 @@ var init_server = __esm({
143325
143442
  init_dev_server_routes();
143326
143443
  init_auth_middleware();
143327
143444
  init_remote_auth();
143328
- __dirname2 = dirname16(fileURLToPath4(import.meta.url));
143445
+ __dirname = dirname16(fileURLToPath4(import.meta.url));
143329
143446
  PACKAGE_VERSION = (() => {
143330
143447
  try {
143331
- const packageJsonPath = join48(__dirname2, "..", "package.json");
143448
+ const packageJsonPath = join47(__dirname, "..", "package.json");
143332
143449
  const packageJson = JSON.parse(readFileSync11(packageJsonPath, "utf-8"));
143333
143450
  if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
143334
143451
  return packageJson.version;
@@ -143339,10 +143456,18 @@ var init_server = __esm({
143339
143456
  })();
143340
143457
  CLI_PACKAGE_VERSION2 = (() => {
143341
143458
  try {
143342
- const packageJsonPath = join48(__dirname2, "..", "..", "cli", "package.json");
143343
- const packageJson = JSON.parse(readFileSync11(packageJsonPath, "utf-8"));
143344
- if (typeof packageJson.version === "string" && packageJson.version.length > 0) {
143345
- return packageJson.version;
143459
+ let cur = __dirname;
143460
+ for (let i = 0; i < 8; i++) {
143461
+ const pkgPath = resolve25(cur, "package.json");
143462
+ if (existsSync31(pkgPath)) {
143463
+ const parsed = JSON.parse(readFileSync11(pkgPath, "utf-8"));
143464
+ if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string" && parsed.version.length > 0) {
143465
+ return parsed.version;
143466
+ }
143467
+ }
143468
+ const parent2 = resolve25(cur, "..");
143469
+ if (parent2 === cur) break;
143470
+ cur = parent2;
143346
143471
  }
143347
143472
  } catch {
143348
143473
  }
@@ -143362,7 +143487,7 @@ var init_server = __esm({
143362
143487
 
143363
143488
  // ../dashboard/src/skills-adapter.ts
143364
143489
  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";
143490
+ import { join as join48, relative as relative11, dirname as dirname17 } from "node:path";
143366
143491
  async function pathExists(path5) {
143367
143492
  try {
143368
143493
  await access9(path5);
@@ -143618,7 +143743,7 @@ function createSkillsAdapter(options) {
143618
143743
  } catch {
143619
143744
  skillDir = dirname17(skill.path);
143620
143745
  }
143621
- const skillMdPath = join49(skillDir, "SKILL.md");
143746
+ const skillMdPath = join48(skillDir, "SKILL.md");
143622
143747
  let skillMd = "";
143623
143748
  try {
143624
143749
  skillMd = await readFile22(skillMdPath, "utf-8");
@@ -143826,7 +143951,7 @@ function normalizeEntry(entry) {
143826
143951
  };
143827
143952
  }
143828
143953
  function getProjectSettingsPath(rootDir) {
143829
- return join49(rootDir, ".fusion", "settings.json");
143954
+ return join48(rootDir, ".fusion", "settings.json");
143830
143955
  }
143831
143956
  var MIN_PUBLIC_SEARCH_QUERY_LENGTH;
143832
143957
  var init_skills_adapter = __esm({
@@ -144001,7 +144126,7 @@ var init_task_lifecycle = __esm({
144001
144126
  // src/commands/port-prompt.ts
144002
144127
  import { createInterface } from "node:readline";
144003
144128
  function promptForPort(defaultPort = 4040, input = process.stdin) {
144004
- return new Promise((resolve37, reject2) => {
144129
+ return new Promise((resolve39, reject2) => {
144005
144130
  const rl = createInterface({
144006
144131
  input,
144007
144132
  output: process.stdout
@@ -144018,7 +144143,7 @@ function promptForPort(defaultPort = 4040, input = process.stdin) {
144018
144143
  if (trimmed === "") {
144019
144144
  process.removeListener("SIGINT", sigintHandler);
144020
144145
  rl.close();
144021
- resolve37(defaultPort);
144146
+ resolve39(defaultPort);
144022
144147
  return;
144023
144148
  }
144024
144149
  const port = parseInt(trimmed, 10);
@@ -144034,7 +144159,7 @@ function promptForPort(defaultPort = 4040, input = process.stdin) {
144034
144159
  }
144035
144160
  process.removeListener("SIGINT", sigintHandler);
144036
144161
  rl.close();
144037
- resolve37(port);
144162
+ resolve39(port);
144038
144163
  });
144039
144164
  };
144040
144165
  ask();
@@ -144047,16 +144172,16 @@ var init_port_prompt = __esm({
144047
144172
  });
144048
144173
 
144049
144174
  // src/commands/provider-settings.ts
144050
- import { existsSync as existsSync31, readFileSync as readFileSync12, writeFileSync as writeFileSync2, mkdirSync as mkdirSync6 } from "node:fs";
144051
- import { join as join50, dirname as dirname18, basename as basename13 } from "node:path";
144175
+ import { existsSync as existsSync32, readFileSync as readFileSync12, writeFileSync as writeFileSync2, mkdirSync as mkdirSync6 } from "node:fs";
144176
+ import { join as join49, dirname as dirname18, basename as basename13 } from "node:path";
144052
144177
  function siblingAgentDir2(agentDir, siblingRoot) {
144053
144178
  if (basename13(agentDir) !== "agent") {
144054
144179
  return void 0;
144055
144180
  }
144056
- return join50(dirname18(dirname18(agentDir)), siblingRoot, "agent");
144181
+ return join49(dirname18(dirname18(agentDir)), siblingRoot, "agent");
144057
144182
  }
144058
144183
  function readJsonObject4(path5) {
144059
- if (!existsSync31(path5)) {
144184
+ if (!existsSync32(path5)) {
144060
144185
  return {};
144061
144186
  }
144062
144187
  try {
@@ -144067,13 +144192,13 @@ function readJsonObject4(path5) {
144067
144192
  }
144068
144193
  }
144069
144194
  function createReadOnlyProviderSettingsView(cwd, agentDir) {
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"));
144195
+ const fusionAgentDir = agentDir.includes(`${join49(".fusion", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".fusion");
144196
+ const legacyAgentDir = agentDir.includes(`${join49(".pi", "agent")}`) ? agentDir : siblingAgentDir2(agentDir, ".pi");
144197
+ const legacyGlobalSettings = legacyAgentDir ? readJsonObject4(join49(legacyAgentDir, "settings.json")) : {};
144198
+ const fusionGlobalSettings = fusionAgentDir ? readJsonObject4(join49(fusionAgentDir, "settings.json")) : {};
144199
+ const directGlobalSettings = readJsonObject4(join49(agentDir, "settings.json"));
144075
144200
  const globalSettings = { ...legacyGlobalSettings, ...directGlobalSettings, ...fusionGlobalSettings };
144076
- const fusionProjectSettings = readJsonObject4(join50(cwd, ".fusion", "settings.json"));
144201
+ const fusionProjectSettings = readJsonObject4(join49(cwd, ".fusion", "settings.json"));
144077
144202
  const mergedSettings = { ...globalSettings, ...fusionProjectSettings };
144078
144203
  return {
144079
144204
  getGlobalSettings: () => structuredClone(globalSettings),
@@ -144088,7 +144213,7 @@ var init_provider_settings = __esm({
144088
144213
  });
144089
144214
 
144090
144215
  // src/commands/provider-auth.ts
144091
- import { existsSync as existsSync32, readFileSync as readFileSync13 } from "node:fs";
144216
+ import { existsSync as existsSync33, readFileSync as readFileSync13 } from "node:fs";
144092
144217
  import { getOAuthProvider as getOAuthProvider2 } from "@mariozechner/pi-ai/oauth";
144093
144218
  function getProviderDisplayName(providerId) {
144094
144219
  const knownProviderNames = new Map(
@@ -144217,7 +144342,7 @@ function createReadOnlyAuthFileStorage(authPaths) {
144217
144342
  const reload = () => {
144218
144343
  const nextCredentials = {};
144219
144344
  for (const authPath of authPaths) {
144220
- if (!existsSync32(authPath)) {
144345
+ if (!existsSync33(authPath)) {
144221
144346
  continue;
144222
144347
  }
144223
144348
  try {
@@ -144258,41 +144383,41 @@ var init_provider_auth = __esm({
144258
144383
 
144259
144384
  // src/commands/auth-paths.ts
144260
144385
  import { homedir as homedir7 } from "node:os";
144261
- import { existsSync as existsSync33, readFileSync as readFileSync14 } from "node:fs";
144262
- import { join as join51 } from "node:path";
144386
+ import { existsSync as existsSync34, readFileSync as readFileSync14 } from "node:fs";
144387
+ import { join as join50 } from "node:path";
144263
144388
  function getFusionAgentDir3(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144264
- return join51(home, ".fusion", "agent");
144389
+ return join50(home, ".fusion", "agent");
144265
144390
  }
144266
144391
  function getLegacyAgentDir(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144267
- return join51(home, ".pi", "agent");
144392
+ return join50(home, ".pi", "agent");
144268
144393
  }
144269
144394
  function getFusionAuthPath3(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144270
- return join51(getFusionAgentDir3(home), "auth.json");
144395
+ return join50(getFusionAgentDir3(home), "auth.json");
144271
144396
  }
144272
144397
  function getLegacyAuthPaths2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144273
144398
  return [
144274
- join51(home, ".pi", "agent", "auth.json"),
144275
- join51(home, ".pi", "auth.json")
144399
+ join50(home, ".pi", "agent", "auth.json"),
144400
+ join50(home, ".pi", "auth.json")
144276
144401
  ];
144277
144402
  }
144278
144403
  function getFusionModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144279
- return join51(getFusionAgentDir3(home), "models.json");
144404
+ return join50(getFusionAgentDir3(home), "models.json");
144280
144405
  }
144281
144406
  function getLegacyModelsPaths2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144282
144407
  return [
144283
- join51(home, ".pi", "agent", "models.json"),
144284
- join51(home, ".pi", "models.json")
144408
+ join50(home, ".pi", "agent", "models.json"),
144409
+ join50(home, ".pi", "models.json")
144285
144410
  ];
144286
144411
  }
144287
144412
  function getModelRegistryModelsPath2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144288
144413
  const fusionModelsPath = getFusionModelsPath2(home);
144289
- if (existsSync33(fusionModelsPath)) {
144414
+ if (existsSync34(fusionModelsPath)) {
144290
144415
  return fusionModelsPath;
144291
144416
  }
144292
- return getLegacyModelsPaths2(home).find((modelsPath) => existsSync33(modelsPath)) ?? fusionModelsPath;
144417
+ return getLegacyModelsPaths2(home).find((modelsPath) => existsSync34(modelsPath)) ?? fusionModelsPath;
144293
144418
  }
144294
144419
  function readJsonObject5(path5) {
144295
- if (!existsSync33(path5)) {
144420
+ if (!existsSync34(path5)) {
144296
144421
  return {};
144297
144422
  }
144298
144423
  try {
@@ -144308,15 +144433,15 @@ function hasPackageManagerSettings3(settings) {
144308
144433
  function getPackageManagerAgentDir2(home = process.env.HOME || process.env.USERPROFILE || homedir7()) {
144309
144434
  const fusionAgentDir = getFusionAgentDir3(home);
144310
144435
  const legacyAgentDir = getLegacyAgentDir(home);
144311
- const fusionSettings = readJsonObject5(join51(fusionAgentDir, "settings.json"));
144312
- const legacySettings = readJsonObject5(join51(legacyAgentDir, "settings.json"));
144313
- if (hasPackageManagerSettings3(fusionSettings) || !existsSync33(legacyAgentDir)) {
144436
+ const fusionSettings = readJsonObject5(join50(fusionAgentDir, "settings.json"));
144437
+ const legacySettings = readJsonObject5(join50(legacyAgentDir, "settings.json"));
144438
+ if (hasPackageManagerSettings3(fusionSettings) || !existsSync34(legacyAgentDir)) {
144314
144439
  return fusionAgentDir;
144315
144440
  }
144316
144441
  if (hasPackageManagerSettings3(legacySettings)) {
144317
144442
  return legacyAgentDir;
144318
144443
  }
144319
- return existsSync33(fusionAgentDir) ? fusionAgentDir : legacyAgentDir;
144444
+ return existsSync34(fusionAgentDir) ? fusionAgentDir : legacyAgentDir;
144320
144445
  }
144321
144446
  var init_auth_paths2 = __esm({
144322
144447
  "src/commands/auth-paths.ts"() {
@@ -144325,8 +144450,8 @@ var init_auth_paths2 = __esm({
144325
144450
  });
144326
144451
 
144327
144452
  // src/project-context.ts
144328
- import { resolve as resolve24, dirname as dirname19 } from "node:path";
144329
- import { existsSync as existsSync34 } from "node:fs";
144453
+ import { resolve as resolve26, dirname as dirname19 } from "node:path";
144454
+ import { existsSync as existsSync35 } from "node:fs";
144330
144455
  async function resolveProject(projectNameFlag, cwd = process.cwd(), globalDir) {
144331
144456
  const central = new CentralCore(globalDir);
144332
144457
  await central.init();
@@ -144417,10 +144542,10 @@ async function clearDefaultProject(globalDir) {
144417
144542
  await globalStore.updateSettings(rest);
144418
144543
  }
144419
144544
  async function detectProjectFromCwd(cwd, central) {
144420
- let currentDir = resolve24(cwd);
144545
+ let currentDir = resolve26(cwd);
144421
144546
  while (true) {
144422
- const kbPath = resolve24(currentDir, ".fusion", "fusion.db");
144423
- if (existsSync34(kbPath)) {
144547
+ const kbPath = resolve26(currentDir, ".fusion", "fusion.db");
144548
+ if (existsSync35(kbPath)) {
144424
144549
  const project = await central.getProjectByPath(currentDir);
144425
144550
  if (project) {
144426
144551
  return project;
@@ -144475,7 +144600,7 @@ var init_project_context = __esm({
144475
144600
  // src/commands/claude-skills.ts
144476
144601
  import {
144477
144602
  cpSync,
144478
- existsSync as existsSync35,
144603
+ existsSync as existsSync36,
144479
144604
  lstatSync as lstatSync2,
144480
144605
  mkdirSync as mkdirSync7,
144481
144606
  readlinkSync,
@@ -144483,7 +144608,7 @@ import {
144483
144608
  symlinkSync,
144484
144609
  unlinkSync
144485
144610
  } from "node:fs";
144486
- import { dirname as dirname20, join as join52, resolve as resolve25 } from "node:path";
144611
+ import { dirname as dirname20, join as join51, resolve as resolve27 } from "node:path";
144487
144612
  import { fileURLToPath as fileURLToPath5 } from "node:url";
144488
144613
  function isPiClaudeCliConfigured(globalSettings) {
144489
144614
  if (!globalSettings || typeof globalSettings !== "object") {
@@ -144503,11 +144628,11 @@ function isPiClaudeCliConfigured(globalSettings) {
144503
144628
  }
144504
144629
  function resolveFusionSkillSource() {
144505
144630
  const here = fileURLToPath5(import.meta.url);
144506
- const candidate = resolve25(dirname20(here), "..", "..", "skill", FUSION_SKILL_NAME);
144507
- return existsSync35(candidate) ? candidate : null;
144631
+ const candidate = resolve27(dirname20(here), "..", "..", "skill", FUSION_SKILL_NAME);
144632
+ return existsSync36(candidate) ? candidate : null;
144508
144633
  }
144509
144634
  function installFusionSkillIntoProject(projectPath, options = {}) {
144510
- const target = join52(projectPath, ".claude", "skills", FUSION_SKILL_NAME);
144635
+ const target = join51(projectPath, ".claude", "skills", FUSION_SKILL_NAME);
144511
144636
  if (options.enabled === false) {
144512
144637
  return { outcome: "skipped", target, reason: "pi-claude-cli not configured" };
144513
144638
  }
@@ -144522,18 +144647,18 @@ function installFusionSkillIntoProject(projectPath, options = {}) {
144522
144647
  try {
144523
144648
  mkdirSync7(dirname20(target), { recursive: true });
144524
144649
  let replaced = false;
144525
- if (existsSync35(target) || isBrokenSymlink(target)) {
144650
+ if (existsSync36(target) || isBrokenSymlink(target)) {
144526
144651
  const stat12 = lstatSync2(target);
144527
144652
  if (stat12.isSymbolicLink()) {
144528
144653
  const current = safeReadlink(target);
144529
- if (current && resolve25(dirname20(target), current) === resolve25(source)) {
144654
+ if (current && resolve27(dirname20(target), current) === resolve27(source)) {
144530
144655
  return { outcome: "already-installed", target, source };
144531
144656
  }
144532
144657
  unlinkSync(target);
144533
144658
  replaced = true;
144534
144659
  } else {
144535
- const skillMd = join52(target, "SKILL.md");
144536
- if (!existsSync35(skillMd)) {
144660
+ const skillMd = join51(target, "SKILL.md");
144661
+ if (!existsSync36(skillMd)) {
144537
144662
  return {
144538
144663
  outcome: "failed",
144539
144664
  target,
@@ -144579,7 +144704,7 @@ function ensureFusionSkillForProjects(projects, options = { enabled: false }) {
144579
144704
  if (!options.enabled) {
144580
144705
  return projects.map((p) => ({
144581
144706
  outcome: "skipped",
144582
- target: join52(p.path, ".claude", "skills", FUSION_SKILL_NAME),
144707
+ target: join51(p.path, ".claude", "skills", FUSION_SKILL_NAME),
144583
144708
  reason: "pi-claude-cli not configured"
144584
144709
  }));
144585
144710
  }
@@ -144592,7 +144717,7 @@ function isBrokenSymlink(path5) {
144592
144717
  try {
144593
144718
  const stat12 = lstatSync2(path5);
144594
144719
  if (!stat12.isSymbolicLink()) return false;
144595
- return !existsSync35(path5);
144720
+ return !existsSync36(path5);
144596
144721
  } catch {
144597
144722
  return false;
144598
144723
  }
@@ -144689,16 +144814,16 @@ var init_claude_skills_runner = __esm({
144689
144814
  });
144690
144815
 
144691
144816
  // src/commands/claude-cli-extension.ts
144692
- import { existsSync as existsSync36, readFileSync as readFileSync15 } from "node:fs";
144817
+ import { existsSync as existsSync37, readFileSync as readFileSync15 } from "node:fs";
144693
144818
  import { createRequire as createRequire4 } from "node:module";
144694
- import { dirname as dirname21, resolve as resolve26 } from "node:path";
144819
+ import { dirname as dirname21, resolve as resolve28 } from "node:path";
144695
144820
  import { fileURLToPath as fileURLToPath6 } from "node:url";
144696
144821
  function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
144697
144822
  let pkgJsonPath;
144698
144823
  const here = dirname21(fileURLToPath6(moduleUrl));
144699
144824
  for (const rel of ["pi-claude-cli", "../pi-claude-cli", "../../pi-claude-cli"]) {
144700
- const candidate = resolve26(here, rel, "package.json");
144701
- if (existsSync36(candidate)) {
144825
+ const candidate = resolve28(here, rel, "package.json");
144826
+ if (existsSync37(candidate)) {
144702
144827
  pkgJsonPath = candidate;
144703
144828
  break;
144704
144829
  }
@@ -144733,8 +144858,8 @@ function resolveClaudeCliExtensionFromModuleUrl(moduleUrl) {
144733
144858
  reason: "@fusion/pi-claude-cli pi.extensions[0] is not a valid path string"
144734
144859
  };
144735
144860
  }
144736
- const entryPath = resolve26(dirname21(pkgJsonPath), rawEntry);
144737
- if (!existsSync36(entryPath)) {
144861
+ const entryPath = resolve28(dirname21(pkgJsonPath), rawEntry);
144862
+ if (!existsSync37(entryPath)) {
144738
144863
  return {
144739
144864
  status: "missing-entry",
144740
144865
  reason: `@fusion/pi-claude-cli extension file not found at ${entryPath}`
@@ -144786,10 +144911,10 @@ var init_claude_cli_extension = __esm({
144786
144911
 
144787
144912
  // src/update-cache.ts
144788
144913
  import { readFileSync as readFileSync16 } from "node:fs";
144789
- import { join as join53 } from "node:path";
144914
+ import { join as join52 } from "node:path";
144790
144915
  function getCachedUpdateStatus() {
144791
144916
  try {
144792
- const cachePath = join53(resolveGlobalDir(), "update-check.json");
144917
+ const cachePath = join52(resolveGlobalDir(), "update-check.json");
144793
144918
  const raw = readFileSync16(cachePath, "utf-8");
144794
144919
  const parsed = JSON.parse(raw);
144795
144920
  if (parsed.updateAvailable === true && typeof parsed.latestVersion === "string" && parsed.latestVersion.length > 0 && typeof parsed.currentVersion === "string" && parsed.currentVersion.length > 0) {
@@ -144818,17 +144943,17 @@ var init_update_cache = __esm({
144818
144943
  });
144819
144944
 
144820
144945
  // src/commands/self-extension.ts
144821
- import { existsSync as existsSync37, readFileSync as readFileSync17 } from "node:fs";
144822
- import { dirname as dirname22, resolve as resolve27 } from "node:path";
144946
+ import { existsSync as existsSync38, readFileSync as readFileSync17 } from "node:fs";
144947
+ import { dirname as dirname22, resolve as resolve29 } from "node:path";
144823
144948
  import { fileURLToPath as fileURLToPath7 } from "node:url";
144824
144949
  function resolveSelfExtension() {
144825
144950
  const here = dirname22(fileURLToPath7(import.meta.url));
144826
144951
  let pkgDir;
144827
144952
  let cur = here;
144828
144953
  for (let i = 0; i < 5; i++) {
144829
- if (existsSync37(resolve27(cur, "package.json"))) {
144954
+ if (existsSync38(resolve29(cur, "package.json"))) {
144830
144955
  try {
144831
- const parsed = JSON.parse(readFileSync17(resolve27(cur, "package.json"), "utf-8"));
144956
+ const parsed = JSON.parse(readFileSync17(resolve29(cur, "package.json"), "utf-8"));
144832
144957
  if (parsed.name === "@runfusion/fusion") {
144833
144958
  pkgDir = cur;
144834
144959
  break;
@@ -144836,7 +144961,7 @@ function resolveSelfExtension() {
144836
144961
  } catch {
144837
144962
  }
144838
144963
  }
144839
- const parent2 = resolve27(cur, "..");
144964
+ const parent2 = resolve29(cur, "..");
144840
144965
  if (parent2 === cur) break;
144841
144966
  cur = parent2;
144842
144967
  }
@@ -144845,12 +144970,12 @@ function resolveSelfExtension() {
144845
144970
  }
144846
144971
  let pkgJson;
144847
144972
  try {
144848
- pkgJson = JSON.parse(readFileSync17(resolve27(pkgDir, "package.json"), "utf-8"));
144973
+ pkgJson = JSON.parse(readFileSync17(resolve29(pkgDir, "package.json"), "utf-8"));
144849
144974
  } catch (err) {
144850
144975
  return { status: "missing", reason: `Failed to read @runfusion/fusion package.json: ${err instanceof Error ? err.message : String(err)}` };
144851
144976
  }
144852
- const srcEntry = resolve27(pkgDir, "src", "extension.ts");
144853
- if (existsSync37(srcEntry)) {
144977
+ const srcEntry = resolve29(pkgDir, "src", "extension.ts");
144978
+ if (existsSync38(srcEntry)) {
144854
144979
  return { status: "ok", path: srcEntry, packageVersion: pkgJson.version ?? "unknown" };
144855
144980
  }
144856
144981
  const extensions = pkgJson.pi?.extensions;
@@ -144861,8 +144986,8 @@ function resolveSelfExtension() {
144861
144986
  if (typeof rawEntry !== "string" || rawEntry.length === 0) {
144862
144987
  return { status: "missing", reason: "@runfusion/fusion pi.extensions[0] is not a valid path string" };
144863
144988
  }
144864
- const entryPath = resolve27(pkgDir, rawEntry);
144865
- if (!existsSync37(entryPath)) {
144989
+ const entryPath = resolve29(pkgDir, rawEntry);
144990
+ if (!existsSync38(entryPath)) {
144866
144991
  return { status: "missing", reason: `@runfusion/fusion extension file not found at ${entryPath}` };
144867
144992
  }
144868
144993
  return { status: "ok", path: entryPath, packageVersion: pkgJson.version ?? "unknown" };
@@ -144921,21 +145046,21 @@ var init_state = __esm({
144921
145046
  });
144922
145047
 
144923
145048
  // src/commands/dashboard-tui/logo.ts
144924
- import { existsSync as existsSync38, readFileSync as readFileSync18 } from "node:fs";
144925
- import { dirname as dirname23, resolve as resolve28 } from "node:path";
145049
+ import { existsSync as existsSync39, readFileSync as readFileSync18 } from "node:fs";
145050
+ import { dirname as dirname23, resolve as resolve30 } from "node:path";
144926
145051
  import { fileURLToPath as fileURLToPath8 } from "node:url";
144927
145052
  function readFusionVersion() {
144928
145053
  try {
144929
145054
  let cur = dirname23(fileURLToPath8(import.meta.url));
144930
145055
  for (let i = 0; i < 6; i++) {
144931
- const pkgPath = resolve28(cur, "package.json");
144932
- if (existsSync38(pkgPath)) {
145056
+ const pkgPath = resolve30(cur, "package.json");
145057
+ if (existsSync39(pkgPath)) {
144933
145058
  const parsed = JSON.parse(readFileSync18(pkgPath, "utf-8"));
144934
145059
  if (parsed.name === "@runfusion/fusion" && typeof parsed.version === "string") {
144935
145060
  return parsed.version;
144936
145061
  }
144937
145062
  }
144938
- const parent2 = resolve28(cur, "..");
145063
+ const parent2 = resolve30(cur, "..");
144939
145064
  if (parent2 === cur) break;
144940
145065
  cur = parent2;
144941
145066
  }
@@ -145040,14 +145165,14 @@ async function copyToClipboard(text) {
145040
145165
  { cmd: "xsel", args: ["--clipboard", "--input"] }
145041
145166
  ];
145042
145167
  for (const { cmd, args } of candidates) {
145043
- const ok = await new Promise((resolve37) => {
145168
+ const ok = await new Promise((resolve39) => {
145044
145169
  try {
145045
145170
  const child = spawn11(cmd, args, { stdio: ["pipe", "ignore", "ignore"] });
145046
- child.once("error", () => resolve37(false));
145047
- child.once("close", (code) => resolve37(code === 0));
145171
+ child.once("error", () => resolve39(false));
145172
+ child.once("close", (code) => resolve39(code === 0));
145048
145173
  child.stdin.end(text);
145049
145174
  } catch {
145050
- resolve37(false);
145175
+ resolve39(false);
145051
145176
  }
145052
145177
  });
145053
145178
  if (ok) return true;
@@ -145190,6 +145315,13 @@ function SystemPanel({ state, isFocused }) {
145190
145315
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "URL" }),
145191
145316
  /* @__PURE__ */ jsx(Text, { color: "cyanBright", wrap: "truncate-end", children: info.baseUrl })
145192
145317
  ] }),
145318
+ info.authToken && // Pinned right after URL so the token is part of the primary
145319
+ // identity row and wraps to a new line at narrow widths instead
145320
+ // of being pushed off-panel.
145321
+ /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, flexShrink: 0, children: [
145322
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Token" }),
145323
+ /* @__PURE__ */ jsx(Text, { color: "yellow", wrap: "truncate-end", children: info.authToken })
145324
+ ] }),
145193
145325
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, flexShrink: 0, children: [
145194
145326
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Engine" }),
145195
145327
  info.engineMode === "dev" && /* @__PURE__ */ jsx(Text, { color: "yellow", children: "dev" }),
@@ -145207,10 +145339,6 @@ function SystemPanel({ state, isFocused }) {
145207
145339
  /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, flexShrink: 0, children: [
145208
145340
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Uptime" }),
145209
145341
  /* @__PURE__ */ jsx(Text, { children: formatUptime(Date.now() - info.startTimeMs) })
145210
- ] }),
145211
- info.authToken && /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, flexShrink: 1, children: [
145212
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "Token" }),
145213
- /* @__PURE__ */ jsx(Text, { wrap: "truncate-end", color: "yellow", children: info.authToken })
145214
145342
  ] })
145215
145343
  ] }) });
145216
145344
  }
@@ -145551,7 +145679,7 @@ function StatusModeGrid({
145551
145679
  const rows = stdout?.rows ?? 24;
145552
145680
  const cols = stdout?.columns ?? 80;
145553
145681
  const middleHeight = Math.max(1, rows - 2);
145554
- const SYSTEM_HEIGHT = 4;
145682
+ const SYSTEM_HEIGHT = state.systemInfo?.authToken ? 5 : 4;
145555
145683
  const bottomShare = Math.min(10, Math.max(6, Math.floor(middleHeight * 0.35)));
145556
145684
  const logsShare = Math.max(1, middleHeight - SYSTEM_HEIGHT - bottomShare);
145557
145685
  const logsAvailableRows = Math.max(1, logsShare - 4);
@@ -145560,7 +145688,7 @@ function StatusModeGrid({
145560
145688
  tuiDebug("StatusModeGrid", { cols, rows, middleHeight, logsShare, bottomShare, focused, wideLayout });
145561
145689
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, children: [
145562
145690
  /* @__PURE__ */ jsxs(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: [
145563
- /* @__PURE__ */ jsx(Box, { height: 4, flexShrink: 0, overflow: "hidden", children: /* @__PURE__ */ jsx(SystemPanel, { state, isFocused: focused === "system" }) }),
145691
+ /* @__PURE__ */ jsx(Box, { height: SYSTEM_HEIGHT, flexShrink: 0, overflow: "hidden", children: /* @__PURE__ */ jsx(SystemPanel, { state, isFocused: focused === "system" }) }),
145564
145692
  wideLayout ? /* @__PURE__ */ jsxs(Fragment, { children: [
145565
145693
  /* @__PURE__ */ jsxs(Box, { flexGrow: 1, flexShrink: 0, flexDirection: "row", overflow: "hidden", children: [
145566
145694
  /* @__PURE__ */ jsx(Box, { flexDirection: "column", width: "30%", flexShrink: 0, overflow: "hidden", children: /* @__PURE__ */ jsx(StatsPanel, { state, isFocused: focused === "stats" }) }),
@@ -148071,8 +148199,8 @@ function DashboardApp({ controller }) {
148071
148199
  const sectionForNumber = {
148072
148200
  "1": "system",
148073
148201
  "2": "logs",
148074
- "3": "utilities",
148075
- "4": "stats",
148202
+ "3": "stats",
148203
+ "4": "utilities",
148076
148204
  "5": "settings"
148077
148205
  };
148078
148206
  const targetSection = sectionForNumber[input];
@@ -148217,7 +148345,7 @@ var init_app = __esm({
148217
148345
  LARGE_LOGO_MIN_ROWS = 16;
148218
148346
  PREFIX_WIDTH = 14;
148219
148347
  NARROW_PREFIX_WIDTH = 8;
148220
- PANEL_ORDER = ["system", "logs", "utilities", "stats", "settings"];
148348
+ PANEL_ORDER = ["system", "logs", "stats", "utilities", "settings"];
148221
148349
  KANBAN_COLUMNS = ["todo", "in-progress", "in-review", "done"];
148222
148350
  COLUMN_COLORS = {
148223
148351
  todo: "yellow",
@@ -148262,6 +148390,17 @@ import os6 from "node:os";
148262
148390
  import v82 from "node:v8";
148263
148391
  import { execSync as execSync2 } from "node:child_process";
148264
148392
  import { appendFileSync as appendFileSync2 } from "node:fs";
148393
+ function getAvailableMemory() {
148394
+ const fn = os6.availableMemory;
148395
+ if (typeof fn === "function") {
148396
+ try {
148397
+ const v = fn.call(os6);
148398
+ if (Number.isFinite(v) && v >= 0) return v;
148399
+ } catch {
148400
+ }
148401
+ }
148402
+ return os6.freemem();
148403
+ }
148265
148404
  function tuiDebug2(tag, data) {
148266
148405
  if (!TUI_DEBUG_LOG2) return;
148267
148406
  try {
@@ -148447,14 +148586,14 @@ var init_controller = __esm({
148447
148586
  loadAvg: [load[0] ?? 0, load[1] ?? 0, load[2] ?? 0],
148448
148587
  cpuCount: os6.cpus().length,
148449
148588
  systemTotalMem: os6.totalmem(),
148450
- systemFreeMem: os6.freemem(),
148589
+ systemFreeMem: getAvailableMemory(),
148451
148590
  pid: process.pid,
148452
148591
  nodeVersion: process.version,
148453
148592
  platform: `${process.platform}/${process.arch}`
148454
148593
  });
148455
148594
  if (this.autoKillVitestOnPressure) {
148456
148595
  const total = os6.totalmem();
148457
- const free = os6.freemem();
148596
+ const free = getAvailableMemory();
148458
148597
  if (total > 0) {
148459
148598
  const usedRatio = (total - free) / total;
148460
148599
  if (usedRatio > this.vitestKillThreshold && now - this.lastAutoKillAt > 3e4) {
@@ -148963,7 +149102,7 @@ __export(dashboard_exports, {
148963
149102
  promptForPort: () => promptForPort,
148964
149103
  runDashboard: () => runDashboard
148965
149104
  });
148966
- import { join as join54, resolve as pathResolve } from "node:path";
149105
+ import { join as join53, resolve as pathResolve } from "node:path";
148967
149106
  import { execFile as execFileCb } from "node:child_process";
148968
149107
  import { promisify as promisify14 } from "node:util";
148969
149108
  import { stat as stat11, readdir as readdir11, readFile as fsReadFile3 } from "node:fs/promises";
@@ -149270,7 +149409,7 @@ async function buildFileListDirectory(projectPath, relativePath) {
149270
149409
  let size = 0;
149271
149410
  let modifiedAt = (/* @__PURE__ */ new Date(0)).toISOString();
149272
149411
  try {
149273
- const s = await stat11(join54(absDir, d.name));
149412
+ const s = await stat11(join53(absDir, d.name));
149274
149413
  size = d.isDirectory() ? 0 : s.size;
149275
149414
  modifiedAt = s.mtime.toISOString();
149276
149415
  } catch {
@@ -149699,7 +149838,7 @@ async function runDashboard(port, opts = {}) {
149699
149838
  ...claudeCliPaths
149700
149839
  ],
149701
149840
  cwd,
149702
- join54(cwd, ".fusion", "disabled-auto-extension-discovery")
149841
+ join53(cwd, ".fusion", "disabled-auto-extension-discovery")
149703
149842
  );
149704
149843
  for (const { path: path5, error } of extensionsResult.errors) {
149705
149844
  logSink.log(`Failed to load ${path5}: ${error}`, "extensions");
@@ -150180,8 +150319,8 @@ async function runDashboard(port, opts = {}) {
150180
150319
  try {
150181
150320
  const updateCheckEnabled = await Promise.race([
150182
150321
  isUpdateCheckEnabled(),
150183
- new Promise((resolve37) => {
150184
- setTimeout(() => resolve37(false), 3e3);
150322
+ new Promise((resolve39) => {
150323
+ setTimeout(() => resolve39(false), 3e3);
150185
150324
  })
150186
150325
  ]);
150187
150326
  if (!updateCheckEnabled) {
@@ -151150,7 +151289,7 @@ var serve_exports = {};
151150
151289
  __export(serve_exports, {
151151
151290
  runServe: () => runServe
151152
151291
  });
151153
- import { join as join55 } from "node:path";
151292
+ import { join as join54 } from "node:path";
151154
151293
  import {
151155
151294
  AuthStorage as AuthStorage3,
151156
151295
  DefaultPackageManager as DefaultPackageManager3,
@@ -151422,7 +151561,7 @@ async function runServe(port, opts = {}) {
151422
151561
  ...claudeCliPaths
151423
151562
  ],
151424
151563
  cwd,
151425
- join55(cwd, ".fusion", "disabled-auto-extension-discovery")
151564
+ join54(cwd, ".fusion", "disabled-auto-extension-discovery")
151426
151565
  );
151427
151566
  for (const { path: path5, error } of extensionsResult.errors) {
151428
151567
  console.log(`[extensions] Failed to load ${path5}: ${error}`);
@@ -151576,8 +151715,8 @@ async function runServe(port, opts = {}) {
151576
151715
  https: loadTlsCredentialsFromEnv()
151577
151716
  });
151578
151717
  const server = app.listen(selectedPort, selectedHost);
151579
- await new Promise((resolve37, reject2) => {
151580
- server.once("listening", resolve37);
151718
+ await new Promise((resolve39, reject2) => {
151719
+ server.once("listening", resolve39);
151581
151720
  server.once("error", reject2);
151582
151721
  });
151583
151722
  const actualPort = server.address().port;
@@ -151734,7 +151873,7 @@ var daemon_exports = {};
151734
151873
  __export(daemon_exports, {
151735
151874
  runDaemon: () => runDaemon
151736
151875
  });
151737
- import { join as join56 } from "node:path";
151876
+ import { join as join55 } from "node:path";
151738
151877
  import {
151739
151878
  AuthStorage as AuthStorage4,
151740
151879
  DefaultPackageManager as DefaultPackageManager4,
@@ -152004,7 +152143,7 @@ async function runDaemon(opts = {}) {
152004
152143
  const extensionsResult = await discoverAndLoadExtensions4(
152005
152144
  reconciledExtensionPaths,
152006
152145
  cwd,
152007
- join56(cwd, ".fusion", "disabled-auto-extension-discovery")
152146
+ join55(cwd, ".fusion", "disabled-auto-extension-discovery")
152008
152147
  );
152009
152148
  for (const { path: path5, error } of extensionsResult.errors) {
152010
152149
  console.log(`[extensions] Failed to load ${path5}: ${error}`);
@@ -152095,8 +152234,8 @@ async function runDaemon(opts = {}) {
152095
152234
  https: loadTlsCredentialsFromEnv()
152096
152235
  });
152097
152236
  const server = app.listen(selectedPort, selectedHost);
152098
- await new Promise((resolve37, reject2) => {
152099
- server.once("listening", resolve37);
152237
+ await new Promise((resolve39, reject2) => {
152238
+ server.once("listening", resolve39);
152100
152239
  server.once("error", reject2);
152101
152240
  });
152102
152241
  const actualPort = server.address().port;
@@ -152207,10 +152346,10 @@ __export(desktop_exports, {
152207
152346
  });
152208
152347
  import { spawn as spawn13 } from "node:child_process";
152209
152348
  import { once as once2 } from "node:events";
152210
- import { join as join57 } from "node:path";
152349
+ import { join as join56 } from "node:path";
152211
152350
  import { createRequire as createRequire5 } from "node:module";
152212
152351
  function runCommand(command, args, cwd) {
152213
- return new Promise((resolve37, reject2) => {
152352
+ return new Promise((resolve39, reject2) => {
152214
152353
  const child = spawn13(command, args, {
152215
152354
  cwd,
152216
152355
  stdio: "inherit",
@@ -152219,7 +152358,7 @@ function runCommand(command, args, cwd) {
152219
152358
  child.on("error", (error) => reject2(error));
152220
152359
  child.on("exit", (code) => {
152221
152360
  if (code === 0) {
152222
- resolve37();
152361
+ resolve39();
152223
152362
  return;
152224
152363
  }
152225
152364
  reject2(new Error(`${command} ${args.join(" ")} exited with code ${code ?? "unknown"}`));
@@ -152262,8 +152401,8 @@ async function startDashboardRuntime(rootDir, paused) {
152262
152401
  };
152263
152402
  }
152264
152403
  async function closeDashboardRuntime(runtime) {
152265
- await new Promise((resolve37) => {
152266
- runtime.server.close(() => resolve37());
152404
+ await new Promise((resolve39) => {
152405
+ runtime.server.close(() => resolve39());
152267
152406
  });
152268
152407
  runtime.store.close();
152269
152408
  }
@@ -152286,7 +152425,7 @@ async function runDesktop(options = {}) {
152286
152425
  }
152287
152426
  const runtime = await startDashboardRuntime(rootDir, Boolean(options.paused));
152288
152427
  const electronBinary = resolveElectronBinary();
152289
- const desktopEntry = join57(rootDir, "packages", "desktop", "dist", "main.js");
152428
+ const desktopEntry = join56(rootDir, "packages", "desktop", "dist", "main.js");
152290
152429
  const electronArgs = ["--enable-source-maps", desktopEntry, ...options.dev ? ["--dev"] : []];
152291
152430
  const electronEnv = {
152292
152431
  ...process.env,
@@ -152371,8 +152510,8 @@ __export(task_exports, {
152371
152510
  runTaskUpdate: () => runTaskUpdate
152372
152511
  });
152373
152512
  import { createInterface as createInterface3 } from "node:readline/promises";
152374
- import { watchFile, unwatchFile, statSync as statSync6, existsSync as existsSync39, readFileSync as readFileSync19 } from "node:fs";
152375
- import { join as join58 } from "node:path";
152513
+ import { watchFile, unwatchFile, statSync as statSync6, existsSync as existsSync40, readFileSync as readFileSync19 } from "node:fs";
152514
+ import { join as join57 } from "node:path";
152376
152515
  function asLocalProjectContext(store) {
152377
152516
  const cwd = process.cwd();
152378
152517
  return {
@@ -152492,9 +152631,9 @@ async function runTaskCreate(descriptionArg, attachFiles, depends, projectName,
152492
152631
  console.log(` Path: .fusion/tasks/${task.id}/`);
152493
152632
  if (attachFiles && attachFiles.length > 0) {
152494
152633
  const { readFile: readFile24 } = await import("node:fs/promises");
152495
- const { basename: basename17, extname: extname2, resolve: resolve37 } = await import("node:path");
152634
+ const { basename: basename17, extname: extname2, resolve: resolve39 } = await import("node:path");
152496
152635
  for (const filePath of attachFiles) {
152497
- const resolvedPath = resolve37(filePath);
152636
+ const resolvedPath = resolve39(filePath);
152498
152637
  const filename = basename17(resolvedPath);
152499
152638
  const ext = extname2(filename).toLowerCase();
152500
152639
  const mimeType = MIME_TYPES[ext];
@@ -152628,8 +152767,8 @@ async function runTaskLogs(id, options = {}, projectName) {
152628
152767
  printEntries(filteredEntries);
152629
152768
  if (options.follow) {
152630
152769
  const projectPath = projectContext?.projectPath ?? process.cwd();
152631
- const logPath = join58(projectPath, ".fusion", "tasks", id, "agent.log");
152632
- if (!existsSync39(logPath)) {
152770
+ const logPath = join57(projectPath, ".fusion", "tasks", id, "agent.log");
152771
+ if (!existsSync40(logPath)) {
152633
152772
  console.log(`
152634
152773
  Waiting for log file to be created...`);
152635
152774
  }
@@ -152788,8 +152927,8 @@ async function runTaskMerge(id, projectName) {
152788
152927
  async function runTaskAttach(id, filePath, projectName) {
152789
152928
  const { readFile: readFile24 } = await import("node:fs/promises");
152790
152929
  const { basename: basename17, extname: extname2 } = await import("node:path");
152791
- const { resolve: resolve37 } = await import("node:path");
152792
- const resolvedPath = resolve37(filePath);
152930
+ const { resolve: resolve39 } = await import("node:path");
152931
+ const resolvedPath = resolve39(filePath);
152793
152932
  const filename = basename17(resolvedPath);
152794
152933
  const ext = extname2(filename).toLowerCase();
152795
152934
  const mimeType = MIME_TYPES[ext];
@@ -153320,12 +153459,12 @@ async function promptText(question) {
153320
153459
  console.log(" (Enter your response. Type DONE on its own line when finished):\n");
153321
153460
  const rl = createInterface3({ input: process.stdin, output: process.stdout });
153322
153461
  const lines = [];
153323
- return new Promise((resolve37) => {
153462
+ return new Promise((resolve39) => {
153324
153463
  const askLine = () => {
153325
153464
  rl.question(" ").then((line) => {
153326
153465
  if (line.trim() === "DONE") {
153327
153466
  rl.close();
153328
- resolve37(lines.join("\n"));
153467
+ resolve39(lines.join("\n"));
153329
153468
  } else {
153330
153469
  lines.push(line);
153331
153470
  askLine();
@@ -153893,7 +154032,7 @@ __export(settings_export_exports, {
153893
154032
  runSettingsExport: () => runSettingsExport
153894
154033
  });
153895
154034
  import { writeFile as writeFile17 } from "node:fs/promises";
153896
- import { resolve as resolve29, join as join59 } from "node:path";
154035
+ import { resolve as resolve31, join as join58 } from "node:path";
153897
154036
  async function runSettingsExport(options = {}) {
153898
154037
  const scope = options.scope ?? "both";
153899
154038
  const project = options.projectName ? await resolveProject(options.projectName) : void 0;
@@ -153904,10 +154043,10 @@ async function runSettingsExport(options = {}) {
153904
154043
  const exportData = await exportSettings(store, { scope });
153905
154044
  let targetPath;
153906
154045
  if (outputPath) {
153907
- targetPath = resolve29(outputPath);
154046
+ targetPath = resolve31(outputPath);
153908
154047
  } else {
153909
154048
  const filename = generateExportFilename();
153910
- targetPath = join59(process.cwd(), filename);
154049
+ targetPath = join58(process.cwd(), filename);
153911
154050
  }
153912
154051
  const jsonContent = JSON.stringify(exportData, null, 2);
153913
154052
  await writeFile17(targetPath, jsonContent);
@@ -153953,8 +154092,8 @@ var settings_import_exports = {};
153953
154092
  __export(settings_import_exports, {
153954
154093
  runSettingsImport: () => runSettingsImport
153955
154094
  });
153956
- import { existsSync as existsSync40 } from "node:fs";
153957
- import { resolve as resolve30 } from "node:path";
154095
+ import { existsSync as existsSync41 } from "node:fs";
154096
+ import { resolve as resolve32 } from "node:path";
153958
154097
  async function runSettingsImport(filePath, options = {}) {
153959
154098
  const scope = options.scope ?? "both";
153960
154099
  const project = options.projectName ? await resolveProject(options.projectName) : void 0;
@@ -153963,8 +154102,8 @@ async function runSettingsImport(filePath, options = {}) {
153963
154102
  const merge = options.merge ?? true;
153964
154103
  const skipConfirm = options.yes ?? false;
153965
154104
  try {
153966
- const resolvedPath = resolve30(filePath);
153967
- if (!existsSync40(resolvedPath)) {
154105
+ const resolvedPath = resolve32(filePath);
154106
+ if (!existsSync41(resolvedPath)) {
153968
154107
  console.error(`Error: File not found: ${filePath}`);
153969
154108
  process.exit(1);
153970
154109
  }
@@ -154437,8 +154576,8 @@ var init_backup2 = __esm({
154437
154576
  });
154438
154577
 
154439
154578
  // src/project-resolver.ts
154440
- import { existsSync as existsSync41, statSync as statSync7 } from "node:fs";
154441
- import { dirname as dirname24, resolve as resolve31, normalize as normalize5 } from "node:path";
154579
+ import { existsSync as existsSync42, statSync as statSync7 } from "node:fs";
154580
+ import { dirname as dirname24, resolve as resolve33, normalize as normalize5 } from "node:path";
154442
154581
  import { createInterface as createInterface5 } from "node:readline/promises";
154443
154582
  async function getCentralCore() {
154444
154583
  if (!centralCoreInstance) {
@@ -154455,10 +154594,10 @@ async function getProjectManager() {
154455
154594
  return projectManagerInstance;
154456
154595
  }
154457
154596
  function findKbDir(startPath) {
154458
- let current = resolve31(startPath);
154597
+ let current = resolve33(startPath);
154459
154598
  for (let i = 0; i < 100; i++) {
154460
- const kbPath = resolve31(current, ".fusion");
154461
- if (existsSync41(kbPath) && statSync7(kbPath).isDirectory()) {
154599
+ const kbPath = resolve33(current, ".fusion");
154600
+ if (existsSync42(kbPath) && statSync7(kbPath).isDirectory()) {
154462
154601
  return current;
154463
154602
  }
154464
154603
  const parent2 = dirname24(current);
@@ -154513,7 +154652,7 @@ async function resolveProject2(options = {}) {
154513
154652
  { searchedName: options.project, availableProjects: projects.map((p) => p.name) }
154514
154653
  );
154515
154654
  }
154516
- if (!existsSync41(match.path)) {
154655
+ if (!existsSync42(match.path)) {
154517
154656
  throw new ProjectResolutionError(
154518
154657
  `Project "${match.name}" is registered but the directory no longer exists: ${match.path}
154519
154658
 
@@ -154524,14 +154663,14 @@ Run \`fn project remove ` + match.name + "` to clean up the registry entry.",
154524
154663
  }
154525
154664
  return createResolvedProject(match);
154526
154665
  }
154527
- const cwd = options.cwd ? resolve31(options.cwd) : process.cwd();
154666
+ const cwd = options.cwd ? resolve33(options.cwd) : process.cwd();
154528
154667
  const fusionDir = findKbDir(cwd);
154529
154668
  if (fusionDir) {
154530
154669
  const allProjects2 = await central.listProjects();
154531
154670
  const normalizedKbDir = normalize5(fusionDir);
154532
154671
  const match = allProjects2.find((p) => normalize5(p.path) === normalizedKbDir);
154533
154672
  if (match) {
154534
- if (!existsSync41(match.path)) {
154673
+ if (!existsSync42(match.path)) {
154535
154674
  throw new ProjectResolutionError(
154536
154675
  `Project "${match.name}" is registered but the directory no longer exists: ${match.path}
154537
154676
 
@@ -154596,7 +154735,7 @@ Run \`fn project add ` + fusionDir + "` to register it, or use --project <name>.
154596
154735
  }
154597
154736
  if (allProjects.length === 1) {
154598
154737
  const project = allProjects[0];
154599
- if (!existsSync41(project.path)) {
154738
+ if (!existsSync42(project.path)) {
154600
154739
  throw new ProjectResolutionError(
154601
154740
  `The only registered project "${project.name}" has a missing directory: ${project.path}
154602
154741
 
@@ -155036,8 +155175,8 @@ __export(project_exports, {
155036
155175
  runProjectSetDefault: () => runProjectSetDefault,
155037
155176
  runProjectShow: () => runProjectShow
155038
155177
  });
155039
- import { resolve as resolve32, isAbsolute as isAbsolute16, relative as relative12, basename as basename14 } from "node:path";
155040
- import { existsSync as existsSync42, statSync as statSync8 } from "node:fs";
155178
+ import { resolve as resolve34, isAbsolute as isAbsolute16, relative as relative12, basename as basename14 } from "node:path";
155179
+ import { existsSync as existsSync43, statSync as statSync8 } from "node:fs";
155041
155180
  import { createInterface as createInterface7 } from "node:readline/promises";
155042
155181
  function formatDisplayPath(projectPath) {
155043
155182
  const rel = relative12(process.cwd(), projectPath);
@@ -155165,8 +155304,8 @@ async function runProjectAdd(name, path5, options = {}) {
155165
155304
  const pathInput = await rl.question(` Project path [${defaultPath}]: `);
155166
155305
  projectPath = pathInput.trim() || defaultPath;
155167
155306
  }
155168
- const absolutePath2 = isAbsolute16(projectPath) ? projectPath : resolve32(process.cwd(), projectPath);
155169
- if (!existsSync42(absolutePath2)) {
155307
+ const absolutePath2 = isAbsolute16(projectPath) ? projectPath : resolve34(process.cwd(), projectPath);
155308
+ if (!existsSync43(absolutePath2)) {
155170
155309
  console.error(`
155171
155310
  \u2717 Path does not exist: ${projectPath}`);
155172
155311
  rl.close();
@@ -155178,8 +155317,8 @@ async function runProjectAdd(name, path5, options = {}) {
155178
155317
  rl.close();
155179
155318
  process.exit(1);
155180
155319
  }
155181
- const kbDbPath2 = resolve32(absolutePath2, ".fusion", "fusion.db");
155182
- if (!existsSync42(kbDbPath2) && !options.force) {
155320
+ const kbDbPath2 = resolve34(absolutePath2, ".fusion", "fusion.db");
155321
+ if (!existsSync43(kbDbPath2) && !options.force) {
155183
155322
  console.log(`
155184
155323
  No fn project found at ${formatDisplayPath(absolutePath2)}`);
155185
155324
  const init = await rl.question(" Initialize fn here first? [Y/n] ");
@@ -155210,8 +155349,8 @@ async function runProjectAdd(name, path5, options = {}) {
155210
155349
  console.error(" Name must be 1-64 characters and contain only: a-z, A-Z, 0-9, _, -\n");
155211
155350
  process.exit(1);
155212
155351
  }
155213
- const absolutePath = isAbsolute16(projectPath) ? projectPath : resolve32(process.cwd(), projectPath);
155214
- if (!existsSync42(absolutePath)) {
155352
+ const absolutePath = isAbsolute16(projectPath) ? projectPath : resolve34(process.cwd(), projectPath);
155353
+ if (!existsSync43(absolutePath)) {
155215
155354
  console.error(`
155216
155355
  \u2717 Path does not exist: ${projectPath}
155217
155356
  `);
@@ -155223,8 +155362,8 @@ async function runProjectAdd(name, path5, options = {}) {
155223
155362
  `);
155224
155363
  process.exit(1);
155225
155364
  }
155226
- const kbDbPath = resolve32(absolutePath, ".fusion", "fusion.db");
155227
- if (!existsSync42(kbDbPath) && !options.force) {
155365
+ const kbDbPath = resolve34(absolutePath, ".fusion", "fusion.db");
155366
+ if (!existsSync43(kbDbPath) && !options.force) {
155228
155367
  console.error(`
155229
155368
  \u2717 No fn project found at ${formatDisplayPath(absolutePath)}`);
155230
155369
  console.error(" Run `fn init` first to initialize the project.\n");
@@ -155480,21 +155619,21 @@ var init_project = __esm({
155480
155619
  });
155481
155620
 
155482
155621
  // src/commands/skill-installation.ts
155483
- import { cpSync as cpSync2, existsSync as existsSync43, mkdirSync as mkdirSync8 } from "node:fs";
155622
+ import { cpSync as cpSync2, existsSync as existsSync44, mkdirSync as mkdirSync8 } from "node:fs";
155484
155623
  import { homedir as homedir8 } from "node:os";
155485
- import { dirname as dirname25, join as join60, resolve as resolve33 } from "node:path";
155624
+ import { dirname as dirname25, join as join59, resolve as resolve35 } from "node:path";
155486
155625
  import { fileURLToPath as fileURLToPath9 } from "node:url";
155487
155626
  function getSupportedSkillInstallTargets(homeDir = process.env.HOME || process.env.USERPROFILE || homedir8()) {
155488
155627
  return [
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) }
155628
+ { client: "claude", targetDir: join59(homeDir, ".claude", "skills", FUSION_SKILL_NAME2) },
155629
+ { client: "codex", targetDir: join59(homeDir, ".codex", "skills", FUSION_SKILL_NAME2) },
155630
+ { client: "gemini", targetDir: join59(homeDir, ".gemini", "skills", FUSION_SKILL_NAME2) }
155492
155631
  ];
155493
155632
  }
155494
155633
  function resolveBundledFusionSkillSource() {
155495
155634
  const here = fileURLToPath9(import.meta.url);
155496
- const source = resolve33(dirname25(here), "..", "..", "skill", FUSION_SKILL_NAME2);
155497
- return existsSync43(source) ? source : null;
155635
+ const source = resolve35(dirname25(here), "..", "..", "skill", FUSION_SKILL_NAME2);
155636
+ return existsSync44(source) ? source : null;
155498
155637
  }
155499
155638
  function installBundledFusionSkill(options = {}) {
155500
155639
  const sourceDir = options.sourceDir ?? resolveBundledFusionSkillSource();
@@ -155512,7 +155651,7 @@ function installBundledFusionSkill(options = {}) {
155512
155651
  }
155513
155652
  const results = targets.map((target) => {
155514
155653
  try {
155515
- if (existsSync43(target.targetDir)) {
155654
+ if (existsSync44(target.targetDir)) {
155516
155655
  return {
155517
155656
  client: target.client,
155518
155657
  targetDir: target.targetDir,
@@ -155551,15 +155690,15 @@ var init_exports = {};
155551
155690
  __export(init_exports, {
155552
155691
  runInit: () => runInit
155553
155692
  });
155554
- import { existsSync as existsSync44, mkdirSync as mkdirSync9, writeFileSync as writeFileSync3, readFileSync as readFileSync20 } from "node:fs";
155555
- import { join as join61, resolve as resolve34, basename as basename15 } from "node:path";
155693
+ import { existsSync as existsSync45, mkdirSync as mkdirSync9, writeFileSync as writeFileSync3, readFileSync as readFileSync20 } from "node:fs";
155694
+ import { join as join60, resolve as resolve36, basename as basename15 } from "node:path";
155556
155695
  import { exec as exec11 } from "node:child_process";
155557
155696
  import { promisify as promisify16 } from "node:util";
155558
155697
  async function runInit(options = {}) {
155559
- const cwd = options.path ? resolve34(options.path) : process.cwd();
155560
- const fusionDir = join61(cwd, ".fusion");
155561
- const dbPath = join61(fusionDir, "fusion.db");
155562
- if (existsSync44(fusionDir) && existsSync44(dbPath)) {
155698
+ const cwd = options.path ? resolve36(options.path) : process.cwd();
155699
+ const fusionDir = join60(cwd, ".fusion");
155700
+ const dbPath = join60(fusionDir, "fusion.db");
155701
+ if (existsSync45(fusionDir) && existsSync45(dbPath)) {
155563
155702
  const central2 = new CentralCore();
155564
155703
  await central2.init();
155565
155704
  const existing = await central2.getProjectByPath(cwd);
@@ -155584,7 +155723,7 @@ async function runInit(options = {}) {
155584
155723
  const projectName = options.name ?? await detectProjectName(cwd);
155585
155724
  console.log(`Initializing fn project: "${projectName}"`);
155586
155725
  console.log(` Path: ${cwd}`);
155587
- if (!existsSync44(fusionDir)) {
155726
+ if (!existsSync45(fusionDir)) {
155588
155727
  mkdirSync9(fusionDir, { recursive: true });
155589
155728
  console.log(` \u2713 Created .fusion/ directory`);
155590
155729
  }
@@ -155597,7 +155736,7 @@ async function runInit(options = {}) {
155597
155736
  }
155598
155737
  await addLocalStorageToGitignore(cwd);
155599
155738
  await warnIfQmdMissing();
155600
- if (!existsSync44(dbPath)) {
155739
+ if (!existsSync45(dbPath)) {
155601
155740
  const sqliteHeader = Buffer.from([
155602
155741
  83,
155603
155742
  81,
@@ -155665,7 +155804,7 @@ async function runInit(options = {}) {
155665
155804
  }
155666
155805
  }
155667
155806
  async function detectProjectName(dir2) {
155668
- if (!existsSync44(join61(dir2, ".git"))) {
155807
+ if (!existsSync45(join60(dir2, ".git"))) {
155669
155808
  return basename15(dir2) || "my-project";
155670
155809
  }
155671
155810
  try {
@@ -155685,9 +155824,9 @@ async function detectProjectName(dir2) {
155685
155824
  return basename15(dir2) || "my-project";
155686
155825
  }
155687
155826
  async function addLocalStorageToGitignore(cwd) {
155688
- const gitignorePath = join61(cwd, ".gitignore");
155827
+ const gitignorePath = join60(cwd, ".gitignore");
155689
155828
  let content = "";
155690
- if (existsSync44(gitignorePath)) {
155829
+ if (existsSync45(gitignorePath)) {
155691
155830
  try {
155692
155831
  content = readFileSync20(gitignorePath, "utf-8");
155693
155832
  } catch {
@@ -155728,8 +155867,8 @@ async function initializeGitRepo(cwd) {
155728
155867
  }
155729
155868
  await ensureGitConfig(cwd, "user.name", "Fusion");
155730
155869
  await ensureGitConfig(cwd, "user.email", "noreply@runfusion.ai");
155731
- const gitkeepPath = join61(cwd, ".gitkeep");
155732
- if (!existsSync44(gitkeepPath)) {
155870
+ const gitkeepPath = join60(cwd, ".gitkeep");
155871
+ if (!existsSync45(gitkeepPath)) {
155733
155872
  writeFileSync3(gitkeepPath, "\n");
155734
155873
  }
155735
155874
  await execAsync11("git add .gitkeep", { cwd, timeout: 1e4 });
@@ -155867,8 +156006,8 @@ var agent_import_exports = {};
155867
156006
  __export(agent_import_exports, {
155868
156007
  runAgentImport: () => runAgentImport
155869
156008
  });
155870
- import { existsSync as existsSync45, mkdirSync as mkdirSync10, readFileSync as readFileSync21, statSync as statSync9, writeFileSync as writeFileSync4 } from "node:fs";
155871
- import { resolve as resolve35 } from "node:path";
156009
+ import { existsSync as existsSync46, mkdirSync as mkdirSync10, readFileSync as readFileSync21, statSync as statSync9, writeFileSync as writeFileSync4 } from "node:fs";
156010
+ import { resolve as resolve37 } from "node:path";
155872
156011
  function slugifyPathSegment(input) {
155873
156012
  if (!input || typeof input !== "string") {
155874
156013
  return "unnamed";
@@ -155917,16 +156056,16 @@ async function importSkillsToProject(projectPath, skills, companySlug, dryRun) {
155917
156056
  errors: []
155918
156057
  };
155919
156058
  const companyDir = slugifyPathSegment(companySlug ?? "unknown-company");
155920
- const baseSkillsDir = resolve35(projectPath, "skills", "imported", companyDir);
156059
+ const baseSkillsDir = resolve37(projectPath, "skills", "imported", companyDir);
155921
156060
  for (const skill of skills) {
155922
156061
  if (!skill.name || typeof skill.name !== "string" || skill.name.trim().length === 0) {
155923
156062
  result.errors.push({ name: "(unnamed)", error: "Skill is missing required 'name' field" });
155924
156063
  continue;
155925
156064
  }
155926
156065
  const skillSlug = slugifyPathSegment(skill.name);
155927
- const skillDir = resolve35(baseSkillsDir, skillSlug);
155928
- const skillPath = resolve35(skillDir, "SKILL.md");
155929
- if (existsSync45(skillPath)) {
156066
+ const skillDir = resolve37(baseSkillsDir, skillSlug);
156067
+ const skillPath = resolve37(skillDir, "SKILL.md");
156068
+ if (existsSync46(skillPath)) {
155930
156069
  result.skipped.push(skill.name);
155931
156070
  continue;
155932
156071
  }
@@ -155998,8 +156137,8 @@ function isArchivePath(path5) {
155998
156137
  async function runAgentImport(source, options) {
155999
156138
  const dryRun = options?.dryRun ?? false;
156000
156139
  const skipExisting = options?.skipExisting ?? false;
156001
- const sourcePath = resolve35(source);
156002
- if (!existsSync45(sourcePath)) {
156140
+ const sourcePath = resolve37(source);
156141
+ if (!existsSync46(sourcePath)) {
156003
156142
  console.error(`Path not found: ${sourcePath}`);
156004
156143
  process.exit(1);
156005
156144
  }
@@ -156137,7 +156276,7 @@ var agent_export_exports = {};
156137
156276
  __export(agent_export_exports, {
156138
156277
  runAgentExport: () => runAgentExport
156139
156278
  });
156140
- import { resolve as resolve36 } from "node:path";
156279
+ import { resolve as resolve38 } from "node:path";
156141
156280
  async function getProjectPath4(projectName) {
156142
156281
  if (projectName) {
156143
156282
  const context = await resolveProject(projectName);
@@ -156175,7 +156314,7 @@ async function runAgentExport(outputDir, options) {
156175
156314
  console.error("No agents found to export");
156176
156315
  process.exit(1);
156177
156316
  }
156178
- const result = await exportAgentsToDirectory(agents, resolve36(outputDir), {
156317
+ const result = await exportAgentsToDirectory(agents, resolve38(outputDir), {
156179
156318
  companyName: options?.companyName,
156180
156319
  companySlug: options?.companySlug
156181
156320
  });
@@ -156394,8 +156533,8 @@ __export(plugin_exports, {
156394
156533
  runPluginList: () => runPluginList,
156395
156534
  runPluginUninstall: () => runPluginUninstall
156396
156535
  });
156397
- import { existsSync as existsSync46 } from "node:fs";
156398
- import { join as join62 } from "node:path";
156536
+ import { existsSync as existsSync47 } from "node:fs";
156537
+ import { join as join61 } from "node:path";
156399
156538
  import { readFile as readFile23 } from "node:fs/promises";
156400
156539
  import * as readline from "node:readline";
156401
156540
  async function getProjectPath6(projectName) {
@@ -156433,8 +156572,8 @@ async function createPluginLoader(pluginStore, projectName) {
156433
156572
  return { store: pluginStore, loader };
156434
156573
  }
156435
156574
  async function loadManifestFromPath(pluginPath) {
156436
- const manifestPath = join62(pluginPath, "manifest.json");
156437
- if (!existsSync46(manifestPath)) {
156575
+ const manifestPath = join61(pluginPath, "manifest.json");
156576
+ if (!existsSync47(manifestPath)) {
156438
156577
  throw new Error(`Plugin manifest not found at: ${manifestPath}`);
156439
156578
  }
156440
156579
  const content = await readFile23(manifestPath, "utf-8");
@@ -156492,7 +156631,7 @@ async function runPluginInstall(source, options) {
156492
156631
  console.error("Please provide a local path to the plugin directory.");
156493
156632
  process.exit(1);
156494
156633
  }
156495
- if (!existsSync46(source)) {
156634
+ if (!existsSync47(source)) {
156496
156635
  console.error(`Plugin path does not exist: ${source}`);
156497
156636
  process.exit(1);
156498
156637
  }
@@ -156537,14 +156676,14 @@ async function runPluginUninstall(id, options) {
156537
156676
  console.log(` Uninstall "${plugin4.name}"?`);
156538
156677
  console.log(` This will stop and remove the plugin.`);
156539
156678
  console.log();
156540
- const response = await new Promise((resolve37) => {
156679
+ const response = await new Promise((resolve39) => {
156541
156680
  const rl = readline.createInterface({
156542
156681
  input: process.stdin,
156543
156682
  output: process.stdout
156544
156683
  });
156545
156684
  rl.question(" Continue? [y/N] ", (answer) => {
156546
156685
  rl.close();
156547
- resolve37(answer.toLowerCase());
156686
+ resolve39(answer.toLowerCase());
156548
156687
  });
156549
156688
  });
156550
156689
  if (response !== "y" && response !== "yes") {
@@ -156624,8 +156763,8 @@ var plugin_scaffold_exports = {};
156624
156763
  __export(plugin_scaffold_exports, {
156625
156764
  runPluginCreate: () => runPluginCreate
156626
156765
  });
156627
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync5, existsSync as existsSync47 } from "node:fs";
156628
- import { join as join63 } from "node:path";
156766
+ import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync5, existsSync as existsSync48 } from "node:fs";
156767
+ import { join as join62 } from "node:path";
156629
156768
  function toTitleCase(str) {
156630
156769
  return str.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
156631
156770
  }
@@ -156758,24 +156897,24 @@ async function runPluginCreate(name, options) {
156758
156897
  process.exit(1);
156759
156898
  }
156760
156899
  const targetDir = options?.output ?? name;
156761
- const targetPath = join63(process.cwd(), targetDir);
156762
- if (existsSync47(targetPath)) {
156900
+ const targetPath = join62(process.cwd(), targetDir);
156901
+ if (existsSync48(targetPath)) {
156763
156902
  console.error(`Error: Directory '${targetDir}' already exists.`);
156764
156903
  console.error("Please choose a different name or remove the existing directory.");
156765
156904
  process.exit(1);
156766
156905
  }
156767
156906
  try {
156768
156907
  mkdirSync11(targetPath, { recursive: true });
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));
156908
+ mkdirSync11(join62(targetPath, "src", "__tests__"), { recursive: true });
156909
+ writeFileSync5(join62(targetPath, "package.json"), generatePackageJson(name));
156910
+ writeFileSync5(join62(targetPath, "tsconfig.json"), generateTsconfig());
156911
+ writeFileSync5(join62(targetPath, "vitest.config.ts"), generateVitestConfig());
156912
+ writeFileSync5(join62(targetPath, "src", "index.ts"), generateIndexTs(name));
156774
156913
  writeFileSync5(
156775
- join63(targetPath, "src", "__tests__", "index.test.ts"),
156914
+ join62(targetPath, "src", "__tests__", "index.test.ts"),
156776
156915
  generateTestTs(name)
156777
156916
  );
156778
- writeFileSync5(join63(targetPath, "README.md"), generateReadme(name));
156917
+ writeFileSync5(join62(targetPath, "README.md"), generateReadme(name));
156779
156918
  } catch (err) {
156780
156919
  console.error(
156781
156920
  `Error creating plugin files: ${err instanceof Error ? err.message : String(err)}`
@@ -156892,9 +157031,9 @@ async function runSkillsInstall(args, options) {
156892
157031
  stdio: "inherit",
156893
157032
  shell: true
156894
157033
  });
156895
- const exitCode = await new Promise((resolve37, reject2) => {
157034
+ const exitCode = await new Promise((resolve39, reject2) => {
156896
157035
  child.on("exit", (code) => {
156897
- resolve37(code ?? 1);
157036
+ resolve39(code ?? 1);
156898
157037
  });
156899
157038
  child.on("error", (err) => {
156900
157039
  reject2(err);
@@ -156925,21 +157064,21 @@ __export(native_patch_exports, {
156925
157064
  isTerminalAvailable: () => isTerminalAvailable,
156926
157065
  setupNativeResolution: () => setupNativeResolution
156927
157066
  });
156928
- import { join as join64, basename as basename16, dirname as dirname26 } from "node:path";
156929
- import { existsSync as existsSync48, copyFileSync, mkdirSync as mkdirSync12, symlinkSync as symlinkSync2, rmSync as rmSync5, lstatSync as lstatSync3, readlinkSync as readlinkSync2 } from "node:fs";
157067
+ import { join as join63, basename as basename16, dirname as dirname26 } from "node:path";
157068
+ import { existsSync as existsSync49, copyFileSync, mkdirSync as mkdirSync12, symlinkSync as symlinkSync2, rmSync as rmSync5, lstatSync as lstatSync3, readlinkSync as readlinkSync2 } from "node:fs";
156930
157069
  import { tmpdir as tmpdir4 } from "node:os";
156931
157070
  function findStagedNativeDir2() {
156932
157071
  const platform3 = process.platform === "darwin" ? "darwin" : process.platform === "linux" ? "linux" : process.platform === "win32" ? "win32" : "unknown";
156933
157072
  const arch = process.arch === "arm64" ? "arm64" : process.arch === "x64" ? "x64" : "unknown";
156934
157073
  const prebuildName = `${platform3}-${arch}`;
156935
157074
  const execDir = dirname26(process.execPath);
156936
- const nextToBinary = join64(execDir, "runtime", prebuildName);
156937
- if (existsSync48(join64(nextToBinary, "pty.node"))) {
157075
+ const nextToBinary = join63(execDir, "runtime", prebuildName);
157076
+ if (existsSync49(join63(nextToBinary, "pty.node"))) {
156938
157077
  return nextToBinary;
156939
157078
  }
156940
157079
  if (process.env.FUSION_RUNTIME_DIR) {
156941
- const envPath = join64(process.env.FUSION_RUNTIME_DIR, prebuildName);
156942
- if (existsSync48(join64(envPath, "pty.node"))) {
157080
+ const envPath = join63(process.env.FUSION_RUNTIME_DIR, prebuildName);
157081
+ if (existsSync49(join63(envPath, "pty.node"))) {
156943
157082
  return envPath;
156944
157083
  }
156945
157084
  }
@@ -156949,11 +157088,11 @@ function cleanupStaleBunfsLinks() {
156949
157088
  if (process.platform === "win32") return;
156950
157089
  const bunfsRoot = "/$bunfs/root";
156951
157090
  try {
156952
- if (existsSync48(bunfsRoot)) {
157091
+ if (existsSync49(bunfsRoot)) {
156953
157092
  const stats = lstatSync3(bunfsRoot);
156954
157093
  if (stats.isSymbolicLink()) {
156955
157094
  const target = readlinkSync2(bunfsRoot);
156956
- if (target.includes("fn-bunfs-") && !existsSync48(target)) {
157095
+ if (target.includes("fn-bunfs-") && !existsSync49(target)) {
156957
157096
  rmSync5(bunfsRoot);
156958
157097
  console.log("[fn-native-patch] Cleaned up stale /$bunfs/root symlink");
156959
157098
  }
@@ -156972,23 +157111,23 @@ function setupNativeResolution() {
156972
157111
  process.env.NODE_PTY_SPAWN_HELPER_DIR = nativeDir;
156973
157112
  }
156974
157113
  process.env.FUSION_NATIVE_ASSETS_PATH = 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));
157114
+ const tmpRoot = join63(tmpdir4(), `fn-bunfs-${process.pid}`);
157115
+ const fnDir = join63(tmpRoot, "fn");
157116
+ const prebuildsDir = join63(fnDir, "prebuilds");
157117
+ const platformDir = join63(prebuildsDir, basename16(nativeDir));
156979
157118
  try {
156980
157119
  cleanupStaleBunfsLinks();
156981
157120
  mkdirSync12(platformDir, { recursive: true });
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"));
157121
+ const ptyNodeDest = join63(platformDir, "pty.node");
157122
+ copyFileSync(join63(nativeDir, "pty.node"), ptyNodeDest);
157123
+ if (existsSync49(join63(nativeDir, "spawn-helper"))) {
157124
+ copyFileSync(join63(nativeDir, "spawn-helper"), join63(platformDir, "spawn-helper"));
156986
157125
  }
156987
157126
  process.env.FUSION_FAKE_BUNFS_ROOT = tmpRoot;
156988
157127
  if (process.platform !== "win32") {
156989
157128
  const bunfsRoot = "/$bunfs/root";
156990
157129
  try {
156991
- if (existsSync48(bunfsRoot)) {
157130
+ if (existsSync49(bunfsRoot)) {
156992
157131
  const stats = lstatSync3(bunfsRoot);
156993
157132
  if (stats.isSymbolicLink()) {
156994
157133
  rmSync5(bunfsRoot);
@@ -157011,7 +157150,7 @@ function setupNativeResolution() {
157011
157150
  function cleanupNativeResolution() {
157012
157151
  if (bunfsSymlinkPath && process.platform !== "win32") {
157013
157152
  try {
157014
- if (existsSync48(bunfsSymlinkPath)) {
157153
+ if (existsSync49(bunfsSymlinkPath)) {
157015
157154
  const stats = lstatSync3(bunfsSymlinkPath);
157016
157155
  if (stats.isSymbolicLink()) {
157017
157156
  rmSync5(bunfsSymlinkPath);
@@ -157057,9 +157196,9 @@ var init_native_patch = __esm({
157057
157196
  });
157058
157197
 
157059
157198
  // src/bin.ts
157060
- import { existsSync as existsSync49, mkdtempSync as mkdtempSync2, readFileSync as readFileSync22, symlinkSync as symlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
157199
+ import { existsSync as existsSync50, mkdtempSync as mkdtempSync2, readFileSync as readFileSync22, symlinkSync as symlinkSync3, writeFileSync as writeFileSync6 } from "node:fs";
157061
157200
  import { createRequire as createRequire6 } from "node:module";
157062
- import { join as join65, dirname as dirname27 } from "node:path";
157201
+ import { join as join64, dirname as dirname27 } from "node:path";
157063
157202
  import { tmpdir as tmpdir5 } from "node:os";
157064
157203
  import { performance as performance3 } from "node:perf_hooks";
157065
157204
  var isBunBinary3 = typeof Bun !== "undefined" && !!Bun.embeddedFiles;
@@ -157067,7 +157206,7 @@ function configurePiPackage() {
157067
157206
  if (process.env.PI_PACKAGE_DIR) {
157068
157207
  return;
157069
157208
  }
157070
- const tmp = mkdtempSync2(join65(tmpdir5(), "fn-pkg-"));
157209
+ const tmp = mkdtempSync2(join64(tmpdir5(), "fn-pkg-"));
157071
157210
  let packageJson = {
157072
157211
  name: "pi",
157073
157212
  version: "0.1.0",
@@ -157079,9 +157218,9 @@ function configurePiPackage() {
157079
157218
  const piPackageDir = dirname27(piPackagePath);
157080
157219
  packageJson = JSON.parse(readFileSync22(piPackagePath, "utf-8"));
157081
157220
  for (const entry of ["dist", "docs", "examples", "README.md", "CHANGELOG.md"]) {
157082
- const source = join65(piPackageDir, entry);
157083
- if (existsSync49(source)) {
157084
- symlinkSync3(source, join65(tmp, entry));
157221
+ const source = join64(piPackageDir, entry);
157222
+ if (existsSync50(source)) {
157223
+ symlinkSync3(source, join64(tmp, entry));
157085
157224
  }
157086
157225
  }
157087
157226
  } catch {
@@ -157090,7 +157229,7 @@ function configurePiPackage() {
157090
157229
  ...packageJson.piConfig ?? {},
157091
157230
  configDir: ".fusion"
157092
157231
  };
157093
- writeFileSync6(join65(tmp, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
157232
+ writeFileSync6(join64(tmp, "package.json"), JSON.stringify(packageJson, null, 2) + "\n");
157094
157233
  process.env.PI_PACKAGE_DIR = tmp;
157095
157234
  }
157096
157235
  configurePiPackage();
@@ -157099,7 +157238,7 @@ setInterval(() => {
157099
157238
  performance3.clearMarks();
157100
157239
  }, 3e4).unref();
157101
157240
  function loadEnvFile(path5) {
157102
- if (!existsSync49(path5)) return;
157241
+ if (!existsSync50(path5)) return;
157103
157242
  const contents = readFileSync22(path5, "utf-8");
157104
157243
  for (const rawLine of contents.split(/\r?\n/)) {
157105
157244
  const line = rawLine.trim();
@@ -157118,8 +157257,8 @@ function loadEnvFile(path5) {
157118
157257
  }
157119
157258
  function loadLocalEnv() {
157120
157259
  const cwd = process.cwd();
157121
- loadEnvFile(join65(cwd, ".env"));
157122
- loadEnvFile(join65(cwd, ".env.local"));
157260
+ loadEnvFile(join64(cwd, ".env"));
157261
+ loadEnvFile(join64(cwd, ".env.local"));
157123
157262
  }
157124
157263
  loadLocalEnv();
157125
157264
  async function loadCommandHandlers() {
@@ -157352,9 +157491,6 @@ Options:
157352
157491
 
157353
157492
  Columns: triage, todo, in-progress, in-review, done, archived
157354
157493
  Supported file types: png, jpg, gif, webp, txt, log, json, yaml, yml, toml, csv, xml
157355
-
157356
- The AI engine uses pi (github.com/badlogic/pi-mono) for agent sessions.
157357
- Requires configured API keys \u2014 run "pi" first to set up authentication.
157358
157494
  `.trim();
157359
157495
  function extractGlobalProjectFlag(argv) {
157360
157496
  const cleanedArgs = [];
@@ -157402,10 +157538,8 @@ async function main() {
157402
157538
  console.log(HELP);
157403
157539
  process.exit(0);
157404
157540
  }
157405
- if (args.length === 0) {
157406
- const { runDashboard: runDashboard3 } = await Promise.resolve().then(() => (init_dashboard(), dashboard_exports));
157407
- await runDashboard3(4040);
157408
- return;
157541
+ if (args.length === 0 || args[0].startsWith("-")) {
157542
+ args.unshift("dashboard");
157409
157543
  }
157410
157544
  const command = args[0];
157411
157545
  const {