open-agents-ai 0.140.0 → 0.140.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +283 -31
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5645,6 +5645,86 @@ async function handleCmd(cmd) {
5645
5645
  break;
5646
5646
  }
5647
5647
 
5648
+ // \u2500\u2500 IPFS pin external CID \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
5649
+ case 'ipfs_pin': {
5650
+ var _ipCid = args.cid || '';
5651
+ if (!_ipCid) { writeResp(id, { ok: false, output: 'cid required' }); break; }
5652
+ // Validate CID format
5653
+ if (!_ipCid.startsWith('bafy') && !_ipCid.startsWith('bafk') && !_ipCid.startsWith('Qm')) {
5654
+ writeResp(id, { ok: false, output: 'Invalid CID format. Must start with bafy, bafk, or Qm' });
5655
+ break;
5656
+ }
5657
+ var _ipReady = await _ensureHelia();
5658
+ if (!_ipReady || !_heliaNode) {
5659
+ writeResp(id, { ok: false, output: 'Helia not available \u2014 cannot pin external CIDs' });
5660
+ break;
5661
+ }
5662
+ try {
5663
+ var { CID: _ipCIDClass } = await import('multiformats/cid');
5664
+ var _ipParsed = _ipCIDClass.parse(_ipCid);
5665
+ for await (var _ipPin of _heliaNode.pins.add(_ipParsed)) { /* pinning */ }
5666
+ // Register in CID registry
5667
+ var _ipRegDir = join(nexusDir, 'ipfs', 'cid-registry');
5668
+ mkdirSync(_ipRegDir, { recursive: true });
5669
+ var _ipRegFile = join(_ipRegDir, 'learning-cids.json');
5670
+ var _ipReg = {};
5671
+ try { if (existsSync(_ipRegFile)) _ipReg = JSON.parse(readFileSync(_ipRegFile, 'utf8')); } catch {}
5672
+ _ipReg['pin-' + Date.now().toString(36)] = {
5673
+ cid: _ipCid,
5674
+ source: args.source || 'manual-pin',
5675
+ pinned: true,
5676
+ timestamp: Date.now(),
5677
+ };
5678
+ writeFileSync(_ipRegFile, JSON.stringify(_ipReg, null, 2));
5679
+ dlog('IPFS: pinned external CID ' + _ipCid.slice(0, 20) + '...');
5680
+ writeResp(id, { ok: true, output: JSON.stringify({ cid: _ipCid, pinned: true }) });
5681
+ } catch (_ipErr) {
5682
+ writeResp(id, { ok: false, output: 'Pin error: ' + (_ipErr.message || _ipErr) });
5683
+ }
5684
+ break;
5685
+ }
5686
+
5687
+ // \u2500\u2500 IPFS list pinned CIDs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
5688
+ case 'ipfs_ls': {
5689
+ var _ilPins = [];
5690
+ // Merge from Helia pins (if available) + CID registry
5691
+ try {
5692
+ if (_heliaReady && _heliaNode) {
5693
+ for await (var _ilCid of _heliaNode.pins.ls()) {
5694
+ _ilPins.push({ cid: _ilCid.cid.toString(), source: 'helia', pinned: true });
5695
+ }
5696
+ }
5697
+ } catch {}
5698
+ // Merge CID registry metadata
5699
+ try {
5700
+ var _ilRegFile = join(nexusDir, 'ipfs', 'cid-registry', 'learning-cids.json');
5701
+ if (existsSync(_ilRegFile)) {
5702
+ var _ilReg = JSON.parse(readFileSync(_ilRegFile, 'utf8'));
5703
+ for (var _ilKey of Object.keys(_ilReg)) {
5704
+ var _ilEntry = _ilReg[_ilKey];
5705
+ if (!_ilPins.some(function(p) { return p.cid === _ilEntry.cid; })) {
5706
+ _ilPins.push({ cid: _ilEntry.cid, source: _ilEntry.source, pinned: _ilEntry.pinned, timestamp: _ilEntry.timestamp });
5707
+ }
5708
+ }
5709
+ }
5710
+ } catch {}
5711
+ // Also include identity CIDs
5712
+ try {
5713
+ var _ilIdFile = join(nexusDir, '..', 'identity', 'cids.json');
5714
+ if (existsSync(_ilIdFile)) {
5715
+ var _ilIdCids = JSON.parse(readFileSync(_ilIdFile, 'utf8'));
5716
+ for (var _ilIdKey of Object.keys(_ilIdCids)) {
5717
+ var _ilIdCid = _ilIdCids[_ilIdKey];
5718
+ if (_ilIdCid && !_ilPins.some(function(p) { return p.cid === _ilIdCid; })) {
5719
+ _ilPins.push({ cid: _ilIdCid, source: 'identity-' + _ilIdKey, pinned: true });
5720
+ }
5721
+ }
5722
+ }
5723
+ } catch {}
5724
+ writeResp(id, { ok: true, output: JSON.stringify({ pins: _ilPins, count: _ilPins.length }) });
5725
+ break;
5726
+ }
5727
+
5648
5728
  // \u2500\u2500 COHERE distributed learning \u2014 publish insight to mesh \u2500\u2500\u2500\u2500\u2500\u2500
5649
5729
  case 'cohere_publish_insight': {
5650
5730
  if (!cohereActive) { writeResp(id, { ok: false, output: 'COHERE not active' }); break; }
@@ -7214,6 +7294,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
7214
7294
  "cohere_deny_model",
7215
7295
  "cohere_list_models",
7216
7296
  "ipfs_add",
7297
+ "ipfs_pin",
7298
+ "ipfs_ls",
7217
7299
  "cohere_publish_insight"
7218
7300
  ],
7219
7301
  description: "The nexus action. MUST call 'connect' first (spawns daemon). Then: join_room, send_message, discover_peers, expose, status, cohere_stats, cohere_enable, cohere_disable, cohere_allow_model, cohere_deny_model, cohere_list_models, ipfs_add, etc."
@@ -7454,6 +7536,12 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
7454
7536
  case "ipfs_add":
7455
7537
  result = await this.sendDaemonCmd("ipfs_add", { content: String(args.content ?? args.message ?? "") });
7456
7538
  break;
7539
+ case "ipfs_pin":
7540
+ result = await this.sendDaemonCmd("ipfs_pin", { cid: String(args.cid ?? args.content ?? ""), source: String(args.source ?? "agent") });
7541
+ break;
7542
+ case "ipfs_ls":
7543
+ result = await this.sendDaemonCmd("ipfs_ls", {});
7544
+ break;
7457
7545
  case "cohere_publish_insight":
7458
7546
  result = await this.sendDaemonCmd("cohere_publish_insight", {
7459
7547
  insight: String(args.insight ?? args.content ?? ""),
@@ -30995,43 +31083,42 @@ function setContentWriteHook(hook) {
30995
31083
  }
30996
31084
  function renderError(message) {
30997
31085
  const redir = _contentWriteHook?.redirect?.();
30998
- const icon = _emojisEnabled ? "\x1B[38;5;178m\u2716\x1B[0m" : c2.red("E");
31086
+ const icon = _emojisEnabled ? "\x1B[38;5;198m\u2716\x1B[0m" : "\x1B[38;5;198mE\x1B[0m";
31087
+ const text = `
31088
+ ${icon} \x1B[38;5;198m${message}\x1B[0m
31089
+ `;
30999
31090
  if (redir) {
31000
- redir(`
31001
- ${icon} ${message}
31002
- `);
31091
+ redir(text);
31003
31092
  return;
31004
31093
  }
31005
31094
  _contentWriteHook?.begin();
31006
- process.stdout.write(`
31007
- ${icon} ${message}
31008
- `);
31095
+ process.stdout.write(text);
31009
31096
  _contentWriteHook?.end();
31010
31097
  }
31011
31098
  function renderInfo(message) {
31012
31099
  const redir = _contentWriteHook?.redirect?.();
31013
- const icon = _emojisEnabled ? "\x1B[38;5;178m\u2139\x1B[0m" : "\x1B[38;5;178mi\x1B[0m";
31100
+ const icon = "\x1B[38;5;178mi\x1B[0m";
31101
+ const text = `${icon} \x1B[38;5;252m${message}\x1B[0m
31102
+ `;
31014
31103
  if (redir) {
31015
- redir(`${icon} ${message}
31016
- `);
31104
+ redir(text);
31017
31105
  return;
31018
31106
  }
31019
31107
  _contentWriteHook?.begin();
31020
- process.stdout.write(`${icon} ${message}
31021
- `);
31108
+ process.stdout.write(text);
31022
31109
  _contentWriteHook?.end();
31023
31110
  }
31024
31111
  function renderWarning(message) {
31025
31112
  const redir = _contentWriteHook?.redirect?.();
31026
- const icon = _emojisEnabled ? "\x1B[38;5;178m\u26A0\x1B[0m" : "\x1B[38;5;178m!\x1B[0m";
31113
+ const icon = "\x1B[38;5;214m!\x1B[0m";
31114
+ const text = `${icon} \x1B[38;5;214m${message}\x1B[0m
31115
+ `;
31027
31116
  if (redir) {
31028
- redir(`${icon} ${message}
31029
- `);
31117
+ redir(text);
31030
31118
  return;
31031
31119
  }
31032
31120
  _contentWriteHook?.begin();
31033
- process.stdout.write(`${icon} ${message}
31034
- `);
31121
+ process.stdout.write(text);
31035
31122
  _contentWriteHook?.end();
31036
31123
  }
31037
31124
  function renderVerbose(message) {
@@ -40445,14 +40532,49 @@ var init_voice = __esm({
40445
40532
  async drainQueue() {
40446
40533
  this.speaking = true;
40447
40534
  let isFirst = true;
40535
+ let prefetchedWav = null;
40448
40536
  while (this.speakQueue.length > 0) {
40449
40537
  const item = this.speakQueue.shift();
40450
40538
  if (!isFirst) {
40451
- await this.sleep(250);
40539
+ await this.sleep(120);
40452
40540
  }
40453
40541
  isFirst = false;
40454
40542
  try {
40455
- await this.synthesizeAndPlay(item.text, item.volume, item.pitchFactor, item.speedFactor, item.stereoDelayMs);
40543
+ if (this.luxttsActive) {
40544
+ let wavPath = null;
40545
+ if (prefetchedWav && prefetchedWav.item === item) {
40546
+ wavPath = prefetchedWav.path;
40547
+ prefetchedWav = null;
40548
+ }
40549
+ const nextItem = this.speakQueue[0] ?? null;
40550
+ let prefetchPromise = null;
40551
+ if (nextItem && this.luxttsActive) {
40552
+ prefetchPromise = this.synthesizeLuxttsWav(nextItem.text, nextItem.speedFactor);
40553
+ }
40554
+ if (!wavPath) {
40555
+ wavPath = await this.synthesizeLuxttsWav(item.text, item.speedFactor);
40556
+ }
40557
+ if (wavPath) {
40558
+ await this.postProcessAndPlayLuxtts(wavPath, item.volume, item.pitchFactor, item.stereoDelayMs);
40559
+ }
40560
+ if (prefetchPromise && nextItem) {
40561
+ try {
40562
+ const nextWav = await prefetchPromise;
40563
+ if (nextWav) {
40564
+ prefetchedWav = { path: nextWav, item: nextItem };
40565
+ }
40566
+ } catch {
40567
+ }
40568
+ }
40569
+ } else {
40570
+ await this.synthesizeAndPlay(item.text, item.volume, item.pitchFactor, item.speedFactor, item.stereoDelayMs);
40571
+ }
40572
+ } catch {
40573
+ }
40574
+ }
40575
+ if (prefetchedWav) {
40576
+ try {
40577
+ unlinkSync8(prefetchedWav.path);
40456
40578
  } catch {
40457
40579
  }
40458
40580
  }
@@ -41151,10 +41273,19 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
41151
41273
  renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
41152
41274
  }
41153
41275
  }
41276
+ const isJetson = isArm && (existsSync35("/etc/nv_tegra_release") || existsSync35("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
41154
41277
  const installSteps = isArm ? [
41155
41278
  // ARM: install individually so we get clear error messages per package.
41156
41279
  // ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
41157
41280
  { cmd: `${pipCmd} -m pip install --quiet "setuptools<81" wheel`, fatal: true, label: "setuptools" },
41281
+ // Jetson: try NVIDIA's prebuilt PyTorch wheel first (has CUDA support)
41282
+ ...isJetson ? [
41283
+ { cmd: `${pipCmd} -m pip install --quiet torch --index-url https://developer.download.nvidia.com/compute/redist/jp/v60/pytorch/ 2>/dev/null || ${pipCmd} -m pip install --quiet torch`, fatal: true, label: "PyTorch (Jetson L4T)" },
41284
+ { cmd: `${pipCmd} -m pip install --quiet onnxruntime-gpu 2>/dev/null || true`, fatal: false, label: "onnxruntime-gpu (Jetson, optional)" }
41285
+ ] : [
41286
+ // Non-Jetson ARM: standard PyTorch (CPU)
41287
+ { cmd: `${pipCmd} -m pip install --quiet torch --index-url https://download.pytorch.org/whl/cpu`, fatal: true, label: "PyTorch (ARM CPU)" }
41288
+ ],
41158
41289
  { cmd: `${pipCmd} -m pip install --quiet numpy`, fatal: true, label: "numpy" },
41159
41290
  { cmd: `${pipCmd} -m pip install --quiet huggingface_hub safetensors`, fatal: true, label: "huggingface_hub + safetensors" },
41160
41291
  { cmd: `${pipCmd} -m pip install --quiet "transformers<=4.57.6"`, fatal: true, label: "transformers" },
@@ -41397,17 +41528,21 @@ if __name__ == '__main__':
41397
41528
  * Speed is passed natively to LuxTTS. Pitch is post-processed via resampling.
41398
41529
  * Volume is applied via WAV sample scaling. Stereo ITD applied for depth.
41399
41530
  */
41400
- async synthesizeWithLuxtts(text, volume = 1, pitchFactor = 1, speedFactor = 1, stereoDelayMs = 0.6) {
41401
- if (!this.luxttsCloneRef || !existsSync35(this.luxttsCloneRef)) {
41402
- return;
41403
- }
41531
+ /**
41532
+ * Synthesize text to a WAV file via LuxTTS daemon (synthesis only, no playback).
41533
+ * Returns the WAV file path or null on failure.
41534
+ * Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
41535
+ */
41536
+ async synthesizeLuxttsWav(text, speedFactor = 1) {
41537
+ if (!this.luxttsCloneRef || !existsSync35(this.luxttsCloneRef))
41538
+ return null;
41404
41539
  const cleaned = text.replace(/\*/g, "").trim();
41405
41540
  if (!cleaned)
41406
- return;
41541
+ return null;
41407
41542
  const ready = await this.ensureLuxttsDaemon();
41408
41543
  if (!ready)
41409
- return;
41410
- const wavPath = join50(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
41544
+ return null;
41545
+ const wavPath = join50(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
41411
41546
  try {
41412
41547
  await this.luxttsRequest({
41413
41548
  action: "synthesize",
@@ -41417,8 +41552,15 @@ if __name__ == '__main__':
41417
41552
  speed: speedFactor
41418
41553
  });
41419
41554
  } catch {
41420
- return;
41555
+ return null;
41421
41556
  }
41557
+ return existsSync35(wavPath) ? wavPath : null;
41558
+ }
41559
+ /**
41560
+ * Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
41561
+ * Cleans up the WAV file after playback.
41562
+ */
41563
+ async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
41422
41564
  if (!existsSync35(wavPath))
41423
41565
  return;
41424
41566
  try {
@@ -41493,6 +41635,13 @@ if __name__ == '__main__':
41493
41635
  } catch {
41494
41636
  }
41495
41637
  }
41638
+ /** Combined synthesize + post-process + play for LuxTTS (used by synthesizeAndPlay) */
41639
+ async synthesizeWithLuxtts(text, volume = 1, pitchFactor = 1, speedFactor = 1, stereoDelayMs = 0.6) {
41640
+ const wavPath = await this.synthesizeLuxttsWav(text, speedFactor);
41641
+ if (!wavPath)
41642
+ return;
41643
+ await this.postProcessAndPlayLuxtts(wavPath, volume, pitchFactor, stereoDelayMs);
41644
+ }
41496
41645
  /**
41497
41646
  * Synthesize text to WAV buffer using LuxTTS (no playback).
41498
41647
  * Used for Telegram voice messages and WebSocket streaming.
@@ -42124,6 +42273,85 @@ async function handleSlashCommand(input, ctx) {
42124
42273
  return "handled";
42125
42274
  }
42126
42275
  case "ipfs": {
42276
+ const ipfsSubCmd = (arg || "").trim().split(/\s+/);
42277
+ const ipfsAction = ipfsSubCmd[0]?.toLowerCase() || "";
42278
+ const ipfsArg = ipfsSubCmd.slice(1).join(" ");
42279
+ if (ipfsAction === "pin" && ipfsArg) {
42280
+ const cidToPin = ipfsArg.trim();
42281
+ if (!cidToPin.startsWith("bafy") && !cidToPin.startsWith("bafk") && !cidToPin.startsWith("Qm")) {
42282
+ renderWarning("Invalid CID format. Must start with bafy, bafk, or Qm");
42283
+ return "handled";
42284
+ }
42285
+ try {
42286
+ const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
42287
+ const nexus = new NexusTool2(ctx.repoRoot);
42288
+ const result = await nexus.execute({ action: "ipfs_pin", cid: cidToPin, source: "user-pin" });
42289
+ if (result.success) {
42290
+ renderInfo(`Pinned: ${cidToPin}`);
42291
+ } else {
42292
+ renderWarning(`Pin failed: ${result.output}`);
42293
+ }
42294
+ } catch (e) {
42295
+ renderWarning(`Pin failed: ${e.message ?? e}`);
42296
+ }
42297
+ return "handled";
42298
+ }
42299
+ if (ipfsAction === "publish") {
42300
+ try {
42301
+ const { IdentityKernelTool: IdentityKernelTool2 } = __require("@open-agents/execution");
42302
+ const ik = new IdentityKernelTool2(ctx.repoRoot);
42303
+ const result = await ik.execute({ operation: "publish_snapshot" });
42304
+ if (result.success) {
42305
+ const cidMatch = result.output.match(/CID:\s*(bafy\S+|bafk\S+)/);
42306
+ if (cidMatch) {
42307
+ safeLog(`
42308
+ ${c2.bold("Identity Published")}`);
42309
+ safeLog(` CID: ${c2.bold(cidMatch[1])}`);
42310
+ safeLog(` ${c2.dim("Share this CID with other agents: /ipfs pin " + cidMatch[1])}
42311
+ `);
42312
+ } else {
42313
+ safeLog(result.output);
42314
+ }
42315
+ } else {
42316
+ renderWarning(result.output);
42317
+ }
42318
+ } catch (e) {
42319
+ renderWarning(`Publish failed: ${e.message ?? e}`);
42320
+ }
42321
+ return "handled";
42322
+ }
42323
+ if (ipfsAction === "cids" || ipfsAction === "ls" || ipfsAction === "pins") {
42324
+ try {
42325
+ const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
42326
+ const nexus = new NexusTool2(ctx.repoRoot);
42327
+ const result = await nexus.execute({ action: "ipfs_ls" });
42328
+ if (result.success) {
42329
+ const data = JSON.parse(result.output);
42330
+ const pins = data.pins || [];
42331
+ if (pins.length === 0) {
42332
+ renderInfo("No pinned CIDs. Use /ipfs publish to publish your identity.");
42333
+ } else {
42334
+ const lines2 = [`
42335
+ ${c2.bold("Pinned CIDs")} (${pins.length})
42336
+ `];
42337
+ for (const p of pins.slice(0, 20)) {
42338
+ const src = p.source ? c2.dim(` (${p.source})`) : "";
42339
+ const pin = p.pinned ? c2.green("pinned") : c2.yellow("registered");
42340
+ lines2.push(` ${pin} ${c2.bold(p.cid.slice(0, 30))}...${src}`);
42341
+ }
42342
+ if (pins.length > 20)
42343
+ lines2.push(` ${c2.dim(`... and ${pins.length - 20} more`)}`);
42344
+ lines2.push("");
42345
+ safeLog(lines2.join("\n"));
42346
+ }
42347
+ } else {
42348
+ renderWarning(result.output);
42349
+ }
42350
+ } catch (e) {
42351
+ renderWarning(`List failed: ${e.message ?? e}`);
42352
+ }
42353
+ return "handled";
42354
+ }
42127
42355
  const lines = [];
42128
42356
  lines.push(`
42129
42357
  ${c2.bold("IPFS / Helia Status")}
@@ -42169,6 +42397,26 @@ async function handleSlashCommand(input, ctx) {
42169
42397
  lines.push(` ${c2.dim("Helia blocks:")}`);
42170
42398
  lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
42171
42399
  lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
42400
+ try {
42401
+ const statusFile = join51(ctx.repoRoot, ".oa", "nexus", "status.json");
42402
+ if (existsSync36(statusFile)) {
42403
+ const status = JSON.parse(readFileSync25(statusFile, "utf8"));
42404
+ if (status.peerId) {
42405
+ lines.push(`
42406
+ ${c2.bold("Peer Info")}`);
42407
+ lines.push(` Peer ID: ${c2.bold(status.peerId.slice(0, 20))}...`);
42408
+ if (status.multiaddrs && status.multiaddrs.length > 0) {
42409
+ lines.push(` Addresses: ${status.multiaddrs.length}`);
42410
+ for (const addr of status.multiaddrs.slice(0, 3)) {
42411
+ lines.push(` ${c2.dim(addr)}`);
42412
+ }
42413
+ }
42414
+ }
42415
+ }
42416
+ } catch {
42417
+ }
42418
+ lines.push(`
42419
+ ${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
42172
42420
  lines.push(`
42173
42421
  ${c2.bold("Identity Kernel")}`);
42174
42422
  const idDir = join51(ctx.repoRoot, ".oa", "identity");
@@ -56448,7 +56696,6 @@ ${entry.fullContent}`
56448
56696
  break;
56449
56697
  case "sudo_request":
56450
56698
  contentWrite(() => renderWarning(`Sudo required: ${event.content ?? "elevated privileges needed"}`));
56451
- contentWrite(() => renderInfo("Enter your password at the prompt below to continue."));
56452
56699
  if (sudoCallback)
56453
56700
  sudoCallback(event.content ?? "");
56454
56701
  break;
@@ -57445,8 +57692,13 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
57445
57692
  if (process.stdout.isTTY) {
57446
57693
  process.stdout.write("\x1B[?1002l\x1B[?1006l");
57447
57694
  }
57448
- writeContent(() => renderInfo("Password required for sudo. Type below, Enter to submit. Ctrl+O to show/hide."));
57449
- const pwPrompt = `\x1B[38;5;178m\u{1F511}\x1B[0m `;
57695
+ writeContent(() => {
57696
+ process.stdout.write(`
57697
+ \x1B[5;38;5;198m\u2B24 Enter Password:\x1B[0m \x1B[38;5;245mType below, Enter to submit. Ctrl+O to show/hide.\x1B[0m
57698
+
57699
+ `);
57700
+ });
57701
+ const pwPrompt = `\x1B[38;5;198m\u25CF password:\x1B[0m `;
57450
57702
  rl.setPrompt(pwPrompt);
57451
57703
  if (statusBar.isActive) {
57452
57704
  const origProvider = statusBar.inputStateProvider;
@@ -57456,7 +57708,7 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
57456
57708
  return state;
57457
57709
  return { line: "\u25CF".repeat(state.line.length), cursor: state.cursor };
57458
57710
  };
57459
- statusBar.setPromptText(pwPrompt, 3);
57711
+ statusBar.setPromptText(pwPrompt, 12);
57460
57712
  }
57461
57713
  showPrompt();
57462
57714
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "open-agents-ai",
3
- "version": "0.140.0",
3
+ "version": "0.140.2",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",