open-agents-ai 0.173.0 → 0.174.0

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 (2) hide show
  1. package/dist/index.js +386 -217
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1374,7 +1374,7 @@ ${stdinInput ?? ""}`);
1374
1374
  }
1375
1375
  runCommand(command, timeout, stdinInput) {
1376
1376
  const start = performance.now();
1377
- return new Promise((resolve34) => {
1377
+ return new Promise((resolve35) => {
1378
1378
  const child = spawn("bash", ["-c", command], {
1379
1379
  cwd: this.workingDir,
1380
1380
  env: {
@@ -1405,7 +1405,7 @@ ${stdinInput ?? ""}`);
1405
1405
  clearTimeout(timer);
1406
1406
  if (exitFlushTimer)
1407
1407
  clearTimeout(exitFlushTimer);
1408
- resolve34(result);
1408
+ resolve35(result);
1409
1409
  };
1410
1410
  const timer = setTimeout(() => {
1411
1411
  killed = true;
@@ -3161,7 +3161,7 @@ ${JSON.stringify(extracted, null, 2)}`);
3161
3161
  return null;
3162
3162
  }
3163
3163
  runProcess(cmd, args, timeoutMs) {
3164
- return new Promise((resolve34, reject) => {
3164
+ return new Promise((resolve35, reject) => {
3165
3165
  const proc = execFile3(cmd, args, {
3166
3166
  timeout: timeoutMs,
3167
3167
  maxBuffer: 10 * 1024 * 1024,
@@ -3171,7 +3171,7 @@ ${JSON.stringify(extracted, null, 2)}`);
3171
3171
  reject(new Error(`Process timeout after ${timeoutMs}ms`));
3172
3172
  return;
3173
3173
  }
3174
- resolve34({
3174
+ resolve35({
3175
3175
  stdout: String(stdout),
3176
3176
  stderr: String(stderr),
3177
3177
  exitCode: error ? error.code ?? 1 : 0
@@ -10602,7 +10602,7 @@ var init_custom_tool = __esm({
10602
10602
  }
10603
10603
  /** Execute a single shell command and return output */
10604
10604
  runCommand(command) {
10605
- return new Promise((resolve34) => {
10605
+ return new Promise((resolve35) => {
10606
10606
  const child = spawn4("bash", ["-c", command], {
10607
10607
  cwd: this.workingDir,
10608
10608
  env: { ...process.env, CI: "true", NO_COLOR: "1" },
@@ -10627,11 +10627,11 @@ var init_custom_tool = __esm({
10627
10627
  child.kill("SIGTERM");
10628
10628
  } catch {
10629
10629
  }
10630
- resolve34({ success: false, output: stdout, error: "Command timed out after 60s" });
10630
+ resolve35({ success: false, output: stdout, error: "Command timed out after 60s" });
10631
10631
  }, 6e4);
10632
10632
  child.on("close", (code) => {
10633
10633
  clearTimeout(timer);
10634
- resolve34({
10634
+ resolve35({
10635
10635
  success: code === 0,
10636
10636
  output: stdout + (stderr && code === 0 ? `
10637
10637
  STDERR:
@@ -10641,7 +10641,7 @@ ${stderr}` : ""),
10641
10641
  });
10642
10642
  child.on("error", (err) => {
10643
10643
  clearTimeout(timer);
10644
- resolve34({ success: false, output: stdout, error: err.message });
10644
+ resolve35({ success: false, output: stdout, error: err.message });
10645
10645
  });
10646
10646
  });
10647
10647
  }
@@ -11659,8 +11659,8 @@ async function loadTranscribeCli() {
11659
11659
  const nvmBase = join19(homedir6(), ".nvm", "versions", "node");
11660
11660
  if (existsSync16(nvmBase)) {
11661
11661
  try {
11662
- const { readdirSync: readdirSync20 } = await import("node:fs");
11663
- for (const ver of readdirSync20(nvmBase)) {
11662
+ const { readdirSync: readdirSync21 } = await import("node:fs");
11663
+ for (const ver of readdirSync21(nvmBase)) {
11664
11664
  const tcPath = join19(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
11665
11665
  if (existsSync16(join19(tcPath, "dist", "index.js"))) {
11666
11666
  const { createRequire: createRequire4 } = await import("node:module");
@@ -12205,7 +12205,7 @@ import { writeFile as writeFile8, mkdtemp, rm, readdir as readdir3, stat } from
12205
12205
  import { join as join20 } from "node:path";
12206
12206
  import { tmpdir as tmpdir2 } from "node:os";
12207
12207
  function runProcess(cmd, args, options) {
12208
- return new Promise((resolve34) => {
12208
+ return new Promise((resolve35) => {
12209
12209
  const proc = spawn6(cmd, args, {
12210
12210
  cwd: options.cwd,
12211
12211
  timeout: options.timeout,
@@ -12235,7 +12235,7 @@ function runProcess(cmd, args, options) {
12235
12235
  }
12236
12236
  });
12237
12237
  proc.on("error", (err) => {
12238
- resolve34({
12238
+ resolve35({
12239
12239
  stdout,
12240
12240
  stderr: stderr || err.message,
12241
12241
  exitCode: 1,
@@ -12247,7 +12247,7 @@ function runProcess(cmd, args, options) {
12247
12247
  if (signal === "SIGTERM" || signal === "SIGKILL") {
12248
12248
  timedOut = true;
12249
12249
  }
12250
- resolve34({
12250
+ resolve35({
12251
12251
  stdout,
12252
12252
  stderr,
12253
12253
  exitCode: code ?? (timedOut ? 124 : 1),
@@ -12730,7 +12730,7 @@ Justification: ${justification || "(none provided)"}`,
12730
12730
  })();
12731
12731
  const ipfsResult = await Promise.race([
12732
12732
  ipfsPromise,
12733
- new Promise((resolve34) => setTimeout(() => resolve34(null), 2e3))
12733
+ new Promise((resolve35) => setTimeout(() => resolve35(null), 2e3))
12734
12734
  ]);
12735
12735
  if (ipfsResult && ipfsResult.success) {
12736
12736
  const cidData = JSON.parse(ipfsResult.output);
@@ -13177,7 +13177,7 @@ print("__OA_REPL_READY__")
13177
13177
  return;
13178
13178
  const sockId = randomBytes5(8).toString("hex");
13179
13179
  this.ipcPath = join22(tmpdir3(), `oa-repl-ipc-${sockId}.sock`);
13180
- return new Promise((resolve34, reject) => {
13180
+ return new Promise((resolve35, reject) => {
13181
13181
  this.ipcServer = createServer((conn) => {
13182
13182
  let buffer = new Uint8Array(0);
13183
13183
  conn.on("data", (chunk) => {
@@ -13193,7 +13193,7 @@ print("__OA_REPL_READY__")
13193
13193
  });
13194
13194
  });
13195
13195
  this.ipcServer.on("error", reject);
13196
- this.ipcServer.listen(this.ipcPath, () => resolve34());
13196
+ this.ipcServer.listen(this.ipcPath, () => resolve35());
13197
13197
  });
13198
13198
  }
13199
13199
  async processIpcBuffer(conn, input) {
@@ -13256,9 +13256,9 @@ print("__OA_REPL_READY__")
13256
13256
  }
13257
13257
  // ── Code execution ─────────────────────────────────────────────────────
13258
13258
  executeCode(code, isInit = false) {
13259
- return new Promise((resolve34) => {
13259
+ return new Promise((resolve35) => {
13260
13260
  if (!this.proc?.stdin || !this.proc?.stdout || !this.proc?.stderr) {
13261
- resolve34({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
13261
+ resolve35({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
13262
13262
  return;
13263
13263
  }
13264
13264
  const sentinel = `__OA_SENTINEL_${randomBytes5(6).toString("hex")}__`;
@@ -13268,7 +13268,7 @@ print("__OA_REPL_READY__")
13268
13268
  const timeout = setTimeout(() => {
13269
13269
  if (!resolved) {
13270
13270
  resolved = true;
13271
- resolve34({
13271
+ resolve35({
13272
13272
  success: false,
13273
13273
  output: stdout || "Execution timed out",
13274
13274
  error: `Timeout after ${this.execTimeout / 1e3}s`,
@@ -13285,13 +13285,13 @@ print("__OA_REPL_READY__")
13285
13285
  if (isInit) {
13286
13286
  const ready = cleanOutput.includes("__OA_REPL_READY__");
13287
13287
  const displayOutput = cleanOutput.replace("__OA_REPL_READY__", "").trim();
13288
- resolve34({
13288
+ resolve35({
13289
13289
  success: ready,
13290
13290
  output: displayOutput || "REPL initialized",
13291
13291
  durationMs: 0
13292
13292
  });
13293
13293
  } else {
13294
- resolve34({
13294
+ resolve35({
13295
13295
  success: true,
13296
13296
  output: cleanOutput || "(no output)",
13297
13297
  durationMs: 0
@@ -13300,7 +13300,7 @@ print("__OA_REPL_READY__")
13300
13300
  }
13301
13301
  if (stdout.length > 2e5) {
13302
13302
  cleanup();
13303
- resolve34({
13303
+ resolve35({
13304
13304
  success: true,
13305
13305
  output: stdout.slice(0, 2e5) + "\n[output truncated at 200KB]",
13306
13306
  durationMs: 0
@@ -13402,9 +13402,9 @@ print("${sentinel}")
13402
13402
  if (!this.proc || this.proc.killed) {
13403
13403
  return { success: false, path: "" };
13404
13404
  }
13405
- const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = await import("node:fs");
13405
+ const { mkdirSync: mkdirSync26, writeFileSync: writeFileSync25 } = await import("node:fs");
13406
13406
  const sessionDir = join22(this.cwd, ".oa", "rlm");
13407
- mkdirSync25(sessionDir, { recursive: true });
13407
+ mkdirSync26(sessionDir, { recursive: true });
13408
13408
  const sessionPath = join22(sessionDir, "session.json");
13409
13409
  try {
13410
13410
  const inspectCode = `
@@ -13428,7 +13428,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
13428
13428
  trajectoryCount: this.trajectory.length,
13429
13429
  subCallCount: this.subCallCount
13430
13430
  };
13431
- writeFileSync24(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
13431
+ writeFileSync25(sessionPath, JSON.stringify(sessionData, null, 2), "utf8");
13432
13432
  return { success: true, path: sessionPath };
13433
13433
  }
13434
13434
  } catch {
@@ -13440,11 +13440,11 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
13440
13440
  * what was previously computed. */
13441
13441
  async loadSessionInfo() {
13442
13442
  try {
13443
- const { readFileSync: readFileSync39, existsSync: existsSync51 } = await import("node:fs");
13443
+ const { readFileSync: readFileSync40, existsSync: existsSync52 } = await import("node:fs");
13444
13444
  const sessionPath = join22(this.cwd, ".oa", "rlm", "session.json");
13445
- if (!existsSync51(sessionPath))
13445
+ if (!existsSync52(sessionPath))
13446
13446
  return null;
13447
- return JSON.parse(readFileSync39(sessionPath, "utf8"));
13447
+ return JSON.parse(readFileSync40(sessionPath, "utf8"));
13448
13448
  } catch {
13449
13449
  return null;
13450
13450
  }
@@ -13621,10 +13621,10 @@ var init_memory_metabolism = __esm({
13621
13621
  const trajDir = join23(this.cwd, ".oa", "rlm-trajectories");
13622
13622
  let lessons = [];
13623
13623
  try {
13624
- const { readdirSync: readdirSync20, readFileSync: readFileSync39 } = await import("node:fs");
13625
- const files = readdirSync20(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
13624
+ const { readdirSync: readdirSync21, readFileSync: readFileSync40 } = await import("node:fs");
13625
+ const files = readdirSync21(trajDir).filter((f) => f.endsWith(".jsonl")).sort().reverse().slice(0, 3);
13626
13626
  for (const file of files) {
13627
- const lines = readFileSync39(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
13627
+ const lines = readFileSync40(join23(trajDir, file), "utf8").split("\n").filter((l) => l.trim());
13628
13628
  for (const line of lines) {
13629
13629
  try {
13630
13630
  const entry = JSON.parse(line);
@@ -14008,14 +14008,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14008
14008
  * Optionally filter by task type for phase-aware context (FSM paper insight).
14009
14009
  */
14010
14010
  getTopMemoriesSync(k = 5, taskType) {
14011
- const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
14011
+ const { readFileSync: readFileSync40, existsSync: existsSync52 } = __require("node:fs");
14012
14012
  const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
14013
14013
  const storeFile = join23(metaDir, "store.json");
14014
- if (!existsSync51(storeFile))
14014
+ if (!existsSync52(storeFile))
14015
14015
  return "";
14016
14016
  let store = [];
14017
14017
  try {
14018
- store = JSON.parse(readFileSync39(storeFile, "utf8"));
14018
+ store = JSON.parse(readFileSync40(storeFile, "utf8"));
14019
14019
  } catch {
14020
14020
  return "";
14021
14021
  }
@@ -14037,14 +14037,14 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14037
14037
  /** Update memory scores based on task outcome. Called after task completion.
14038
14038
  * Memories used in successful tasks get boosted. Memories present during failures get decayed. */
14039
14039
  updateFromOutcomeSync(surfacedMemoryText, succeeded) {
14040
- const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
14040
+ const { readFileSync: readFileSync40, writeFileSync: writeFileSync25, existsSync: existsSync52, mkdirSync: mkdirSync26 } = __require("node:fs");
14041
14041
  const metaDir = join23(this.cwd, ".oa", "memory", "metabolism");
14042
14042
  const storeFile = join23(metaDir, "store.json");
14043
- if (!existsSync51(storeFile))
14043
+ if (!existsSync52(storeFile))
14044
14044
  return;
14045
14045
  let store = [];
14046
14046
  try {
14047
- store = JSON.parse(readFileSync39(storeFile, "utf8"));
14047
+ store = JSON.parse(readFileSync40(storeFile, "utf8"));
14048
14048
  } catch {
14049
14049
  return;
14050
14050
  }
@@ -14068,8 +14068,8 @@ ${issues.map((i) => ` - ${i}`).join("\n")}` : " No issues found."),
14068
14068
  updated = true;
14069
14069
  }
14070
14070
  if (updated) {
14071
- mkdirSync25(metaDir, { recursive: true });
14072
- writeFileSync24(storeFile, JSON.stringify(store, null, 2));
14071
+ mkdirSync26(metaDir, { recursive: true });
14072
+ writeFileSync25(storeFile, JSON.stringify(store, null, 2));
14073
14073
  }
14074
14074
  }
14075
14075
  // ── Storage ──────────────────────────────────────────────────────────
@@ -14491,13 +14491,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14491
14491
  // Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
14492
14492
  /** Retrieve top-K strategies for context injection. Returns "" if none. */
14493
14493
  getRelevantStrategiesSync(k = 3, taskType) {
14494
- const { readFileSync: readFileSync39, existsSync: existsSync51 } = __require("node:fs");
14494
+ const { readFileSync: readFileSync40, existsSync: existsSync52 } = __require("node:fs");
14495
14495
  const archiveFile = join25(this.cwd, ".oa", "arche", "variants.json");
14496
- if (!existsSync51(archiveFile))
14496
+ if (!existsSync52(archiveFile))
14497
14497
  return "";
14498
14498
  let variants = [];
14499
14499
  try {
14500
- variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
14500
+ variants = JSON.parse(readFileSync40(archiveFile, "utf8"));
14501
14501
  } catch {
14502
14502
  return "";
14503
14503
  }
@@ -14515,13 +14515,13 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14515
14515
  }
14516
14516
  /** Archive a strategy variant synchronously (for task completion path) */
14517
14517
  archiveVariantSync(strategy, outcome, tags = []) {
14518
- const { readFileSync: readFileSync39, writeFileSync: writeFileSync24, existsSync: existsSync51, mkdirSync: mkdirSync25 } = __require("node:fs");
14518
+ const { readFileSync: readFileSync40, writeFileSync: writeFileSync25, existsSync: existsSync52, mkdirSync: mkdirSync26 } = __require("node:fs");
14519
14519
  const dir = join25(this.cwd, ".oa", "arche");
14520
14520
  const archiveFile = join25(dir, "variants.json");
14521
14521
  let variants = [];
14522
14522
  try {
14523
- if (existsSync51(archiveFile))
14524
- variants = JSON.parse(readFileSync39(archiveFile, "utf8"));
14523
+ if (existsSync52(archiveFile))
14524
+ variants = JSON.parse(readFileSync40(archiveFile, "utf8"));
14525
14525
  } catch {
14526
14526
  }
14527
14527
  variants.push({
@@ -14536,8 +14536,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
14536
14536
  });
14537
14537
  if (variants.length > 50)
14538
14538
  variants = variants.slice(-50);
14539
- mkdirSync25(dir, { recursive: true });
14540
- writeFileSync24(archiveFile, JSON.stringify(variants, null, 2));
14539
+ mkdirSync26(dir, { recursive: true });
14540
+ writeFileSync25(archiveFile, JSON.stringify(variants, null, 2));
14541
14541
  }
14542
14542
  async saveArchive(variants) {
14543
14543
  const dir = join25(this.cwd, ".oa", "arche");
@@ -21684,7 +21684,7 @@ import { spawn as spawn14 } from "node:child_process";
21684
21684
  async function runShell(options) {
21685
21685
  const { command, args = [], cwd: cwd4, env, timeoutMs = DEFAULT_TIMEOUT_MS } = options;
21686
21686
  const mergedEnv = env ? { ...process.env, ...env } : process.env;
21687
- return new Promise((resolve34) => {
21687
+ return new Promise((resolve35) => {
21688
21688
  const start = Date.now();
21689
21689
  let timedOut = false;
21690
21690
  const child = spawn14(command, args, {
@@ -21708,7 +21708,7 @@ async function runShell(options) {
21708
21708
  clearTimeout(timer);
21709
21709
  const durationMs = Date.now() - start;
21710
21710
  const exitCode = timedOut ? -1 : code ?? -1;
21711
- resolve34({
21711
+ resolve35({
21712
21712
  stdout,
21713
21713
  stderr,
21714
21714
  exitCode,
@@ -21720,7 +21720,7 @@ async function runShell(options) {
21720
21720
  child.on("error", (err) => {
21721
21721
  clearTimeout(timer);
21722
21722
  const durationMs = Date.now() - start;
21723
- resolve34({
21723
+ resolve35({
21724
21724
  stdout,
21725
21725
  stderr: stderr + err.message,
21726
21726
  exitCode: -1,
@@ -21835,7 +21835,7 @@ async function applyUnifiedDiff(patch) {
21835
21835
  }
21836
21836
  function runWithStdin(options) {
21837
21837
  const { command, args, cwd: cwd4, stdin } = options;
21838
- return new Promise((resolve34) => {
21838
+ return new Promise((resolve35) => {
21839
21839
  const child = spawn15(command, args, {
21840
21840
  cwd: cwd4,
21841
21841
  stdio: ["pipe", "pipe", "pipe"]
@@ -21852,10 +21852,10 @@ function runWithStdin(options) {
21852
21852
  child.stdin.end();
21853
21853
  child.on("close", (code) => {
21854
21854
  const exitCode = code ?? -1;
21855
- resolve34({ success: exitCode === 0, exitCode, stdout, stderr });
21855
+ resolve35({ success: exitCode === 0, exitCode, stdout, stderr });
21856
21856
  });
21857
21857
  child.on("error", (err) => {
21858
- resolve34({ success: false, exitCode: -1, stdout, stderr: err.message });
21858
+ resolve35({ success: false, exitCode: -1, stdout, stderr: err.message });
21859
21859
  });
21860
21860
  });
21861
21861
  }
@@ -25597,8 +25597,8 @@ ${this.options.dynamicContext}`,
25597
25597
  async waitIfPaused() {
25598
25598
  if (!this._paused)
25599
25599
  return true;
25600
- await new Promise((resolve34) => {
25601
- this._pauseResolve = resolve34;
25600
+ await new Promise((resolve35) => {
25601
+ this._pauseResolve = resolve35;
25602
25602
  });
25603
25603
  return !this.aborted;
25604
25604
  }
@@ -26699,14 +26699,14 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
26699
26699
  waitForSudoPassword(timeoutMs = 12e4) {
26700
26700
  if (this._sudoPassword)
26701
26701
  return Promise.resolve(this._sudoPassword);
26702
- return new Promise((resolve34) => {
26702
+ return new Promise((resolve35) => {
26703
26703
  const timer = setTimeout(() => {
26704
26704
  this._sudoResolve = null;
26705
- resolve34(null);
26705
+ resolve35(null);
26706
26706
  }, timeoutMs);
26707
26707
  this._sudoResolve = (pw) => {
26708
26708
  clearTimeout(timer);
26709
- resolve34(pw);
26709
+ resolve35(pw);
26710
26710
  };
26711
26711
  });
26712
26712
  }
@@ -26839,10 +26839,10 @@ ${marker}` : marker);
26839
26839
  if (!this._workingDirectory)
26840
26840
  return;
26841
26841
  try {
26842
- const { mkdirSync: mkdirSync25, writeFileSync: writeFileSync24 } = __require("node:fs");
26843
- const { join: join71 } = __require("node:path");
26844
- const sessionDir = join71(this._workingDirectory, ".oa", "session", this._sessionId);
26845
- mkdirSync25(sessionDir, { recursive: true });
26842
+ const { mkdirSync: mkdirSync26, writeFileSync: writeFileSync25 } = __require("node:fs");
26843
+ const { join: join72 } = __require("node:path");
26844
+ const sessionDir = join72(this._workingDirectory, ".oa", "session", this._sessionId);
26845
+ mkdirSync26(sessionDir, { recursive: true });
26846
26846
  const checkpoint = {
26847
26847
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
26848
26848
  sessionId: this._sessionId,
@@ -26854,7 +26854,7 @@ ${marker}` : marker);
26854
26854
  memexEntryCount: this._memexArchive.size,
26855
26855
  fileRegistrySize: this._fileRegistry.size
26856
26856
  };
26857
- writeFileSync24(join71(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
26857
+ writeFileSync25(join72(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
26858
26858
  } catch {
26859
26859
  }
26860
26860
  }
@@ -28430,12 +28430,12 @@ var init_nexusBackend = __esm({
28430
28430
  const deadline = Date.now() + (request.timeoutMs ?? 12e4);
28431
28431
  try {
28432
28432
  while (!done && Date.now() < deadline) {
28433
- await new Promise((resolve34) => {
28433
+ await new Promise((resolve35) => {
28434
28434
  let resolved = false;
28435
28435
  const finish = () => {
28436
28436
  if (!resolved) {
28437
28437
  resolved = true;
28438
- resolve34();
28438
+ resolve35();
28439
28439
  }
28440
28440
  };
28441
28441
  let watcher = null;
@@ -29517,9 +29517,9 @@ function ensureTranscribeCliBackground() {
29517
29517
  }
29518
29518
  try {
29519
29519
  const { exec: exec4 } = await import("node:child_process");
29520
- return new Promise((resolve34) => {
29520
+ return new Promise((resolve35) => {
29521
29521
  exec4("npm i -g transcribe-cli", { timeout: 18e4 }, (err) => {
29522
- resolve34(!err);
29522
+ resolve35(!err);
29523
29523
  });
29524
29524
  });
29525
29525
  } catch {
@@ -29578,7 +29578,7 @@ var init_listen = __esm({
29578
29578
  return this._ready;
29579
29579
  }
29580
29580
  async start() {
29581
- return new Promise((resolve34, reject) => {
29581
+ return new Promise((resolve35, reject) => {
29582
29582
  const timeout = setTimeout(() => {
29583
29583
  reject(new Error("Whisper fallback: model load timeout (5 min). First run downloads the model."));
29584
29584
  }, 3e5);
@@ -29606,7 +29606,7 @@ var init_listen = __esm({
29606
29606
  this._ready = true;
29607
29607
  clearTimeout(timeout);
29608
29608
  this.emit("ready");
29609
- resolve34();
29609
+ resolve35();
29610
29610
  break;
29611
29611
  case "transcript":
29612
29612
  this.emit("transcript", {
@@ -29744,8 +29744,8 @@ var init_listen = __esm({
29744
29744
  const nvmBase = join48(homedir10(), ".nvm", "versions", "node");
29745
29745
  if (existsSync32(nvmBase)) {
29746
29746
  try {
29747
- const { readdirSync: readdirSync20 } = await import("node:fs");
29748
- for (const ver of readdirSync20(nvmBase)) {
29747
+ const { readdirSync: readdirSync21 } = await import("node:fs");
29748
+ for (const ver of readdirSync21(nvmBase)) {
29749
29749
  const tcPath = join48(nvmBase, ver, "lib", "node_modules", "transcribe-cli");
29750
29750
  if (existsSync32(join48(tcPath, "dist", "index.js"))) {
29751
29751
  const { createRequire: createRequire4 } = await import("node:module");
@@ -29810,11 +29810,11 @@ var init_listen = __esm({
29810
29810
  this.liveTranscriber.on("error", (err) => {
29811
29811
  this.emit("error", err);
29812
29812
  });
29813
- await new Promise((resolve34, reject) => {
29813
+ await new Promise((resolve35, reject) => {
29814
29814
  const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
29815
29815
  this.liveTranscriber.on("ready", () => {
29816
29816
  clearTimeout(timeout);
29817
- resolve34();
29817
+ resolve35();
29818
29818
  });
29819
29819
  this.liveTranscriber.on("error", (err) => {
29820
29820
  clearTimeout(timeout);
@@ -29976,11 +29976,11 @@ transcribe-cli error: ${transcribeCliError}` : "";
29976
29976
  sampleWidth: 2,
29977
29977
  chunkDuration: 3
29978
29978
  });
29979
- await new Promise((resolve34, reject) => {
29979
+ await new Promise((resolve35, reject) => {
29980
29980
  const timeout = setTimeout(() => reject(new Error("Model load timeout (60s)")), 6e4);
29981
29981
  transcriber.on("ready", () => {
29982
29982
  clearTimeout(timeout);
29983
- resolve34();
29983
+ resolve35();
29984
29984
  });
29985
29985
  transcriber.on("error", (err) => {
29986
29986
  clearTimeout(timeout);
@@ -32283,7 +32283,7 @@ var require_websocket = __commonJS({
32283
32283
  var http = __require("http");
32284
32284
  var net = __require("net");
32285
32285
  var tls = __require("tls");
32286
- var { randomBytes: randomBytes15, createHash: createHash6 } = __require("crypto");
32286
+ var { randomBytes: randomBytes16, createHash: createHash6 } = __require("crypto");
32287
32287
  var { Duplex, Readable } = __require("stream");
32288
32288
  var { URL: URL3 } = __require("url");
32289
32289
  var PerMessageDeflate = require_permessage_deflate();
@@ -32813,7 +32813,7 @@ var require_websocket = __commonJS({
32813
32813
  }
32814
32814
  }
32815
32815
  const defaultPort = isSecure ? 443 : 80;
32816
- const key = randomBytes15(16).toString("base64");
32816
+ const key = randomBytes16(16).toString("base64");
32817
32817
  const request = isSecure ? https.request : http.request;
32818
32818
  const protocolSet = /* @__PURE__ */ new Set();
32819
32819
  let perMessageDeflate;
@@ -34953,8 +34953,8 @@ var init_voice_session = __esm({
34953
34953
  this.server.keepAliveTimeout = 0;
34954
34954
  this.wss = new import_websocket_server.default({ server: this.server, path: "/ws" });
34955
34955
  this.wss.on("connection", (ws, req) => this.handleWSConnection(ws, req));
34956
- await new Promise((resolve34, reject) => {
34957
- this.server.listen(port, "127.0.0.1", () => resolve34());
34956
+ await new Promise((resolve35, reject) => {
34957
+ this.server.listen(port, "127.0.0.1", () => resolve35());
34958
34958
  this.server.on("error", reject);
34959
34959
  });
34960
34960
  try {
@@ -35172,7 +35172,7 @@ var init_voice_session = __esm({
35172
35172
  }
35173
35173
  // ── Cloudflared tunnel ────────────────────────────────────────────────
35174
35174
  startCloudflared(port) {
35175
- return new Promise((resolve34, reject) => {
35175
+ return new Promise((resolve35, reject) => {
35176
35176
  const timeout = setTimeout(() => {
35177
35177
  reject(new Error("Cloudflared tunnel start timeout (30s)"));
35178
35178
  }, 3e4);
@@ -35190,7 +35190,7 @@ var init_voice_session = __esm({
35190
35190
  if (urlMatch && !urlFound) {
35191
35191
  urlFound = true;
35192
35192
  clearTimeout(timeout);
35193
- resolve34(urlMatch[0]);
35193
+ resolve35(urlMatch[0]);
35194
35194
  }
35195
35195
  };
35196
35196
  this.cloudflaredProcess.stdout?.on("data", handleOutput);
@@ -35230,13 +35230,13 @@ var init_voice_session = __esm({
35230
35230
  }
35231
35231
  // ── Helpers ───────────────────────────────────────────────────────────
35232
35232
  findFreePort() {
35233
- return new Promise((resolve34, reject) => {
35233
+ return new Promise((resolve35, reject) => {
35234
35234
  const srv = createServer2();
35235
35235
  srv.listen(0, "127.0.0.1", () => {
35236
35236
  const addr = srv.address();
35237
35237
  if (addr && typeof addr === "object") {
35238
35238
  const port = addr.port;
35239
- srv.close(() => resolve34(port));
35239
+ srv.close(() => resolve35(port));
35240
35240
  } else {
35241
35241
  srv.close(() => reject(new Error("Could not find free port")));
35242
35242
  }
@@ -35359,8 +35359,8 @@ async function collectSystemMetricsAsync() {
35359
35359
  vramUtilization: 0
35360
35360
  };
35361
35361
  try {
35362
- const smi = await new Promise((resolve34, reject) => {
35363
- exec("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve34(stdout));
35362
+ const smi = await new Promise((resolve35, reject) => {
35363
+ exec("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve35(stdout));
35364
35364
  });
35365
35365
  const line = smi.trim().split("\n")[0];
35366
35366
  if (line) {
@@ -35508,8 +35508,8 @@ var init_expose = __esm({
35508
35508
  throw new Error("Gateway already running");
35509
35509
  const port = await this.findFreePort();
35510
35510
  this.server = this.createProxyServer(port);
35511
- await new Promise((resolve34, reject) => {
35512
- this.server.listen(port, "127.0.0.1", () => resolve34());
35511
+ await new Promise((resolve35, reject) => {
35512
+ this.server.listen(port, "127.0.0.1", () => resolve35());
35513
35513
  this.server.on("error", reject);
35514
35514
  });
35515
35515
  let lastStartErr;
@@ -35571,8 +35571,8 @@ var init_expose = __esm({
35571
35571
  this._cloudflaredPid = state.pid;
35572
35572
  this._proxyPort = state.proxyPort;
35573
35573
  this.server = this.createProxyServer(state.proxyPort);
35574
- await new Promise((resolve34, reject) => {
35575
- this.server.listen(state.proxyPort, "127.0.0.1", () => resolve34());
35574
+ await new Promise((resolve35, reject) => {
35575
+ this.server.listen(state.proxyPort, "127.0.0.1", () => resolve35());
35576
35576
  this.server.on("error", reject);
35577
35577
  });
35578
35578
  this._stats.status = "active";
@@ -35597,8 +35597,8 @@ var init_expose = __esm({
35597
35597
  }
35598
35598
  this._cloudflaredPid = null;
35599
35599
  if (this.server) {
35600
- await new Promise((resolve34) => {
35601
- this.server.close(() => resolve34());
35600
+ await new Promise((resolve35) => {
35601
+ this.server.close(() => resolve35());
35602
35602
  });
35603
35603
  this.server = null;
35604
35604
  }
@@ -35930,7 +35930,7 @@ var init_expose = __esm({
35930
35930
  _proxyPort = 0;
35931
35931
  startCloudflared(port) {
35932
35932
  this._proxyPort = port;
35933
- return new Promise((resolve34, reject) => {
35933
+ return new Promise((resolve35, reject) => {
35934
35934
  const timeout = setTimeout(() => {
35935
35935
  reject(new Error("Cloudflared tunnel start timeout (30s)"));
35936
35936
  }, 3e4);
@@ -35959,7 +35959,7 @@ var init_expose = __esm({
35959
35959
  this.cloudflaredProcess?.unref();
35960
35960
  this.cloudflaredProcess?.stdout?.destroy();
35961
35961
  this.cloudflaredProcess?.stderr?.destroy();
35962
- resolve34(urlMatch[0]);
35962
+ resolve35(urlMatch[0]);
35963
35963
  }
35964
35964
  };
35965
35965
  this.cloudflaredProcess.stdout?.on("data", handleOutput);
@@ -36048,13 +36048,13 @@ ${this.formatConnectionInfo()}`);
36048
36048
  }
36049
36049
  // ── Helpers ─────────────────────────────────────────────────────────────
36050
36050
  findFreePort() {
36051
- return new Promise((resolve34, reject) => {
36051
+ return new Promise((resolve35, reject) => {
36052
36052
  const srv = createServer3();
36053
36053
  srv.listen(0, "127.0.0.1", () => {
36054
36054
  const addr = srv.address();
36055
36055
  if (addr && typeof addr === "object") {
36056
36056
  const port = addr.port;
36057
- srv.close(() => resolve34(port));
36057
+ srv.close(() => resolve35(port));
36058
36058
  } else {
36059
36059
  srv.close(() => reject(new Error("Could not find free port")));
36060
36060
  }
@@ -37001,8 +37001,8 @@ var init_peer_mesh = __esm({
37001
37001
  this.wss.on("connection", (ws, req) => {
37002
37002
  this.handleInboundConnection(ws, req.url ?? "");
37003
37003
  });
37004
- await new Promise((resolve34, reject) => {
37005
- this.server.listen(port, "127.0.0.1", () => resolve34());
37004
+ await new Promise((resolve35, reject) => {
37005
+ this.server.listen(port, "127.0.0.1", () => resolve35());
37006
37006
  this.server.on("error", reject);
37007
37007
  });
37008
37008
  this.pingTimer = setInterval(() => this.pingAll(), PING_INTERVAL_MS);
@@ -37041,7 +37041,7 @@ var init_peer_mesh = __esm({
37041
37041
  this.wss = null;
37042
37042
  }
37043
37043
  if (this.server) {
37044
- await new Promise((resolve34) => this.server.close(() => resolve34()));
37044
+ await new Promise((resolve35) => this.server.close(() => resolve35()));
37045
37045
  this.server = null;
37046
37046
  }
37047
37047
  this.emit("stopped");
@@ -37059,7 +37059,7 @@ var init_peer_mesh = __esm({
37059
37059
  if (!wsUrl.includes("/p2p"))
37060
37060
  wsUrl += "/p2p";
37061
37061
  wsUrl += `?key=${encodeURIComponent(this._authKey)}`;
37062
- return new Promise((resolve34, reject) => {
37062
+ return new Promise((resolve35, reject) => {
37063
37063
  const ws = new import_websocket.default(wsUrl, { handshakeTimeout: 1e4 });
37064
37064
  let resolved = false;
37065
37065
  const timeout = setTimeout(() => {
@@ -37099,7 +37099,7 @@ var init_peer_mesh = __esm({
37099
37099
  this.connections.set(peer.peerId, ws);
37100
37100
  this.setupPeerHandlers(ws, peer.peerId);
37101
37101
  this.emit("peer_connected", peer);
37102
- resolve34(peer);
37102
+ resolve35(peer);
37103
37103
  } else {
37104
37104
  this.handleMessage(msg, ws);
37105
37105
  }
@@ -37154,12 +37154,12 @@ var init_peer_mesh = __esm({
37154
37154
  throw new Error(`Peer ${peerId} not connected`);
37155
37155
  }
37156
37156
  const msgId = randomBytes14(8).toString("hex");
37157
- return new Promise((resolve34, reject) => {
37157
+ return new Promise((resolve35, reject) => {
37158
37158
  const timeout = setTimeout(() => {
37159
37159
  this.pendingRequests.delete(msgId);
37160
37160
  reject(new Error(`Inference timeout (${timeoutMs}ms)`));
37161
37161
  }, timeoutMs);
37162
- this.pendingRequests.set(msgId, { resolve: resolve34, reject, timeout, chunks: [] });
37162
+ this.pendingRequests.set(msgId, { resolve: resolve35, reject, timeout, chunks: [] });
37163
37163
  this.sendMsg(ws, "infer_request", request, msgId);
37164
37164
  });
37165
37165
  }
@@ -37381,13 +37381,13 @@ var init_peer_mesh = __esm({
37381
37381
  ws.send(JSON.stringify(msg));
37382
37382
  }
37383
37383
  findFreePort() {
37384
- return new Promise((resolve34, reject) => {
37384
+ return new Promise((resolve35, reject) => {
37385
37385
  const srv = createServer4();
37386
37386
  srv.listen(0, "127.0.0.1", () => {
37387
37387
  const addr = srv.address();
37388
37388
  if (addr && typeof addr === "object") {
37389
37389
  const port = addr.port;
37390
- srv.close(() => resolve34(port));
37390
+ srv.close(() => resolve35(port));
37391
37391
  } else {
37392
37392
  srv.close(() => reject(new Error("Could not find free port")));
37393
37393
  }
@@ -38017,26 +38017,26 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
38017
38017
  async function fetchPeerModels(peerId, authKey) {
38018
38018
  try {
38019
38019
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist2(), dist_exports));
38020
- const { existsSync: existsSync51, readFileSync: readFileSync39 } = await import("node:fs");
38021
- const { join: join71 } = await import("node:path");
38020
+ const { existsSync: existsSync52, readFileSync: readFileSync40 } = await import("node:fs");
38021
+ const { join: join72 } = await import("node:path");
38022
38022
  const cwd4 = process.cwd();
38023
38023
  const nexusTool = new NexusTool2(cwd4);
38024
38024
  const nexusDir = nexusTool.getNexusDir();
38025
38025
  let isLocalPeer = false;
38026
38026
  try {
38027
- const statusPath = join71(nexusDir, "status.json");
38028
- if (existsSync51(statusPath)) {
38029
- const status = JSON.parse(readFileSync39(statusPath, "utf8"));
38027
+ const statusPath = join72(nexusDir, "status.json");
38028
+ if (existsSync52(statusPath)) {
38029
+ const status = JSON.parse(readFileSync40(statusPath, "utf8"));
38030
38030
  if (status.peerId === peerId)
38031
38031
  isLocalPeer = true;
38032
38032
  }
38033
38033
  } catch {
38034
38034
  }
38035
38035
  if (isLocalPeer) {
38036
- const pricingPath = join71(nexusDir, "pricing.json");
38037
- if (existsSync51(pricingPath)) {
38036
+ const pricingPath = join72(nexusDir, "pricing.json");
38037
+ if (existsSync52(pricingPath)) {
38038
38038
  try {
38039
- const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
38039
+ const pricing = JSON.parse(readFileSync40(pricingPath, "utf8"));
38040
38040
  const localModels = (pricing.models || []).map((m) => ({
38041
38041
  name: m.model || "unknown",
38042
38042
  size: m.parameterSize || "",
@@ -38050,10 +38050,10 @@ async function fetchPeerModels(peerId, authKey) {
38050
38050
  }
38051
38051
  }
38052
38052
  }
38053
- const cachePath = join71(nexusDir, "peer-models-cache.json");
38054
- if (existsSync51(cachePath)) {
38053
+ const cachePath = join72(nexusDir, "peer-models-cache.json");
38054
+ if (existsSync52(cachePath)) {
38055
38055
  try {
38056
- const cache4 = JSON.parse(readFileSync39(cachePath, "utf8"));
38056
+ const cache4 = JSON.parse(readFileSync40(cachePath, "utf8"));
38057
38057
  if (cache4.peerId === peerId && cache4.models?.length > 0) {
38058
38058
  const age = Date.now() - new Date(cache4.cachedAt).getTime();
38059
38059
  if (age < 5 * 60 * 1e3) {
@@ -38168,10 +38168,10 @@ async function fetchPeerModels(peerId, authKey) {
38168
38168
  } catch {
38169
38169
  }
38170
38170
  if (isLocalPeer) {
38171
- const pricingPath = join71(nexusDir, "pricing.json");
38172
- if (existsSync51(pricingPath)) {
38171
+ const pricingPath = join72(nexusDir, "pricing.json");
38172
+ if (existsSync52(pricingPath)) {
38173
38173
  try {
38174
- const pricing = JSON.parse(readFileSync39(pricingPath, "utf8"));
38174
+ const pricing = JSON.parse(readFileSync40(pricingPath, "utf8"));
38175
38175
  return (pricing.models || []).map((m) => ({
38176
38176
  name: m.model || "unknown",
38177
38177
  size: m.parameterSize || "",
@@ -39313,12 +39313,12 @@ function calculateContextWindow(specs, modelSizeGB2, kvBytesPerToken, archMax) {
39313
39313
  return { numCtx, label };
39314
39314
  }
39315
39315
  function ask(rl, question) {
39316
- return new Promise((resolve34) => {
39317
- rl.question(question, (answer) => resolve34(answer.trim()));
39316
+ return new Promise((resolve35) => {
39317
+ rl.question(question, (answer) => resolve35(answer.trim()));
39318
39318
  });
39319
39319
  }
39320
39320
  function askSecret(rl, question) {
39321
- return new Promise((resolve34) => {
39321
+ return new Promise((resolve35) => {
39322
39322
  process.stdout.write(question);
39323
39323
  let secret = "";
39324
39324
  const stdin = process.stdin;
@@ -39336,7 +39336,7 @@ function askSecret(rl, question) {
39336
39336
  stdin.setRawMode(hadRawMode ?? false);
39337
39337
  }
39338
39338
  process.stdout.write("\n");
39339
- resolve34(secret.trim());
39339
+ resolve35(secret.trim());
39340
39340
  return;
39341
39341
  } else if (c3 === "") {
39342
39342
  stdin.removeListener("data", onData);
@@ -39344,7 +39344,7 @@ function askSecret(rl, question) {
39344
39344
  stdin.setRawMode(hadRawMode ?? false);
39345
39345
  }
39346
39346
  process.stdout.write("\n");
39347
- resolve34("");
39347
+ resolve35("");
39348
39348
  return;
39349
39349
  } else if (c3 === "\x7F" || c3 === "\b") {
39350
39350
  if (secret.length > 0) {
@@ -39579,7 +39579,7 @@ async function ensureOllamaRunning(backendUrl, rl) {
39579
39579
  return false;
39580
39580
  }
39581
39581
  for (let i = 0; i < 5; i++) {
39582
- await new Promise((resolve34) => setTimeout(resolve34, 2e3));
39582
+ await new Promise((resolve35) => setTimeout(resolve35, 2e3));
39583
39583
  try {
39584
39584
  const resp = await fetch(`${backendUrl}/api/tags`, {
39585
39585
  signal: AbortSignal.timeout(3e3)
@@ -40040,7 +40040,7 @@ async function doSetup(config, rl) {
40040
40040
  try {
40041
40041
  const child = spawn19("ollama", ["serve"], { stdio: "ignore", detached: true });
40042
40042
  child.unref();
40043
- await new Promise((resolve34) => setTimeout(resolve34, 3e3));
40043
+ await new Promise((resolve35) => setTimeout(resolve35, 3e3));
40044
40044
  try {
40045
40045
  models = await fetchOllamaModels(config.backendUrl);
40046
40046
  process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
@@ -40068,7 +40068,7 @@ async function doSetup(config, rl) {
40068
40068
  try {
40069
40069
  const child = spawn19("ollama", ["serve"], { stdio: "ignore", detached: true });
40070
40070
  child.unref();
40071
- await new Promise((resolve34) => setTimeout(resolve34, 3e3));
40071
+ await new Promise((resolve35) => setTimeout(resolve35, 3e3));
40072
40072
  try {
40073
40073
  models = await fetchOllamaModels(config.backendUrl);
40074
40074
  process.stdout.write(` ${c2.green("\u2714")} Ollama is running.
@@ -41057,7 +41057,7 @@ function tuiSelect(opts) {
41057
41057
  const maxVisible = opts.maxVisible ?? Math.max(3, contentArea - selectChrome);
41058
41058
  let scrollOffset = 0;
41059
41059
  let lastRenderedLines = 0;
41060
- return new Promise((resolve34) => {
41060
+ return new Promise((resolve35) => {
41061
41061
  const stdin = process.stdin;
41062
41062
  const hadRawMode = stdin.isRaw;
41063
41063
  const savedRlListeners = [];
@@ -41232,7 +41232,7 @@ function tuiSelect(opts) {
41232
41232
  if (!isSkippable(itemIdx) && matchSet.has(itemIdx)) {
41233
41233
  cursor = itemIdx;
41234
41234
  cleanup();
41235
- resolve34({ confirmed: true, key: items[cursor].key, index: cursor });
41235
+ resolve35({ confirmed: true, key: items[cursor].key, index: cursor });
41236
41236
  return;
41237
41237
  } else if (!isSkippable(itemIdx)) {
41238
41238
  cursor = itemIdx;
@@ -41308,7 +41308,7 @@ function tuiSelect(opts) {
41308
41308
  items.splice(deletedIdx, 1);
41309
41309
  if (items.length === 0) {
41310
41310
  cleanup();
41311
- resolve34({ confirmed: false, key: null, index: -1 });
41311
+ resolve35({ confirmed: false, key: null, index: -1 });
41312
41312
  return;
41313
41313
  }
41314
41314
  updateFilter();
@@ -41397,7 +41397,7 @@ function tuiSelect(opts) {
41397
41397
  } else if (seq === "\r" || seq === "\n") {
41398
41398
  if (!isSkippable(cursor) && matchSet.has(cursor)) {
41399
41399
  cleanup();
41400
- resolve34({ confirmed: true, key: items[cursor].key, index: cursor });
41400
+ resolve35({ confirmed: true, key: items[cursor].key, index: cursor });
41401
41401
  }
41402
41402
  } else if (seq === "\x1B" || seq === "\x1B\x1B") {
41403
41403
  if (filter) {
@@ -41410,14 +41410,14 @@ function tuiSelect(opts) {
41410
41410
  render();
41411
41411
  } else if (hasBreadcrumbs) {
41412
41412
  cleanup();
41413
- resolve34({ confirmed: false, key: "__back__", index: cursor });
41413
+ resolve35({ confirmed: false, key: "__back__", index: cursor });
41414
41414
  } else {
41415
41415
  cleanup();
41416
- resolve34({ confirmed: false, key: null, index: cursor });
41416
+ resolve35({ confirmed: false, key: null, index: cursor });
41417
41417
  }
41418
41418
  } else if (seq === "") {
41419
41419
  cleanup();
41420
- resolve34({ confirmed: false, key: null, index: cursor });
41420
+ resolve35({ confirmed: false, key: null, index: cursor });
41421
41421
  } else if (seq === "\x7F" || seq === "\b") {
41422
41422
  if (filter.length > 0) {
41423
41423
  filter = filter.slice(0, -1);
@@ -41431,7 +41431,7 @@ function tuiSelect(opts) {
41431
41431
  render();
41432
41432
  } else if (hasBreadcrumbs) {
41433
41433
  cleanup();
41434
- resolve34({ confirmed: false, key: "__back__", index: cursor });
41434
+ resolve35({ confirmed: false, key: "__back__", index: cursor });
41435
41435
  }
41436
41436
  } else if (seq.length === 1 && seq.charCodeAt(0) >= 32 && seq.charCodeAt(0) < 127) {
41437
41437
  if (opts.onCustomKey && !isSkippable(cursor) && matchSet.has(cursor)) {
@@ -41439,7 +41439,7 @@ function tuiSelect(opts) {
41439
41439
  done: () => render(),
41440
41440
  resolve: (result) => {
41441
41441
  cleanup();
41442
- resolve34(result);
41442
+ resolve35(result);
41443
41443
  },
41444
41444
  getInput: (prompt, prefill) => getInputFromUser(prompt, prefill),
41445
41445
  render: () => render(),
@@ -41981,12 +41981,12 @@ function stopNeovimMode() {
41981
41981
  } catch {
41982
41982
  }
41983
41983
  const s = _state;
41984
- return new Promise((resolve34) => {
41984
+ return new Promise((resolve35) => {
41985
41985
  setTimeout(() => {
41986
41986
  if (s && !s.cleanedUp) {
41987
41987
  doCleanup(s);
41988
41988
  }
41989
- resolve34();
41989
+ resolve35();
41990
41990
  }, 300);
41991
41991
  });
41992
41992
  }
@@ -43657,7 +43657,7 @@ var init_voice = __esm({
43657
43657
  this.speaking = false;
43658
43658
  }
43659
43659
  sleep(ms) {
43660
- return new Promise((resolve34) => setTimeout(resolve34, ms));
43660
+ return new Promise((resolve35) => setTimeout(resolve35, ms));
43661
43661
  }
43662
43662
  // -------------------------------------------------------------------------
43663
43663
  // Synthesis pipeline
@@ -43923,7 +43923,7 @@ var init_voice = __esm({
43923
43923
  const cmd = this.getPlayCommand(path);
43924
43924
  if (!cmd)
43925
43925
  return;
43926
- return new Promise((resolve34) => {
43926
+ return new Promise((resolve35) => {
43927
43927
  const child = nodeSpawn(cmd[0], cmd.slice(1), {
43928
43928
  stdio: "ignore",
43929
43929
  detached: false
@@ -43932,12 +43932,12 @@ var init_voice = __esm({
43932
43932
  child.on("close", () => {
43933
43933
  if (this.currentPlayback === child)
43934
43934
  this.currentPlayback = null;
43935
- resolve34();
43935
+ resolve35();
43936
43936
  });
43937
43937
  child.on("error", () => {
43938
43938
  if (this.currentPlayback === child)
43939
43939
  this.currentPlayback = null;
43940
- resolve34();
43940
+ resolve35();
43941
43941
  });
43942
43942
  setTimeout(() => {
43943
43943
  if (this.currentPlayback === child) {
@@ -43947,7 +43947,7 @@ var init_voice = __esm({
43947
43947
  }
43948
43948
  this.currentPlayback = null;
43949
43949
  }
43950
- resolve34();
43950
+ resolve35();
43951
43951
  }, 15e3);
43952
43952
  });
43953
43953
  }
@@ -44022,7 +44022,7 @@ var init_voice = __esm({
44022
44022
  /** Non-blocking shell execution — async alternative to execSync.
44023
44023
  * Returns stdout string on exit 0, rejects otherwise. */
44024
44024
  asyncShell(command, timeoutMs = 3e4) {
44025
- return new Promise((resolve34, reject) => {
44025
+ return new Promise((resolve35, reject) => {
44026
44026
  const proc = nodeSpawn("sh", ["-c", command], {
44027
44027
  stdio: ["ignore", "pipe", "pipe"],
44028
44028
  cwd: tmpdir9()
@@ -44043,7 +44043,7 @@ var init_voice = __esm({
44043
44043
  proc.on("close", (code) => {
44044
44044
  clearTimeout(timer);
44045
44045
  if (code === 0)
44046
- resolve34(stdout.trim());
44046
+ resolve35(stdout.trim());
44047
44047
  else
44048
44048
  reject(new Error(stderr.slice(0, 300) || `Exit code ${code}`));
44049
44049
  });
@@ -44535,7 +44535,7 @@ if __name__ == '__main__':
44535
44535
  const venvPy = luxttsVenvPy();
44536
44536
  if (!existsSync40(venvPy))
44537
44537
  return false;
44538
- return new Promise((resolve34) => {
44538
+ return new Promise((resolve35) => {
44539
44539
  const env = { ...process.env, LUXTTS_REPO_PATH: luxttsRepoDir() };
44540
44540
  const daemon = nodeSpawn(venvPy, [luxttsInferScript()], {
44541
44541
  stdio: ["pipe", "pipe", "pipe"],
@@ -44554,7 +44554,7 @@ if __name__ == '__main__':
44554
44554
  try {
44555
44555
  const msg = JSON.parse(line);
44556
44556
  if (msg.type === "ready") {
44557
- resolve34(true);
44557
+ resolve35(true);
44558
44558
  } else if (msg.type === "result" || msg.type === "error") {
44559
44559
  const pending = this._luxttsPending.get(msg.id);
44560
44560
  if (pending) {
@@ -44578,25 +44578,25 @@ if __name__ == '__main__':
44578
44578
  });
44579
44579
  daemon.on("error", () => {
44580
44580
  this._luxttsDaemon = null;
44581
- resolve34(false);
44581
+ resolve35(false);
44582
44582
  });
44583
44583
  setTimeout(() => {
44584
44584
  if (this._luxttsDaemon === daemon && !this._luxttsPending.has("__ready__")) {
44585
- resolve34(false);
44585
+ resolve35(false);
44586
44586
  }
44587
44587
  }, 6e4);
44588
44588
  });
44589
44589
  }
44590
44590
  /** Send a request to the LuxTTS daemon and await the response */
44591
44591
  luxttsRequest(req) {
44592
- return new Promise((resolve34, reject) => {
44592
+ return new Promise((resolve35, reject) => {
44593
44593
  if (!this._luxttsDaemon || this._luxttsDaemon.killed) {
44594
44594
  reject(new Error("LuxTTS daemon not running"));
44595
44595
  return;
44596
44596
  }
44597
44597
  const id = `req_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
44598
44598
  req.id = id;
44599
- this._luxttsPending.set(id, { resolve: resolve34, reject });
44599
+ this._luxttsPending.set(id, { resolve: resolve35, reject });
44600
44600
  this._luxttsDaemon.stdin.write(JSON.stringify(req) + "\n");
44601
44601
  setTimeout(() => {
44602
44602
  if (this._luxttsPending.has(id)) {
@@ -45979,8 +45979,8 @@ async function handleSlashCommand(input, ctx) {
45979
45979
  writeFileSync18(jwtFile, JSON.stringify(jwtPayload, null, 2));
45980
45980
  renderInfo(`Launching fortemi-react from ${fDir}...`);
45981
45981
  try {
45982
- const { spawn: spawn21 } = __require("node:child_process");
45983
- const child = spawn21("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
45982
+ const { spawn: spawn22 } = __require("node:child_process");
45983
+ const child = spawn22("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
45984
45984
  cwd: join57(fDir, "apps", "standalone"),
45985
45985
  stdio: "ignore",
45986
45986
  detached: true,
@@ -47737,12 +47737,12 @@ async function handleVoiceMenu(ctx, save, hasLocal) {
47737
47737
  continue;
47738
47738
  }
47739
47739
  const { basename: basename18, join: pathJoin } = await import("node:path");
47740
- const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync25, existsSync: exists } = await import("node:fs");
47740
+ const { copyFileSync: copyFileSync2, mkdirSync: mkdirSync26, existsSync: exists } = await import("node:fs");
47741
47741
  const { homedir: homedir18 } = await import("node:os");
47742
47742
  const modelName = basename18(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
47743
47743
  const destDir = pathJoin(homedir18(), ".open-agents", "voice", "models", modelName);
47744
47744
  if (!exists(destDir))
47745
- mkdirSync25(destDir, { recursive: true });
47745
+ mkdirSync26(destDir, { recursive: true });
47746
47746
  copyFileSync2(onnxDrop.path, pathJoin(destDir, "model.onnx"));
47747
47747
  copyFileSync2(jsonDrop.path, pathJoin(destDir, "config.json"));
47748
47748
  const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
@@ -48234,11 +48234,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx, local) {
48234
48234
  const models = await fetchModels(peerUrl, authKey);
48235
48235
  if (models.length > 0) {
48236
48236
  try {
48237
- const { writeFileSync: writeFileSync24, mkdirSync: mkdirSync25 } = await import("node:fs");
48238
- const { join: join71, dirname: dirname22 } = await import("node:path");
48239
- const cachePath = join71(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
48240
- mkdirSync25(dirname22(cachePath), { recursive: true });
48241
- writeFileSync24(cachePath, JSON.stringify({
48237
+ const { writeFileSync: writeFileSync25, mkdirSync: mkdirSync26 } = await import("node:fs");
48238
+ const { join: join72, dirname: dirname22 } = await import("node:path");
48239
+ const cachePath = join72(ctx.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
48240
+ mkdirSync26(dirname22(cachePath), { recursive: true });
48241
+ writeFileSync25(cachePath, JSON.stringify({
48242
48242
  peerId,
48243
48243
  cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
48244
48244
  models: models.map((m) => ({ name: m.name, size: m.size, parameterSize: m.parameterSize }))
@@ -48389,8 +48389,8 @@ Environment="OLLAMA_NUM_PARALLEL=${n}"
48389
48389
  }
48390
48390
  await new Promise((r) => setTimeout(r, 1e3));
48391
48391
  process.env.OLLAMA_NUM_PARALLEL = String(n);
48392
- const { spawn: spawn21 } = await import("node:child_process");
48393
- const child = spawn21("ollama", ["serve"], {
48392
+ const { spawn: spawn22 } = await import("node:child_process");
48393
+ const child = spawn22("ollama", ["serve"], {
48394
48394
  stdio: "ignore",
48395
48395
  detached: true,
48396
48396
  env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n) }
@@ -48437,17 +48437,17 @@ async function handleUpdate(subcommand, ctx) {
48437
48437
  try {
48438
48438
  const { createRequire: createRequire4 } = await import("node:module");
48439
48439
  const { fileURLToPath: fileURLToPath14 } = await import("node:url");
48440
- const { dirname: dirname22, join: join71 } = await import("node:path");
48441
- const { existsSync: existsSync51 } = await import("node:fs");
48440
+ const { dirname: dirname22, join: join72 } = await import("node:path");
48441
+ const { existsSync: existsSync52 } = await import("node:fs");
48442
48442
  const req = createRequire4(import.meta.url);
48443
48443
  const thisDir = dirname22(fileURLToPath14(import.meta.url));
48444
48444
  const candidates = [
48445
- join71(thisDir, "..", "package.json"),
48446
- join71(thisDir, "..", "..", "package.json"),
48447
- join71(thisDir, "..", "..", "..", "package.json")
48445
+ join72(thisDir, "..", "package.json"),
48446
+ join72(thisDir, "..", "..", "package.json"),
48447
+ join72(thisDir, "..", "..", "..", "package.json")
48448
48448
  ];
48449
48449
  for (const pkgPath of candidates) {
48450
- if (existsSync51(pkgPath)) {
48450
+ if (existsSync52(pkgPath)) {
48451
48451
  const pkg = req(pkgPath);
48452
48452
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
48453
48453
  currentVersion = pkg.version ?? "0.0.0";
@@ -48641,11 +48641,11 @@ async function handleUpdate(subcommand, ctx) {
48641
48641
  const targetVersion = info?.latestVersion ?? currentVersion;
48642
48642
  const installOverlay = startInstallOverlay(targetVersion);
48643
48643
  let installError = "";
48644
- const runInstall2 = (cmd) => new Promise((resolve34) => {
48644
+ const runInstall2 = (cmd) => new Promise((resolve35) => {
48645
48645
  const child = exec4(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
48646
48646
  if (err)
48647
48647
  installError = (stderr || err.message || "").trim();
48648
- resolve34(!err);
48648
+ resolve35(!err);
48649
48649
  });
48650
48650
  child.stdout?.on("data", (chunk) => {
48651
48651
  const text = String(chunk);
@@ -48739,8 +48739,8 @@ async function handleUpdate(subcommand, ctx) {
48739
48739
  }
48740
48740
  if (doRebuild) {
48741
48741
  installOverlay.setStatus("Rebuilding native modules...");
48742
- await new Promise((resolve34) => {
48743
- const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve34(true));
48742
+ await new Promise((resolve35) => {
48743
+ const child = exec4(`${sudoPrefix}npm rebuild -g open-agents-ai 2>/dev/null || true`, { timeout: 12e4 }, () => resolve35(true));
48744
48744
  child.stdout?.resume();
48745
48745
  child.stderr?.resume();
48746
48746
  });
@@ -48772,8 +48772,8 @@ async function handleUpdate(subcommand, ctx) {
48772
48772
  const venvPip2 = isWin2 ? pathJoin(venvDir, "Scripts", "pip.exe") : pathJoin(venvDir, "bin", "pip");
48773
48773
  if (fsExists(venvPip2)) {
48774
48774
  installOverlay.setStatus("Upgrading Python packages...");
48775
- await new Promise((resolve34) => {
48776
- const child = exec4(`"${venvPip2}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve34(!err));
48775
+ await new Promise((resolve35) => {
48776
+ const child = exec4(`"${venvPip2}" install --upgrade moondream-station pytesseract Pillow opencv-python-headless numpy 2>/dev/null || true`, { timeout: 3e5 }, (err) => resolve35(!err));
48777
48777
  child.stdout?.resume();
48778
48778
  child.stderr?.resume();
48779
48779
  });
@@ -49169,16 +49169,16 @@ async function showExposeDashboard(gateway, rl, ctx) {
49169
49169
  renderDashboard();
49170
49170
  }, 1e3);
49171
49171
  let stopGateway = false;
49172
- await new Promise((resolve34) => {
49172
+ await new Promise((resolve35) => {
49173
49173
  const onData = (data) => {
49174
49174
  const key = data.toString();
49175
49175
  if (key === "q" || key === "Q" || key === "\x1B" || key === "") {
49176
- resolve34();
49176
+ resolve35();
49177
49177
  return;
49178
49178
  }
49179
49179
  if (key === "s" || key === "S") {
49180
49180
  stopGateway = true;
49181
- resolve34();
49181
+ resolve35();
49182
49182
  return;
49183
49183
  }
49184
49184
  if (key === "c" || key === "C") {
@@ -49229,8 +49229,8 @@ async function showExposeDashboard(gateway, rl, ctx) {
49229
49229
  process.stdout.write("\x1B[?1002h\x1B[?1006h");
49230
49230
  }
49231
49231
  };
49232
- const origResolve = resolve34;
49233
- resolve34 = (() => {
49232
+ const origResolve = resolve35;
49233
+ resolve35 = (() => {
49234
49234
  cleanup();
49235
49235
  origResolve();
49236
49236
  });
@@ -56631,8 +56631,8 @@ async function collectNetworkMetrics() {
56631
56631
  }
56632
56632
  if (plat === "darwin") {
56633
56633
  try {
56634
- const output = await new Promise((resolve34, reject) => {
56635
- exec3("netstat -ib 2>/dev/null | head -30", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve34(stdout));
56634
+ const output = await new Promise((resolve35, reject) => {
56635
+ exec3("netstat -ib 2>/dev/null | head -30", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve35(stdout));
56636
56636
  });
56637
56637
  let rxBytes = 0, txBytes = 0;
56638
56638
  for (const line of output.split("\n")) {
@@ -56666,8 +56666,8 @@ async function collectGpuMetrics() {
56666
56666
  if (_nvidiaSmiAvailable === false)
56667
56667
  return noGpu;
56668
56668
  try {
56669
- const smi = await new Promise((resolve34, reject) => {
56670
- exec3("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve34(stdout));
56669
+ const smi = await new Promise((resolve35, reject) => {
56670
+ exec3("nvidia-smi --query-gpu=utilization.gpu,memory.used,memory.total,name --format=csv,noheader,nounits 2>/dev/null", { encoding: "utf8", timeout: 3e3 }, (err, stdout) => err ? reject(err) : resolve35(stdout));
56671
56671
  });
56672
56672
  _nvidiaSmiAvailable = true;
56673
56673
  const line = smi.trim().split("\n")[0];
@@ -61044,14 +61044,14 @@ Review its full output in the [${id}] tab or via full_sub_agent(action='output',
61044
61044
  renderInfo(msg);
61045
61045
  statusBar.endContentWrite();
61046
61046
  }
61047
- }, () => new Promise((resolve34) => {
61047
+ }, () => new Promise((resolve35) => {
61048
61048
  depSudoPromptPending = true;
61049
61049
  depSudoResolver = (pw) => {
61050
61050
  depSudoPromptPending = false;
61051
61051
  depSudoResolver = null;
61052
61052
  if (pw)
61053
61053
  sessionSudoPassword = pw;
61054
- resolve34(pw);
61054
+ resolve35(pw);
61055
61055
  };
61056
61056
  const pwPrompt1 = ` ${c2.bold(c2.yellow("\u{1F511} Password needed for dependency install:"))}
61057
61057
  `;
@@ -64082,8 +64082,21 @@ var init_interactive = __esm({
64082
64082
  // packages/cli/dist/commands/run.js
64083
64083
  var run_exports = {};
64084
64084
  __export(run_exports, {
64085
- runCommand: () => runCommand
64085
+ jobsCommand: () => jobsCommand,
64086
+ runCommand: () => runCommand,
64087
+ statusCommand: () => statusCommand
64086
64088
  });
64089
+ import { resolve as resolve32 } from "node:path";
64090
+ import { spawn as spawn20 } from "node:child_process";
64091
+ import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23, readFileSync as readFileSync39, readdirSync as readdirSync20, existsSync as existsSync50 } from "node:fs";
64092
+ import { randomBytes as randomBytes15 } from "node:crypto";
64093
+ import { join as join67 } from "node:path";
64094
+ function jobsDir(repoPath) {
64095
+ const root = resolve32(repoPath ?? process.cwd());
64096
+ const dir = join67(root, ".oa", "jobs");
64097
+ mkdirSync24(dir, { recursive: true });
64098
+ return dir;
64099
+ }
64087
64100
  async function runCommand(opts, config) {
64088
64101
  const mergedConfig = {
64089
64102
  ...config,
@@ -64093,11 +64106,148 @@ async function runCommand(opts, config) {
64093
64106
  ...opts.maxRetries !== void 0 ? { maxRetries: opts.maxRetries } : {}
64094
64107
  };
64095
64108
  if (opts.task) {
64096
- await runWithTUI(opts.task, mergedConfig, opts.repoPath);
64109
+ if (opts.background) {
64110
+ await runBackground(opts.task, mergedConfig, opts);
64111
+ } else if (opts.json) {
64112
+ await runJson(opts.task, mergedConfig, opts.repoPath);
64113
+ } else {
64114
+ await runWithTUI(opts.task, mergedConfig, opts.repoPath);
64115
+ }
64097
64116
  } else {
64098
64117
  await startInteractive(mergedConfig, opts.repoPath);
64099
64118
  }
64100
64119
  }
64120
+ async function runJson(task, config, repoPath) {
64121
+ const startTime = Date.now();
64122
+ const origWrite = process.stdout.write.bind(process.stdout);
64123
+ const captured = [];
64124
+ process.stdout.write = ((chunk, ...args) => {
64125
+ if (typeof chunk === "string")
64126
+ captured.push(chunk);
64127
+ return true;
64128
+ });
64129
+ let result;
64130
+ try {
64131
+ await runWithTUI(task, config, repoPath);
64132
+ result = {
64133
+ status: "completed",
64134
+ summary: extractSummary(captured),
64135
+ durationMs: Date.now() - startTime,
64136
+ exitCode: 0
64137
+ };
64138
+ } catch (err) {
64139
+ result = {
64140
+ status: "failed",
64141
+ error: err instanceof Error ? err.message : String(err),
64142
+ durationMs: Date.now() - startTime,
64143
+ exitCode: 1
64144
+ };
64145
+ }
64146
+ process.stdout.write = origWrite;
64147
+ process.stdout.write(JSON.stringify(result, null, 2) + "\n");
64148
+ if (result.exitCode !== 0)
64149
+ process.exit(1);
64150
+ }
64151
+ function extractSummary(captured) {
64152
+ const all = captured.join("");
64153
+ const match = all.match(/task_complete.*?summary[:\s]*["']?([^"'\n]+)/i);
64154
+ if (match)
64155
+ return match[1].trim();
64156
+ const lines = all.replace(/\x1B\[[0-9;]*[A-Za-z]/g, "").split("\n").filter((l) => l.trim());
64157
+ return lines.slice(-3).join(" ").slice(0, 200);
64158
+ }
64159
+ async function runBackground(task, config, opts) {
64160
+ const id = `job-${randomBytes15(3).toString("hex")}`;
64161
+ const dir = jobsDir(opts.repoPath);
64162
+ const repoRoot = resolve32(opts.repoPath ?? process.cwd());
64163
+ const job = {
64164
+ id,
64165
+ pid: 0,
64166
+ task,
64167
+ status: "running",
64168
+ startedAt: (/* @__PURE__ */ new Date()).toISOString()
64169
+ };
64170
+ const oaBin = process.argv[1] || "oa";
64171
+ const args = [task, "--json"];
64172
+ if (config.model)
64173
+ args.push("--model", config.model);
64174
+ const child = spawn20("node", [oaBin, ...args], {
64175
+ cwd: repoRoot,
64176
+ env: { ...process.env, OA_JOB_ID: id },
64177
+ stdio: ["ignore", "pipe", "pipe"],
64178
+ detached: true
64179
+ });
64180
+ child.unref();
64181
+ job.pid = child.pid ?? 0;
64182
+ writeFileSync23(join67(dir, `${id}.json`), JSON.stringify(job, null, 2));
64183
+ let output = "";
64184
+ child.stdout?.on("data", (chunk) => {
64185
+ output += chunk.toString();
64186
+ });
64187
+ child.stderr?.on("data", (chunk) => {
64188
+ output += chunk.toString();
64189
+ });
64190
+ child.on("exit", (code) => {
64191
+ try {
64192
+ const result = output.trim() ? JSON.parse(output) : { status: code === 0 ? "completed" : "failed" };
64193
+ job.status = result.status || (code === 0 ? "completed" : "failed");
64194
+ job.completedAt = (/* @__PURE__ */ new Date()).toISOString();
64195
+ job.summary = result.summary;
64196
+ job.durationMs = result.durationMs;
64197
+ job.error = result.error;
64198
+ writeFileSync23(join67(dir, `${id}.json`), JSON.stringify(job, null, 2));
64199
+ } catch {
64200
+ }
64201
+ });
64202
+ console.log(`Job started: ${id} (PID ${job.pid})`);
64203
+ console.log("");
64204
+ console.log("Monitor this job:");
64205
+ console.log(` oa status ${id} # Check progress`);
64206
+ console.log(` oa output ${id} # See full output`);
64207
+ console.log(` oa jobs # List all jobs`);
64208
+ console.log(` kill ${job.pid} # Stop the job`);
64209
+ console.log("");
64210
+ console.log(`Job file: .oa/jobs/${id}.json`);
64211
+ }
64212
+ function statusCommand(jobId, repoPath) {
64213
+ const dir = jobsDir(repoPath);
64214
+ const file = join67(dir, `${jobId}.json`);
64215
+ if (!existsSync50(file)) {
64216
+ console.error(`Job not found: ${jobId}`);
64217
+ console.log(`Available jobs: oa jobs`);
64218
+ process.exit(1);
64219
+ }
64220
+ const job = JSON.parse(readFileSync39(file, "utf-8"));
64221
+ const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
64222
+ const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
64223
+ console.log(`${icon} ${job.id} [${job.status}] ${runtime}`);
64224
+ console.log(` Task: ${job.task.slice(0, 80)}`);
64225
+ console.log(` PID: ${job.pid}`);
64226
+ if (job.summary)
64227
+ console.log(` Summary: ${job.summary}`);
64228
+ if (job.error)
64229
+ console.log(` Error: ${job.error}`);
64230
+ if (job.durationMs)
64231
+ console.log(` Duration: ${(job.durationMs / 1e3).toFixed(1)}s`);
64232
+ }
64233
+ function jobsCommand(repoPath) {
64234
+ const dir = jobsDir(repoPath);
64235
+ const files = readdirSync20(dir).filter((f) => f.endsWith(".json")).sort();
64236
+ if (files.length === 0) {
64237
+ console.log("No jobs found.");
64238
+ return;
64239
+ }
64240
+ console.log("Jobs:");
64241
+ for (const file of files) {
64242
+ try {
64243
+ const job = JSON.parse(readFileSync39(join67(dir, file), "utf-8"));
64244
+ const icon = job.status === "completed" ? "\u2713" : job.status === "failed" ? "\u2717" : "\u25CF";
64245
+ const runtime = job.completedAt ? `${((new Date(job.completedAt).getTime() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s` : `${((Date.now() - new Date(job.startedAt).getTime()) / 1e3).toFixed(0)}s`;
64246
+ console.log(` ${icon} ${job.id} [${job.status}] ${runtime} \u2014 ${job.task.slice(0, 60)}`);
64247
+ } catch {
64248
+ }
64249
+ }
64250
+ }
64101
64251
  var init_run = __esm({
64102
64252
  "packages/cli/dist/commands/run.js"() {
64103
64253
  "use strict";
@@ -64110,7 +64260,7 @@ import { glob } from "glob";
64110
64260
  import ignore from "ignore";
64111
64261
  import { readFile as readFile23, stat as stat4 } from "node:fs/promises";
64112
64262
  import { createHash as createHash5 } from "node:crypto";
64113
- import { join as join67, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
64263
+ import { join as join68, relative as relative4, extname as extname12, basename as basename17 } from "node:path";
64114
64264
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
64115
64265
  var init_codebase_indexer = __esm({
64116
64266
  "packages/indexer/dist/codebase-indexer.js"() {
@@ -64154,7 +64304,7 @@ var init_codebase_indexer = __esm({
64154
64304
  const ig = ignore.default();
64155
64305
  if (this.config.respectGitignore) {
64156
64306
  try {
64157
- const gitignoreContent = await readFile23(join67(this.config.rootDir, ".gitignore"), "utf-8");
64307
+ const gitignoreContent = await readFile23(join68(this.config.rootDir, ".gitignore"), "utf-8");
64158
64308
  ig.add(gitignoreContent);
64159
64309
  } catch {
64160
64310
  }
@@ -64169,7 +64319,7 @@ var init_codebase_indexer = __esm({
64169
64319
  for (const relativePath of files) {
64170
64320
  if (ig.ignores(relativePath))
64171
64321
  continue;
64172
- const fullPath = join67(this.config.rootDir, relativePath);
64322
+ const fullPath = join68(this.config.rootDir, relativePath);
64173
64323
  try {
64174
64324
  const fileStat = await stat4(fullPath);
64175
64325
  if (fileStat.size > this.config.maxFileSize)
@@ -64215,7 +64365,7 @@ var init_codebase_indexer = __esm({
64215
64365
  if (!child) {
64216
64366
  child = {
64217
64367
  name: part,
64218
- path: join67(current.path, part),
64368
+ path: join68(current.path, part),
64219
64369
  type: "directory",
64220
64370
  children: []
64221
64371
  };
@@ -64297,14 +64447,14 @@ var index_repo_exports = {};
64297
64447
  __export(index_repo_exports, {
64298
64448
  indexRepoCommand: () => indexRepoCommand
64299
64449
  });
64300
- import { resolve as resolve32 } from "node:path";
64301
- import { existsSync as existsSync50, statSync as statSync16 } from "node:fs";
64450
+ import { resolve as resolve33 } from "node:path";
64451
+ import { existsSync as existsSync51, statSync as statSync16 } from "node:fs";
64302
64452
  import { cwd as cwd2 } from "node:process";
64303
64453
  async function indexRepoCommand(opts, _config) {
64304
- const repoRoot = resolve32(opts.repoPath ?? cwd2());
64454
+ const repoRoot = resolve33(opts.repoPath ?? cwd2());
64305
64455
  printHeader("Index Repository");
64306
64456
  printInfo(`Indexing: ${repoRoot}`);
64307
- if (!existsSync50(repoRoot)) {
64457
+ if (!existsSync51(repoRoot)) {
64308
64458
  printError(`Path does not exist: ${repoRoot}`);
64309
64459
  process.exit(1);
64310
64460
  }
@@ -64396,9 +64546,9 @@ var init_index_repo = __esm({
64396
64546
  // packages/cli/dist/commands/status.js
64397
64547
  var status_exports = {};
64398
64548
  __export(status_exports, {
64399
- statusCommand: () => statusCommand
64549
+ statusCommand: () => statusCommand2
64400
64550
  });
64401
- async function statusCommand(opts, config) {
64551
+ async function statusCommand2(opts, config) {
64402
64552
  printHeader("open-agents status");
64403
64553
  const backendType = config.backendType;
64404
64554
  if (backendType === "ollama") {
@@ -64556,7 +64706,7 @@ var config_exports = {};
64556
64706
  __export(config_exports, {
64557
64707
  configCommand: () => configCommand
64558
64708
  });
64559
- import { join as join68, resolve as resolve33 } from "node:path";
64709
+ import { join as join69, resolve as resolve34 } from "node:path";
64560
64710
  import { homedir as homedir17 } from "node:os";
64561
64711
  import { cwd as cwd3 } from "node:process";
64562
64712
  function redactIfSensitive(key, value) {
@@ -64589,7 +64739,7 @@ async function configCommand(opts, config) {
64589
64739
  return handleShow(opts, config);
64590
64740
  }
64591
64741
  function handleShow(opts, config) {
64592
- const repoRoot = resolve33(opts.repoPath ?? cwd3());
64742
+ const repoRoot = resolve34(opts.repoPath ?? cwd3());
64593
64743
  printHeader("Configuration");
64594
64744
  const resolved = resolveSettings(repoRoot);
64595
64745
  printSection("Core Inference");
@@ -64639,7 +64789,7 @@ function handleShow(opts, config) {
64639
64789
  }
64640
64790
  }
64641
64791
  printSection("Config File");
64642
- printInfo(`~/.open-agents/config.json (${join68(homedir17(), ".open-agents", "config.json")})`);
64792
+ printInfo(`~/.open-agents/config.json (${join69(homedir17(), ".open-agents", "config.json")})`);
64643
64793
  printSection("Priority Chain");
64644
64794
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
64645
64795
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -64672,13 +64822,13 @@ function handleSet(opts, _config) {
64672
64822
  process.exit(1);
64673
64823
  }
64674
64824
  if (opts.local) {
64675
- const repoRoot = resolve33(opts.repoPath ?? cwd3());
64825
+ const repoRoot = resolve34(opts.repoPath ?? cwd3());
64676
64826
  try {
64677
64827
  initOaDirectory(repoRoot);
64678
64828
  const coerced = coerceForSettings(key, value);
64679
64829
  saveProjectSettings(repoRoot, { [key]: coerced });
64680
64830
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value)}`);
64681
- printInfo(`Saved to ${join68(repoRoot, ".oa", "settings.json")}`);
64831
+ printInfo(`Saved to ${join69(repoRoot, ".oa", "settings.json")}`);
64682
64832
  printInfo("This override applies only when running in this workspace.");
64683
64833
  } catch (err) {
64684
64834
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -64778,7 +64928,7 @@ var serve_exports = {};
64778
64928
  __export(serve_exports, {
64779
64929
  serveCommand: () => serveCommand
64780
64930
  });
64781
- import { spawn as spawn20 } from "node:child_process";
64931
+ import { spawn as spawn21 } from "node:child_process";
64782
64932
  async function serveCommand(opts, config) {
64783
64933
  const backendType = config.backendType;
64784
64934
  if (backendType === "ollama") {
@@ -64870,8 +65020,8 @@ async function serveVllm(opts, config) {
64870
65020
  await runVllmServer(args, opts.verbose ?? false);
64871
65021
  }
64872
65022
  async function runVllmServer(args, verbose) {
64873
- return new Promise((resolve34, reject) => {
64874
- const child = spawn20("python", args, {
65023
+ return new Promise((resolve35, reject) => {
65024
+ const child = spawn21("python", args, {
64875
65025
  stdio: verbose ? "inherit" : ["ignore", "pipe", "pipe"],
64876
65026
  env: { ...process.env }
64877
65027
  });
@@ -64905,10 +65055,10 @@ async function runVllmServer(args, verbose) {
64905
65055
  child.once("exit", (code, signal) => {
64906
65056
  if (signal) {
64907
65057
  printInfo(`vLLM server stopped by signal ${signal}`);
64908
- resolve34();
65058
+ resolve35();
64909
65059
  } else if (code === 0) {
64910
65060
  printSuccess("vLLM server exited cleanly");
64911
- resolve34();
65061
+ resolve35();
64912
65062
  } else {
64913
65063
  printError(`vLLM server exited with code ${code}`);
64914
65064
  reject(new Error(`vLLM exited with code ${code}`));
@@ -64936,8 +65086,8 @@ __export(eval_exports, {
64936
65086
  evalCommand: () => evalCommand
64937
65087
  });
64938
65088
  import { tmpdir as tmpdir10 } from "node:os";
64939
- import { mkdirSync as mkdirSync24, writeFileSync as writeFileSync23 } from "node:fs";
64940
- import { join as join69 } from "node:path";
65089
+ import { mkdirSync as mkdirSync25, writeFileSync as writeFileSync24 } from "node:fs";
65090
+ import { join as join70 } from "node:path";
64941
65091
  async function evalCommand(opts, config) {
64942
65092
  const suiteName = opts.suite ?? "basic";
64943
65093
  const suite = SUITES[suiteName];
@@ -65062,9 +65212,9 @@ async function evalCommand(opts, config) {
65062
65212
  process.exit(failed > 0 ? 1 : 0);
65063
65213
  }
65064
65214
  function createTempEvalRepo() {
65065
- const dir = join69(tmpdir10(), `open-agents-eval-${Date.now()}`);
65066
- mkdirSync24(dir, { recursive: true });
65067
- writeFileSync23(join69(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
65215
+ const dir = join70(tmpdir10(), `open-agents-eval-${Date.now()}`);
65216
+ mkdirSync25(dir, { recursive: true });
65217
+ writeFileSync24(join70(dir, "package.json"), JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n", "utf8");
65068
65218
  return dir;
65069
65219
  }
65070
65220
  var BASIC_SUITE, FULL_SUITE, SUITES;
@@ -65124,7 +65274,7 @@ init_updater();
65124
65274
  import { parseArgs as nodeParseArgs2 } from "node:util";
65125
65275
  import { createRequire as createRequire3 } from "node:module";
65126
65276
  import { fileURLToPath as fileURLToPath13 } from "node:url";
65127
- import { dirname as dirname21, join as join70 } from "node:path";
65277
+ import { dirname as dirname21, join as join71 } from "node:path";
65128
65278
 
65129
65279
  // packages/cli/dist/cli.js
65130
65280
  import { createInterface } from "node:readline";
@@ -65231,7 +65381,7 @@ init_output();
65231
65381
  function getVersion4() {
65232
65382
  try {
65233
65383
  const require2 = createRequire3(import.meta.url);
65234
- const pkgPath = join70(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
65384
+ const pkgPath = join71(dirname21(fileURLToPath13(import.meta.url)), "..", "package.json");
65235
65385
  const pkg = require2(pkgPath);
65236
65386
  return pkg.version;
65237
65387
  } catch {
@@ -65239,7 +65389,7 @@ function getVersion4() {
65239
65389
  }
65240
65390
  }
65241
65391
  function routeCommand(command) {
65242
- const valid = /* @__PURE__ */ new Set(["run", "index", "status", "config", "serve", "eval"]);
65392
+ const valid = /* @__PURE__ */ new Set(["run", "index", "status", "config", "serve", "eval", "jobs"]);
65243
65393
  return valid.has(command) ? command : "unknown";
65244
65394
  }
65245
65395
  function parseCliArgs(argv) {
@@ -65259,6 +65409,8 @@ function parseCliArgs(argv) {
65259
65409
  local: { type: "boolean", short: "l" },
65260
65410
  port: { type: "string" },
65261
65411
  suite: { type: "string" },
65412
+ json: { type: "boolean", short: "j" },
65413
+ background: { type: "boolean" },
65262
65414
  help: { type: "boolean", short: "h" },
65263
65415
  version: { type: "boolean", short: "V" }
65264
65416
  },
@@ -65279,6 +65431,8 @@ function parseCliArgs(argv) {
65279
65431
  timeoutMs: typeof values["timeout-ms"] === "string" ? parseInt(values["timeout-ms"], 10) : void 0,
65280
65432
  offline: values.offline === true,
65281
65433
  local: values.local === true,
65434
+ json: values.json === true,
65435
+ background: values.background === true,
65282
65436
  help: values.help === true,
65283
65437
  version: values.version === true
65284
65438
  };
@@ -65309,6 +65463,9 @@ function parseCliArgs(argv) {
65309
65463
  result.servePort = parseInt(values.port, 10);
65310
65464
  }
65311
65465
  break;
65466
+ case "status":
65467
+ result.task = rest[0];
65468
+ break;
65312
65469
  case "eval":
65313
65470
  result.evalSuite = typeof values.suite === "string" ? values.suite : void 0;
65314
65471
  break;
@@ -65415,7 +65572,9 @@ async function main() {
65415
65572
  verbose: parsed.verbose,
65416
65573
  maxRetries: parsed.maxRetries,
65417
65574
  timeoutMs: parsed.timeoutMs,
65418
- offline: parsed.offline
65575
+ offline: parsed.offline,
65576
+ json: parsed.json,
65577
+ background: parsed.background
65419
65578
  }, config);
65420
65579
  break;
65421
65580
  }
@@ -65428,8 +65587,18 @@ async function main() {
65428
65587
  break;
65429
65588
  }
65430
65589
  case "status": {
65431
- const { statusCommand: statusCommand2 } = await Promise.resolve().then(() => (init_status(), status_exports));
65432
- await statusCommand2({ verbose: parsed.verbose }, config);
65590
+ if (parsed.task && parsed.task.startsWith("job-")) {
65591
+ const { statusCommand: jobStatusCmd } = await Promise.resolve().then(() => (init_run(), run_exports));
65592
+ jobStatusCmd(parsed.task, parsed.repoPath);
65593
+ } else {
65594
+ const { statusCommand: statusCommand3 } = await Promise.resolve().then(() => (init_status(), status_exports));
65595
+ await statusCommand3({ verbose: parsed.verbose }, config);
65596
+ }
65597
+ break;
65598
+ }
65599
+ case "jobs": {
65600
+ const { jobsCommand: jobsCommand2 } = await Promise.resolve().then(() => (init_run(), run_exports));
65601
+ jobsCommand2(parsed.repoPath);
65433
65602
  break;
65434
65603
  }
65435
65604
  case "config": {