open-agents-ai 0.187.535 → 0.187.537

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.
package/dist/index.js CHANGED
@@ -9457,6 +9457,45 @@ process.on('unhandledRejection', (reason) => {
9457
9457
  }
9458
9458
  connected = true;
9459
9459
 
9460
+ // Register this nexus dir in the global registry so the API daemon
9461
+ // (and any other consumer) can discover us regardless of cwd.
9462
+ try {
9463
+ var nodePath_reg = require('node:path');
9464
+ var nodeFs_reg = require('node:fs');
9465
+ var nodeOs_reg = require('node:os');
9466
+ var regDir = nodePath_reg.join(nodeOs_reg.homedir(), '.open-agents');
9467
+ if (!nodeFs_reg.existsSync(regDir)) nodeFs_reg.mkdirSync(regDir, { recursive: true });
9468
+ var regFile = nodePath_reg.join(regDir, 'nexus-registry.json');
9469
+ var existing = { dirs: [] };
9470
+ try {
9471
+ if (nodeFs_reg.existsSync(regFile)) existing = JSON.parse(nodeFs_reg.readFileSync(regFile, 'utf-8')) || { dirs: [] };
9472
+ if (!Array.isArray(existing.dirs)) existing.dirs = [];
9473
+ } catch { existing = { dirs: [] }; }
9474
+ // Drop entries that no longer exist on disk
9475
+ existing.dirs = existing.dirs.filter(function(e) {
9476
+ var d = typeof e === 'string' ? e : (e && e.dir);
9477
+ return d && nodeFs_reg.existsSync(nodePath_reg.join(d, 'status.json'));
9478
+ });
9479
+ // De-dup + prepend ourselves
9480
+ var meDir = nexusDir;
9481
+ existing.dirs = existing.dirs.filter(function(e) {
9482
+ var d = typeof e === 'string' ? e : (e && e.dir);
9483
+ return d !== meDir;
9484
+ });
9485
+ existing.dirs.unshift({
9486
+ dir: meDir,
9487
+ peerId: nexus.peerId || '',
9488
+ pid: process.pid,
9489
+ startedAt: new Date().toISOString(),
9490
+ });
9491
+ // Cap at 16 entries
9492
+ if (existing.dirs.length > 16) existing.dirs = existing.dirs.slice(0, 16);
9493
+ nodeFs_reg.writeFileSync(regFile, JSON.stringify(existing, null, 2));
9494
+ dlog('nexus-registry: registered ' + meDir);
9495
+ } catch (regErr) {
9496
+ dlog('nexus-registry write failed: ' + (regErr.message || regErr));
9497
+ }
9498
+
9460
9499
  // http_tunnel capability — proxies HTTP requests from remote peers
9461
9500
  // to the local OA API daemon. Auth is delegated to the API key store
9462
9501
  // (remote sends share key in Authorization header). SSE streams are
@@ -247788,9 +247827,9 @@ print("${sentinel}")
247788
247827
  if (!this.proc || this.proc.killed) {
247789
247828
  return { success: false, path: "" };
247790
247829
  }
247791
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
247830
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
247792
247831
  const sessionDir = join28(this.cwd, ".oa", "rlm");
247793
- mkdirSync67(sessionDir, { recursive: true });
247832
+ mkdirSync68(sessionDir, { recursive: true });
247794
247833
  const sessionPath2 = join28(sessionDir, "session.json");
247795
247834
  try {
247796
247835
  const inspectCode = `
@@ -247814,7 +247853,7 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
247814
247853
  trajectoryCount: this.trajectory.length,
247815
247854
  subCallCount: this.subCallCount
247816
247855
  };
247817
- writeFileSync59(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
247856
+ writeFileSync60(sessionPath2, JSON.stringify(sessionData, null, 2), "utf8");
247818
247857
  return { success: true, path: sessionPath2 };
247819
247858
  }
247820
247859
  } catch {
@@ -247826,9 +247865,9 @@ print("__SESSION__" + json.dumps(_session) + "__SESSION__")
247826
247865
  * what was previously computed. */
247827
247866
  async loadSessionInfo() {
247828
247867
  try {
247829
- const { readFileSync: readFileSync89, existsSync: existsSync110 } = await import("node:fs");
247868
+ const { readFileSync: readFileSync89, existsSync: existsSync111 } = await import("node:fs");
247830
247869
  const sessionPath2 = join28(this.cwd, ".oa", "rlm", "session.json");
247831
- if (!existsSync110(sessionPath2))
247870
+ if (!existsSync111(sessionPath2))
247832
247871
  return null;
247833
247872
  return JSON.parse(readFileSync89(sessionPath2, "utf8"));
247834
247873
  } catch {
@@ -248394,10 +248433,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
248394
248433
  * Optionally filter by task type for phase-aware context (FSM paper insight).
248395
248434
  */
248396
248435
  getTopMemoriesSync(k = 5, taskType) {
248397
- const { readFileSync: readFileSync89, existsSync: existsSync110 } = __require("node:fs");
248436
+ const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
248398
248437
  const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
248399
248438
  const storeFile = join29(metaDir, "store.json");
248400
- if (!existsSync110(storeFile))
248439
+ if (!existsSync111(storeFile))
248401
248440
  return "";
248402
248441
  let store2 = [];
248403
248442
  try {
@@ -248423,10 +248462,10 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
248423
248462
  /** Update memory scores based on task outcome. Called after task completion.
248424
248463
  * Memories used in successful tasks get boosted. Memories present during failures get decayed. */
248425
248464
  updateFromOutcomeSync(surfacedMemoryText, succeeded) {
248426
- const { readFileSync: readFileSync89, writeFileSync: writeFileSync59, existsSync: existsSync110, mkdirSync: mkdirSync67 } = __require("node:fs");
248465
+ const { readFileSync: readFileSync89, writeFileSync: writeFileSync60, existsSync: existsSync111, mkdirSync: mkdirSync68 } = __require("node:fs");
248427
248466
  const metaDir = join29(this.cwd, ".oa", "memory", "metabolism");
248428
248467
  const storeFile = join29(metaDir, "store.json");
248429
- if (!existsSync110(storeFile))
248468
+ if (!existsSync111(storeFile))
248430
248469
  return;
248431
248470
  let store2 = [];
248432
248471
  try {
@@ -248454,8 +248493,8 @@ ${issues.map((i2) => ` - ${i2}`).join("\n")}` : " No issues found."),
248454
248493
  updated = true;
248455
248494
  }
248456
248495
  if (updated) {
248457
- mkdirSync67(metaDir, { recursive: true });
248458
- writeFileSync59(storeFile, JSON.stringify(store2, null, 2));
248496
+ mkdirSync68(metaDir, { recursive: true });
248497
+ writeFileSync60(storeFile, JSON.stringify(store2, null, 2));
248459
248498
  }
248460
248499
  }
248461
248500
  // ── Storage ──────────────────────────────────────────────────────────
@@ -248877,9 +248916,9 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
248877
248916
  // Per EvoSkill (arXiv:2603.02766): retrieve relevant strategies from archive.
248878
248917
  /** Retrieve top-K strategies for context injection. Returns "" if none. */
248879
248918
  getRelevantStrategiesSync(k = 3, taskType) {
248880
- const { readFileSync: readFileSync89, existsSync: existsSync110 } = __require("node:fs");
248919
+ const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
248881
248920
  const archiveFile = join31(this.cwd, ".oa", "arche", "variants.json");
248882
- if (!existsSync110(archiveFile))
248921
+ if (!existsSync111(archiveFile))
248883
248922
  return "";
248884
248923
  let variants = [];
248885
248924
  try {
@@ -248901,12 +248940,12 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
248901
248940
  }
248902
248941
  /** Archive a strategy variant synchronously (for task completion path) */
248903
248942
  archiveVariantSync(strategy, outcome, tags = []) {
248904
- const { readFileSync: readFileSync89, writeFileSync: writeFileSync59, existsSync: existsSync110, mkdirSync: mkdirSync67 } = __require("node:fs");
248943
+ const { readFileSync: readFileSync89, writeFileSync: writeFileSync60, existsSync: existsSync111, mkdirSync: mkdirSync68 } = __require("node:fs");
248905
248944
  const dir = join31(this.cwd, ".oa", "arche");
248906
248945
  const archiveFile = join31(dir, "variants.json");
248907
248946
  let variants = [];
248908
248947
  try {
248909
- if (existsSync110(archiveFile))
248948
+ if (existsSync111(archiveFile))
248910
248949
  variants = JSON.parse(readFileSync89(archiveFile, "utf8"));
248911
248950
  } catch {
248912
248951
  }
@@ -248922,8 +248961,8 @@ Recommendation: Strategy ${scored[0].index + 1} scores highest.`;
248922
248961
  });
248923
248962
  if (variants.length > 50)
248924
248963
  variants = variants.slice(-50);
248925
- mkdirSync67(dir, { recursive: true });
248926
- writeFileSync59(archiveFile, JSON.stringify(variants, null, 2));
248964
+ mkdirSync68(dir, { recursive: true });
248965
+ writeFileSync60(archiveFile, JSON.stringify(variants, null, 2));
248927
248966
  }
248928
248967
  async saveArchive(variants) {
248929
248968
  const dir = join31(this.cwd, ".oa", "arche");
@@ -257187,7 +257226,7 @@ var require_util9 = __commonJS({
257187
257226
  return path8;
257188
257227
  }
257189
257228
  exports.normalize = normalize2;
257190
- function join128(aRoot, aPath) {
257229
+ function join129(aRoot, aPath) {
257191
257230
  if (aRoot === "") {
257192
257231
  aRoot = ".";
257193
257232
  }
@@ -257219,7 +257258,7 @@ var require_util9 = __commonJS({
257219
257258
  }
257220
257259
  return joined;
257221
257260
  }
257222
- exports.join = join128;
257261
+ exports.join = join129;
257223
257262
  exports.isAbsolute = function(aPath) {
257224
257263
  return aPath.charAt(0) === "/" || urlRegexp.test(aPath);
257225
257264
  };
@@ -257392,7 +257431,7 @@ var require_util9 = __commonJS({
257392
257431
  parsed.path = parsed.path.substring(0, index + 1);
257393
257432
  }
257394
257433
  }
257395
- sourceURL = join128(urlGenerate(parsed), sourceURL);
257434
+ sourceURL = join129(urlGenerate(parsed), sourceURL);
257396
257435
  }
257397
257436
  return normalize2(sourceURL);
257398
257437
  }
@@ -472295,10 +472334,10 @@ var require_commonjs3 = __commonJS({
472295
472334
  let ai = 0;
472296
472335
  let bi = 0;
472297
472336
  let result = [];
472298
- let which = "";
472337
+ let which2 = "";
472299
472338
  while (ai < a2.length && bi < b.length) {
472300
472339
  if (a2[ai] === b[bi]) {
472301
- result.push(which === "b" ? b[bi] : a2[ai]);
472340
+ result.push(which2 === "b" ? b[bi] : a2[ai]);
472302
472341
  ai++;
472303
472342
  bi++;
472304
472343
  } else if (emptyGSMatch && a2[ai] === "**" && b[bi] === a2[ai + 1]) {
@@ -472308,16 +472347,16 @@ var require_commonjs3 = __commonJS({
472308
472347
  result.push(b[bi]);
472309
472348
  bi++;
472310
472349
  } else if (a2[ai] === "*" && b[bi] && (this.options.dot || !b[bi].startsWith(".")) && b[bi] !== "**") {
472311
- if (which === "b")
472350
+ if (which2 === "b")
472312
472351
  return false;
472313
- which = "a";
472352
+ which2 = "a";
472314
472353
  result.push(a2[ai]);
472315
472354
  ai++;
472316
472355
  bi++;
472317
472356
  } else if (b[bi] === "*" && a2[ai] && (this.options.dot || !a2[ai].startsWith(".")) && a2[ai] !== "**") {
472318
- if (which === "a")
472357
+ if (which2 === "a")
472319
472358
  return false;
472320
- which = "b";
472359
+ which2 = "b";
472321
472360
  result.push(b[bi]);
472322
472361
  ai++;
472323
472362
  bi++;
@@ -472812,7 +472851,7 @@ var require_path_browserify = __commonJS({
472812
472851
  assertPath(path8);
472813
472852
  return path8.length > 0 && path8.charCodeAt(0) === 47;
472814
472853
  },
472815
- join: function join128() {
472854
+ join: function join129() {
472816
472855
  if (arguments.length === 0)
472817
472856
  return ".";
472818
472857
  var joined;
@@ -507800,7 +507839,7 @@ var init_agent_tool = __esm({
507800
507839
  })();
507801
507840
  if (isolation === "worktree") {
507802
507841
  this.callbacks.onViewRegister?.(agentId, label);
507803
- const spawn27 = this.callbacks.spawnSubprocess({
507842
+ const spawn28 = this.callbacks.spawnSubprocess({
507804
507843
  id: agentId,
507805
507844
  task: composedPrompt,
507806
507845
  model,
@@ -507810,7 +507849,7 @@ var init_agent_tool = __esm({
507810
507849
  success: true,
507811
507850
  output: `Agent spawned (subprocess, worktree): ${agentId}
507812
507851
  Type: ${subagentType}
507813
- PID: ${spawn27.pid}
507852
+ PID: ${spawn28.pid}
507814
507853
  Task: ${prompt.slice(0, 100)}
507815
507854
  Use task_status("${agentId}") to check progress.`,
507816
507855
  durationMs: performance.now() - start2
@@ -522926,8 +522965,8 @@ var init_reflectionBuffer = __esm({
522926
522965
  this.persistPath = persistPath ?? null;
522927
522966
  if (this.persistPath) {
522928
522967
  try {
522929
- const { readFileSync: readFileSync89, existsSync: existsSync110 } = __require("node:fs");
522930
- if (existsSync110(this.persistPath)) {
522968
+ const { readFileSync: readFileSync89, existsSync: existsSync111 } = __require("node:fs");
522969
+ if (existsSync111(this.persistPath)) {
522931
522970
  this.state = JSON.parse(readFileSync89(this.persistPath, "utf-8"));
522932
522971
  return;
522933
522972
  }
@@ -523161,12 +523200,12 @@ var init_reflectionBuffer = __esm({
523161
523200
  if (!this.persistPath)
523162
523201
  return;
523163
523202
  try {
523164
- const { writeFileSync: writeFileSync59, mkdirSync: mkdirSync67, existsSync: existsSync110 } = __require("node:fs");
523165
- const { join: join128 } = __require("node:path");
523166
- const dir = join128(this.persistPath, "..");
523167
- if (!existsSync110(dir))
523168
- mkdirSync67(dir, { recursive: true });
523169
- writeFileSync59(this.persistPath, JSON.stringify(this.state, null, 2));
523203
+ const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68, existsSync: existsSync111 } = __require("node:fs");
523204
+ const { join: join129 } = __require("node:path");
523205
+ const dir = join129(this.persistPath, "..");
523206
+ if (!existsSync111(dir))
523207
+ mkdirSync68(dir, { recursive: true });
523208
+ writeFileSync60(this.persistPath, JSON.stringify(this.state, null, 2));
523170
523209
  } catch {
523171
523210
  }
523172
523211
  }
@@ -533706,10 +533745,10 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
533706
533745
  if (nodes > 0) {
533707
533746
  this.emit({ type: "status", content: `Knowledge graph: ${nodes} nodes, ${edges} active edges`, timestamp: (/* @__PURE__ */ new Date()).toISOString() });
533708
533747
  try {
533709
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = __require("node:fs");
533710
- const { join: join128 } = __require("node:path");
533711
- const contextDir = join128(this._workingDirectory || process.cwd(), ".oa", "context");
533712
- mkdirSync67(contextDir, { recursive: true });
533748
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
533749
+ const { join: join129 } = __require("node:path");
533750
+ const contextDir = join129(this._workingDirectory || process.cwd(), ".oa", "context");
533751
+ mkdirSync68(contextDir, { recursive: true });
533713
533752
  const topEntities = this._temporalGraph.nodesByType("entity", 3);
533714
533753
  const topFiles = this._temporalGraph.nodesByType("file", 3);
533715
533754
  const topConcepts = this._temporalGraph.nodesByType("concept", 3);
@@ -533749,9 +533788,9 @@ Full content available via: repl_exec(code="data = retrieve('${handleId}')") or
533749
533788
  section("Top Files", topFiles);
533750
533789
  section("Top Concepts", topConcepts);
533751
533790
  lines.push("(Use file_read on this file for quick recall. See provenance JSON for full edge detail.)");
533752
- const outPath = join128(contextDir, `kg-summary-${this._sessionId}.md`);
533753
- writeFileSync59(outPath, lines.join("\n"), "utf-8");
533754
- writeFileSync59(join128(contextDir, `kg-summary-latest.md`), lines.join("\n"), "utf-8");
533791
+ const outPath = join129(contextDir, `kg-summary-${this._sessionId}.md`);
533792
+ writeFileSync60(outPath, lines.join("\n"), "utf-8");
533793
+ writeFileSync60(join129(contextDir, `kg-summary-latest.md`), lines.join("\n"), "utf-8");
533755
533794
  } catch {
533756
533795
  }
533757
533796
  }
@@ -533919,11 +533958,11 @@ ${errOutput}`;
533919
533958
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
533920
533959
  });
533921
533960
  try {
533922
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = __require("node:fs");
533923
- const { join: join128 } = __require("node:path");
533924
- const resultsDir = join128(process.cwd(), ".oa", "tool-results");
533925
- mkdirSync67(resultsDir, { recursive: true });
533926
- writeFileSync59(join128(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
533961
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
533962
+ const { join: join129 } = __require("node:path");
533963
+ const resultsDir = join129(process.cwd(), ".oa", "tool-results");
533964
+ mkdirSync68(resultsDir, { recursive: true });
533965
+ writeFileSync60(join129(resultsDir, `${handleId}.txt`), `# Tool: ${toolName}
533927
533966
  # Turn: ${turn}
533928
533967
  # Timestamp: ${(/* @__PURE__ */ new Date()).toISOString()}
533929
533968
  # Size: ${result.output.length} chars, ${lineCount} lines
@@ -534139,10 +534178,10 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
534139
534178
  if (!this._workingDirectory)
534140
534179
  return;
534141
534180
  try {
534142
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = __require("node:fs");
534143
- const { join: join128 } = __require("node:path");
534144
- const sessionDir = join128(this._workingDirectory, ".oa", "session", this._sessionId);
534145
- mkdirSync67(sessionDir, { recursive: true });
534181
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
534182
+ const { join: join129 } = __require("node:path");
534183
+ const sessionDir = join129(this._workingDirectory, ".oa", "session", this._sessionId);
534184
+ mkdirSync68(sessionDir, { recursive: true });
534146
534185
  const checkpoint = {
534147
534186
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
534148
534187
  sessionId: this._sessionId,
@@ -534154,7 +534193,7 @@ Actions: (1) list_directory on the parent directory to see what's there, (2) Che
534154
534193
  memexEntryCount: this._memexArchive.size,
534155
534194
  fileRegistrySize: this._fileRegistry.size
534156
534195
  };
534157
- writeFileSync59(join128(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
534196
+ writeFileSync60(join129(sessionDir, "checkpoint.json"), JSON.stringify(checkpoint, null, 2));
534158
534197
  } catch {
534159
534198
  }
534160
534199
  }
@@ -535981,12 +536020,12 @@ ${result}`
535981
536020
  let resizedBase64 = null;
535982
536021
  try {
535983
536022
  const { execSync: execSync59 } = await import("node:child_process");
535984
- const { writeFileSync: writeFileSync59, readFileSync: readFileSync89, unlinkSync: unlinkSync25 } = await import("node:fs");
535985
- const { join: join128 } = await import("node:path");
535986
- const { tmpdir: tmpdir22 } = await import("node:os");
535987
- const tmpIn = join128(tmpdir22(), `oa_img_in_${Date.now()}.png`);
535988
- const tmpOut = join128(tmpdir22(), `oa_img_out_${Date.now()}.jpg`);
535989
- writeFileSync59(tmpIn, buffer2);
536023
+ const { writeFileSync: writeFileSync60, readFileSync: readFileSync89, unlinkSync: unlinkSync25 } = await import("node:fs");
536024
+ const { join: join129 } = await import("node:path");
536025
+ const { tmpdir: tmpdir23 } = await import("node:os");
536026
+ const tmpIn = join129(tmpdir23(), `oa_img_in_${Date.now()}.png`);
536027
+ const tmpOut = join129(tmpdir23(), `oa_img_out_${Date.now()}.jpg`);
536028
+ writeFileSync60(tmpIn, buffer2);
535990
536029
  const pyBin = process.platform === "win32" ? "python" : "python3";
535991
536030
  const escapedIn = tmpIn.replace(/\\/g, "\\\\");
535992
536031
  const escapedOut = tmpOut.replace(/\\/g, "\\\\");
@@ -544531,23 +544570,23 @@ async function fetchOpenAIModels(baseUrl, apiKey) {
544531
544570
  async function fetchPeerModels(peerId, authKey) {
544532
544571
  try {
544533
544572
  const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
544534
- const { existsSync: existsSync110, readFileSync: readFileSync89 } = await import("node:fs");
544535
- const { join: join128 } = await import("node:path");
544573
+ const { existsSync: existsSync111, readFileSync: readFileSync89 } = await import("node:fs");
544574
+ const { join: join129 } = await import("node:path");
544536
544575
  const cwd4 = process.cwd();
544537
544576
  const nexusTool = new NexusTool2(cwd4);
544538
544577
  const nexusDir = nexusTool.getNexusDir();
544539
544578
  let isLocalPeer = false;
544540
544579
  try {
544541
- const statusPath = join128(nexusDir, "status.json");
544542
- if (existsSync110(statusPath)) {
544580
+ const statusPath = join129(nexusDir, "status.json");
544581
+ if (existsSync111(statusPath)) {
544543
544582
  const status = JSON.parse(readFileSync89(statusPath, "utf8"));
544544
544583
  if (status.peerId === peerId) isLocalPeer = true;
544545
544584
  }
544546
544585
  } catch {
544547
544586
  }
544548
544587
  if (isLocalPeer) {
544549
- const pricingPath = join128(nexusDir, "pricing.json");
544550
- if (existsSync110(pricingPath)) {
544588
+ const pricingPath = join129(nexusDir, "pricing.json");
544589
+ if (existsSync111(pricingPath)) {
544551
544590
  try {
544552
544591
  const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
544553
544592
  const localModels = (pricing.models || []).map((m2) => ({
@@ -544562,8 +544601,8 @@ async function fetchPeerModels(peerId, authKey) {
544562
544601
  }
544563
544602
  }
544564
544603
  }
544565
- const cachePath = join128(nexusDir, "peer-models-cache.json");
544566
- if (existsSync110(cachePath)) {
544604
+ const cachePath = join129(nexusDir, "peer-models-cache.json");
544605
+ if (existsSync111(cachePath)) {
544567
544606
  try {
544568
544607
  const cache8 = JSON.parse(readFileSync89(cachePath, "utf8"));
544569
544608
  if (cache8.peerId === peerId && cache8.models?.length > 0) {
@@ -544677,8 +544716,8 @@ async function fetchPeerModels(peerId, authKey) {
544677
544716
  } catch {
544678
544717
  }
544679
544718
  if (isLocalPeer) {
544680
- const pricingPath = join128(nexusDir, "pricing.json");
544681
- if (existsSync110(pricingPath)) {
544719
+ const pricingPath = join129(nexusDir, "pricing.json");
544720
+ if (existsSync111(pricingPath)) {
544682
544721
  try {
544683
544722
  const pricing = JSON.parse(readFileSync89(pricingPath, "utf8"));
544684
544723
  return (pricing.models || []).map((m2) => ({
@@ -562459,13 +562498,13 @@ async function runSudoScript(ctx3, script) {
562459
562498
  } catch {
562460
562499
  }
562461
562500
  try {
562462
- const { spawn: spawn27 } = await import("node:child_process");
562501
+ const { spawn: spawn28 } = await import("node:child_process");
562463
562502
  const full = `set -e; ${script}`;
562464
562503
  await new Promise((resolve43) => {
562465
562504
  const usePkexec = process.platform === "linux";
562466
562505
  const cmd = usePkexec ? "pkexec" : "sudo";
562467
562506
  const args = usePkexec ? ["bash", "-lc", full] : ["-n", "bash", "-lc", full];
562468
- const child = spawn27(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
562507
+ const child = spawn28(cmd, args, { stdio: ["ignore", "pipe", "pipe"] });
562469
562508
  let stdout = "";
562470
562509
  let stderr = "";
562471
562510
  child.stdout?.on("data", (data) => {
@@ -562499,9 +562538,9 @@ async function ensureVoiceDeps(ctx3) {
562499
562538
  }
562500
562539
  if (typeof mod2.getVenvPython === "function") {
562501
562540
  const { dirname: dirname39 } = await import("node:path");
562502
- const { existsSync: existsSync110 } = await import("node:fs");
562541
+ const { existsSync: existsSync111 } = await import("node:fs");
562503
562542
  const venvPy = mod2.getVenvPython();
562504
- if (existsSync110(venvPy)) {
562543
+ if (existsSync111(venvPy)) {
562505
562544
  process.env.TRANSCRIBE_PYTHON = venvPy;
562506
562545
  const venvBin = dirname39(venvPy);
562507
562546
  const sep2 = process.platform === "win32" ? ";" : ":";
@@ -562820,10 +562859,10 @@ async function handleSlashCommand(input, ctx3) {
562820
562859
  if (!key) {
562821
562860
  try {
562822
562861
  const { homedir: homedir46 } = await import("node:os");
562823
- const { readFileSync: readFileSync89, existsSync: existsSync110 } = await import("node:fs");
562824
- const { join: join128 } = await import("node:path");
562825
- const p2 = join128(homedir46(), ".open-agents", "api.key");
562826
- if (existsSync110(p2)) key = readFileSync89(p2, "utf8").trim();
562862
+ const { readFileSync: readFileSync89, existsSync: existsSync111 } = await import("node:fs");
562863
+ const { join: join129 } = await import("node:path");
562864
+ const p2 = join129(homedir46(), ".open-agents", "api.key");
562865
+ if (existsSync111(p2)) key = readFileSync89(p2, "utf8").trim();
562827
562866
  } catch {
562828
562867
  }
562829
562868
  }
@@ -562862,13 +562901,13 @@ async function handleSlashCommand(input, ctx3) {
562862
562901
  try {
562863
562902
  const { randomBytes: randomBytes25 } = await import("node:crypto");
562864
562903
  const { homedir: homedir46 } = await import("node:os");
562865
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
562866
- const { join: join128 } = await import("node:path");
562904
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
562905
+ const { join: join129 } = await import("node:path");
562867
562906
  const newKey = randomBytes25(16).toString("hex");
562868
562907
  process.env["OA_API_KEY"] = newKey;
562869
- const dir = join128(homedir46(), ".open-agents");
562870
- mkdirSync67(dir, { recursive: true });
562871
- writeFileSync59(join128(dir, "api.key"), newKey + "\n", "utf8");
562908
+ const dir = join129(homedir46(), ".open-agents");
562909
+ mkdirSync68(dir, { recursive: true });
562910
+ writeFileSync60(join129(dir, "api.key"), newKey + "\n", "utf8");
562872
562911
  renderInfo2(`New API key: ${c3.bold(c3.yellow(newKey))}`);
562873
562912
  renderInfo2("Restart the daemon to apply if needed. Use /access any to restart quickly.");
562874
562913
  } catch (e2) {
@@ -563056,11 +563095,11 @@ async function handleSlashCommand(input, ctx3) {
563056
563095
  renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
563057
563096
  try {
563058
563097
  const { homedir: homedir47 } = await import("node:os");
563059
- const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
563060
- const { join: join129 } = await import("node:path");
563061
- const dir = join129(homedir47(), ".open-agents");
563062
- mkdirSync68(dir, { recursive: true });
563063
- writeFileSync60(join129(dir, "api.key"), apiKey + "\n", "utf8");
563098
+ const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
563099
+ const { join: join130 } = await import("node:path");
563100
+ const dir = join130(homedir47(), ".open-agents");
563101
+ mkdirSync69(dir, { recursive: true });
563102
+ writeFileSync61(join130(dir, "api.key"), apiKey + "\n", "utf8");
563064
563103
  } catch {
563065
563104
  }
563066
563105
  }
@@ -563072,11 +563111,11 @@ async function handleSlashCommand(input, ctx3) {
563072
563111
  const port2 = parseInt(process.env["OA_PORT"] || "11435", 10);
563073
563112
  try {
563074
563113
  const { homedir: homedir47 } = await import("node:os");
563075
- const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
563076
- const { join: join129 } = await import("node:path");
563077
- const dir = join129(homedir47(), ".open-agents");
563078
- mkdirSync68(dir, { recursive: true });
563079
- writeFileSync60(join129(dir, "access"), `${val2}
563114
+ const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
563115
+ const { join: join130 } = await import("node:path");
563116
+ const dir = join130(homedir47(), ".open-agents");
563117
+ mkdirSync69(dir, { recursive: true });
563118
+ writeFileSync61(join130(dir, "access"), `${val2}
563080
563119
  `, "utf8");
563081
563120
  } catch {
563082
563121
  }
@@ -563158,11 +563197,11 @@ async function handleSlashCommand(input, ctx3) {
563158
563197
  renderInfo2("Use the Web UI ‘key’ button to paste this token, or set Authorization: Bearer <key> in your client.");
563159
563198
  try {
563160
563199
  const { homedir: homedir47 } = await import("node:os");
563161
- const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
563162
- const { join: join129 } = await import("node:path");
563163
- const dir = join129(homedir47(), ".open-agents");
563164
- mkdirSync68(dir, { recursive: true });
563165
- writeFileSync60(join129(dir, "api.key"), apiKey + "\n", "utf8");
563200
+ const { mkdirSync: mkdirSync69, writeFileSync: writeFileSync61 } = await import("node:fs");
563201
+ const { join: join130 } = await import("node:path");
563202
+ const dir = join130(homedir47(), ".open-agents");
563203
+ mkdirSync69(dir, { recursive: true });
563204
+ writeFileSync61(join130(dir, "api.key"), apiKey + "\n", "utf8");
563166
563205
  } catch {
563167
563206
  }
563168
563207
  }
@@ -563173,12 +563212,12 @@ async function handleSlashCommand(input, ctx3) {
563173
563212
  }
563174
563213
  const port = parseInt(process.env["OA_PORT"] || "11435", 10);
563175
563214
  const { homedir: homedir46 } = await import("node:os");
563176
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
563177
- const { join: join128 } = await import("node:path");
563215
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
563216
+ const { join: join129 } = await import("node:path");
563178
563217
  try {
563179
- const dir = join128(homedir46(), ".open-agents");
563180
- mkdirSync67(dir, { recursive: true });
563181
- writeFileSync59(join128(dir, "access"), `${val}
563218
+ const dir = join129(homedir46(), ".open-agents");
563219
+ mkdirSync68(dir, { recursive: true });
563220
+ writeFileSync60(join129(dir, "access"), `${val}
563182
563221
  `, "utf8");
563183
563222
  } catch (e2) {
563184
563223
  renderWarning2(`Could not persist ~/.open-agents/access: ${e2 instanceof Error ? e2.message : String(e2)}`);
@@ -564230,8 +564269,8 @@ async function handleSlashCommand(input, ctx3) {
564230
564269
  writeFileSync41(jwtFile, JSON.stringify(jwtPayload, null, 2));
564231
564270
  renderInfo2(`Launching fortemi-react from ${fDir}...`);
564232
564271
  try {
564233
- const { spawn: spawn27 } = __require("node:child_process");
564234
- const child = spawn27("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
564272
+ const { spawn: spawn28 } = __require("node:child_process");
564273
+ const child = spawn28("npx", ["vite", "dev", "--host", "0.0.0.0", "--port", "3000"], {
564235
564274
  cwd: join99(fDir, "apps", "standalone"),
564236
564275
  stdio: "ignore",
564237
564276
  detached: true,
@@ -564956,9 +564995,9 @@ systemctl --user daemon-reload || true
564956
564995
  systemctl --user enable --now open-agents-daemon.service || true
564957
564996
  sleep 1
564958
564997
  `;
564959
- const { spawn: spawn27 } = await import("node:child_process");
564998
+ const { spawn: spawn28 } = await import("node:child_process");
564960
564999
  await new Promise((resolve43) => {
564961
- const child = spawn27("bash", ["-lc", takeover], { stdio: "inherit" });
565000
+ const child = spawn28("bash", ["-lc", takeover], { stdio: "inherit" });
564962
565001
  onChildExit(child, () => resolve43());
564963
565002
  });
564964
565003
  renderInfo2("Daemon takeover complete.");
@@ -567395,11 +567434,11 @@ async function handleVoiceMenu(ctx3, save2, hasLocal) {
567395
567434
  continue;
567396
567435
  }
567397
567436
  const { basename: basename21, join: pathJoin } = await import("node:path");
567398
- const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync67, existsSync: exists2 } = await import("node:fs");
567437
+ const { copyFileSync: copyFileSync3, mkdirSync: mkdirSync68, existsSync: exists2 } = await import("node:fs");
567399
567438
  const { homedir: homedir46 } = await import("node:os");
567400
567439
  const modelName = basename21(onnxDrop.path, ".onnx").replace(/[^a-zA-Z0-9_-]/g, "-");
567401
567440
  const destDir = pathJoin(homedir46(), ".open-agents", "voice", "models", modelName);
567402
- if (!exists2(destDir)) mkdirSync67(destDir, { recursive: true });
567441
+ if (!exists2(destDir)) mkdirSync68(destDir, { recursive: true });
567403
567442
  copyFileSync3(onnxDrop.path, pathJoin(destDir, "model.onnx"));
567404
567443
  copyFileSync3(jsonDrop.path, pathJoin(destDir, "config.json"));
567405
567444
  const { registerCustomOnnxModel: registerCustomOnnxModel2 } = await Promise.resolve().then(() => (init_voice(), voice_exports));
@@ -568149,10 +568188,10 @@ async function handleSponsoredEndpoint(ctx3, local) {
568149
568188
  sponsors.push(...verified);
568150
568189
  if (verified.length > 0) {
568151
568190
  try {
568152
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = __require("node:fs");
568153
- mkdirSync67(sponsorDir2, { recursive: true });
568191
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = __require("node:fs");
568192
+ mkdirSync68(sponsorDir2, { recursive: true });
568154
568193
  const cached = verified.map((s2) => ({ ...s2, lastVerified: Date.now() }));
568155
- writeFileSync59(knownFile, JSON.stringify(cached, null, 2));
568194
+ writeFileSync60(knownFile, JSON.stringify(cached, null, 2));
568156
568195
  } catch {
568157
568196
  }
568158
568197
  }
@@ -568325,11 +568364,11 @@ async function handlePeerEndpoint(peerId, authKey, ctx3, local) {
568325
568364
  const models = await fetchModels(peerUrl, authKey);
568326
568365
  if (models.length > 0) {
568327
568366
  try {
568328
- const { writeFileSync: writeFileSync59, mkdirSync: mkdirSync67 } = await import("node:fs");
568329
- const { join: join128, dirname: dirname39 } = await import("node:path");
568330
- const cachePath = join128(ctx3.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
568331
- mkdirSync67(dirname39(cachePath), { recursive: true });
568332
- writeFileSync59(cachePath, JSON.stringify({
568367
+ const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68 } = await import("node:fs");
568368
+ const { join: join129, dirname: dirname39 } = await import("node:path");
568369
+ const cachePath = join129(ctx3.repoRoot || process.cwd(), ".oa", "nexus", "peer-models-cache.json");
568370
+ mkdirSync68(dirname39(cachePath), { recursive: true });
568371
+ writeFileSync60(cachePath, JSON.stringify({
568333
568372
  peerId,
568334
568373
  cachedAt: (/* @__PURE__ */ new Date()).toISOString(),
568335
568374
  models: models.map((m2) => ({ name: m2.name, size: m2.size, parameterSize: m2.parameterSize }))
@@ -568481,8 +568520,8 @@ ${escapedContent}EOF'`, { timeoutMs: 3e4 });
568481
568520
  }
568482
568521
  await new Promise((r2) => setTimeout(r2, 1e3));
568483
568522
  process.env.OLLAMA_NUM_PARALLEL = String(n2);
568484
- const { spawn: spawn27 } = await import("node:child_process");
568485
- const child = spawn27("ollama", ["serve"], {
568523
+ const { spawn: spawn28 } = await import("node:child_process");
568524
+ const child = spawn28("ollama", ["serve"], {
568486
568525
  stdio: "ignore",
568487
568526
  detached: true,
568488
568527
  env: { ...process.env, OLLAMA_NUM_PARALLEL: String(n2) }
@@ -568898,17 +568937,17 @@ async function handleUpdate(subcommand, ctx3) {
568898
568937
  try {
568899
568938
  const { createRequire: createRequire8 } = await import("node:module");
568900
568939
  const { fileURLToPath: fileURLToPath20 } = await import("node:url");
568901
- const { dirname: dirname39, join: join128 } = await import("node:path");
568902
- const { existsSync: existsSync110 } = await import("node:fs");
568940
+ const { dirname: dirname39, join: join129 } = await import("node:path");
568941
+ const { existsSync: existsSync111 } = await import("node:fs");
568903
568942
  const req2 = createRequire8(import.meta.url);
568904
568943
  const thisDir = dirname39(fileURLToPath20(import.meta.url));
568905
568944
  const candidates = [
568906
- join128(thisDir, "..", "package.json"),
568907
- join128(thisDir, "..", "..", "package.json"),
568908
- join128(thisDir, "..", "..", "..", "package.json")
568945
+ join129(thisDir, "..", "package.json"),
568946
+ join129(thisDir, "..", "..", "package.json"),
568947
+ join129(thisDir, "..", "..", "..", "package.json")
568909
568948
  ];
568910
568949
  for (const pkgPath of candidates) {
568911
- if (existsSync110(pkgPath)) {
568950
+ if (existsSync111(pkgPath)) {
568912
568951
  const pkg = req2(pkgPath);
568913
568952
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli") {
568914
568953
  currentVersion = pkg.version ?? "0.0.0";
@@ -570056,13 +570095,13 @@ var init_commands = __esm({
570056
570095
  try {
570057
570096
  const { randomBytes: randomBytes25 } = await import("node:crypto");
570058
570097
  const { homedir: homedir46 } = await import("node:os");
570059
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
570060
- const { join: join128 } = await import("node:path");
570098
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
570099
+ const { join: join129 } = await import("node:path");
570061
570100
  const apiKey = randomBytes25(16).toString("hex");
570062
570101
  process.env["OA_API_KEY"] = apiKey;
570063
- const dir = join128(homedir46(), ".open-agents");
570064
- mkdirSync67(dir, { recursive: true });
570065
- writeFileSync59(join128(dir, "api.key"), apiKey + "\n", "utf8");
570102
+ const dir = join129(homedir46(), ".open-agents");
570103
+ mkdirSync68(dir, { recursive: true });
570104
+ writeFileSync60(join129(dir, "api.key"), apiKey + "\n", "utf8");
570066
570105
  renderInfo2(`Generated API key: ${c3.bold(c3.yellow(apiKey))}`);
570067
570106
  renderInfo2("Use Authorization: Bearer <key> or click 'key' in the Web UI header to paste it.");
570068
570107
  } catch (e2) {
@@ -570077,11 +570116,11 @@ var init_commands = __esm({
570077
570116
  const port = parseInt(process.env["OA_PORT"] || "11435", 10);
570078
570117
  try {
570079
570118
  const { homedir: homedir46 } = await import("node:os");
570080
- const { mkdirSync: mkdirSync67, writeFileSync: writeFileSync59 } = await import("node:fs");
570081
- const { join: join128 } = await import("node:path");
570082
- const dir = join128(homedir46(), ".open-agents");
570083
- mkdirSync67(dir, { recursive: true });
570084
- writeFileSync59(join128(dir, "access"), `${val}
570119
+ const { mkdirSync: mkdirSync68, writeFileSync: writeFileSync60 } = await import("node:fs");
570120
+ const { join: join129 } = await import("node:path");
570121
+ const dir = join129(homedir46(), ".open-agents");
570122
+ mkdirSync68(dir, { recursive: true });
570123
+ writeFileSync60(join129(dir, "access"), `${val}
570085
570124
  `, "utf8");
570086
570125
  } catch {
570087
570126
  }
@@ -581893,11 +581932,11 @@ Telegram admin: @${msg.username}` : `Telegram ${isGroup ? "group" : "public"} ch
581893
581932
  let mimeType = "audio/wav";
581894
581933
  try {
581895
581934
  const { execSync: execSyncLocal } = await import("node:child_process");
581896
- const { tmpdir: tmpdir22 } = await import("node:os");
581935
+ const { tmpdir: tmpdir23 } = await import("node:os");
581897
581936
  const { join: joinPath } = await import("node:path");
581898
581937
  const { writeFileSync: writeFs, readFileSync: readFs, unlinkSync: unlinkFs } = await import("node:fs");
581899
- const tmpWav = joinPath(tmpdir22(), `oa-tg-voice-${Date.now()}.wav`);
581900
- const tmpOgg = joinPath(tmpdir22(), `oa-tg-voice-${Date.now()}.ogg`);
581938
+ const tmpWav = joinPath(tmpdir23(), `oa-tg-voice-${Date.now()}.wav`);
581939
+ const tmpOgg = joinPath(tmpdir23(), `oa-tg-voice-${Date.now()}.ogg`);
581901
581940
  writeFs(tmpWav, wavBuffer);
581902
581941
  execSyncLocal(`ffmpeg -i "${tmpWav}" -c:a libopus -b:a 48k -ar 48000 -ac 1 "${tmpOgg}" -y 2>/dev/null`, {
581903
581942
  timeout: 15e3,
@@ -585772,9 +585811,131 @@ var init_tor_fallback = __esm({
585772
585811
  }
585773
585812
  });
585774
585813
 
585814
+ // packages/cli/src/api/graphical-sudo.ts
585815
+ var graphical_sudo_exports = {};
585816
+ __export(graphical_sudo_exports, {
585817
+ detectSudoHelper: () => detectSudoHelper,
585818
+ runGraphicalSudo: () => runGraphicalSudo
585819
+ });
585820
+ import { spawn as spawn24 } from "node:child_process";
585821
+ import { existsSync as existsSync102, mkdirSync as mkdirSync60, writeFileSync as writeFileSync52, chmodSync as chmodSync2 } from "node:fs";
585822
+ import { join as join118 } from "node:path";
585823
+ import { tmpdir as tmpdir21 } from "node:os";
585824
+ function detectSudoHelper() {
585825
+ if (process.platform === "win32") return null;
585826
+ if (process.platform === "darwin") return "osascript";
585827
+ if (which("pkexec")) return "pkexec";
585828
+ if (which("ssh-askpass")) return "ssh-askpass";
585829
+ if (which("zenity")) return "zenity";
585830
+ if (which("kdialog")) return "kdialog";
585831
+ if (which("sudo")) return "sudo-tty";
585832
+ return null;
585833
+ }
585834
+ function which(cmd) {
585835
+ const path8 = process.env["PATH"] || "/usr/bin:/bin:/usr/local/bin";
585836
+ for (const dir of path8.split(":")) {
585837
+ if (!dir) continue;
585838
+ const full = join118(dir, cmd);
585839
+ if (existsSync102(full)) return full;
585840
+ }
585841
+ return null;
585842
+ }
585843
+ function ensureAskpassShim(helper, description) {
585844
+ const shimDir = join118(tmpdir21(), "oa-askpass");
585845
+ mkdirSync60(shimDir, { recursive: true });
585846
+ const shim = join118(shimDir, `${helper}.sh`);
585847
+ let body;
585848
+ if (helper === "zenity") {
585849
+ body = `#!/bin/sh
585850
+ exec zenity --password --title="OA needs sudo" --text="${description.replace(/"/g, '\\"')}" 2>/dev/null
585851
+ `;
585852
+ } else {
585853
+ body = `#!/bin/sh
585854
+ exec kdialog --password "${description.replace(/"/g, '\\"')}" 2>/dev/null
585855
+ `;
585856
+ }
585857
+ writeFileSync52(shim, body, "utf-8");
585858
+ chmodSync2(shim, 493);
585859
+ return shim;
585860
+ }
585861
+ async function runGraphicalSudo(opts) {
585862
+ const helper = detectSudoHelper();
585863
+ const description = opts.description || "Open Agents needs admin access to set up Tor (.onion hidden service)";
585864
+ const timeoutMs = opts.timeoutMs ?? 5 * 6e4;
585865
+ if (!helper) throw new Error("No suitable sudo helper found (pkexec, zenity, kdialog, ssh-askpass).");
585866
+ let cmd;
585867
+ let args;
585868
+ let extraEnv = {};
585869
+ const envFlags = [];
585870
+ for (const [k, v] of Object.entries(opts.env || {})) envFlags.push(`${k}=${v}`);
585871
+ if (helper === "pkexec") {
585872
+ cmd = "pkexec";
585873
+ args = [];
585874
+ if (envFlags.length) args.push(...envFlags.flatMap((e2) => ["--user", "root", "env", e2]));
585875
+ args = ["env", ...envFlags, "/bin/bash", opts.scriptPath, ...opts.args ?? []];
585876
+ } else if (helper === "osascript") {
585877
+ const inner = `${envFlags.map((e2) => `${e2}`).join(" ")} /bin/bash ${shellQuote(opts.scriptPath)} ${shellQuote((opts.args ?? []).join(" "))}`.trim();
585878
+ cmd = "osascript";
585879
+ args = ["-e", `do shell script "${inner.replace(/"/g, '\\"')}" with administrator privileges`];
585880
+ } else if (helper === "ssh-askpass" || helper === "zenity" || helper === "kdialog") {
585881
+ const shim = helper === "ssh-askpass" ? which("ssh-askpass") : ensureAskpassShim(helper, description);
585882
+ extraEnv = { ...extraEnv, SUDO_ASKPASS: shim, DISPLAY: process.env["DISPLAY"] || ":0" };
585883
+ cmd = "sudo";
585884
+ args = ["-A", "-E", "/bin/bash", opts.scriptPath, ...opts.args ?? []];
585885
+ } else {
585886
+ cmd = "sudo";
585887
+ args = ["/bin/bash", opts.scriptPath, ...opts.args ?? []];
585888
+ }
585889
+ return new Promise((resolve43, reject) => {
585890
+ const child = spawn24(cmd, args, {
585891
+ env: { ...process.env, ...opts.env || {}, ...extraEnv },
585892
+ stdio: ["ignore", "pipe", "pipe"]
585893
+ });
585894
+ let stdout = "";
585895
+ let stderr = "";
585896
+ let timedOut = false;
585897
+ const timer = setTimeout(() => {
585898
+ timedOut = true;
585899
+ try {
585900
+ child.kill("SIGTERM");
585901
+ } catch {
585902
+ }
585903
+ setTimeout(() => {
585904
+ try {
585905
+ child.kill("SIGKILL");
585906
+ } catch {
585907
+ }
585908
+ }, 2e3);
585909
+ }, timeoutMs);
585910
+ child.stdout.on("data", (d2) => {
585911
+ stdout += d2.toString("utf-8");
585912
+ });
585913
+ child.stderr.on("data", (d2) => {
585914
+ stderr += d2.toString("utf-8");
585915
+ });
585916
+ child.on("error", (e2) => {
585917
+ clearTimeout(timer);
585918
+ reject(e2);
585919
+ });
585920
+ child.on("close", (code8) => {
585921
+ clearTimeout(timer);
585922
+ if (timedOut) return reject(new Error(`graphical sudo timed out after ${timeoutMs}ms`));
585923
+ resolve43({ code: code8 ?? -1, stdout, stderr, helper });
585924
+ });
585925
+ });
585926
+ }
585927
+ function shellQuote(s2) {
585928
+ return "'" + s2.replace(/'/g, "'\\''") + "'";
585929
+ }
585930
+ var init_graphical_sudo = __esm({
585931
+ "packages/cli/src/api/graphical-sudo.ts"() {
585932
+ "use strict";
585933
+ }
585934
+ });
585935
+
585775
585936
  // packages/cli/src/api/routes-v1.ts
585776
- import { existsSync as existsSync102, readFileSync as readFileSync83, readdirSync as readdirSync34, statSync as statSync34 } from "node:fs";
585777
- import { join as join118, resolve as pathResolve2 } from "node:path";
585937
+ import { existsSync as existsSync103, readFileSync as readFileSync83, readdirSync as readdirSync34, statSync as statSync34 } from "node:fs";
585938
+ import { join as join119, resolve as pathResolve2 } from "node:path";
585778
585939
  import { homedir as homedir40 } from "node:os";
585779
585940
  async function tryRouteV1(ctx3) {
585780
585941
  const { pathname, method } = ctx3;
@@ -585859,6 +586020,9 @@ async function tryRouteV1(ctx3) {
585859
586020
  }
585860
586021
  if (pathname === "/v1/share/generate" && method === "POST") return handleGenerateShare(ctx3);
585861
586022
  if (pathname === "/v1/remote-proxy" && method === "POST") return handleRemoteProxy(ctx3);
586023
+ if (pathname === "/v1/tor/status" && method === "GET") return handleTorStatus(ctx3);
586024
+ if (pathname === "/v1/tor/enable" && method === "POST") return handleTorEnable(ctx3);
586025
+ if (pathname === "/v1/tor/disable" && method === "POST") return handleTorDisable(ctx3);
585862
586026
  if (pathname === "/v1/tools" && method === "GET") {
585863
586027
  return handleListTools(ctx3);
585864
586028
  }
@@ -586005,11 +586169,11 @@ async function handleGetSkill(ctx3, name10) {
586005
586169
  async function fallbackDiscoverSkills() {
586006
586170
  return (_root) => {
586007
586171
  const roots = [
586008
- join118(homedir40(), ".local", "share", "ai-writing-guide")
586172
+ join119(homedir40(), ".local", "share", "ai-writing-guide")
586009
586173
  ];
586010
586174
  const out = [];
586011
586175
  for (const root of roots) {
586012
- if (!existsSync102(root)) continue;
586176
+ if (!existsSync103(root)) continue;
586013
586177
  walkForSkills(root, out, 0);
586014
586178
  }
586015
586179
  return out;
@@ -586020,7 +586184,7 @@ function walkForSkills(dir, out, depth) {
586020
586184
  try {
586021
586185
  for (const e2 of readdirSync34(dir, { withFileTypes: true })) {
586022
586186
  if (e2.name.startsWith(".") || e2.name === "node_modules") continue;
586023
- const p2 = join118(dir, e2.name);
586187
+ const p2 = join119(dir, e2.name);
586024
586188
  if (e2.isDirectory()) {
586025
586189
  walkForSkills(p2, out, depth + 1);
586026
586190
  } else if (e2.isFile() && e2.name === "SKILL.md") {
@@ -586209,7 +586373,7 @@ async function getMemoryStores() {
586209
586373
  if (memoryInitTried) return null;
586210
586374
  memoryInitTried = true;
586211
586375
  try {
586212
- const dbPath = join118(homedir40(), ".open-agents", "memory.db");
586376
+ const dbPath = join119(homedir40(), ".open-agents", "memory.db");
586213
586377
  const sharedDb = initDb(dbPath);
586214
586378
  memoryStoresCache = {
586215
586379
  episode: new EpisodeStore(dbPath),
@@ -586467,7 +586631,7 @@ async function handleFilesRead(ctx3) {
586467
586631
  }));
586468
586632
  return true;
586469
586633
  }
586470
- if (!existsSync102(resolved)) {
586634
+ if (!existsSync103(resolved)) {
586471
586635
  sendProblem(res, problemDetails({
586472
586636
  type: P.notFound,
586473
586637
  status: 404,
@@ -586732,12 +586896,12 @@ async function handleNexusStatus(ctx3) {
586732
586896
  const { res, requestId } = ctx3;
586733
586897
  try {
586734
586898
  const statePaths = [
586735
- join118(process.cwd(), ".oa", "nexus-peer-state.json"),
586736
- join118(homedir40(), ".open-agents", "nexus-peer-cache.json")
586899
+ join119(process.cwd(), ".oa", "nexus-peer-state.json"),
586900
+ join119(homedir40(), ".open-agents", "nexus-peer-cache.json")
586737
586901
  ];
586738
586902
  const states = [];
586739
586903
  for (const p2 of statePaths) {
586740
- if (!existsSync102(p2)) continue;
586904
+ if (!existsSync103(p2)) continue;
586741
586905
  try {
586742
586906
  const raw = readFileSync83(p2, "utf-8");
586743
586907
  states.push({ source: p2, data: JSON.parse(raw) });
@@ -586766,8 +586930,8 @@ async function handleNexusStatus(ctx3) {
586766
586930
  }
586767
586931
  function loadAgentName() {
586768
586932
  try {
586769
- const p2 = join118(homedir40(), ".open-agents", "agent-name");
586770
- if (existsSync102(p2)) return readFileSync83(p2, "utf-8").trim();
586933
+ const p2 = join119(homedir40(), ".open-agents", "agent-name");
586934
+ if (existsSync103(p2)) return readFileSync83(p2, "utf-8").trim();
586771
586935
  } catch {
586772
586936
  }
586773
586937
  return null;
@@ -586776,12 +586940,12 @@ async function handleSponsors(ctx3) {
586776
586940
  const { req: req2, res, url, requestId } = ctx3;
586777
586941
  try {
586778
586942
  const candidates = [
586779
- join118(homedir40(), ".open-agents", "sponsor-cache.json"),
586780
- join118(homedir40(), ".open-agents", "sponsors.json")
586943
+ join119(homedir40(), ".open-agents", "sponsor-cache.json"),
586944
+ join119(homedir40(), ".open-agents", "sponsors.json")
586781
586945
  ];
586782
586946
  let sponsors = [];
586783
586947
  for (const p2 of candidates) {
586784
- if (!existsSync102(p2)) continue;
586948
+ if (!existsSync103(p2)) continue;
586785
586949
  try {
586786
586950
  const raw = JSON.parse(readFileSync83(p2, "utf-8"));
586787
586951
  if (Array.isArray(raw)) {
@@ -586852,8 +587016,8 @@ async function handleEvaluate(ctx3) {
586852
587016
  }));
586853
587017
  return true;
586854
587018
  }
586855
- const jobPath = join118(process.cwd(), ".oa", "jobs", `${runId}.json`);
586856
- if (!existsSync102(jobPath)) {
587019
+ const jobPath = join119(process.cwd(), ".oa", "jobs", `${runId}.json`);
587020
+ if (!existsSync103(jobPath)) {
586857
587021
  sendProblem(res, problemDetails({
586858
587022
  type: P.notFound,
586859
587023
  status: 404,
@@ -587000,23 +587164,211 @@ async function handleMintKey(ctx3) {
587000
587164
  }
587001
587165
  return true;
587002
587166
  }
587167
+ function _readStatusFile(p2) {
587168
+ if (!existsSync103(p2)) return null;
587169
+ try {
587170
+ const data = JSON.parse(readFileSync83(p2, "utf-8"));
587171
+ if (data?.connected && typeof data.peerId === "string" && data.peerId.length > 10) {
587172
+ return {
587173
+ peerId: data.peerId,
587174
+ agentName: typeof data.agentName === "string" ? data.agentName : null,
587175
+ source: p2
587176
+ };
587177
+ }
587178
+ } catch {
587179
+ }
587180
+ return null;
587181
+ }
587003
587182
  function resolveLocalPeerId() {
587183
+ const override = process.env["OA_NEXUS_DIR"];
587184
+ if (override) {
587185
+ const r2 = _readStatusFile(join119(override, "status.json"));
587186
+ if (r2) return r2;
587187
+ }
587188
+ try {
587189
+ const regPath = join119(homedir40(), ".open-agents", "nexus-registry.json");
587190
+ if (existsSync103(regPath)) {
587191
+ const reg = JSON.parse(readFileSync83(regPath, "utf-8"));
587192
+ const entries = Array.isArray(reg?.dirs) ? reg.dirs : [];
587193
+ for (const entry of entries) {
587194
+ const dir = typeof entry === "string" ? entry : entry?.dir;
587195
+ if (typeof dir === "string") {
587196
+ const r2 = _readStatusFile(join119(dir, "status.json"));
587197
+ if (r2) return r2;
587198
+ }
587199
+ }
587200
+ }
587201
+ } catch {
587202
+ }
587004
587203
  const candidates = [
587005
- join118(process.cwd(), ".oa", "nexus", "status.json"),
587006
- join118(homedir40(), ".oa", "nexus", "status.json"),
587007
- join118(homedir40(), ".open-agents", "nexus", "status.json")
587204
+ join119(process.cwd(), ".oa", "nexus", "status.json"),
587205
+ join119(homedir40(), ".oa", "nexus", "status.json"),
587206
+ join119(homedir40(), ".open-agents", "nexus", "status.json")
587008
587207
  ];
587009
587208
  for (const p2 of candidates) {
587010
- if (!existsSync102(p2)) continue;
587011
- try {
587012
- const data = JSON.parse(readFileSync83(p2, "utf-8"));
587013
- if (data?.connected && typeof data.peerId === "string" && data.peerId.length > 10) {
587014
- return { peerId: data.peerId, agentName: typeof data.agentName === "string" ? data.agentName : null, source: p2 };
587209
+ const r2 = _readStatusFile(p2);
587210
+ if (r2) return r2;
587211
+ }
587212
+ const now = Date.now();
587213
+ if (_peerIdScanCache && now - _peerIdScanCache.ts < 6e4) {
587214
+ return _peerIdScanCache.result;
587215
+ }
587216
+ let scanResult = null;
587217
+ try {
587218
+ const { execSync: execSync59 } = __require("node:child_process");
587219
+ const cmd = `find "${homedir40()}" -maxdepth 4 -path '*/.oa/nexus/status.json' -type f 2>/dev/null | head -50`;
587220
+ const out = execSync59(cmd, { encoding: "utf-8", timeout: 2e3 }).trim();
587221
+ for (const line of out.split("\n")) {
587222
+ const f2 = line.trim();
587223
+ if (!f2) continue;
587224
+ const r2 = _readStatusFile(f2);
587225
+ if (r2) {
587226
+ scanResult = r2;
587227
+ break;
587015
587228
  }
587016
- } catch {
587017
587229
  }
587230
+ } catch {
587018
587231
  }
587019
- return null;
587232
+ _peerIdScanCache = { ts: now, result: scanResult };
587233
+ return scanResult;
587234
+ }
587235
+ async function handleTorStatus(ctx3) {
587236
+ const { res } = ctx3;
587237
+ const { getLocalOnion: getLocalOnion2, torIsReachable: torIsReachable2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
587238
+ const { detectSudoHelper: detectSudoHelper2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
587239
+ const onion = getLocalOnion2();
587240
+ const reachable = await torIsReachable2();
587241
+ sendJson(res, 200, {
587242
+ onion,
587243
+ socks5_reachable: reachable,
587244
+ sudo_helper: detectSudoHelper2()
587245
+ });
587246
+ return true;
587247
+ }
587248
+ async function handleTorEnable(ctx3) {
587249
+ const { req: req2, res, requestId } = ctx3;
587250
+ const reqAuth = req2;
587251
+ if (reqAuth._authScope !== "admin") {
587252
+ sendProblem(res, problemDetails({
587253
+ type: P.forbidden,
587254
+ status: 403,
587255
+ title: "Admin scope required",
587256
+ detail: "Tor setup requires elevated privileges; only admin keys can request it.",
587257
+ instance: requestId
587258
+ }));
587259
+ return true;
587260
+ }
587261
+ const { getLocalOnion: getLocalOnion2 } = await Promise.resolve().then(() => (init_tor_fallback(), tor_fallback_exports));
587262
+ if (getLocalOnion2()) {
587263
+ sendJson(res, 409, {
587264
+ status: "already_configured",
587265
+ onion: getLocalOnion2(),
587266
+ _note: "Tor hidden service already exists. Use /v1/tor/disable to remove."
587267
+ });
587268
+ return true;
587269
+ }
587270
+ let scriptPath2 = null;
587271
+ try {
587272
+ const candidates = [
587273
+ join119(process.cwd(), "scripts", "tor", "tor_setup.sh"),
587274
+ join119(__dirname, "..", "..", "scripts", "tor", "tor_setup.sh"),
587275
+ join119(__dirname, "..", "scripts", "tor", "tor_setup.sh")
587276
+ ];
587277
+ for (const p2 of candidates) {
587278
+ if (existsSync103(p2)) {
587279
+ scriptPath2 = p2;
587280
+ break;
587281
+ }
587282
+ }
587283
+ if (!scriptPath2) {
587284
+ const { execSync: execSync59 } = __require("node:child_process");
587285
+ const root = execSync59("npm root -g", { encoding: "utf-8", timeout: 5e3 }).trim();
587286
+ const p2 = join119(root, "open-agents-ai", "scripts", "tor", "tor_setup.sh");
587287
+ if (existsSync103(p2)) scriptPath2 = p2;
587288
+ }
587289
+ } catch {
587290
+ }
587291
+ if (!scriptPath2) {
587292
+ sendProblem(res, problemDetails({
587293
+ type: P.internalError,
587294
+ status: 500,
587295
+ title: "tor_setup.sh not found",
587296
+ detail: "Could not locate the bundled Tor setup script.",
587297
+ instance: requestId
587298
+ }));
587299
+ return true;
587300
+ }
587301
+ const { detectSudoHelper: detectSudoHelper2, runGraphicalSudo: runGraphicalSudo2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
587302
+ const helper = detectSudoHelper2();
587303
+ if (!helper) {
587304
+ sendProblem(res, problemDetails({
587305
+ type: P.internalError,
587306
+ status: 503,
587307
+ title: "No graphical sudo helper",
587308
+ detail: "Install one of: pkexec (PolKit), zenity, kdialog, or ssh-askpass — then retry.",
587309
+ instance: requestId
587310
+ }));
587311
+ return true;
587312
+ }
587313
+ sendJson(res, 202, {
587314
+ status: "accepted",
587315
+ helper,
587316
+ script: scriptPath2,
587317
+ poll: "/v1/tor/status"
587318
+ });
587319
+ const apiPort = req2.socket?.localPort || parseInt(process.env["OA_API_PORT"] || "11435", 10);
587320
+ runGraphicalSudo2({
587321
+ scriptPath: scriptPath2,
587322
+ env: { OA_API_PORT: String(apiPort) },
587323
+ description: "Open Agents needs admin access to install Tor and configure a hidden service"
587324
+ }).then((r2) => {
587325
+ if (r2.code !== 0) {
587326
+ console.warn(`[tor-enable] sudo helper ${r2.helper} exited ${r2.code}: ${r2.stderr.slice(-300)}`);
587327
+ }
587328
+ }).catch((e2) => {
587329
+ console.warn(`[tor-enable] failed: ${e2 instanceof Error ? e2.message : String(e2)}`);
587330
+ });
587331
+ return true;
587332
+ }
587333
+ async function handleTorDisable(ctx3) {
587334
+ const { req: req2, res, requestId } = ctx3;
587335
+ const reqAuth = req2;
587336
+ if (reqAuth._authScope !== "admin") {
587337
+ sendProblem(res, problemDetails({
587338
+ type: P.forbidden,
587339
+ status: 403,
587340
+ title: "Admin scope required",
587341
+ detail: "Tor teardown requires admin scope.",
587342
+ instance: requestId
587343
+ }));
587344
+ return true;
587345
+ }
587346
+ let scriptPath2 = null;
587347
+ const candidates = [
587348
+ join119(process.cwd(), "scripts", "tor", "destroy_tor.sh"),
587349
+ join119(__dirname, "..", "..", "scripts", "tor", "destroy_tor.sh"),
587350
+ join119(__dirname, "..", "scripts", "tor", "destroy_tor.sh")
587351
+ ];
587352
+ for (const p2 of candidates) {
587353
+ if (existsSync103(p2)) {
587354
+ scriptPath2 = p2;
587355
+ break;
587356
+ }
587357
+ }
587358
+ if (!scriptPath2) {
587359
+ sendProblem(res, problemDetails({
587360
+ type: P.internalError,
587361
+ status: 500,
587362
+ title: "destroy_tor.sh not found",
587363
+ detail: "Bundled teardown script missing.",
587364
+ instance: requestId
587365
+ }));
587366
+ return true;
587367
+ }
587368
+ const { runGraphicalSudo: runGraphicalSudo2 } = await Promise.resolve().then(() => (init_graphical_sudo(), graphical_sudo_exports));
587369
+ sendJson(res, 202, { status: "accepted", script: scriptPath2 });
587370
+ runGraphicalSudo2({ scriptPath: scriptPath2, description: "Open Agents needs admin access to remove the Tor hidden service" }).catch((e2) => console.warn(`[tor-disable] failed: ${e2 instanceof Error ? e2.message : String(e2)}`));
587371
+ return true;
587020
587372
  }
587021
587373
  async function handleGenerateShare(ctx3) {
587022
587374
  const { req: req2, res, requestId } = ctx3;
@@ -587085,9 +587437,11 @@ async function handleGenerateShare(ctx3) {
587085
587437
  if (onion) plainParams.push(`oa-onion=${encodeURIComponent(onion)}`);
587086
587438
  plainParams.push(`oa-share-label=${encodeURIComponent(label)}`);
587087
587439
  const plainUrl = `${scheme}://${hostPort}/?${plainParams.join("&")}`;
587440
+ const torShareUrl = onion ? `oa-share-tor://${onion}#${fullKey}` : null;
587088
587441
  sendJson(res, 201, {
587089
587442
  shareUrl,
587090
587443
  plainUrl,
587444
+ torShareUrl,
587091
587445
  mode,
587092
587446
  peerId: peerInfo?.peerId || null,
587093
587447
  onion: onion || null,
@@ -587103,7 +587457,7 @@ async function handleGenerateShare(ctx3) {
587103
587457
  tor: !!onion,
587104
587458
  direct: !peerInfo
587105
587459
  },
587106
- _note: peerInfo && onion ? "Globally reachable via libp2p (primary) and Tor (.onion fallback)." : peerInfo ? "Globally reachable via libp2p. For maximum reach add Tor: see scripts/tor/tor_setup.sh." : "Nexus daemon offline — URL is direct-HTTP only (LAN/VPN reach). Start nexus for global reach."
587460
+ _note: peerInfo && onion ? "Globally reachable via libp2p (primary) and Tor (.onion fallback)." : peerInfo ? "Globally reachable via libp2p. For maximum reach add Tor: run `oa tor enable`." : onion ? "Globally reachable via Tor only (.onion). Start nexus for libp2p tier." : "Nexus offline + no Tor — URL is direct-HTTP only (LAN/VPN reach)."
587107
587461
  });
587108
587462
  } catch (err) {
587109
587463
  sendProblem(res, problemDetails({
@@ -587161,13 +587515,13 @@ async function handleRemoteProxy(ctx3) {
587161
587515
  return true;
587162
587516
  }
587163
587517
  const nexusCandidates = [
587164
- join118(process.cwd(), ".oa", "nexus"),
587165
- join118(homedir40(), ".oa", "nexus"),
587166
- join118(homedir40(), ".open-agents", "nexus")
587518
+ join119(process.cwd(), ".oa", "nexus"),
587519
+ join119(homedir40(), ".oa", "nexus"),
587520
+ join119(homedir40(), ".open-agents", "nexus")
587167
587521
  ];
587168
587522
  let nexusDirPath = null;
587169
587523
  for (const p2 of nexusCandidates) {
587170
- if (existsSync102(join118(p2, "status.json"))) {
587524
+ if (existsSync103(join119(p2, "status.json"))) {
587171
587525
  nexusDirPath = p2;
587172
587526
  break;
587173
587527
  }
@@ -587263,7 +587617,7 @@ async function handleRemoteProxy(ctx3) {
587263
587617
  }));
587264
587618
  return true;
587265
587619
  }
587266
- const streamFile = join118(nexusDirPath, `tunnel-${requestId}-${Date.now()}.jsonl`);
587620
+ const streamFile = join119(nexusDirPath, `tunnel-${requestId}-${Date.now()}.jsonl`);
587267
587621
  try {
587268
587622
  const { writeFileSync: _wfs } = await import("node:fs");
587269
587623
  _wfs(streamFile, "");
@@ -587706,14 +588060,14 @@ async function handleListEngines(ctx3) {
587706
588060
  const home = homedir40();
587707
588061
  sendJson(res, 200, {
587708
588062
  engines: [
587709
- { name: "dream", state_file: join118(process.cwd(), ".oa", "dreams"), controllable_via: "SSE + slash commands" },
587710
- { name: "bless", state_file: join118(process.cwd(), ".oa", "bless-state.json"), controllable_via: "slash commands" },
587711
- { name: "call", state_file: join118(process.cwd(), ".oa", "call-state.json"), controllable_via: "slash commands" },
587712
- { name: "listen", state_file: join118(process.cwd(), ".oa", "listen-state.json"), controllable_via: "slash commands" },
587713
- { name: "telegram", state_file: join118(home, ".open-agents", "telegram-state.json"), controllable_via: "slash commands" },
587714
- { name: "expose", state_file: join118(process.cwd(), ".oa", "expose-state.json"), controllable_via: "/expose commands" },
587715
- { name: "nexus", state_file: join118(home, ".open-agents", "nexus-peer-cache.json"), controllable_via: "/nexus commands" },
587716
- { name: "ipfs", state_file: join118(process.cwd(), ".oa", "ipfs"), controllable_via: "slash commands" }
588063
+ { name: "dream", state_file: join119(process.cwd(), ".oa", "dreams"), controllable_via: "SSE + slash commands" },
588064
+ { name: "bless", state_file: join119(process.cwd(), ".oa", "bless-state.json"), controllable_via: "slash commands" },
588065
+ { name: "call", state_file: join119(process.cwd(), ".oa", "call-state.json"), controllable_via: "slash commands" },
588066
+ { name: "listen", state_file: join119(process.cwd(), ".oa", "listen-state.json"), controllable_via: "slash commands" },
588067
+ { name: "telegram", state_file: join119(home, ".open-agents", "telegram-state.json"), controllable_via: "slash commands" },
588068
+ { name: "expose", state_file: join119(process.cwd(), ".oa", "expose-state.json"), controllable_via: "/expose commands" },
588069
+ { name: "nexus", state_file: join119(home, ".open-agents", "nexus-peer-cache.json"), controllable_via: "/nexus commands" },
588070
+ { name: "ipfs", state_file: join119(process.cwd(), ".oa", "ipfs"), controllable_via: "slash commands" }
587717
588071
  ],
587718
588072
  note: "Engine instrumentation lives in the running TUI process. Full status + control requires the daemon↔TUI bridge (PT-07). See parity audit WO-PARITY-04."
587719
588073
  });
@@ -587796,21 +588150,21 @@ async function tryAimsRoute(ctx3) {
587796
588150
  return false;
587797
588151
  }
587798
588152
  function aimsDir() {
587799
- return join118(homedir40(), ".open-agents", "aims");
588153
+ return join119(homedir40(), ".open-agents", "aims");
587800
588154
  }
587801
588155
  function readAimsFile(name10, fallback) {
587802
588156
  try {
587803
- const p2 = join118(aimsDir(), name10);
587804
- if (existsSync102(p2)) return JSON.parse(readFileSync83(p2, "utf-8"));
588157
+ const p2 = join119(aimsDir(), name10);
588158
+ if (existsSync103(p2)) return JSON.parse(readFileSync83(p2, "utf-8"));
587805
588159
  } catch {
587806
588160
  }
587807
588161
  return fallback;
587808
588162
  }
587809
588163
  function writeAimsFile(name10, data) {
587810
588164
  const dir = aimsDir();
587811
- const { mkdirSync: mkdirSync67, writeFileSync: wf, renameSync: rn } = __require("node:fs");
587812
- mkdirSync67(dir, { recursive: true });
587813
- const finalPath = join118(dir, name10);
588165
+ const { mkdirSync: mkdirSync68, writeFileSync: wf, renameSync: rn } = __require("node:fs");
588166
+ mkdirSync68(dir, { recursive: true });
588167
+ const finalPath = join119(dir, name10);
587814
588168
  const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
587815
588169
  try {
587816
588170
  wf(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode: 384 });
@@ -588140,10 +588494,10 @@ async function handleAimsSuppliers(ctx3) {
588140
588494
  }
588141
588495
  ];
588142
588496
  const sponsorPaths = [
588143
- join118(homedir40(), ".open-agents", "sponsor-cache.json")
588497
+ join119(homedir40(), ".open-agents", "sponsor-cache.json")
588144
588498
  ];
588145
588499
  for (const p2 of sponsorPaths) {
588146
- if (!existsSync102(p2)) continue;
588500
+ if (!existsSync103(p2)) continue;
588147
588501
  try {
588148
588502
  const raw = JSON.parse(readFileSync83(p2, "utf-8"));
588149
588503
  const list = Array.isArray(raw) ? raw : raw?.sponsors ?? [];
@@ -588287,7 +588641,7 @@ async function handleAimsConfigHistory(ctx3) {
588287
588641
  return true;
588288
588642
  }
588289
588643
  }
588290
- var PROBLEM_BASE, P, mcpManagerCache, memoryStoresCache, memoryInitTried, FILE_READ_MAX_BYTES, _aimsLocks;
588644
+ var PROBLEM_BASE, P, mcpManagerCache, memoryStoresCache, memoryInitTried, FILE_READ_MAX_BYTES, _peerIdScanCache, _aimsLocks;
588291
588645
  var init_routes_v1 = __esm({
588292
588646
  "packages/cli/src/api/routes-v1.ts"() {
588293
588647
  "use strict";
@@ -588313,6 +588667,7 @@ var init_routes_v1 = __esm({
588313
588667
  memoryStoresCache = null;
588314
588668
  memoryInitTried = false;
588315
588669
  FILE_READ_MAX_BYTES = 2 * 1024 * 1024;
588670
+ _peerIdScanCache = null;
588316
588671
  _aimsLocks = /* @__PURE__ */ new Map();
588317
588672
  }
588318
588673
  });
@@ -591669,6 +592024,19 @@ function _looksLikePeerId(s) {
591669
592024
  function parseShareInput(raw) {
591670
592025
  const v = String(raw || '').trim();
591671
592026
  if (!v) return null;
592027
+ // oa-share-tor scheme — Tor-only routing via SOCKS5 to <onion>:80
592028
+ if (v.toLowerCase().startsWith('oa-share-tor://')) {
592029
+ const after = v.slice('oa-share-tor://'.length);
592030
+ const hashIdx = after.indexOf('#');
592031
+ if (hashIdx < 0) return null;
592032
+ const onionRaw = after.slice(0, hashIdx);
592033
+ // Strip optional :port suffix; we always dial 80 since hidden services
592034
+ // are configured to forward 80 → local API per the leek_messenger setup.
592035
+ const onion = onionRaw.split(':')[0];
592036
+ const key = after.slice(hashIdx + 1);
592037
+ if (!onion.endsWith('.onion') || !key) return null;
592038
+ return { peerId: null, onion, host: null, key, scheme: 'tor' };
592039
+ }
591672
592040
  // oa-share scheme — custom parser since URL() doesn't always honor it.
591673
592041
  if (v.toLowerCase().startsWith('oa-share://')) {
591674
592042
  const after = v.slice('oa-share://'.length);
@@ -591829,10 +592197,25 @@ async function generateShareUrl() {
591829
592197
  const j = await r.json();
591830
592198
  const safeShare = escapeHtml(j.shareUrl || '');
591831
592199
  const safePlain = escapeHtml(j.plainUrl || '');
592200
+ const safeTor = escapeHtml(j.torShareUrl || '');
592201
+ const torRow = j.torShareUrl
592202
+ ? '<div style="margin:6px 0">' +
592203
+ '<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">tor-only URL (.onion routed via SOCKS5 — works through any firewall)</label>' +
592204
+ '<div style="display:flex;gap:6px;align-items:center">' +
592205
+ '<input readonly value="' + safeTor + '" style="flex:1;background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:5px 8px;border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:0.74rem">' +
592206
+ '<button type="button" onclick="copyShareUrl(\\'tor\\')" style="font-size:0.74rem">copy</button>' +
592207
+ '</div>' +
592208
+ '</div>'
592209
+ : '<div style="margin:8px 0;padding:8px;background:var(--color-bg-input);border:1px dashed var(--color-border);border-radius:var(--radius-sm)">' +
592210
+ '<div style="font-size:0.74rem;margin-bottom:4px">Tor (.onion) is not configured on this OA.</div>' +
592211
+ '<div style="font-size:0.68rem;color:var(--color-fg-muted);margin-bottom:6px">Enable Tor for global reach when libp2p fails. Asks for sudo via your system password dialog.</div>' +
592212
+ '<button type="button" onclick="enableTorShare()" style="font-size:0.74rem;background:var(--color-accent);color:#fff;border:none;padding:4px 12px;border-radius:var(--radius-sm);cursor:pointer">enable Tor</button>' +
592213
+ '<span id="enable-tor-status" style="font-size:0.68rem;margin-left:8px;color:var(--color-fg-muted)"></span>' +
592214
+ '</div>';
591832
592215
  out.innerHTML =
591833
592216
  '<div style="font-weight:500;margin-bottom:6px;color:var(--color-success)">✓ Share URL generated — hand off to remote</div>' +
591834
592217
  '<div style="margin:6px 0">' +
591835
- '<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">oa-share URL (compact, recommended for OA-to-OA)</label>' +
592218
+ '<label style="display:block;font-size:0.7rem;color:var(--color-fg-muted);margin-bottom:2px">oa-share URL (libp2p, compact, recommended for OA-to-OA)</label>' +
591836
592219
  '<div style="display:flex;gap:6px;align-items:center">' +
591837
592220
  '<input readonly value="' + safeShare + '" style="flex:1;background:var(--color-bg-input);border:1px solid var(--color-border);color:var(--color-fg);padding:5px 8px;border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:0.74rem">' +
591838
592221
  '<button type="button" onclick="copyShareUrl(\\'oa-share\\')" style="font-size:0.74rem">copy</button>' +
@@ -591845,17 +592228,22 @@ async function generateShareUrl() {
591845
592228
  '<button type="button" onclick="copyShareUrl(\\'plain\\')" style="font-size:0.74rem">copy</button>' +
591846
592229
  '</div>' +
591847
592230
  '</div>' +
591848
- '<p style="font-size:0.68rem;color:var(--color-fg-muted);margin:6px 0 0">Note: this URL contains the full secret. Anyone with it can use this OA. To revoke: open Advanced settings → keys → revoke the prefix <code>' + escapeHtml(j.keyPrefix || '') + '</code>.</p>';
592231
+ torRow +
592232
+ '<p style="font-size:0.68rem;color:var(--color-fg-muted);margin:6px 0 0">Note: these URLs contain the full secret. Anyone with one can use this OA. To revoke: Advanced settings → keys → revoke prefix <code>' + escapeHtml(j.keyPrefix || '') + '</code>.</p>';
591849
592233
  // Stash for the copy buttons + add to recent.
591850
592234
  window.__oaLastShareUrl = j.shareUrl;
591851
592235
  window.__oaLastPlainUrl = j.plainUrl;
592236
+ window.__oaLastTorUrl = j.torShareUrl || null;
591852
592237
  saveRecentKey({ key: j.key, host: j.host + ':' + j.port, label: j.label || ('shared ' + j.host) });
591853
592238
  } catch (e) {
591854
592239
  out.innerHTML = '<div style="color:var(--color-error)">✗ ' + escapeHtml(e && e.message ? e.message : String(e)) + '</div>';
591855
592240
  }
591856
592241
  }
591857
592242
  function copyShareUrl(which) {
591858
- const v = which === 'plain' ? window.__oaLastPlainUrl : window.__oaLastShareUrl;
592243
+ let v;
592244
+ if (which === 'plain') v = window.__oaLastPlainUrl;
592245
+ else if (which === 'tor') v = window.__oaLastTorUrl;
592246
+ else v = window.__oaLastShareUrl;
591859
592247
  if (!v) return;
591860
592248
  if (navigator.clipboard && navigator.clipboard.writeText) {
591861
592249
  navigator.clipboard.writeText(v).then(
@@ -591875,6 +592263,46 @@ function fallbackCopy(v) {
591875
592263
  window.generateShareUrl = generateShareUrl;
591876
592264
  window.copyShareUrl = copyShareUrl;
591877
592265
 
592266
+ // ─── Enable Tor (graphical sudo) ────────────────────────────────────────
592267
+ async function enableTorShare() {
592268
+ const status = document.getElementById('enable-tor-status');
592269
+ if (status) { status.textContent = 'launching graphical sudo prompt…'; status.style.color = 'var(--color-fg-muted)'; }
592270
+ try {
592271
+ const r = await fetch('/v1/tor/enable', {
592272
+ method: 'POST',
592273
+ headers: { ...headers(), 'Content-Type': 'application/json' },
592274
+ body: '{}',
592275
+ });
592276
+ const j = await r.json().catch(() => ({}));
592277
+ if (r.status === 202) {
592278
+ if (status) {
592279
+ status.textContent = 'started — waiting for hidden service…';
592280
+ status.style.color = 'var(--color-accent)';
592281
+ }
592282
+ // Poll up to 90s for the .onion to appear
592283
+ for (let i = 0; i < 30; i++) {
592284
+ await new Promise(r => setTimeout(r, 3000));
592285
+ const s = await fetch('/v1/tor/status', { headers: headers() }).then(x => x.json()).catch(() => ({}));
592286
+ if (s.onion) {
592287
+ if (status) { status.textContent = '✓ Tor enabled: ' + s.onion; status.style.color = 'var(--color-success)'; }
592288
+ // Re-generate share URL to pick up the .onion field
592289
+ setTimeout(() => generateShareUrl(), 500);
592290
+ return;
592291
+ }
592292
+ }
592293
+ if (status) { status.textContent = '⚠ setup ran but no .onion appeared. Check journalctl -u tor for errors.'; status.style.color = 'var(--color-warning)'; }
592294
+ } else if (r.status === 409) {
592295
+ if (status) { status.textContent = '✓ already enabled — re-generating'; status.style.color = 'var(--color-success)'; }
592296
+ setTimeout(() => generateShareUrl(), 500);
592297
+ } else {
592298
+ if (status) { status.textContent = '✗ ' + (j.detail || ('HTTP ' + r.status)); status.style.color = 'var(--color-error)'; }
592299
+ }
592300
+ } catch (e) {
592301
+ if (status) { status.textContent = '✗ ' + (e && e.message ? e.message : String(e)); status.style.color = 'var(--color-error)'; }
592302
+ }
592303
+ }
592304
+ window.enableTorShare = enableTorShare;
592305
+
591878
592306
  // ─── Remote-state helpers (visual indicator on the key button) ───────
591879
592307
  // When localStorage carries oa.remoteHost we are in REMOTE mode: the
591880
592308
  // key was loaded from an oa-share URL or via on-load ?oa-key=. The key
@@ -596752,14 +597180,14 @@ var init_auth_oidc = __esm({
596752
597180
  });
596753
597181
 
596754
597182
  // packages/cli/src/api/usage-tracker.ts
596755
- import { mkdirSync as mkdirSync60, readFileSync as readFileSync84, writeFileSync as writeFileSync52, existsSync as existsSync103 } from "node:fs";
596756
- import { join as join119 } from "node:path";
597183
+ import { mkdirSync as mkdirSync61, readFileSync as readFileSync84, writeFileSync as writeFileSync53, existsSync as existsSync104 } from "node:fs";
597184
+ import { join as join120 } from "node:path";
596757
597185
  function initUsageTracker(oaDir) {
596758
- const dir = join119(oaDir, "usage");
596759
- mkdirSync60(dir, { recursive: true });
596760
- usageFile = join119(dir, "token-usage.json");
597186
+ const dir = join120(oaDir, "usage");
597187
+ mkdirSync61(dir, { recursive: true });
597188
+ usageFile = join120(dir, "token-usage.json");
596761
597189
  try {
596762
- if (existsSync103(usageFile)) {
597190
+ if (existsSync104(usageFile)) {
596763
597191
  store = JSON.parse(readFileSync84(usageFile, "utf-8"));
596764
597192
  }
596765
597193
  } catch {
@@ -596796,7 +597224,7 @@ function flush2() {
596796
597224
  if (!initialized2 || !dirty) return;
596797
597225
  try {
596798
597226
  store.lastSaved = (/* @__PURE__ */ new Date()).toISOString();
596799
- writeFileSync52(usageFile, JSON.stringify(store, null, 2), "utf-8");
597227
+ writeFileSync53(usageFile, JSON.stringify(store, null, 2), "utf-8");
596800
597228
  dirty = false;
596801
597229
  } catch {
596802
597230
  }
@@ -596824,24 +597252,24 @@ var init_usage_tracker = __esm({
596824
597252
  });
596825
597253
 
596826
597254
  // packages/cli/src/api/profiles.ts
596827
- import { existsSync as existsSync104, readFileSync as readFileSync85, writeFileSync as writeFileSync53, mkdirSync as mkdirSync61, readdirSync as readdirSync35, unlinkSync as unlinkSync23 } from "node:fs";
596828
- import { join as join120 } from "node:path";
597255
+ import { existsSync as existsSync105, readFileSync as readFileSync85, writeFileSync as writeFileSync54, mkdirSync as mkdirSync62, readdirSync as readdirSync35, unlinkSync as unlinkSync23 } from "node:fs";
597256
+ import { join as join121 } from "node:path";
596829
597257
  import { homedir as homedir41 } from "node:os";
596830
597258
  import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes22, scryptSync as scryptSync3 } from "node:crypto";
596831
597259
  function globalProfileDir() {
596832
- return join120(homedir41(), ".open-agents", "profiles");
597260
+ return join121(homedir41(), ".open-agents", "profiles");
596833
597261
  }
596834
597262
  function projectProfileDir(projectDir2) {
596835
- return join120(projectDir2 || process.cwd(), ".oa", "profiles");
597263
+ return join121(projectDir2 || process.cwd(), ".oa", "profiles");
596836
597264
  }
596837
597265
  function listProfiles(projectDir2) {
596838
597266
  const result = [];
596839
597267
  const seen = /* @__PURE__ */ new Set();
596840
597268
  const projDir = projectProfileDir(projectDir2);
596841
- if (existsSync104(projDir)) {
597269
+ if (existsSync105(projDir)) {
596842
597270
  for (const f2 of readdirSync35(projDir).filter((f3) => f3.endsWith(".json"))) {
596843
597271
  try {
596844
- const raw = JSON.parse(readFileSync85(join120(projDir, f2), "utf8"));
597272
+ const raw = JSON.parse(readFileSync85(join121(projDir, f2), "utf8"));
596845
597273
  const name10 = f2.replace(".json", "");
596846
597274
  seen.add(name10);
596847
597275
  result.push({
@@ -596855,12 +597283,12 @@ function listProfiles(projectDir2) {
596855
597283
  }
596856
597284
  }
596857
597285
  const globDir = globalProfileDir();
596858
- if (existsSync104(globDir)) {
597286
+ if (existsSync105(globDir)) {
596859
597287
  for (const f2 of readdirSync35(globDir).filter((f3) => f3.endsWith(".json"))) {
596860
597288
  const name10 = f2.replace(".json", "");
596861
597289
  if (seen.has(name10)) continue;
596862
597290
  try {
596863
- const raw = JSON.parse(readFileSync85(join120(globDir, f2), "utf8"));
597291
+ const raw = JSON.parse(readFileSync85(join121(globDir, f2), "utf8"));
596864
597292
  result.push({
596865
597293
  name: name10,
596866
597294
  description: raw.description || "",
@@ -596875,9 +597303,9 @@ function listProfiles(projectDir2) {
596875
597303
  }
596876
597304
  function loadProfile(name10, password, projectDir2) {
596877
597305
  const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
596878
- const projPath = join120(projectProfileDir(projectDir2), `${sanitized}.json`);
596879
- const globPath = join120(globalProfileDir(), `${sanitized}.json`);
596880
- const filePath = existsSync104(projPath) ? projPath : existsSync104(globPath) ? globPath : null;
597306
+ const projPath = join121(projectProfileDir(projectDir2), `${sanitized}.json`);
597307
+ const globPath = join121(globalProfileDir(), `${sanitized}.json`);
597308
+ const filePath = existsSync105(projPath) ? projPath : existsSync105(globPath) ? globPath : null;
596881
597309
  if (!filePath) return null;
596882
597310
  const raw = JSON.parse(readFileSync85(filePath, "utf8"));
596883
597311
  if (raw.encrypted === true) {
@@ -596888,23 +597316,23 @@ function loadProfile(name10, password, projectDir2) {
596888
597316
  }
596889
597317
  function saveProfile(profile, password, scope = "global", projectDir2) {
596890
597318
  const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
596891
- mkdirSync61(dir, { recursive: true });
597319
+ mkdirSync62(dir, { recursive: true });
596892
597320
  const sanitized = profile.name.replace(/[^a-zA-Z0-9_-]/g, "");
596893
- const filePath = join120(dir, `${sanitized}.json`);
597321
+ const filePath = join121(dir, `${sanitized}.json`);
596894
597322
  profile.modified = (/* @__PURE__ */ new Date()).toISOString();
596895
597323
  if (password) {
596896
597324
  const encrypted = encryptProfile(profile, password);
596897
- writeFileSync53(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
597325
+ writeFileSync54(filePath, JSON.stringify(encrypted, null, 2), { mode: 384 });
596898
597326
  } else {
596899
597327
  profile.encrypted = false;
596900
- writeFileSync53(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
597328
+ writeFileSync54(filePath, JSON.stringify(profile, null, 2), { mode: 420 });
596901
597329
  }
596902
597330
  }
596903
597331
  function deleteProfile(name10, scope = "global", projectDir2) {
596904
597332
  const sanitized = name10.replace(/[^a-zA-Z0-9_-]/g, "");
596905
597333
  const dir = scope === "project" ? projectProfileDir(projectDir2) : globalProfileDir();
596906
- const filePath = join120(dir, `${sanitized}.json`);
596907
- if (existsSync104(filePath)) {
597334
+ const filePath = join121(dir, `${sanitized}.json`);
597335
+ if (existsSync105(filePath)) {
596908
597336
  unlinkSync23(filePath);
596909
597337
  return true;
596910
597338
  }
@@ -597018,24 +597446,24 @@ var init_profiles = __esm({
597018
597446
  });
597019
597447
 
597020
597448
  // packages/cli/src/docker.ts
597021
- import { execSync as execSync56, spawn as spawn24 } from "node:child_process";
597022
- import { existsSync as existsSync105, mkdirSync as mkdirSync62, writeFileSync as writeFileSync54 } from "node:fs";
597023
- import { join as join121, resolve as resolve37, dirname as dirname35 } from "node:path";
597449
+ import { execSync as execSync56, spawn as spawn25 } from "node:child_process";
597450
+ import { existsSync as existsSync106, mkdirSync as mkdirSync63, writeFileSync as writeFileSync55 } from "node:fs";
597451
+ import { join as join122, resolve as resolve37, dirname as dirname35 } from "node:path";
597024
597452
  import { homedir as homedir42 } from "node:os";
597025
597453
  import { fileURLToPath as fileURLToPath16 } from "node:url";
597026
597454
  function getDockerDir() {
597027
597455
  try {
597028
597456
  if (typeof __dirname !== "undefined") {
597029
- return join121(__dirname, "..", "..", "..", "docker");
597457
+ return join122(__dirname, "..", "..", "..", "docker");
597030
597458
  }
597031
597459
  } catch {
597032
597460
  }
597033
597461
  try {
597034
597462
  const thisDir = dirname35(fileURLToPath16(import.meta.url));
597035
- return join121(thisDir, "..", "..", "..", "docker");
597463
+ return join122(thisDir, "..", "..", "..", "docker");
597036
597464
  } catch {
597037
597465
  }
597038
- return join121(process.cwd(), "docker");
597466
+ return join122(process.cwd(), "docker");
597039
597467
  }
597040
597468
  function isDockerAvailable() {
597041
597469
  try {
@@ -597166,11 +597594,11 @@ async function ensureOaImage(force = false) {
597166
597594
  }
597167
597595
  let buildContext;
597168
597596
  const dockerDir = getDockerDir();
597169
- if (existsSync105(join121(dockerDir, "Dockerfile"))) {
597597
+ if (existsSync106(join122(dockerDir, "Dockerfile"))) {
597170
597598
  buildContext = dockerDir;
597171
597599
  } else {
597172
- buildContext = join121(homedir42(), ".oa", "docker-build");
597173
- mkdirSync62(buildContext, { recursive: true });
597600
+ buildContext = join122(homedir42(), ".oa", "docker-build");
597601
+ mkdirSync63(buildContext, { recursive: true });
597174
597602
  writeDockerfiles(buildContext);
597175
597603
  }
597176
597604
  try {
@@ -597244,8 +597672,8 @@ chown -R node:node /workspace /home/node/.oa /home/node/.open-agents 2>/dev/null
597244
597672
  if [ "$1" = "oa" ]; then shift; exec su - node -c "cd /workspace && oa $*"; fi
597245
597673
  exec "$@"
597246
597674
  `;
597247
- writeFileSync54(join121(dir, "Dockerfile"), dockerfile);
597248
- writeFileSync54(join121(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
597675
+ writeFileSync55(join122(dir, "Dockerfile"), dockerfile);
597676
+ writeFileSync55(join122(dir, "docker-entrypoint.sh"), entrypoint, { mode: 493 });
597249
597677
  }
597250
597678
  function hasNvidiaGpu() {
597251
597679
  try {
@@ -597299,7 +597727,7 @@ function runInContainer(opts) {
597299
597727
  if (opts.maxTurns) oaArgs.push("--max-turns", String(opts.maxTurns));
597300
597728
  if (opts.timeoutS) oaArgs.push("--timeout", String(opts.timeoutS));
597301
597729
  args.push(...oaArgs);
597302
- return spawn24("docker", args, {
597730
+ return spawn25("docker", args, {
597303
597731
  stdio: ["ignore", "pipe", "pipe"]
597304
597732
  });
597305
597733
  }
@@ -597498,23 +597926,23 @@ import * as http5 from "node:http";
597498
597926
  import * as https3 from "node:https";
597499
597927
  import { createRequire as createRequire5 } from "node:module";
597500
597928
  import { fileURLToPath as fileURLToPath17 } from "node:url";
597501
- import { dirname as dirname36, join as join122, resolve as resolve38 } from "node:path";
597929
+ import { dirname as dirname36, join as join123, resolve as resolve38 } from "node:path";
597502
597930
  import { homedir as homedir43 } from "node:os";
597503
- import { spawn as spawn25, execSync as execSync57 } from "node:child_process";
597504
- import { mkdirSync as mkdirSync63, writeFileSync as writeFileSync55, readFileSync as readFileSync86, readdirSync as readdirSync36, existsSync as existsSync106, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync24 } from "node:fs";
597931
+ import { spawn as spawn26, execSync as execSync57 } from "node:child_process";
597932
+ import { mkdirSync as mkdirSync64, writeFileSync as writeFileSync56, readFileSync as readFileSync86, readdirSync as readdirSync36, existsSync as existsSync107, watch as fsWatch3, renameSync as renameSync8, unlinkSync as unlinkSync24 } from "node:fs";
597505
597933
  import { randomBytes as randomBytes23, randomUUID as randomUUID16 } from "node:crypto";
597506
597934
  import { createHash as createHash19 } from "node:crypto";
597507
597935
  function getVersion3() {
597508
597936
  try {
597509
597937
  const thisDir = dirname36(fileURLToPath17(import.meta.url));
597510
597938
  const candidates = [
597511
- join122(thisDir, "..", "package.json"),
597512
- join122(thisDir, "..", "..", "package.json"),
597513
- join122(thisDir, "..", "..", "..", "package.json")
597939
+ join123(thisDir, "..", "package.json"),
597940
+ join123(thisDir, "..", "..", "package.json"),
597941
+ join123(thisDir, "..", "..", "..", "package.json")
597514
597942
  ];
597515
597943
  for (const pkgPath of candidates) {
597516
597944
  try {
597517
- if (!existsSync106(pkgPath)) continue;
597945
+ if (!existsSync107(pkgPath)) continue;
597518
597946
  const pkg = require3(pkgPath);
597519
597947
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
597520
597948
  return pkg.version ?? "0.0.0";
@@ -597716,8 +598144,8 @@ function isOriginAllowed(origin) {
597716
598144
  if (!origin) return true;
597717
598145
  let accessMode = (process.env["OA_ACCESS"] || "").toLowerCase().trim();
597718
598146
  try {
597719
- const accessFile = join122(homedir43(), ".open-agents", "access");
597720
- if (existsSync106(accessFile)) {
598147
+ const accessFile = join123(homedir43(), ".open-agents", "access");
598148
+ if (existsSync107(accessFile)) {
597721
598149
  const persisted = readFileSync86(accessFile, "utf8").trim().toLowerCase();
597722
598150
  if (persisted === "any" || persisted === "lan" || persisted === "loopback") {
597723
598151
  accessMode = persisted;
@@ -597778,7 +598206,7 @@ async function retrieveMemoryContext(userMessage, sessionId, maxEpisodes = 5) {
597778
598206
  if (!memMod || !memMod.EpisodeStore) {
597779
598207
  return { contextBlock: "", retrieved: [] };
597780
598208
  }
597781
- const dbPath = join122(homedir43(), ".open-agents", "memory.db");
598209
+ const dbPath = join123(homedir43(), ".open-agents", "memory.db");
597782
598210
  const store2 = new memMod.EpisodeStore(dbPath);
597783
598211
  const recent = store2.search({ limit: 30, sessionId: void 0 }) ?? [];
597784
598212
  const qLower = userMessage.toLowerCase();
@@ -597821,7 +598249,7 @@ async function writeMemoryEpisodes(sessionId, userMessage, assistantContent, too
597821
598249
  try {
597822
598250
  const memMod = await Promise.resolve().then(() => (init_dist7(), dist_exports2)).catch(() => null);
597823
598251
  if (!memMod || !memMod.EpisodeStore) return 0;
597824
- const dbPath = join122(homedir43(), ".open-agents", "memory.db");
598252
+ const dbPath = join123(homedir43(), ".open-agents", "memory.db");
597825
598253
  const store2 = new memMod.EpisodeStore(dbPath);
597826
598254
  let written = 0;
597827
598255
  try {
@@ -598143,13 +598571,13 @@ function ollamaStream(ollamaUrl, path8, method, body, onData, onEnd, onError, ti
598143
598571
  }
598144
598572
  function jobsDir() {
598145
598573
  const root = resolve38(process.cwd());
598146
- const dir = join122(root, ".oa", "jobs");
598147
- mkdirSync63(dir, { recursive: true });
598574
+ const dir = join123(root, ".oa", "jobs");
598575
+ mkdirSync64(dir, { recursive: true });
598148
598576
  return dir;
598149
598577
  }
598150
598578
  function loadJob(id) {
598151
- const file = join122(jobsDir(), `${id}.json`);
598152
- if (!existsSync106(file)) return null;
598579
+ const file = join123(jobsDir(), `${id}.json`);
598580
+ if (!existsSync107(file)) return null;
598153
598581
  try {
598154
598582
  return JSON.parse(readFileSync86(file, "utf-8"));
598155
598583
  } catch {
@@ -598158,12 +598586,12 @@ function loadJob(id) {
598158
598586
  }
598159
598587
  function listJobs() {
598160
598588
  const dir = jobsDir();
598161
- if (!existsSync106(dir)) return [];
598589
+ if (!existsSync107(dir)) return [];
598162
598590
  const files = readdirSync36(dir).filter((f2) => f2.endsWith(".json")).sort();
598163
598591
  const jobs = [];
598164
598592
  for (const file of files) {
598165
598593
  try {
598166
- jobs.push(JSON.parse(readFileSync86(join122(dir, file), "utf-8")));
598594
+ jobs.push(JSON.parse(readFileSync86(join123(dir, file), "utf-8")));
598167
598595
  } catch {
598168
598596
  }
598169
598597
  }
@@ -598173,12 +598601,12 @@ function pruneOldJobs() {
598173
598601
  const retentionH = parseFloat(process.env["OA_RUN_RETENTION_H"] || "24");
598174
598602
  const cutoffMs = Date.now() - (Number.isFinite(retentionH) && retentionH > 0 ? retentionH : 24) * 36e5;
598175
598603
  const dir = jobsDir();
598176
- if (!existsSync106(dir)) return { pruned: 0, kept: 0 };
598604
+ if (!existsSync107(dir)) return { pruned: 0, kept: 0 };
598177
598605
  let pruned = 0;
598178
598606
  let kept = 0;
598179
598607
  for (const file of readdirSync36(dir)) {
598180
598608
  if (!file.endsWith(".json")) continue;
598181
- const path8 = join122(dir, file);
598609
+ const path8 = join123(dir, file);
598182
598610
  try {
598183
598611
  const job = JSON.parse(readFileSync86(path8, "utf-8"));
598184
598612
  if (job.status === "running") {
@@ -598193,7 +598621,7 @@ function pruneOldJobs() {
598193
598621
  } catch {
598194
598622
  }
598195
598623
  const outFile = path8.replace(/\.json$/, ".output");
598196
- if (existsSync106(outFile)) {
598624
+ if (existsSync107(outFile)) {
598197
598625
  try {
598198
598626
  unlinkSync24(outFile);
598199
598627
  } catch {
@@ -598486,14 +598914,14 @@ function autoSeedTodosFromPrompt(prompt) {
598486
598914
  return [];
598487
598915
  }
598488
598916
  function atomicJobWrite(dir, id, job) {
598489
- const finalPath = join122(dir, `${id}.json`);
598917
+ const finalPath = join123(dir, `${id}.json`);
598490
598918
  const tmpPath = `${finalPath}.tmp.${process.pid}.${Date.now()}`;
598491
598919
  try {
598492
- writeFileSync55(tmpPath, JSON.stringify(job, null, 2), "utf-8");
598920
+ writeFileSync56(tmpPath, JSON.stringify(job, null, 2), "utf-8");
598493
598921
  renameSync8(tmpPath, finalPath);
598494
598922
  } catch {
598495
598923
  try {
598496
- writeFileSync55(finalPath, JSON.stringify(job, null, 2), "utf-8");
598924
+ writeFileSync56(finalPath, JSON.stringify(job, null, 2), "utf-8");
598497
598925
  } catch {
598498
598926
  }
598499
598927
  try {
@@ -599695,7 +600123,7 @@ ${task}` : task;
599695
600123
  runEnv["OA_RUN_SCOPE"] = req2._authScope || "admin";
599696
600124
  runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
599697
600125
  if (currentCfg.apiKey) runEnv["OA_API_KEY_INHERIT"] = currentCfg.apiKey;
599698
- const child = spawn25(process.execPath, [oaBin, ...args], {
600126
+ const child = spawn26(process.execPath, [oaBin, ...args], {
599699
600127
  cwd: resolve38(process.cwd()),
599700
600128
  env: runEnv,
599701
600129
  stdio: ["ignore", "pipe", "pipe"]
@@ -599912,15 +600340,15 @@ ${task}` : task;
599912
600340
  });
599913
600341
  }
599914
600342
  function updateStateFile() {
599915
- return join122(homedir43(), ".open-agents", "update-state.json");
600343
+ return join123(homedir43(), ".open-agents", "update-state.json");
599916
600344
  }
599917
600345
  function updateLogPath() {
599918
- return join122(homedir43(), ".open-agents", "update.log");
600346
+ return join123(homedir43(), ".open-agents", "update.log");
599919
600347
  }
599920
600348
  function readUpdateState() {
599921
600349
  try {
599922
600350
  const p2 = updateStateFile();
599923
- if (!existsSync106(p2)) return null;
600351
+ if (!existsSync107(p2)) return null;
599924
600352
  return JSON.parse(readFileSync86(p2, "utf-8"));
599925
600353
  } catch {
599926
600354
  return null;
@@ -599928,11 +600356,11 @@ function readUpdateState() {
599928
600356
  }
599929
600357
  function writeUpdateState(state) {
599930
600358
  try {
599931
- const dir = join122(homedir43(), ".open-agents");
599932
- mkdirSync63(dir, { recursive: true });
600359
+ const dir = join123(homedir43(), ".open-agents");
600360
+ mkdirSync64(dir, { recursive: true });
599933
600361
  const finalPath = updateStateFile();
599934
600362
  const tmpPath = `${finalPath}.tmp.${process.pid}`;
599935
- writeFileSync55(tmpPath, JSON.stringify(state, null, 2), "utf-8");
600363
+ writeFileSync56(tmpPath, JSON.stringify(state, null, 2), "utf-8");
599936
600364
  renameSync8(tmpPath, finalPath);
599937
600365
  } catch {
599938
600366
  }
@@ -599976,15 +600404,15 @@ async function handleV1Update(req2, res, requestId) {
599976
600404
  const { execSync: es } = require3("node:child_process");
599977
600405
  const isWin2 = process.platform === "win32";
599978
600406
  let npmBin = "";
599979
- for (const candidate of isWin2 ? [join122(nodeDir, "npm.cmd"), join122(nodeDir, "npm")] : [join122(nodeDir, "npm"), "/usr/local/bin/npm", "/usr/bin/npm"]) {
599980
- if (existsSync106(candidate)) {
600407
+ for (const candidate of isWin2 ? [join123(nodeDir, "npm.cmd"), join123(nodeDir, "npm")] : [join123(nodeDir, "npm"), "/usr/local/bin/npm", "/usr/bin/npm"]) {
600408
+ if (existsSync107(candidate)) {
599981
600409
  npmBin = candidate;
599982
600410
  break;
599983
600411
  }
599984
600412
  }
599985
600413
  if (!npmBin) npmBin = isWin2 ? "npm.cmd" : "npm";
599986
600414
  const pkgSpec = `open-agents-ai@${targetVersion}`;
599987
- const dir = join122(homedir43(), ".open-agents");
600415
+ const dir = join123(homedir43(), ".open-agents");
599988
600416
  fs7.mkdirSync(dir, { recursive: true });
599989
600417
  const logFd = fs7.openSync(logPath3, "w");
599990
600418
  const npmPrefix = dirname36(nodeDir);
@@ -599994,13 +600422,13 @@ async function handleV1Update(req2, res, requestId) {
599994
600422
  globalBinDir = es(`${npmBin} bin -g`, { encoding: "utf8", timeout: 5e3, stdio: "pipe" }).trim();
599995
600423
  } else {
599996
600424
  const npmCliCandidates = [
599997
- join122(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
599998
- join122(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
600425
+ join123(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
600426
+ join123(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
599999
600427
  ];
600000
600428
  let npmCli = "";
600001
600429
  for (const c9 of npmCliCandidates) {
600002
600430
  try {
600003
- if (existsSync106(c9)) {
600431
+ if (existsSync107(c9)) {
600004
600432
  npmCli = c9;
600005
600433
  break;
600006
600434
  }
@@ -600024,7 +600452,7 @@ async function handleV1Update(req2, res, requestId) {
600024
600452
  cleanEnv.PATH = pathParts.join(":");
600025
600453
  let child;
600026
600454
  if (isWin2) {
600027
- child = spawn25(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
600455
+ child = spawn26(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
600028
600456
  detached: true,
600029
600457
  stdio: ["ignore", logFd, logFd],
600030
600458
  windowsHide: true,
@@ -600032,13 +600460,13 @@ async function handleV1Update(req2, res, requestId) {
600032
600460
  });
600033
600461
  } else {
600034
600462
  const npmCliCandidates = [
600035
- join122(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
600036
- join122(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
600463
+ join123(nodeDir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js"),
600464
+ join123(npmBin, "..", "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
600037
600465
  ];
600038
600466
  let npmCli = "";
600039
600467
  for (const c9 of npmCliCandidates) {
600040
600468
  try {
600041
- if (existsSync106(c9)) {
600469
+ if (existsSync107(c9)) {
600042
600470
  npmCli = c9;
600043
600471
  break;
600044
600472
  }
@@ -600046,13 +600474,13 @@ async function handleV1Update(req2, res, requestId) {
600046
600474
  }
600047
600475
  }
600048
600476
  if (npmCli) {
600049
- child = spawn25(nodeBin, [npmCli, "install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
600477
+ child = spawn26(nodeBin, [npmCli, "install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
600050
600478
  detached: true,
600051
600479
  stdio: ["ignore", logFd, logFd],
600052
600480
  env: cleanEnv
600053
600481
  });
600054
600482
  } else {
600055
- child = spawn25(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
600483
+ child = spawn26(npmBin, ["install", "-g", pkgSpec, "--no-audit", "--no-fund", "--no-progress"], {
600056
600484
  detached: true,
600057
600485
  stdio: ["ignore", logFd, logFd],
600058
600486
  env: cleanEnv
@@ -600063,7 +600491,7 @@ async function handleV1Update(req2, res, requestId) {
600063
600491
  const installPid = child.pid ?? 0;
600064
600492
  if (installPid > 0 && !isWin2) {
600065
600493
  try {
600066
- const follower = spawn25("bash", ["-c", `while kill -0 ${installPid} 2>/dev/null; do sleep 1; done; echo "__EXIT_CODE=0" >> "${logPath3}"`], {
600494
+ const follower = spawn26("bash", ["-c", `while kill -0 ${installPid} 2>/dev/null; do sleep 1; done; echo "__EXIT_CODE=0" >> "${logPath3}"`], {
600067
600495
  detached: true,
600068
600496
  stdio: "ignore"
600069
600497
  });
@@ -600076,8 +600504,8 @@ async function handleV1Update(req2, res, requestId) {
600076
600504
  }
600077
600505
  let oaAbs = "oa";
600078
600506
  try {
600079
- const which = es("command -v oa 2>/dev/null || which oa 2>/dev/null", { encoding: "utf8", timeout: 2e3, stdio: "pipe", env: cleanEnv }).trim();
600080
- if (which) oaAbs = which;
600507
+ const which2 = es("command -v oa 2>/dev/null || which oa 2>/dev/null", { encoding: "utf8", timeout: 2e3, stdio: "pipe", env: cleanEnv }).trim();
600508
+ if (which2) oaAbs = which2;
600081
600509
  } catch {
600082
600510
  }
600083
600511
  const relaunchScript = [
@@ -600086,7 +600514,7 @@ async function handleV1Update(req2, res, requestId) {
600086
600514
  hasSystemdUnit ? `systemctl --user restart open-agents-daemon.service >/dev/null 2>&1 || true` : `${JSON.stringify(oaAbs)} serve --quiet --daemon >/dev/null 2>&1 & disown`,
600087
600515
  `kill -TERM ${process.pid} >/dev/null 2>&1 || true`
600088
600516
  ].join("; ");
600089
- const relauncher = spawn25("bash", ["-c", relaunchScript], {
600517
+ const relauncher = spawn26("bash", ["-c", relaunchScript], {
600090
600518
  detached: true,
600091
600519
  stdio: "ignore",
600092
600520
  env: cleanEnv
@@ -600135,7 +600563,7 @@ function handleV1UpdateStatus(res) {
600135
600563
  let logTail = "";
600136
600564
  let exitCode = null;
600137
600565
  try {
600138
- if (existsSync106(logPath3)) {
600566
+ if (existsSync107(logPath3)) {
600139
600567
  const raw = readFileSync86(logPath3, "utf-8");
600140
600568
  const m2 = raw.match(/__EXIT_CODE=(\d+)/);
600141
600569
  if (m2) exitCode = parseInt(m2[1], 10);
@@ -600232,8 +600660,8 @@ async function handleV1Run(req2, res) {
600232
600660
  if (workingDir) {
600233
600661
  cwd4 = resolve38(workingDir);
600234
600662
  } else if (isolate) {
600235
- const wsDir = join122(dir, "..", "workspaces", id);
600236
- mkdirSync63(wsDir, { recursive: true });
600663
+ const wsDir = join123(dir, "..", "workspaces", id);
600664
+ mkdirSync64(wsDir, { recursive: true });
600237
600665
  cwd4 = wsDir;
600238
600666
  } else {
600239
600667
  cwd4 = resolve38(process.cwd());
@@ -600308,7 +600736,7 @@ async function handleV1Run(req2, res) {
600308
600736
  });
600309
600737
  job.sandbox = "container";
600310
600738
  } else {
600311
- child = spawn25(process.execPath, [oaBin, ...args], {
600739
+ child = spawn26(process.execPath, [oaBin, ...args], {
600312
600740
  cwd: cwd4,
600313
600741
  env: runEnv,
600314
600742
  stdio: ["ignore", "pipe", "pipe"],
@@ -600419,7 +600847,7 @@ async function handleV1Run(req2, res) {
600419
600847
  let output = "";
600420
600848
  let tailBytes = 0;
600421
600849
  const TAIL_BUDGET = 1048576;
600422
- const outputWriter = new DiskTaskOutput(join122(dir, `${id}.output`));
600850
+ const outputWriter = new DiskTaskOutput(join123(dir, `${id}.output`));
600423
600851
  job.outputFile = outputWriter.path;
600424
600852
  atomicJobWrite(dir, id, job);
600425
600853
  child.stdout?.on("data", (chunk) => {
@@ -600818,7 +601246,7 @@ async function handlePostCommand(res, cmd) {
600818
601246
  return;
600819
601247
  }
600820
601248
  try {
600821
- const child = spawn25("node", [oaBin, "run", `/${cmd}`, "--json"], {
601249
+ const child = spawn26("node", [oaBin, "run", `/${cmd}`, "--json"], {
600822
601250
  env: { ...process.env, __OPEN_AGENTS_NO_AUTO_RUN: "" },
600823
601251
  stdio: ["ignore", "pipe", "pipe"],
600824
601252
  timeout: 3e4
@@ -601335,11 +601763,11 @@ async function handleRequest(req2, res, ollamaUrl, verbose) {
601335
601763
  jsonResponse(res, 400, { error: "audio_too_small", message: "Reference audio must be at least ~4 KB" });
601336
601764
  return;
601337
601765
  }
601338
- const { tmpdir: tmpdir22 } = await import("node:os");
601339
- const { writeFileSync: writeFileSync59, unlinkSync: unlinkSync25 } = await import("node:fs");
601766
+ const { tmpdir: tmpdir23 } = await import("node:os");
601767
+ const { writeFileSync: writeFileSync60, unlinkSync: unlinkSync25 } = await import("node:fs");
601340
601768
  const { join: pjoin } = await import("node:path");
601341
- const tmpPath = pjoin(tmpdir22(), `oa-clone-upload-${Date.now()}-${safeName}`);
601342
- writeFileSync59(tmpPath, buf);
601769
+ const tmpPath = pjoin(tmpdir23(), `oa-clone-upload-${Date.now()}-${safeName}`);
601770
+ writeFileSync60(tmpPath, buf);
601343
601771
  try {
601344
601772
  const ve = getVoiceEngine();
601345
601773
  const msg = await ve.setCloneVoice(tmpPath);
@@ -601889,7 +602317,7 @@ data: ${JSON.stringify(data)}
601889
602317
  }
601890
602318
  for (const f2 of seenFiles) {
601891
602319
  try {
601892
- writeFileSync55(f2, JSON.stringify({ tasks: [] }, null, 2));
602320
+ writeFileSync56(f2, JSON.stringify({ tasks: [] }, null, 2));
601893
602321
  deleted++;
601894
602322
  } catch {
601895
602323
  }
@@ -602190,7 +602618,7 @@ ${historyLines}
602190
602618
  }
602191
602619
  runEnv["OLLAMA_HOST"] = currentCfg.backendUrl || process.env["OLLAMA_HOST"] || "http://127.0.0.1:11434";
602192
602620
  if (currentCfg.apiKey) runEnv["OA_API_KEY_INHERIT"] = currentCfg.apiKey;
602193
- const child = spawn25(process.execPath, [oaBin, ...args], {
602621
+ const child = spawn26(process.execPath, [oaBin, ...args], {
602194
602622
  cwd: cwdPath,
602195
602623
  env: runEnv,
602196
602624
  stdio: ["ignore", "pipe", "pipe"],
@@ -602993,7 +603421,7 @@ ${steering}`;
602993
603421
  function getScheduleRoots() {
602994
603422
  const rootsEnv = process.env["OA_SCHEDULE_ROOTS"] || "";
602995
603423
  const roots = rootsEnv.split(rootsEnv.includes(";") ? ";" : ":").filter(Boolean);
602996
- const defaults3 = [process.cwd(), join122(homedir43(), "Documents")];
603424
+ const defaults3 = [process.cwd(), join123(homedir43(), "Documents")];
602997
603425
  const set = /* @__PURE__ */ new Set([...defaults3, ...roots]);
602998
603426
  return [...set];
602999
603427
  }
@@ -603005,8 +603433,8 @@ function listScheduledTasks() {
603005
603433
  for (const root of roots) {
603006
603434
  try {
603007
603435
  walk(root, 0, (dir) => {
603008
- if (dir.endsWith(`${join122(".oa", "scheduled")}`) || dir.includes(`${join122(".oa", "scheduled")}`)) {
603009
- const file = join122(dir, "tasks.json");
603436
+ if (dir.endsWith(`${join123(".oa", "scheduled")}`) || dir.includes(`${join123(".oa", "scheduled")}`)) {
603437
+ const file = join123(dir, "tasks.json");
603010
603438
  try {
603011
603439
  const raw = readFileSync86(file, "utf-8");
603012
603440
  const json = JSON.parse(raw);
@@ -603073,7 +603501,7 @@ function walk(dir, depth, onDir, maxDepth) {
603073
603501
  if (e2.name === "node_modules" || e2.name.startsWith(".")) {
603074
603502
  if (e2.name !== ".oa") continue;
603075
603503
  }
603076
- const child = join122(dir, e2.name);
603504
+ const child = join123(dir, e2.name);
603077
603505
  walk(child, depth + 1, onDir, maxDepth);
603078
603506
  }
603079
603507
  }
@@ -603089,11 +603517,11 @@ function setScheduledEnabled(id, enabled2) {
603089
603517
  arr[target.index].enabled = enabled2;
603090
603518
  if (Array.isArray(json?.tasks)) {
603091
603519
  json.tasks = arr;
603092
- writeFileSync55(target.file, JSON.stringify(json, null, 2));
603520
+ writeFileSync56(target.file, JSON.stringify(json, null, 2));
603093
603521
  } else if (Array.isArray(json)) {
603094
- writeFileSync55(target.file, JSON.stringify(arr, null, 2));
603522
+ writeFileSync56(target.file, JSON.stringify(arr, null, 2));
603095
603523
  } else {
603096
- writeFileSync55(target.file, JSON.stringify({ tasks: arr }, null, 2));
603524
+ writeFileSync56(target.file, JSON.stringify({ tasks: arr }, null, 2));
603097
603525
  }
603098
603526
  if (!enabled2) {
603099
603527
  try {
@@ -603123,11 +603551,11 @@ function deleteScheduledById(id) {
603123
603551
  arr.splice(target.index, 1);
603124
603552
  if (Array.isArray(json?.tasks)) {
603125
603553
  json.tasks = arr;
603126
- writeFileSync55(target.file, JSON.stringify(json, null, 2));
603554
+ writeFileSync56(target.file, JSON.stringify(json, null, 2));
603127
603555
  } else if (Array.isArray(json)) {
603128
- writeFileSync55(target.file, JSON.stringify(arr, null, 2));
603556
+ writeFileSync56(target.file, JSON.stringify(arr, null, 2));
603129
603557
  } else {
603130
- writeFileSync55(target.file, JSON.stringify({ tasks: arr }, null, 2));
603558
+ writeFileSync56(target.file, JSON.stringify({ tasks: arr }, null, 2));
603131
603559
  }
603132
603560
  const candidates = [];
603133
603561
  if (id) candidates.push(id);
@@ -603380,7 +603808,7 @@ function reconcileScheduledTasks(apply) {
603380
603808
  const errors = [];
603381
603809
  for (const f2 of found) {
603382
603810
  const wdir = f2.workingDir || process.cwd();
603383
- const file = join122(wdir, ".oa", "scheduled", "tasks.json");
603811
+ const file = join123(wdir, ".oa", "scheduled", "tasks.json");
603384
603812
  try {
603385
603813
  let json = { tasks: [] };
603386
603814
  try {
@@ -603395,9 +603823,9 @@ function reconcileScheduledTasks(apply) {
603395
603823
  const entry = { task: f2.task || `legacy ${f2.id}`, schedule: f2.cron, enabled: true };
603396
603824
  arr.push(entry);
603397
603825
  const toWrite = Array.isArray(json?.tasks) ? { ...json, tasks: arr } : Array.isArray(json) ? arr : { tasks: arr };
603398
- mkdirSync63(join122(wdir, ".oa", "scheduled"), { recursive: true });
603399
- mkdirSync63(join122(wdir, ".oa", "scheduled", "logs"), { recursive: true });
603400
- writeFileSync55(file, JSON.stringify(toWrite, null, 2));
603826
+ mkdirSync64(join123(wdir, ".oa", "scheduled"), { recursive: true });
603827
+ mkdirSync64(join123(wdir, ".oa", "scheduled", "logs"), { recursive: true });
603828
+ writeFileSync56(file, JSON.stringify(toWrite, null, 2));
603401
603829
  adopted.push({ file, index: arr.length - 1 });
603402
603830
  }
603403
603831
  } else {
@@ -603441,32 +603869,32 @@ function writeCrontabLines(lines) {
603441
603869
  }
603442
603870
  function canonicalCronLine(rec) {
603443
603871
  const oaBin = findOaBinary4();
603444
- const logDir = join122(rec.workingDir, ".oa", "scheduled", "logs");
603445
- const logFile = join122(logDir, `${rec.id}.log`);
603446
- const storeFile = join122(rec.workingDir, ".oa", "scheduled", "tasks.json");
603872
+ const logDir = join123(rec.workingDir, ".oa", "scheduled", "logs");
603873
+ const logFile = join123(logDir, `${rec.id}.log`);
603874
+ const storeFile = join123(rec.workingDir, ".oa", "scheduled", "tasks.json");
603447
603875
  const taskEsc = rec.task.replace(/'/g, "'\\''");
603448
- const lockDir = join122(rec.workingDir, ".oa", "run");
603449
- const lockPath = join122(lockDir, `${rec.id}.lock`);
603876
+ const lockDir = join123(rec.workingDir, ".oa", "run");
603877
+ const lockPath = join123(lockDir, `${rec.id}.lock`);
603450
603878
  const wrapper = [
603451
603879
  `cd ${JSON.stringify(rec.workingDir)}`,
603452
603880
  `mkdir -p ${JSON.stringify(logDir)}`,
603453
603881
  `mkdir -p ${JSON.stringify(lockDir)}`,
603454
603882
  `if mkdir ${JSON.stringify(lockPath)} 2>/dev/null; then`,
603455
- ` echo $$ > ${JSON.stringify(join122(lockPath, "pid"))}`,
603883
+ ` echo $$ > ${JSON.stringify(join123(lockPath, "pid"))}`,
603456
603884
  ` trap 'rm -rf ${lockPath}' EXIT`,
603457
603885
  `else`,
603458
- ` if [ -f ${JSON.stringify(join122(lockPath, "pid"))} ]; then`,
603459
- ` oldpid=$(cat ${JSON.stringify(join122(lockPath, "pid"))} 2>/dev/null || echo)`,
603886
+ ` if [ -f ${JSON.stringify(join123(lockPath, "pid"))} ]; then`,
603887
+ ` oldpid=$(cat ${JSON.stringify(join123(lockPath, "pid"))} 2>/dev/null || echo)`,
603460
603888
  ` if [ -n "$oldpid" ] && kill -0 "$oldpid" 2>/dev/null; then`,
603461
603889
  ` echo "[oa-scheduler] ${rec.id} already running as PID $oldpid; skipping" >> ${JSON.stringify(logFile)}`,
603462
603890
  ` exit 0`,
603463
603891
  ` else`,
603464
603892
  ` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
603465
- ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join122(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
603893
+ ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join123(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
603466
603894
  ` fi`,
603467
603895
  ` else`,
603468
603896
  ` rm -rf ${JSON.stringify(lockPath)} 2>/dev/null || true`,
603469
- ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join122(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
603897
+ ` mkdir -p ${JSON.stringify(lockPath)} && echo $$ > ${JSON.stringify(join123(lockPath, "pid"))} && trap 'rm -rf ${lockPath}' EXIT`,
603470
603898
  ` fi`,
603471
603899
  `fi`,
603472
603900
  `${oaBin} '${taskEsc}' >> ${JSON.stringify(logFile)} 2>&1; _oa_exit=$?`,
@@ -603498,9 +603926,9 @@ function fixupOrMigrateScheduled(mode, dryRun) {
603498
603926
  try {
603499
603927
  if (!f2.workingDir || !f2.task) continue;
603500
603928
  const unitBase = `oa-${f2.id}`;
603501
- const unitDir = join122(homedir43(), ".config", "systemd", "user");
603502
- const svc = join122(unitDir, `${unitBase}.service`);
603503
- const tim = join122(unitDir, `${unitBase}.timer`);
603929
+ const unitDir = join123(homedir43(), ".config", "systemd", "user");
603930
+ const svc = join123(unitDir, `${unitBase}.service`);
603931
+ const tim = join123(unitDir, `${unitBase}.timer`);
603504
603932
  const oaBin = findOaBinary4();
603505
603933
  const rec = { id: f2.id, cron: f2.cron, workingDir: f2.workingDir, task: f2.task };
603506
603934
  const cmd = canonicalCronLine(rec).split(" ").slice(5).join(" ");
@@ -603530,9 +603958,9 @@ Persistent=true
603530
603958
  WantedBy=timers.target
603531
603959
  `;
603532
603960
  if (!dryRun) {
603533
- mkdirSync63(unitDir, { recursive: true });
603534
- writeFileSync55(svc, svcText);
603535
- writeFileSync55(tim, timText);
603961
+ mkdirSync64(unitDir, { recursive: true });
603962
+ writeFileSync56(svc, svcText);
603963
+ writeFileSync56(tim, timText);
603536
603964
  try {
603537
603965
  const { execSync: es } = require3("node:child_process");
603538
603966
  es("systemctl --user daemon-reload", { stdio: "pipe" });
@@ -603626,8 +604054,8 @@ function startApiServer(options2 = {}) {
603626
604054
  const config = loadConfig();
603627
604055
  const ollamaUrl = options2.ollamaUrl ?? config.backendUrl;
603628
604056
  const cwd4 = process.cwd();
603629
- initAuditLog(join122(cwd4, ".oa"));
603630
- initUsageTracker(join122(cwd4, ".oa"));
604057
+ initAuditLog(join123(cwd4, ".oa"));
604058
+ initUsageTracker(join123(cwd4, ".oa"));
603631
604059
  try {
603632
604060
  const taskMgr = getSharedTaskManager();
603633
604061
  taskMgr.setEventPublisher((type, data, opts) => {
@@ -603669,7 +604097,7 @@ function startApiServer(options2 = {}) {
603669
604097
  try {
603670
604098
  const dir = todoDir();
603671
604099
  try {
603672
- mkdirSync63(dir, { recursive: true });
604100
+ mkdirSync64(dir, { recursive: true });
603673
604101
  } catch {
603674
604102
  }
603675
604103
  const cache8 = /* @__PURE__ */ new Map();
@@ -603678,7 +604106,7 @@ function startApiServer(options2 = {}) {
603678
604106
  if (!f2.endsWith(".json") || f2.includes(".tmp.")) continue;
603679
604107
  const sid = f2.replace(/\.json$/, "");
603680
604108
  try {
603681
- const items = JSON.parse(readFileSync86(join122(dir, f2), "utf-8"));
604109
+ const items = JSON.parse(readFileSync86(join123(dir, f2), "utf-8"));
603682
604110
  if (Array.isArray(items)) {
603683
604111
  cache8.set(sid, new Map(items.map((t2) => [t2.id, t2])));
603684
604112
  }
@@ -603690,10 +604118,10 @@ function startApiServer(options2 = {}) {
603690
604118
  const watcher = fsWatch3(dir, (_evt, fname) => {
603691
604119
  if (!fname || !fname.endsWith(".json") || fname.includes(".tmp.")) return;
603692
604120
  const sid = fname.replace(/\.json$/, "");
603693
- const fp = join122(dir, fname);
604121
+ const fp = join123(dir, fname);
603694
604122
  let next = [];
603695
604123
  try {
603696
- if (!existsSync106(fp)) {
604124
+ if (!existsSync107(fp)) {
603697
604125
  const old = cache8.get(sid);
603698
604126
  if (old) {
603699
604127
  for (const t2 of old.values()) {
@@ -603745,13 +604173,13 @@ function startApiServer(options2 = {}) {
603745
604173
  const retentionDays = parseInt(process.env["OA_JOB_RETENTION_DAYS"] ?? "30", 10);
603746
604174
  if (retentionDays > 0) {
603747
604175
  try {
603748
- const jobsDir3 = join122(cwd4, ".oa", "jobs");
603749
- if (existsSync106(jobsDir3)) {
604176
+ const jobsDir3 = join123(cwd4, ".oa", "jobs");
604177
+ if (existsSync107(jobsDir3)) {
603750
604178
  const cutoff = Date.now() - retentionDays * 864e5;
603751
604179
  for (const f2 of readdirSync36(jobsDir3)) {
603752
604180
  if (!f2.endsWith(".json")) continue;
603753
604181
  try {
603754
- const jobPath = join122(jobsDir3, f2);
604182
+ const jobPath = join123(jobsDir3, f2);
603755
604183
  const job = JSON.parse(readFileSync86(jobPath, "utf-8"));
603756
604184
  const jobTime = new Date(job.startedAt ?? job.completedAt ?? 0).getTime();
603757
604185
  if (jobTime > 0 && jobTime < cutoff && job.status !== "running") {
@@ -603784,8 +604212,8 @@ function startApiServer(options2 = {}) {
603784
604212
  }
603785
604213
  let runtimeAccessMode = resolveAccessMode(process.env["OA_ACCESS"], host);
603786
604214
  try {
603787
- const accessFile = join122(homedir43(), ".open-agents", "access");
603788
- if (existsSync106(accessFile)) {
604215
+ const accessFile = join123(homedir43(), ".open-agents", "access");
604216
+ if (existsSync107(accessFile)) {
603789
604217
  const persisted = readFileSync86(accessFile, "utf8").trim();
603790
604218
  const resolved = resolveAccessMode(persisted, host);
603791
604219
  if (resolved) runtimeAccessMode = resolved;
@@ -603839,9 +604267,9 @@ function startApiServer(options2 = {}) {
603839
604267
  const previous = runtimeAccessMode;
603840
604268
  runtimeAccessMode = requested;
603841
604269
  try {
603842
- const dir = join122(homedir43(), ".open-agents");
603843
- mkdirSync63(dir, { recursive: true });
603844
- writeFileSync55(join122(dir, "access"), `${runtimeAccessMode}
604270
+ const dir = join123(homedir43(), ".open-agents");
604271
+ mkdirSync64(dir, { recursive: true });
604272
+ writeFileSync56(join123(dir, "access"), `${runtimeAccessMode}
603845
604273
  `, "utf8");
603846
604274
  } catch {
603847
604275
  }
@@ -604054,9 +604482,9 @@ function startApiServer(options2 = {}) {
604054
604482
  try {
604055
604483
  const { startEmbeddingWorkers: startEmbeddingWorkers2 } = await Promise.resolve().then(() => (init_embedding_workers(), embedding_workers_exports));
604056
604484
  const { ensureEmbedDeps: ensureEmbedDeps2, runEmbedImage: runEmbedImage2, runEmbedAudio: runEmbedAudio2 } = await Promise.resolve().then(() => (init_py_embed(), py_embed_exports));
604057
- const dbBase = join122(cwd4, ".oa");
604058
- const epStore = new mem.EpisodeStore(join122(dbBase, "memory.db"));
604059
- const kg = new mem.TemporalGraph(join122(dbBase, "kg.db"));
604485
+ const dbBase = join123(cwd4, ".oa");
604486
+ const epStore = new mem.EpisodeStore(join123(dbBase, "memory.db"));
604487
+ const kg = new mem.TemporalGraph(join123(dbBase, "kg.db"));
604060
604488
  try {
604061
604489
  ensureEmbedDeps2();
604062
604490
  } catch {
@@ -604134,7 +604562,7 @@ function startApiServer(options2 = {}) {
604134
604562
  log22(` Primary: ${config.backendUrl} (${config.backendType || "ollama"})
604135
604563
  `);
604136
604564
  try {
604137
- const { writeFileSync: writeFileSync59, mkdirSync: mkdirSync67, existsSync: _exists } = require3("node:fs");
604565
+ const { writeFileSync: writeFileSync60, mkdirSync: mkdirSync68, existsSync: _exists, readFileSync: _rfs } = require3("node:fs");
604138
604566
  const { join: _join } = require3("node:path");
604139
604567
  const { homedir: _homedir } = require3("node:os");
604140
604568
  const apiHint = JSON.stringify({
@@ -604145,22 +604573,111 @@ function startApiServer(options2 = {}) {
604145
604573
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
604146
604574
  version: version4
604147
604575
  }, null, 2);
604148
- const candidates = [
604149
- _join(process.cwd(), ".oa", "nexus"),
604150
- _join(_homedir(), ".oa", "nexus"),
604151
- _join(_homedir(), ".open-agents", "nexus")
604152
- ];
604153
- for (const dir of candidates) {
604576
+ const dirSet = /* @__PURE__ */ new Set();
604577
+ try {
604578
+ const regPath = _join(_homedir(), ".open-agents", "nexus-registry.json");
604579
+ if (_exists(regPath)) {
604580
+ const reg = JSON.parse(_rfs(regPath, "utf-8"));
604581
+ for (const e2 of reg?.dirs || []) {
604582
+ const d2 = typeof e2 === "string" ? e2 : e2?.dir;
604583
+ if (typeof d2 === "string") dirSet.add(d2);
604584
+ }
604585
+ }
604586
+ } catch {
604587
+ }
604588
+ if (process.env["OA_NEXUS_DIR"]) dirSet.add(process.env["OA_NEXUS_DIR"]);
604589
+ dirSet.add(_join(process.cwd(), ".oa", "nexus"));
604590
+ dirSet.add(_join(_homedir(), ".oa", "nexus"));
604591
+ dirSet.add(_join(_homedir(), ".open-agents", "nexus"));
604592
+ let written = 0;
604593
+ for (const dir of dirSet) {
604154
604594
  try {
604155
- if (!_exists(dir)) mkdirSync67(dir, { recursive: true });
604156
- writeFileSync59(_join(dir, "api-port.json"), apiHint);
604595
+ if (!_exists(dir)) mkdirSync68(dir, { recursive: true });
604596
+ writeFileSync60(_join(dir, "api-port.json"), apiHint);
604597
+ written++;
604157
604598
  } catch {
604158
604599
  }
604159
604600
  }
604601
+ if (written > 0) log22(` api-port hint: wrote to ${written} nexus dir(s)
604602
+ `);
604160
604603
  } catch (e2) {
604161
604604
  log22(` WARN: api-port hint write failed: ${e2.message}
604162
604605
  `);
604163
604606
  }
604607
+ if (process.env["OA_AUTO_NEXUS"] !== "0") {
604608
+ (async () => {
604609
+ try {
604610
+ const { join: _j } = require3("node:path");
604611
+ const { homedir: _hd } = require3("node:os");
604612
+ const { existsSync: _ex, readFileSync: _rf, statSync: _st } = require3("node:fs");
604613
+ const { execSync: _ex2 } = require3("node:child_process");
604614
+ let chosenNexusDir = null;
604615
+ if (process.env["OA_NEXUS_DIR"]) chosenNexusDir = process.env["OA_NEXUS_DIR"];
604616
+ if (!chosenNexusDir) {
604617
+ try {
604618
+ const regPath = _j(_hd(), ".open-agents", "nexus-registry.json");
604619
+ if (_ex(regPath)) {
604620
+ const reg = JSON.parse(_rf(regPath, "utf-8"));
604621
+ for (const e2 of reg?.dirs || []) {
604622
+ const d2 = typeof e2 === "string" ? e2 : e2?.dir;
604623
+ if (typeof d2 === "string" && _ex(d2)) {
604624
+ chosenNexusDir = d2;
604625
+ break;
604626
+ }
604627
+ }
604628
+ }
604629
+ } catch {
604630
+ }
604631
+ }
604632
+ if (!chosenNexusDir) {
604633
+ try {
604634
+ const cmd = `find "${_hd()}" -maxdepth 4 -path '*/.oa/nexus' -type d 2>/dev/null | head -10`;
604635
+ const out = _ex2(cmd, { encoding: "utf-8", timeout: 2e3 }).trim();
604636
+ for (const ln of out.split("\n").filter(Boolean)) {
604637
+ if (_ex(_j(ln, "status.json"))) {
604638
+ chosenNexusDir = ln;
604639
+ break;
604640
+ }
604641
+ }
604642
+ if (!chosenNexusDir && out) chosenNexusDir = out.split("\n")[0]?.trim() || null;
604643
+ } catch {
604644
+ }
604645
+ }
604646
+ const finalNexusDir = chosenNexusDir ?? _j(_hd(), ".oa", "nexus");
604647
+ chosenNexusDir = finalNexusDir;
604648
+ const repoRoot = finalNexusDir.replace(/[\\/]\.oa[\\/]nexus$/, "");
604649
+ log22(` Nexus auto-recover: target ${finalNexusDir}
604650
+ `);
604651
+ const { NexusTool: NexusTool2 } = await Promise.resolve().then(() => (init_dist5(), dist_exports));
604652
+ const tool = new NexusTool2(repoRoot);
604653
+ const result = await tool.execute({ action: "connect" });
604654
+ const status = result?.success ? "ok" : "fail";
604655
+ const detail = result?.output || result?.error || "";
604656
+ log22(` Nexus auto-recover: ${status}${detail ? " — " + String(detail).split("\n")[0].slice(0, 120) : ""}
604657
+ `);
604658
+ if (status === "ok") {
604659
+ try {
604660
+ const { writeFileSync: _wfs2, mkdirSync: _mks, existsSync: _exf } = require3("node:fs");
604661
+ const apiHint2 = JSON.stringify({
604662
+ port,
604663
+ host: host === "0.0.0.0" ? "127.0.0.1" : host,
604664
+ scheme: proto,
604665
+ pid: process.pid,
604666
+ startedAt: (/* @__PURE__ */ new Date()).toISOString(),
604667
+ version: version4
604668
+ }, null, 2);
604669
+ const dirOut = chosenNexusDir;
604670
+ if (!_exf(dirOut)) _mks(dirOut, { recursive: true });
604671
+ _wfs2(_j(dirOut, "api-port.json"), apiHint2);
604672
+ } catch {
604673
+ }
604674
+ }
604675
+ } catch (e2) {
604676
+ log22(` Nexus auto-recover: skipped (${e2.message.slice(0, 80)})
604677
+ `);
604678
+ }
604679
+ })();
604680
+ }
604164
604681
  try {
604165
604682
  adoptHandoffRuns();
604166
604683
  } catch (e2) {
@@ -604394,10 +604911,10 @@ async function handleMemoryIngest(req2, res, ollamaUrl) {
604394
604911
  const labels = Array.isArray(b.labels) ? b.labels : [];
604395
604912
  const mediaPath = typeof b.media_path === "string" ? b.media_path : void 0;
604396
604913
  const cwd4 = process.cwd();
604397
- const dbBase = join122(cwd4, ".oa");
604914
+ const dbBase = join123(cwd4, ".oa");
604398
604915
  const { EpisodeStore: EpisodeStore3, TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
604399
- const epStore = new EpisodeStore3(join122(dbBase, "memory.db"));
604400
- const kg = new TemporalGraph3(join122(dbBase, "kg.db"));
604916
+ const epStore = new EpisodeStore3(join123(dbBase, "memory.db"));
604917
+ const kg = new TemporalGraph3(join123(dbBase, "kg.db"));
604401
604918
  const meta = {};
604402
604919
  if (mediaPath) meta.media_path = mediaPath;
604403
604920
  const epId = epStore.insert({ modality, content: content || (mediaPath || ""), metadata: meta, toolName: "memory_ingest" });
@@ -604464,7 +604981,7 @@ async function handleEntitiesList(req2, res) {
604464
604981
  const type = url.searchParams.get("type") || "person";
604465
604982
  const limit = Math.max(1, Math.min(1e3, parseInt(url.searchParams.get("limit") || "100", 10)));
604466
604983
  const { TemporalGraph: TemporalGraph3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
604467
- const kg = new TemporalGraph3(join122(process.cwd(), ".oa", "kg.db"));
604984
+ const kg = new TemporalGraph3(join123(process.cwd(), ".oa", "kg.db"));
604468
604985
  const nodes = kg.nodesByType(type, limit).map((n2) => ({ id: n2.id, text: n2.text, mentionCount: n2.mentionCount, firstSeen: n2.firstSeen, lastSeen: n2.lastSeen }));
604469
604986
  jsonResponse(res, 200, { object: "list", data: nodes });
604470
604987
  } catch (err) {
@@ -604486,7 +605003,7 @@ async function handleMemorySearch2(req2, res) {
604486
605003
  const wLex = typeof b.lexical_weight === "number" ? b.lexical_weight : 1;
604487
605004
  const wEmb = typeof b.embedding_weight === "number" ? b.embedding_weight : 1;
604488
605005
  const { EpisodeStore: EpisodeStore3 } = await Promise.resolve().then(() => (init_dist7(), dist_exports2));
604489
- const epStore = new EpisodeStore3(join122(process.cwd(), ".oa", "memory.db"));
605006
+ const epStore = new EpisodeStore3(join123(process.cwd(), ".oa", "memory.db"));
604490
605007
  const results = epStore.search({ query, modality, limit }, { queryEmbedding: qEmb, lexicalWeight: wLex, embeddingWeight: wEmb });
604491
605008
  jsonResponse(res, 200, { object: "list", data: results.map((e2) => ({ id: e2.id, modality: e2.modality, content: e2.content, timestamp: e2.timestamp })) });
604492
605009
  } catch (err) {
@@ -604603,11 +605120,11 @@ var init_serve = __esm({
604603
605120
 
604604
605121
  // packages/cli/src/tui/interactive.ts
604605
605122
  import { cwd } from "node:process";
604606
- import { resolve as resolve39, join as join123, dirname as dirname37, extname as extname12 } from "node:path";
605123
+ import { resolve as resolve39, join as join124, dirname as dirname37, extname as extname12 } from "node:path";
604607
605124
  import { createRequire as createRequire6 } from "node:module";
604608
605125
  import { fileURLToPath as fileURLToPath18 } from "node:url";
604609
- import { readFileSync as readFileSync87, writeFileSync as writeFileSync56, appendFileSync as appendFileSync8, rmSync as rmSync5, readdirSync as readdirSync37, mkdirSync as mkdirSync64 } from "node:fs";
604610
- import { existsSync as existsSync107 } from "node:fs";
605126
+ import { readFileSync as readFileSync87, writeFileSync as writeFileSync57, appendFileSync as appendFileSync8, rmSync as rmSync5, readdirSync as readdirSync37, mkdirSync as mkdirSync65 } from "node:fs";
605127
+ import { existsSync as existsSync108 } from "node:fs";
604611
605128
  import { execSync as execSync58 } from "node:child_process";
604612
605129
  import { homedir as homedir44 } from "node:os";
604613
605130
  function formatTimeAgo2(date) {
@@ -604625,12 +605142,12 @@ function getVersion4() {
604625
605142
  const require4 = createRequire6(import.meta.url);
604626
605143
  const thisDir = dirname37(fileURLToPath18(import.meta.url));
604627
605144
  const candidates = [
604628
- join123(thisDir, "..", "package.json"),
604629
- join123(thisDir, "..", "..", "package.json"),
604630
- join123(thisDir, "..", "..", "..", "package.json")
605145
+ join124(thisDir, "..", "package.json"),
605146
+ join124(thisDir, "..", "..", "package.json"),
605147
+ join124(thisDir, "..", "..", "..", "package.json")
604631
605148
  ];
604632
605149
  for (const pkgPath of candidates) {
604633
- if (existsSync107(pkgPath)) {
605150
+ if (existsSync108(pkgPath)) {
604634
605151
  const pkg = require4(pkgPath);
604635
605152
  if (pkg.name === "open-agents-ai" || pkg.name === "@open-agents/cli" || pkg.name === "@open-agents/monorepo") {
604636
605153
  return pkg.version ?? "0.0.0";
@@ -605436,14 +605953,14 @@ Meta-critique: quality ${meta.quality}/5, thorough: ${meta.thorough}`;
605436
605953
  function gatherMemorySnippets(root) {
605437
605954
  const snippets = [];
605438
605955
  const dirs = [
605439
- join123(root, ".oa", "memory"),
605440
- join123(root, ".open-agents", "memory")
605956
+ join124(root, ".oa", "memory"),
605957
+ join124(root, ".open-agents", "memory")
605441
605958
  ];
605442
605959
  for (const dir of dirs) {
605443
- if (!existsSync107(dir)) continue;
605960
+ if (!existsSync108(dir)) continue;
605444
605961
  try {
605445
605962
  for (const f2 of readdirSync37(dir).filter((f3) => f3.endsWith(".json"))) {
605446
- const data = JSON.parse(readFileSync87(join123(dir, f2), "utf-8"));
605963
+ const data = JSON.parse(readFileSync87(join124(dir, f2), "utf-8"));
605447
605964
  for (const val of Object.values(data)) {
605448
605965
  const v = typeof val === "object" && val !== null && "value" in val ? String(val.value) : String(val);
605449
605966
  if (v.length > 10) snippets.push(v);
@@ -605597,8 +606114,8 @@ ${metabolismMemories}
605597
606114
  } catch {
605598
606115
  }
605599
606116
  try {
605600
- const archeFile = join123(repoRoot, ".oa", "arche", "variants.json");
605601
- if (existsSync107(archeFile)) {
606117
+ const archeFile = join124(repoRoot, ".oa", "arche", "variants.json");
606118
+ if (existsSync108(archeFile)) {
605602
606119
  const variants = JSON.parse(readFileSync87(archeFile, "utf8"));
605603
606120
  if (variants.length > 0) {
605604
606121
  let filtered = variants;
@@ -605771,8 +606288,8 @@ RULES:
605771
606288
  const compactionThreshold = Number.isFinite(envOverride) && envOverride > 0 ? envOverride : modelTier === "small" ? 12e3 : modelTier === "medium" ? 24e3 : 4e4;
605772
606289
  let identityInjection = "";
605773
606290
  try {
605774
- const ikStateFile = join123(repoRoot, ".oa", "identity", "self-state.json");
605775
- if (existsSync107(ikStateFile)) {
606291
+ const ikStateFile = join124(repoRoot, ".oa", "identity", "self-state.json");
606292
+ if (existsSync108(ikStateFile)) {
605776
606293
  const selfState = JSON.parse(readFileSync87(ikStateFile, "utf8"));
605777
606294
  const lines = [
605778
606295
  `[Identity State v${selfState.version}]`,
@@ -606635,13 +607152,13 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
606635
607152
  });
606636
607153
  }
606637
607154
  try {
606638
- const ikDir = join123(repoRoot, ".oa", "identity");
606639
- const ikFile = join123(ikDir, "self-state.json");
607155
+ const ikDir = join124(repoRoot, ".oa", "identity");
607156
+ const ikFile = join124(ikDir, "self-state.json");
606640
607157
  let ikState;
606641
- if (existsSync107(ikFile)) {
607158
+ if (existsSync108(ikFile)) {
606642
607159
  ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
606643
607160
  } else {
606644
- mkdirSync64(ikDir, { recursive: true });
607161
+ mkdirSync65(ikDir, { recursive: true });
606645
607162
  const machineId = Date.now().toString(36) + Math.random().toString(36).slice(2, 8);
606646
607163
  ikState = {
606647
607164
  self_id: `oa-${machineId}`,
@@ -606697,7 +607214,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
606697
607214
  }
606698
607215
  ikState.session_count = (ikState.session_count || 0) + 1;
606699
607216
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
606700
- writeFileSync56(ikFile, JSON.stringify(ikState, null, 2));
607217
+ writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
606701
607218
  } catch (ikErr) {
606702
607219
  try {
606703
607220
  console.error("[IK-OBSERVE]", ikErr);
@@ -606716,8 +607233,8 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
606716
607233
  } else {
606717
607234
  renderTaskIncomplete(result.turns, result.toolCalls, result.durationMs, tokens);
606718
607235
  try {
606719
- const ikFile = join123(repoRoot, ".oa", "identity", "self-state.json");
606720
- if (existsSync107(ikFile)) {
607236
+ const ikFile = join124(repoRoot, ".oa", "identity", "self-state.json");
607237
+ if (existsSync108(ikFile)) {
606721
607238
  const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
606722
607239
  if (!ikState.stats) ikState.stats = { queries_served: 0 };
606723
607240
  ikState.stats.queries_served = (ikState.stats.queries_served || 0) + 1;
@@ -606729,7 +607246,7 @@ When done, either call task_complete with your answer, or use FINAL_VAR(variable
606729
607246
  if (ikState.version_history.length > 200) ikState.version_history = ikState.version_history.slice(-200);
606730
607247
  ikState.session_count = (ikState.session_count || 0) + 1;
606731
607248
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
606732
- writeFileSync56(ikFile, JSON.stringify(ikState, null, 2));
607249
+ writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
606733
607250
  }
606734
607251
  } catch {
606735
607252
  }
@@ -606974,9 +607491,9 @@ async function startInteractive(config, repoPath) {
606974
607491
  process.stdin.pause();
606975
607492
  }
606976
607493
  try {
606977
- const oaDir = join123(repoRoot, ".oa");
606978
- const nexusPidFile = join123(oaDir, "nexus", "daemon.pid");
606979
- if (existsSync107(nexusPidFile)) {
607494
+ const oaDir = join124(repoRoot, ".oa");
607495
+ const nexusPidFile = join124(oaDir, "nexus", "daemon.pid");
607496
+ if (existsSync108(nexusPidFile)) {
606980
607497
  const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
606981
607498
  if (pid > 0) {
606982
607499
  try {
@@ -607637,7 +608154,7 @@ ${result.summary}`
607637
608154
  let p2pGateway = null;
607638
608155
  let peerMesh = null;
607639
608156
  let inferenceRouter = null;
607640
- const secretVault = new SecretVault(join123(repoRoot, ".oa", "vault.enc"));
608157
+ const secretVault = new SecretVault(join124(repoRoot, ".oa", "vault.enc"));
607641
608158
  let adminSessionKey = null;
607642
608159
  const callSubAgents = /* @__PURE__ */ new Map();
607643
608160
  const streamRenderer = new StreamRenderer();
@@ -607868,12 +608385,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
607868
608385
  const hits = allCompletions.filter((c9) => c9.toLowerCase().startsWith(lower));
607869
608386
  return [hits, line];
607870
608387
  }
607871
- const HISTORY_DIR = join123(homedir44(), ".open-agents");
607872
- const HISTORY_FILE = join123(HISTORY_DIR, "repl-history");
608388
+ const HISTORY_DIR = join124(homedir44(), ".open-agents");
608389
+ const HISTORY_FILE = join124(HISTORY_DIR, "repl-history");
607873
608390
  const MAX_HISTORY_LINES = 500;
607874
608391
  let savedHistory = [];
607875
608392
  try {
607876
- if (existsSync107(HISTORY_FILE)) {
608393
+ if (existsSync108(HISTORY_FILE)) {
607877
608394
  const raw = readFileSync87(HISTORY_FILE, "utf8").trim();
607878
608395
  if (raw) savedHistory = raw.split("\n").reverse();
607879
608396
  }
@@ -608021,12 +608538,12 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
608021
608538
  function persistHistoryLine(line) {
608022
608539
  if (!line.trim()) return;
608023
608540
  try {
608024
- mkdirSync64(HISTORY_DIR, { recursive: true });
608541
+ mkdirSync65(HISTORY_DIR, { recursive: true });
608025
608542
  appendFileSync8(HISTORY_FILE, line + "\n", "utf8");
608026
608543
  if (Math.random() < 0.02) {
608027
608544
  const all2 = readFileSync87(HISTORY_FILE, "utf8").trim().split("\n");
608028
608545
  if (all2.length > MAX_HISTORY_LINES) {
608029
- writeFileSync56(HISTORY_FILE, all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
608546
+ writeFileSync57(HISTORY_FILE, all2.slice(-MAX_HISTORY_LINES).join("\n") + "\n", "utf8");
608030
608547
  }
608031
608548
  }
608032
608549
  } catch {
@@ -608211,10 +608728,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
608211
608728
  const { unlinkSync: _rmStale } = await import("node:fs");
608212
608729
  const { homedir: _hdir } = await import("node:os");
608213
608730
  for (const dp of [
608214
- join123(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
608215
- join123(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
608731
+ join124(repoRoot, ".oa", "nexus", "nexus-daemon.mjs"),
608732
+ join124(_hdir(), ".open-agents", ".oa", "nexus", "nexus-daemon.mjs")
608216
608733
  ]) {
608217
- if (existsSync107(dp)) try {
608734
+ if (existsSync108(dp)) try {
608218
608735
  _rmStale(dp);
608219
608736
  } catch {
608220
608737
  }
@@ -608225,8 +608742,8 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
608225
608742
  const autoNexus = new NexusTool(repoRoot);
608226
608743
  const _registerNexusDaemon = () => {
608227
608744
  try {
608228
- const nexusPidFile = join123(repoRoot, ".oa", "nexus", "daemon.pid");
608229
- if (existsSync107(nexusPidFile)) {
608745
+ const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
608746
+ if (existsSync108(nexusPidFile)) {
608230
608747
  const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
608231
608748
  if (nPid > 0 && !registry2.daemons.has("Nexus")) {
608232
608749
  registry2.register({ name: "Nexus", pid: nPid, startedAt: Date.now(), status: "running" });
@@ -608284,7 +608801,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
608284
608801
  } catch {
608285
608802
  }
608286
608803
  try {
608287
- const oaDir = join123(repoRoot, ".oa");
608804
+ const oaDir = join124(repoRoot, ".oa");
608288
608805
  const reconnected = await ExposeGateway.checkAndReconnect(oaDir, {
608289
608806
  onInfo: (msg) => writeContent(() => renderInfo2(msg)),
608290
608807
  onError: (msg) => writeContent(() => renderWarning2(msg))
@@ -608316,7 +608833,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
608316
608833
  } catch {
608317
608834
  }
608318
608835
  try {
608319
- const oaDir = join123(repoRoot, ".oa");
608836
+ const oaDir = join124(repoRoot, ".oa");
608320
608837
  const reconnectedP2P = await ExposeP2PGateway.checkAndReconnect(oaDir, new NexusTool(repoRoot), {
608321
608838
  onInfo: (msg) => writeContent(() => renderInfo2(msg)),
608322
608839
  onError: (msg) => writeContent(() => renderWarning2(msg))
@@ -608357,10 +608874,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
608357
608874
  }
608358
608875
  try {
608359
608876
  const { homedir: _hd, hostname: _hn, userInfo: _ui } = await import("node:os");
608360
- const globalNamePath = join123(_hd(), ".open-agents", "agent-name");
608877
+ const globalNamePath = join124(_hd(), ".open-agents", "agent-name");
608361
608878
  let agName = "";
608362
608879
  try {
608363
- if (existsSync107(globalNamePath)) agName = readFileSync87(globalNamePath, "utf8").trim();
608880
+ if (existsSync108(globalNamePath)) agName = readFileSync87(globalNamePath, "utf8").trim();
608364
608881
  } catch {
608365
608882
  }
608366
608883
  if (!agName) {
@@ -608389,10 +608906,10 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
608389
608906
  }
608390
608907
  if (!ollamaAlive) {
608391
608908
  try {
608392
- const savedSponsorsPath = join123(repoRoot, ".oa", "sponsor", "known-sponsors.json");
608909
+ const savedSponsorsPath = join124(repoRoot, ".oa", "sponsor", "known-sponsors.json");
608393
608910
  let savedSponsors = [];
608394
608911
  try {
608395
- if (existsSync107(savedSponsorsPath)) {
608912
+ if (existsSync108(savedSponsorsPath)) {
608396
608913
  savedSponsors = JSON.parse(readFileSync87(savedSponsorsPath, "utf8"));
608397
608914
  const oneHourAgo = Date.now() - 36e5;
608398
608915
  savedSponsors = savedSponsors.filter((s2) => (s2.lastVerified || 0) > oneHourAgo);
@@ -609485,10 +610002,10 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609485
610002
  if (name10 === "voice_list_files") {
609486
610003
  const baseDir = String(args?.dir ?? ".");
609487
610004
  const { readdirSync: readdirSync39, statSync: statSync36 } = __require("node:fs");
609488
- const { join: join128, resolve: resolve43 } = __require("node:path");
609489
- const base3 = baseDir.startsWith("/") ? baseDir : resolve43(join128(repoRoot, baseDir));
610005
+ const { join: join129, resolve: resolve43 } = __require("node:path");
610006
+ const base3 = baseDir.startsWith("/") ? baseDir : resolve43(join129(repoRoot, baseDir));
609490
610007
  const items = readdirSync39(base3).slice(0, 200).map((f2) => {
609491
- const s2 = statSync36(join128(base3, f2));
610008
+ const s2 = statSync36(join129(base3, f2));
609492
610009
  return { name: f2, dir: s2.isDirectory(), size: s2.size };
609493
610010
  });
609494
610011
  return JSON.stringify({ dir: base3, items }, null, 2);
@@ -609576,7 +610093,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609576
610093
  kind,
609577
610094
  targetUrl,
609578
610095
  authKey,
609579
- stateDir: join123(repoRoot, ".oa"),
610096
+ stateDir: join124(repoRoot, ".oa"),
609580
610097
  passthrough: passthrough ?? false,
609581
610098
  loadbalance: loadbalance ?? false,
609582
610099
  endpointAuth: passthrough ? currentConfig.apiKey : void 0,
@@ -609622,7 +610139,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609622
610139
  await tunnelGateway.stop();
609623
610140
  tunnelGateway = null;
609624
610141
  }
609625
- const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join123(repoRoot, ".oa") });
610142
+ const newTunnel = new ExposeGateway({ kind, targetUrl, authKey, fullAccess, stateDir: join124(repoRoot, ".oa") });
609626
610143
  newTunnel.on("stats", (stats) => {
609627
610144
  statusBar.setExposeStatus({
609628
610145
  status: stats.status,
@@ -609643,14 +610160,14 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609643
610160
  throw err;
609644
610161
  }
609645
610162
  },
609646
- async exposeStop(which) {
609647
- if (!which || which === "tunnel") {
610163
+ async exposeStop(which2) {
610164
+ if (!which2 || which2 === "tunnel") {
609648
610165
  if (tunnelGateway) {
609649
610166
  await tunnelGateway.stop();
609650
610167
  tunnelGateway = null;
609651
610168
  }
609652
610169
  }
609653
- if (!which || which === "libp2p") {
610170
+ if (!which2 || which2 === "libp2p") {
609654
610171
  if (p2pGateway) {
609655
610172
  await p2pGateway.stop();
609656
610173
  p2pGateway = null;
@@ -609709,8 +610226,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609709
610226
  });
609710
610227
  if (!result.success) throw new Error(result.error || "Connect failed");
609711
610228
  try {
609712
- const nexusPidFile = join123(repoRoot, ".oa", "nexus", "daemon.pid");
609713
- if (existsSync107(nexusPidFile)) {
610229
+ const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
610230
+ if (existsSync108(nexusPidFile)) {
609714
610231
  const pid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
609715
610232
  if (pid > 0) {
609716
610233
  registry2.register({
@@ -609899,9 +610416,9 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609899
610416
  writeContent(() => renderInfo2(`Killed ${bgKilled} background task(s).`));
609900
610417
  }
609901
610418
  try {
609902
- const nexusDir = join123(repoRoot, OA_DIR, "nexus");
609903
- const pidFile = join123(nexusDir, "daemon.pid");
609904
- if (existsSync107(pidFile)) {
610419
+ const nexusDir = join124(repoRoot, OA_DIR, "nexus");
610420
+ const pidFile = join124(nexusDir, "daemon.pid");
610421
+ if (existsSync108(pidFile)) {
609905
610422
  const pid = parseInt(readFileSync87(pidFile, "utf8").trim(), 10);
609906
610423
  if (pid > 0) {
609907
610424
  try {
@@ -609924,11 +610441,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609924
610441
  } catch {
609925
610442
  }
609926
610443
  try {
609927
- const voiceDir2 = join123(homedir44(), ".open-agents", "voice");
610444
+ const voiceDir2 = join124(homedir44(), ".open-agents", "voice");
609928
610445
  const voicePidFiles = ["luxtts-daemon.pid", "piper-daemon.pid"];
609929
610446
  for (const pf of voicePidFiles) {
609930
- const pidPath = join123(voiceDir2, pf);
609931
- if (existsSync107(pidPath)) {
610447
+ const pidPath = join124(voiceDir2, pf);
610448
+ if (existsSync108(pidPath)) {
609932
610449
  try {
609933
610450
  const pid = parseInt(readFileSync87(pidPath, "utf8").trim(), 10);
609934
610451
  if (pid > 0) {
@@ -609954,8 +610471,8 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
609954
610471
  execSync58(process.platform === "win32" ? "timeout /t 1 /nobreak >nul" : "sleep 0.5", { timeout: 3e3, stdio: "ignore" });
609955
610472
  } catch {
609956
610473
  }
609957
- const oaPath = join123(repoRoot, OA_DIR);
609958
- if (existsSync107(oaPath)) {
610474
+ const oaPath = join124(repoRoot, OA_DIR);
610475
+ if (existsSync108(oaPath)) {
609959
610476
  let deleted = false;
609960
610477
  for (let attempt = 0; attempt < 3; attempt++) {
609961
610478
  try {
@@ -610039,18 +610556,18 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
610039
610556
  try {
610040
610557
  const { isPersonaPlexRunning: isPersonaPlexRunning2 } = await Promise.resolve().then(() => (init_personaplex(), personaplex_exports));
610041
610558
  if (isPersonaPlexRunning2()) {
610042
- const ppPidFile = join123(homedir44(), ".open-agents", "voice", "personaplex", "daemon.pid");
610043
- const ppPortFile = join123(homedir44(), ".open-agents", "voice", "personaplex", "daemon.port");
610044
- if (existsSync107(ppPidFile)) {
610559
+ const ppPidFile = join124(homedir44(), ".open-agents", "voice", "personaplex", "daemon.pid");
610560
+ const ppPortFile = join124(homedir44(), ".open-agents", "voice", "personaplex", "daemon.port");
610561
+ if (existsSync108(ppPidFile)) {
610045
610562
  const ppPid = parseInt(readFileSync87(ppPidFile, "utf8").trim(), 10);
610046
- const ppPort = existsSync107(ppPortFile) ? parseInt(readFileSync87(ppPortFile, "utf8").trim(), 10) : void 0;
610563
+ const ppPort = existsSync108(ppPortFile) ? parseInt(readFileSync87(ppPortFile, "utf8").trim(), 10) : void 0;
610047
610564
  if (ppPid > 0 && !registry2.daemons.has("PersonaPlex")) {
610048
610565
  registry2.register({ name: "PersonaPlex", pid: ppPid, port: ppPort, startedAt: Date.now(), status: "running" });
610049
610566
  }
610050
610567
  }
610051
610568
  }
610052
- const nexusPidFile = join123(repoRoot, ".oa", "nexus", "daemon.pid");
610053
- if (existsSync107(nexusPidFile)) {
610569
+ const nexusPidFile = join124(repoRoot, ".oa", "nexus", "daemon.pid");
610570
+ if (existsSync108(nexusPidFile)) {
610054
610571
  const nPid = parseInt(readFileSync87(nexusPidFile, "utf8").trim(), 10);
610055
610572
  if (nPid > 0 && !registry2.daemons.has("Nexus")) {
610056
610573
  try {
@@ -610418,9 +610935,9 @@ Execute this skill now. Follow the behavioral guidance above.`;
610418
610935
  }
610419
610936
  }
610420
610937
  const cleanPath = input.replace(/^['"]|['"]$/g, "").trim();
610421
- const isImage = isImagePath(cleanPath) && existsSync107(resolve39(repoRoot, cleanPath));
610422
- const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync107(resolve39(repoRoot, cleanPath));
610423
- const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) && existsSync107(resolve39(repoRoot, cleanPath));
610938
+ const isImage = isImagePath(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
610939
+ const isMedia = !isImage && isTranscribablePath(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
610940
+ const isMarkdown = !isImage && !isMedia && /\.(md|markdown)$/i.test(cleanPath) && existsSync108(resolve39(repoRoot, cleanPath));
610424
610941
  if (activeTask) {
610425
610942
  if (activeTask.runner.isPaused) {
610426
610943
  activeTask.runner.resume();
@@ -611007,13 +611524,13 @@ async function runWithTUI(task, config, repoPath, callbacks) {
611007
611524
  const handle2 = startTask(task, config, repoRoot);
611008
611525
  await handle2.promise;
611009
611526
  try {
611010
- const ikDir = join123(repoRoot, ".oa", "identity");
611011
- const ikFile = join123(ikDir, "self-state.json");
611527
+ const ikDir = join124(repoRoot, ".oa", "identity");
611528
+ const ikFile = join124(ikDir, "self-state.json");
611012
611529
  let ikState;
611013
- if (existsSync107(ikFile)) {
611530
+ if (existsSync108(ikFile)) {
611014
611531
  ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
611015
611532
  } else {
611016
- mkdirSync64(ikDir, { recursive: true });
611533
+ mkdirSync65(ikDir, { recursive: true });
611017
611534
  ikState = {
611018
611535
  self_id: `oa-${Date.now().toString(36)}`,
611019
611536
  version: 1,
@@ -611035,7 +611552,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
611035
611552
  ikState.homeostasis.coherence = Math.min(1, ikState.homeostasis.coherence + 0.05);
611036
611553
  ikState.session_count = (ikState.session_count || 0) + 1;
611037
611554
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
611038
- writeFileSync56(ikFile, JSON.stringify(ikState, null, 2));
611555
+ writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
611039
611556
  } catch (ikErr) {
611040
611557
  }
611041
611558
  try {
@@ -611048,11 +611565,11 @@ async function runWithTUI(task, config, repoPath, callbacks) {
611048
611565
  );
611049
611566
  } catch {
611050
611567
  try {
611051
- const archeDir = join123(repoRoot, ".oa", "arche");
611052
- const archeFile = join123(archeDir, "variants.json");
611568
+ const archeDir = join124(repoRoot, ".oa", "arche");
611569
+ const archeFile = join124(archeDir, "variants.json");
611053
611570
  let variants = [];
611054
611571
  try {
611055
- if (existsSync107(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
611572
+ if (existsSync108(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
611056
611573
  } catch {
611057
611574
  }
611058
611575
  variants.push({
@@ -611066,14 +611583,14 @@ async function runWithTUI(task, config, repoPath, callbacks) {
611066
611583
  tags: ["general"]
611067
611584
  });
611068
611585
  if (variants.length > 50) variants = variants.slice(-50);
611069
- mkdirSync64(archeDir, { recursive: true });
611070
- writeFileSync56(archeFile, JSON.stringify(variants, null, 2));
611586
+ mkdirSync65(archeDir, { recursive: true });
611587
+ writeFileSync57(archeFile, JSON.stringify(variants, null, 2));
611071
611588
  } catch {
611072
611589
  }
611073
611590
  }
611074
611591
  try {
611075
- const metaFile = join123(repoRoot, ".oa", "memory", "metabolism", "store.json");
611076
- if (existsSync107(metaFile)) {
611592
+ const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
611593
+ if (existsSync108(metaFile)) {
611077
611594
  const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
611078
611595
  const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
611079
611596
  let updated = false;
@@ -611085,7 +611602,7 @@ async function runWithTUI(task, config, repoPath, callbacks) {
611085
611602
  updated = true;
611086
611603
  }
611087
611604
  if (updated) {
611088
- writeFileSync56(metaFile, JSON.stringify(store2, null, 2));
611605
+ writeFileSync57(metaFile, JSON.stringify(store2, null, 2));
611089
611606
  }
611090
611607
  }
611091
611608
  } catch {
@@ -611138,9 +611655,9 @@ Rules:
611138
611655
  try {
611139
611656
  const { initDb: initDb2 } = __require("@open-agents/memory");
611140
611657
  const { ProceduralMemoryStore: ProceduralMemoryStore2 } = __require("@open-agents/memory");
611141
- const dbDir = join123(repoRoot, ".oa", "memory");
611142
- mkdirSync64(dbDir, { recursive: true });
611143
- const db = initDb2(join123(dbDir, "structured.db"));
611658
+ const dbDir = join124(repoRoot, ".oa", "memory");
611659
+ mkdirSync65(dbDir, { recursive: true });
611660
+ const db = initDb2(join124(dbDir, "structured.db"));
611144
611661
  const memStore = new ProceduralMemoryStore2(db);
611145
611662
  memStore.createWithEmbedding({
611146
611663
  content: content.slice(0, 600),
@@ -611155,11 +611672,11 @@ Rules:
611155
611672
  db.close();
611156
611673
  } catch {
611157
611674
  }
611158
- const metaDir = join123(repoRoot, ".oa", "memory", "metabolism");
611159
- const storeFile = join123(metaDir, "store.json");
611675
+ const metaDir = join124(repoRoot, ".oa", "memory", "metabolism");
611676
+ const storeFile = join124(metaDir, "store.json");
611160
611677
  let store2 = [];
611161
611678
  try {
611162
- if (existsSync107(storeFile)) store2 = JSON.parse(readFileSync87(storeFile, "utf8"));
611679
+ if (existsSync108(storeFile)) store2 = JSON.parse(readFileSync87(storeFile, "utf8"));
611163
611680
  } catch {
611164
611681
  }
611165
611682
  store2.push({
@@ -611174,25 +611691,25 @@ Rules:
611174
611691
  accessCount: 0
611175
611692
  });
611176
611693
  if (store2.length > 100) store2 = store2.slice(-100);
611177
- mkdirSync64(metaDir, { recursive: true });
611178
- writeFileSync56(storeFile, JSON.stringify(store2, null, 2));
611694
+ mkdirSync65(metaDir, { recursive: true });
611695
+ writeFileSync57(storeFile, JSON.stringify(store2, null, 2));
611179
611696
  }
611180
611697
  }
611181
611698
  } catch {
611182
611699
  }
611183
611700
  try {
611184
- const cohereSettingsFile = join123(repoRoot, ".oa", "settings.json");
611701
+ const cohereSettingsFile = join124(repoRoot, ".oa", "settings.json");
611185
611702
  let cohereActive = false;
611186
611703
  try {
611187
- if (existsSync107(cohereSettingsFile)) {
611704
+ if (existsSync108(cohereSettingsFile)) {
611188
611705
  const settings = JSON.parse(readFileSync87(cohereSettingsFile, "utf8"));
611189
611706
  cohereActive = settings.cohere === true;
611190
611707
  }
611191
611708
  } catch {
611192
611709
  }
611193
611710
  if (cohereActive) {
611194
- const metaFile = join123(repoRoot, ".oa", "memory", "metabolism", "store.json");
611195
- if (existsSync107(metaFile)) {
611711
+ const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
611712
+ if (existsSync108(metaFile)) {
611196
611713
  const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
611197
611714
  const latest = store2.filter((m2) => m2.sourceTrace === "trajectory-extraction" || m2.sourceTrace === "llm-trajectory-extraction").slice(-1)[0];
611198
611715
  if (latest && latest.scores?.confidence >= 0.6) {
@@ -611218,17 +611735,17 @@ Rules:
611218
611735
  }
611219
611736
  } catch (err) {
611220
611737
  try {
611221
- const ikFile = join123(repoRoot, ".oa", "identity", "self-state.json");
611222
- if (existsSync107(ikFile)) {
611738
+ const ikFile = join124(repoRoot, ".oa", "identity", "self-state.json");
611739
+ if (existsSync108(ikFile)) {
611223
611740
  const ikState = JSON.parse(readFileSync87(ikFile, "utf8"));
611224
611741
  ikState.homeostasis.uncertainty = Math.min(1, ikState.homeostasis.uncertainty + 0.1);
611225
611742
  ikState.homeostasis.coherence = Math.max(0, ikState.homeostasis.coherence - 0.05);
611226
611743
  ikState.session_count = (ikState.session_count || 0) + 1;
611227
611744
  ikState.updated_at = (/* @__PURE__ */ new Date()).toISOString();
611228
- writeFileSync56(ikFile, JSON.stringify(ikState, null, 2));
611745
+ writeFileSync57(ikFile, JSON.stringify(ikState, null, 2));
611229
611746
  }
611230
- const metaFile = join123(repoRoot, ".oa", "memory", "metabolism", "store.json");
611231
- if (existsSync107(metaFile)) {
611747
+ const metaFile = join124(repoRoot, ".oa", "memory", "metabolism", "store.json");
611748
+ if (existsSync108(metaFile)) {
611232
611749
  const store2 = JSON.parse(readFileSync87(metaFile, "utf8"));
611233
611750
  const surfaced = store2.filter((m2) => m2.type !== "quarantine" && m2.scores?.confidence > 0.15).sort((a2, b) => b.scores.utility * b.scores.confidence - a2.scores.utility * a2.scores.confidence).slice(0, 5);
611234
611751
  for (const item of surfaced) {
@@ -611237,14 +611754,14 @@ Rules:
611237
611754
  item.scores.utility = Math.max(0, (item.scores.utility || 0.5) - 0.05);
611238
611755
  item.scores.confidence = Math.max(0, (item.scores.confidence || 0.5) - 0.02);
611239
611756
  }
611240
- writeFileSync56(metaFile, JSON.stringify(store2, null, 2));
611757
+ writeFileSync57(metaFile, JSON.stringify(store2, null, 2));
611241
611758
  }
611242
611759
  try {
611243
- const archeDir = join123(repoRoot, ".oa", "arche");
611244
- const archeFile = join123(archeDir, "variants.json");
611760
+ const archeDir = join124(repoRoot, ".oa", "arche");
611761
+ const archeFile = join124(archeDir, "variants.json");
611245
611762
  let variants = [];
611246
611763
  try {
611247
- if (existsSync107(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
611764
+ if (existsSync108(archeFile)) variants = JSON.parse(readFileSync87(archeFile, "utf8"));
611248
611765
  } catch {
611249
611766
  }
611250
611767
  variants.push({
@@ -611258,8 +611775,8 @@ Rules:
611258
611775
  tags: ["general"]
611259
611776
  });
611260
611777
  if (variants.length > 50) variants = variants.slice(-50);
611261
- mkdirSync64(archeDir, { recursive: true });
611262
- writeFileSync56(archeFile, JSON.stringify(variants, null, 2));
611778
+ mkdirSync65(archeDir, { recursive: true });
611779
+ writeFileSync57(archeFile, JSON.stringify(variants, null, 2));
611263
611780
  } catch {
611264
611781
  }
611265
611782
  } catch {
@@ -611347,14 +611864,14 @@ __export(run_exports, {
611347
611864
  statusCommand: () => statusCommand
611348
611865
  });
611349
611866
  import { resolve as resolve40 } from "node:path";
611350
- import { spawn as spawn26 } from "node:child_process";
611351
- import { mkdirSync as mkdirSync65, writeFileSync as writeFileSync57, readFileSync as readFileSync88, readdirSync as readdirSync38, existsSync as existsSync108 } from "node:fs";
611867
+ import { spawn as spawn27 } from "node:child_process";
611868
+ import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync58, readFileSync as readFileSync88, readdirSync as readdirSync38, existsSync as existsSync109 } from "node:fs";
611352
611869
  import { randomBytes as randomBytes24 } from "node:crypto";
611353
- import { join as join124 } from "node:path";
611870
+ import { join as join125 } from "node:path";
611354
611871
  function jobsDir2(repoPath) {
611355
611872
  const root = resolve40(repoPath ?? process.cwd());
611356
- const dir = join124(root, ".oa", "jobs");
611357
- mkdirSync65(dir, { recursive: true });
611873
+ const dir = join125(root, ".oa", "jobs");
611874
+ mkdirSync66(dir, { recursive: true });
611358
611875
  return dir;
611359
611876
  }
611360
611877
  async function runCommand(opts, config) {
@@ -611460,7 +611977,7 @@ async function runBackground(task, config, opts) {
611460
611977
  const oaBin = process.argv[1] || "oa";
611461
611978
  const args = [task, "--json"];
611462
611979
  if (config.model) args.push("--model", config.model);
611463
- const child = spawn26(process.execPath, [oaBin, ...args], {
611980
+ const child = spawn27(process.execPath, [oaBin, ...args], {
611464
611981
  cwd: repoRoot,
611465
611982
  env: { ...process.env, OA_JOB_ID: id },
611466
611983
  stdio: ["ignore", "pipe", "pipe"],
@@ -611476,7 +611993,7 @@ async function runBackground(task, config, opts) {
611476
611993
  }
611477
611994
  });
611478
611995
  job.pid = child.pid ?? 0;
611479
- writeFileSync57(join124(dir, `${id}.json`), JSON.stringify(job, null, 2));
611996
+ writeFileSync58(join125(dir, `${id}.json`), JSON.stringify(job, null, 2));
611480
611997
  let output = "";
611481
611998
  child.stdout?.on("data", (chunk) => {
611482
611999
  output += chunk.toString();
@@ -611492,7 +612009,7 @@ async function runBackground(task, config, opts) {
611492
612009
  job.summary = result.summary;
611493
612010
  job.durationMs = result.durationMs;
611494
612011
  job.error = result.error;
611495
- writeFileSync57(join124(dir, `${id}.json`), JSON.stringify(job, null, 2));
612012
+ writeFileSync58(join125(dir, `${id}.json`), JSON.stringify(job, null, 2));
611496
612013
  } catch {
611497
612014
  }
611498
612015
  });
@@ -611508,8 +612025,8 @@ async function runBackground(task, config, opts) {
611508
612025
  }
611509
612026
  function statusCommand(jobId, repoPath) {
611510
612027
  const dir = jobsDir2(repoPath);
611511
- const file = join124(dir, `${jobId}.json`);
611512
- if (!existsSync108(file)) {
612028
+ const file = join125(dir, `${jobId}.json`);
612029
+ if (!existsSync109(file)) {
611513
612030
  console.error(`Job not found: ${jobId}`);
611514
612031
  console.log(`Available jobs: oa jobs`);
611515
612032
  process.exit(1);
@@ -611535,7 +612052,7 @@ function jobsCommand(repoPath) {
611535
612052
  console.log("Jobs:");
611536
612053
  for (const file of files) {
611537
612054
  try {
611538
- const job = JSON.parse(readFileSync88(join124(dir, file), "utf-8"));
612055
+ const job = JSON.parse(readFileSync88(join125(dir, file), "utf-8"));
611539
612056
  const icon = job.status === "completed" ? "✓" : job.status === "failed" ? "✗" : "●";
611540
612057
  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`;
611541
612058
  const cleanListTask = cleanForStorage(job.task) || job.task;
@@ -611559,13 +612076,13 @@ __export(index_repo_exports, {
611559
612076
  indexRepoCommand: () => indexRepoCommand
611560
612077
  });
611561
612078
  import { resolve as resolve41 } from "node:path";
611562
- import { existsSync as existsSync109, statSync as statSync35 } from "node:fs";
612079
+ import { existsSync as existsSync110, statSync as statSync35 } from "node:fs";
611563
612080
  import { cwd as cwd2 } from "node:process";
611564
612081
  async function indexRepoCommand(opts, _config3) {
611565
612082
  const repoRoot = resolve41(opts.repoPath ?? cwd2());
611566
612083
  printHeader("Index Repository");
611567
612084
  printInfo(`Indexing: ${repoRoot}`);
611568
- if (!existsSync109(repoRoot)) {
612085
+ if (!existsSync110(repoRoot)) {
611569
612086
  printError(`Path does not exist: ${repoRoot}`);
611570
612087
  process.exit(1);
611571
612088
  }
@@ -611817,7 +612334,7 @@ var config_exports2 = {};
611817
612334
  __export(config_exports2, {
611818
612335
  configCommand: () => configCommand
611819
612336
  });
611820
- import { join as join125, resolve as resolve42 } from "node:path";
612337
+ import { join as join126, resolve as resolve42 } from "node:path";
611821
612338
  import { homedir as homedir45 } from "node:os";
611822
612339
  import { cwd as cwd3 } from "node:process";
611823
612340
  function redactIfSensitive(key, value2) {
@@ -611899,7 +612416,7 @@ function handleShow(opts, config) {
611899
612416
  }
611900
612417
  }
611901
612418
  printSection("Config File");
611902
- printInfo(`~/.open-agents/config.json (${join125(homedir45(), ".open-agents", "config.json")})`);
612419
+ printInfo(`~/.open-agents/config.json (${join126(homedir45(), ".open-agents", "config.json")})`);
611903
612420
  printSection("Priority Chain");
611904
612421
  printInfo(" 1. CLI flags (--model, --backend-url, etc.)");
611905
612422
  printInfo(" 2. Project .oa/settings.json (--local)");
@@ -611938,7 +612455,7 @@ function handleSet(opts, _config3) {
611938
612455
  const coerced = coerceForSettings(key, value2);
611939
612456
  saveProjectSettings(repoRoot, { [key]: coerced });
611940
612457
  printSuccess(`Project override set: ${key} = ${redactIfSensitive(key, value2)}`);
611941
- printInfo(`Saved to ${join125(repoRoot, ".oa", "settings.json")}`);
612458
+ printInfo(`Saved to ${join126(repoRoot, ".oa", "settings.json")}`);
611942
612459
  printInfo("This override applies only when running in this workspace.");
611943
612460
  } catch (err) {
611944
612461
  printError(`Failed to save: ${err instanceof Error ? err.message : String(err)}`);
@@ -612121,9 +612638,9 @@ var eval_exports = {};
612121
612638
  __export(eval_exports, {
612122
612639
  evalCommand: () => evalCommand
612123
612640
  });
612124
- import { tmpdir as tmpdir21 } from "node:os";
612125
- import { mkdirSync as mkdirSync66, writeFileSync as writeFileSync58 } from "node:fs";
612126
- import { join as join126 } from "node:path";
612641
+ import { tmpdir as tmpdir22 } from "node:os";
612642
+ import { mkdirSync as mkdirSync67, writeFileSync as writeFileSync59 } from "node:fs";
612643
+ import { join as join127 } from "node:path";
612127
612644
  async function evalCommand(opts, config) {
612128
612645
  const suiteName = opts.suite ?? "basic";
612129
612646
  const suite = SUITES[suiteName];
@@ -612252,10 +612769,10 @@ async function evalCommand(opts, config) {
612252
612769
  process.exit(failed > 0 ? 1 : 0);
612253
612770
  }
612254
612771
  function createTempEvalRepo() {
612255
- const dir = join126(tmpdir21(), `open-agents-eval-${Date.now()}`);
612256
- mkdirSync66(dir, { recursive: true });
612257
- writeFileSync58(
612258
- join126(dir, "package.json"),
612772
+ const dir = join127(tmpdir22(), `open-agents-eval-${Date.now()}`);
612773
+ mkdirSync67(dir, { recursive: true });
612774
+ writeFileSync59(
612775
+ join127(dir, "package.json"),
612259
612776
  JSON.stringify({ name: "eval-repo", version: "0.0.0" }, null, 2) + "\n",
612260
612777
  "utf8"
612261
612778
  );
@@ -612319,7 +612836,7 @@ init_typed_node_events();
612319
612836
  import { parseArgs as nodeParseArgs2 } from "node:util";
612320
612837
  import { createRequire as createRequire7 } from "node:module";
612321
612838
  import { fileURLToPath as fileURLToPath19 } from "node:url";
612322
- import { dirname as dirname38, join as join127 } from "node:path";
612839
+ import { dirname as dirname38, join as join128 } from "node:path";
612323
612840
 
612324
612841
  // packages/cli/src/cli.ts
612325
612842
  init_typed_node_events();
@@ -612459,7 +612976,7 @@ init_output();
612459
612976
  function getVersion5() {
612460
612977
  try {
612461
612978
  const require4 = createRequire7(import.meta.url);
612462
- const pkgPath = join127(dirname38(fileURLToPath19(import.meta.url)), "..", "package.json");
612979
+ const pkgPath = join128(dirname38(fileURLToPath19(import.meta.url)), "..", "package.json");
612463
612980
  const pkg = require4(pkgPath);
612464
612981
  return pkg.version;
612465
612982
  } catch {
@@ -612648,9 +613165,9 @@ async function main() {
612648
613165
  const mode = process.argv[process.argv.indexOf("--self-test") + 1] || "crossmodal";
612649
613166
  if (mode === "crossmodal") {
612650
613167
  process.stdout.write("Running crossmodal smoke tests...\n");
612651
- const { spawn: spawn27 } = await import("node:child_process");
613168
+ const { spawn: spawn28 } = await import("node:child_process");
612652
613169
  const run = (file) => new Promise((resolve43, reject) => {
612653
- const p2 = spawn27(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
613170
+ const p2 = spawn28(process.execPath, [file], { stdio: ["ignore", "pipe", "pipe"] });
612654
613171
  p2.stdout.on("data", (d2) => process.stdout.write(d2));
612655
613172
  p2.stderr.on("data", (d2) => process.stdout.write(d2));
612656
613173
  onChildExit(p2, (code8) => code8 === 0 ? resolve43() : reject(new Error(`${file} exited ${code8}`)));
@@ -612773,12 +613290,12 @@ function crashLog(label, err) {
612773
613290
  const logLine = `[${timestamp}] ${label}: ${msg}
612774
613291
  `;
612775
613292
  try {
612776
- const { appendFileSync: appendFileSync9, mkdirSync: mkdirSync67 } = __require("node:fs");
612777
- const { join: join128 } = __require("node:path");
613293
+ const { appendFileSync: appendFileSync9, mkdirSync: mkdirSync68 } = __require("node:fs");
613294
+ const { join: join129 } = __require("node:path");
612778
613295
  const { homedir: homedir46 } = __require("node:os");
612779
- const logDir = join128(homedir46(), ".open-agents");
612780
- mkdirSync67(logDir, { recursive: true });
612781
- appendFileSync9(join128(logDir, "crash.log"), logLine);
613296
+ const logDir = join129(homedir46(), ".open-agents");
613297
+ mkdirSync68(logDir, { recursive: true });
613298
+ appendFileSync9(join129(logDir, "crash.log"), logLine);
612782
613299
  } catch {
612783
613300
  }
612784
613301
  try {