open-agents-ai 0.187.227 → 0.187.228

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 +643 -112
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5470,6 +5470,98 @@ var init_git_info = __esm({
5470
5470
  }
5471
5471
  });
5472
5472
 
5473
+ // packages/execution/dist/tools/jibberlink.js
5474
+ import { createCipheriv, createDecipheriv, createHash, randomBytes as randomBytes4 } from "node:crypto";
5475
+ function crc16(bytes) {
5476
+ let crc = 65535;
5477
+ for (let i2 = 0; i2 < bytes.length; i2++) {
5478
+ crc ^= bytes[i2] << 8;
5479
+ for (let j = 0; j < 8; j++) {
5480
+ crc = crc & 32768 ? (crc << 1 ^ 4129) & 65535 : crc << 1 & 65535;
5481
+ }
5482
+ }
5483
+ return crc & 65535;
5484
+ }
5485
+ function deriveRoomKey(roomId, secret = "jibberlink-v1") {
5486
+ const material = `${secret}\0${roomId}`;
5487
+ return createHash("sha256").update(material).digest();
5488
+ }
5489
+ function aesGcmEncrypt(key, plaintext) {
5490
+ if (key.length !== 32)
5491
+ throw new Error("jibberlink: key must be 32 bytes");
5492
+ const iv = randomBytes4(12);
5493
+ const cipher = createCipheriv("aes-256-gcm", key, iv);
5494
+ const ct = Buffer.concat([cipher.update(plaintext), cipher.final()]);
5495
+ const tag = cipher.getAuthTag();
5496
+ return Buffer.concat([iv, tag, ct]);
5497
+ }
5498
+ function bytesToBits(bytes) {
5499
+ const out = new Uint8Array(bytes.length * 8);
5500
+ for (let i2 = 0; i2 < bytes.length; i2++) {
5501
+ const b = bytes[i2];
5502
+ for (let j = 0; j < 8; j++)
5503
+ out[i2 * 8 + j] = b >> j & 1;
5504
+ }
5505
+ return out;
5506
+ }
5507
+ function modulateFSK(bits) {
5508
+ const out = new Float32Array(bits.length * JL_SAMPLES_PER_BIT);
5509
+ let phase = 0;
5510
+ for (let i2 = 0; i2 < bits.length; i2++) {
5511
+ const freq = bits[i2] ? JL_MARK_HZ : JL_SPACE_HZ;
5512
+ const phaseInc = 2 * Math.PI * freq / JL_SAMPLE_RATE;
5513
+ for (let s2 = 0; s2 < JL_SAMPLES_PER_BIT; s2++) {
5514
+ out[i2 * JL_SAMPLES_PER_BIT + s2] = Math.sin(phase) * 0.8;
5515
+ phase += phaseInc;
5516
+ if (phase > 2 * Math.PI)
5517
+ phase -= 2 * Math.PI;
5518
+ }
5519
+ }
5520
+ return out;
5521
+ }
5522
+ function encodeFrame(payload) {
5523
+ if (payload.length > 65535)
5524
+ throw new Error("jibberlink: payload too large");
5525
+ const preamble = [];
5526
+ for (let i2 = 0; i2 < JL_PREAMBLE_BITS; i2++)
5527
+ preamble.push(i2 & 1);
5528
+ const header = new Uint8Array([
5529
+ JL_SYNC_BYTE,
5530
+ payload.length >> 8 & 255,
5531
+ payload.length & 255
5532
+ ]);
5533
+ const bodyBytes = new Uint8Array(header.length + payload.length + 2);
5534
+ bodyBytes.set(header, 0);
5535
+ bodyBytes.set(payload, header.length);
5536
+ const crc = crc16(bodyBytes.subarray(0, header.length + payload.length));
5537
+ bodyBytes[bodyBytes.length - 2] = crc >> 8 & 255;
5538
+ bodyBytes[bodyBytes.length - 1] = crc & 255;
5539
+ const bodyBits = bytesToBits(bodyBytes);
5540
+ const allBits = new Uint8Array(preamble.length + bodyBits.length);
5541
+ for (let i2 = 0; i2 < preamble.length; i2++)
5542
+ allBits[i2] = preamble[i2];
5543
+ allBits.set(bodyBits, preamble.length);
5544
+ return modulateFSK(allBits);
5545
+ }
5546
+ function encodeEncrypted(roomId, payload, secret) {
5547
+ const key = deriveRoomKey(roomId, secret);
5548
+ const wrapped = aesGcmEncrypt(key, Buffer.from(payload));
5549
+ return encodeFrame(wrapped);
5550
+ }
5551
+ var JL_SAMPLE_RATE, JL_MARK_HZ, JL_SPACE_HZ, JL_BAUD, JL_SAMPLES_PER_BIT, JL_SYNC_BYTE, JL_PREAMBLE_BITS;
5552
+ var init_jibberlink = __esm({
5553
+ "packages/execution/dist/tools/jibberlink.js"() {
5554
+ "use strict";
5555
+ JL_SAMPLE_RATE = 16e3;
5556
+ JL_MARK_HZ = 2200;
5557
+ JL_SPACE_HZ = 1200;
5558
+ JL_BAUD = 300;
5559
+ JL_SAMPLES_PER_BIT = Math.floor(JL_SAMPLE_RATE / JL_BAUD);
5560
+ JL_SYNC_BYTE = 126;
5561
+ JL_PREAMBLE_BITS = 16;
5562
+ }
5563
+ });
5564
+
5473
5565
  // packages/execution/dist/tools/nexus.js
5474
5566
  var nexus_exports = {};
5475
5567
  __export(nexus_exports, {
@@ -5478,7 +5570,7 @@ __export(nexus_exports, {
5478
5570
  import { readFile as readFile8, writeFile as writeFile6, mkdir as mkdir3, chmod, unlink, readdir as readdir2, open as fsOpen, copyFile as copyFile2 } from "node:fs/promises";
5479
5571
  import { existsSync as existsSync11, readFileSync as readFileSync8, watch as fsWatchLocal } from "node:fs";
5480
5572
  import { resolve as resolve13, join as join14 } from "node:path";
5481
- import { randomBytes as randomBytes4, createCipheriv, createDecipheriv, scryptSync, createHash } from "node:crypto";
5573
+ import { randomBytes as randomBytes5, createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, scryptSync, createHash as createHash2 } from "node:crypto";
5482
5574
  import { execSync as execSync8, spawn as spawn2 } from "node:child_process";
5483
5575
  import { hostname, userInfo, homedir as homedir4 } from "node:os";
5484
5576
  function containsKeyMaterial(input) {
@@ -5492,6 +5584,7 @@ var DAEMON_SCRIPT, KEY_PATTERNS, NexusTool;
5492
5584
  var init_nexus = __esm({
5493
5585
  "packages/execution/dist/tools/nexus.js"() {
5494
5586
  "use strict";
5587
+ init_jibberlink();
5495
5588
  DAEMON_SCRIPT = `#!/usr/bin/env node
5496
5589
  /**
5497
5590
  * nexus-daemon.mjs — Standalone nexus process with real TCP/UDP sockets.
@@ -5675,6 +5768,27 @@ var _natsConn = null;
5675
5768
  var _natsCodec = null;
5676
5769
  var _tokensByRequest = {};
5677
5770
 
5771
+ // ── Nexus voice subsystem (PCM + ASR) ─────────────────────────────────
5772
+ // Subscribes to nexus.rooms.audio, filters by the rooms this daemon has
5773
+ // joined, writes incoming voice frames to .oa/nexus/inbox/<room>/voice/
5774
+ // as JSON envelopes AND pipes decoded PCM16 into a whisper child process
5775
+ // so agents auto-receive transcripts of other agents' speech. Publishing
5776
+ // side: voice_publish action relays base64 PCM frames to the same subject.
5777
+ //
5778
+ // Transport contract (same as nexus frontend):
5779
+ // subject: nexus.rooms.audio
5780
+ // payload: JSON over StringCodec
5781
+ // { type:'voice', roomId, peerId, agentName,
5782
+ // sampleRate, encoding:'pcm16'|'float32'|'jibberlink', channels,
5783
+ // seq, timestamp, data:<base64> }
5784
+ var VOICE_SUBJECT = 'nexus.rooms.audio';
5785
+ var _voiceSub = null; // active NATS subscription object
5786
+ var _whisperProc = null; // spawned live-whisper.py child process
5787
+ var _whisperPending = ''; // partial stdout line buffer
5788
+ var _voiceListenRooms = new Set(); // rooms actively piped to whisper
5789
+ var _voiceSeq = 0;
5790
+ var _voiceLastActivityMs = 0;
5791
+
5678
5792
  // Check if an error is a connectivity/dial failure (should trigger NATS fallback)
5679
5793
  // vs an application-level error (auth rejected, capability not found — no point retrying via NATS)
5680
5794
  function isDialFailure(errMsg) {
@@ -5694,6 +5808,138 @@ function isDialFailure(errMsg) {
5694
5808
  lower.includes('connection refused');
5695
5809
  }
5696
5810
 
5811
+ // ── Voice helpers ────────────────────────────────────────────────────
5812
+ // Convert a base64 string to a Buffer of raw PCM bytes (browser-safe
5813
+ // atob is unavailable in Node, use Buffer directly).
5814
+ function _voiceB64ToBuf(b64) {
5815
+ try { return Buffer.from(b64, 'base64'); } catch { return Buffer.alloc(0); }
5816
+ }
5817
+ function _voiceBufToB64(buf) {
5818
+ try { return buf.toString('base64'); } catch { return ''; }
5819
+ }
5820
+ // Convert Int16 PCM little-endian Buffer → Float32Array in [-1, 1]
5821
+ function _voicePcm16ToF32(buf) {
5822
+ var n = buf.length >> 1;
5823
+ var out = new Float32Array(n);
5824
+ for (var i = 0; i < n; i++) {
5825
+ var s = buf.readInt16LE(i * 2);
5826
+ out[i] = s / 32768;
5827
+ }
5828
+ return out;
5829
+ }
5830
+ // Convert Float32Array → Int16 PCM little-endian Buffer
5831
+ function _voiceF32ToPcm16(f32) {
5832
+ var out = Buffer.alloc(f32.length * 2);
5833
+ for (var i = 0; i < f32.length; i++) {
5834
+ var s = Math.max(-1, Math.min(1, f32[i]));
5835
+ out.writeInt16LE(s < 0 ? s * 32768 : s * 32767, i * 2);
5836
+ }
5837
+ return out;
5838
+ }
5839
+ // Ensure a whisper child process is running. Returns true on success.
5840
+ // Lazy-spawned on the first voice_listen_start call per daemon lifetime.
5841
+ function _voiceEnsureWhisper() {
5842
+ if (_whisperProc && !_whisperProc.killed) return true;
5843
+ try {
5844
+ var cp = require('node:child_process');
5845
+ var pathMod = require('node:path');
5846
+ var fsMod = require('node:fs');
5847
+ // Resolve live-whisper.py — ships inside the CLI bundle at dist/scripts
5848
+ // relative to the currently-running daemon script.
5849
+ var candidates = [
5850
+ pathMod.resolve(pathMod.dirname(nexusDir), 'scripts', 'live-whisper.py'),
5851
+ pathMod.resolve(process.cwd(), 'packages/execution/scripts/live-whisper.py'),
5852
+ pathMod.resolve(process.cwd(), 'dist/scripts/live-whisper.py'),
5853
+ pathMod.resolve(process.cwd(), 'scripts/live-whisper.py'),
5854
+ ];
5855
+ var whisperPy = null;
5856
+ for (var i = 0; i < candidates.length; i++) {
5857
+ if (fsMod.existsSync(candidates[i])) { whisperPy = candidates[i]; break; }
5858
+ }
5859
+ if (!whisperPy) {
5860
+ dlog('voice: whisper script not found — searched ' + candidates.length + ' paths');
5861
+ return false;
5862
+ }
5863
+ var pyBin = process.env.PYTHON || 'python3';
5864
+ _whisperProc = cp.spawn(pyBin, [whisperPy, '--stdin', '--model', 'base', '--lang', 'en'], {
5865
+ stdio: ['pipe', 'pipe', 'pipe'],
5866
+ });
5867
+ _whisperPending = '';
5868
+ _whisperProc.stdout.on('data', function(chunk) {
5869
+ _whisperPending += chunk.toString('utf8');
5870
+ var lines = _whisperPending.split('
5871
+ ');
5872
+ _whisperPending = lines.pop() || '';
5873
+ for (var li = 0; li < lines.length; li++) {
5874
+ var ln = lines[li].trim();
5875
+ if (!ln) continue;
5876
+ try {
5877
+ var msg = JSON.parse(ln);
5878
+ if (msg && msg.type === 'transcript' && msg.text) {
5879
+ // Write each transcript to every actively-listened room's inbox
5880
+ for (var roomId of _voiceListenRooms) {
5881
+ try {
5882
+ var roomInbox = pathMod.join(inboxDir, roomId, 'voice');
5883
+ fsMod.mkdirSync(roomInbox, { recursive: true });
5884
+ var fname = 'transcript-' + Date.now() + '-' + Math.random().toString(36).slice(2, 8) + '.json';
5885
+ fsMod.writeFileSync(pathMod.join(roomInbox, fname), JSON.stringify({
5886
+ type: 'voice.transcript',
5887
+ roomId: roomId,
5888
+ text: String(msg.text || '').trim(),
5889
+ isFinal: !!msg.isFinal,
5890
+ timestamp: Date.now(),
5891
+ }, null, 2));
5892
+ } catch (we) {
5893
+ dlog('voice: transcript write failed: ' + (we.message || we));
5894
+ }
5895
+ }
5896
+ }
5897
+ } catch { /* non-JSON whisper output — ignore */ }
5898
+ }
5899
+ });
5900
+ _whisperProc.stderr.on('data', function(chunk) {
5901
+ dlog('whisper stderr: ' + chunk.toString('utf8').slice(0, 200));
5902
+ });
5903
+ _whisperProc.on('exit', function(code) {
5904
+ dlog('whisper exited code=' + code);
5905
+ _whisperProc = null;
5906
+ });
5907
+ dlog('voice: whisper child spawned (pid=' + _whisperProc.pid + ')');
5908
+ return true;
5909
+ } catch (err) {
5910
+ dlog('voice: whisper spawn failed: ' + (err.message || err));
5911
+ _whisperProc = null;
5912
+ return false;
5913
+ }
5914
+ }
5915
+ // Feed a PCM16 byte buffer into the whisper stdin. No-op if whisper isn't running.
5916
+ function _voiceFeedWhisper(buf) {
5917
+ if (!_whisperProc || !_whisperProc.stdin || _whisperProc.killed) return;
5918
+ try { _whisperProc.stdin.write(buf); } catch (err) {
5919
+ dlog('voice: whisper stdin write failed: ' + (err.message || err));
5920
+ }
5921
+ }
5922
+ // Write a compact "voice activity" event to the room inbox so the agent
5923
+ // sees who just spoke even when whisper isn't transcribing (no mic drain
5924
+ // on the laptop doing pure listening).
5925
+ function _voiceEmitActivity(env) {
5926
+ try {
5927
+ var pathMod2 = require('node:path');
5928
+ var fsMod2 = require('node:fs');
5929
+ var roomInbox = pathMod2.join(inboxDir, env.roomId, 'voice');
5930
+ fsMod2.mkdirSync(roomInbox, { recursive: true });
5931
+ var fname = 'activity-' + Date.now() + '-' + Math.random().toString(36).slice(2, 6) + '.json';
5932
+ fsMod2.writeFileSync(pathMod2.join(roomInbox, fname), JSON.stringify({
5933
+ type: 'voice.activity',
5934
+ roomId: env.roomId,
5935
+ peerId: env.peerId || '',
5936
+ agentName: env.agentName || '',
5937
+ seq: env.seq || 0,
5938
+ timestamp: env.timestamp || Date.now(),
5939
+ }, null, 2));
5940
+ } catch {}
5941
+ }
5942
+
5697
5943
  function writeStatus(extra = {}) {
5698
5944
  const caps = typeof nexus.getRegisteredCapabilities === 'function'
5699
5945
  ? nexus.getRegisteredCapabilities() : [];
@@ -5828,6 +6074,85 @@ async function handleCmd(cmd) {
5828
6074
  writeResp(id, { ok: true, output: 'Message sent (id: ' + msgId + ')' });
5829
6075
  break;
5830
6076
  }
6077
+ // ── Voice: publish a PCM frame to a room ──
6078
+ // args: { room_id, pcm_base64, sample_rate?, encoding?, channels? }
6079
+ // Relays to nexus.rooms.audio with the same envelope the nexus
6080
+ // frontend decodes. Agents can call this with raw PCM bytes from
6081
+ // any source (TTS, mic, jibberlink modem output).
6082
+ case 'voice_publish': {
6083
+ if (!_natsConn || !_natsCodec) {
6084
+ writeResp(id, { ok: false, output: 'NATS not connected' });
6085
+ return;
6086
+ }
6087
+ if (!args || !args.room_id || !args.pcm_base64) {
6088
+ writeResp(id, { ok: false, output: 'voice_publish requires room_id + pcm_base64' });
6089
+ return;
6090
+ }
6091
+ if (!rooms.has(args.room_id)) {
6092
+ writeResp(id, { ok: false, output: 'Not in room: ' + args.room_id + '. Join first.' });
6093
+ return;
6094
+ }
6095
+ try {
6096
+ var vpEnv = {
6097
+ type: 'voice',
6098
+ roomId: args.room_id,
6099
+ peerId: nexus.peerId || '',
6100
+ agentName: agentName,
6101
+ sampleRate: parseInt(args.sample_rate, 10) || 16000,
6102
+ encoding: args.encoding || 'pcm16',
6103
+ channels: parseInt(args.channels, 10) || 1,
6104
+ seq: _voiceSeq++,
6105
+ timestamp: Date.now(),
6106
+ data: String(args.pcm_base64),
6107
+ };
6108
+ _natsConn.publish(VOICE_SUBJECT, _natsCodec.encode(JSON.stringify(vpEnv)));
6109
+ writeResp(id, { ok: true, output: 'Voice frame published to ' + args.room_id + ' (' + Math.round(args.pcm_base64.length * 0.75) + ' bytes)' });
6110
+ } catch (vpErr) {
6111
+ writeResp(id, { ok: false, output: 'voice_publish error: ' + (vpErr.message || vpErr) });
6112
+ }
6113
+ break;
6114
+ }
6115
+ // ── Voice: start/stop ASR pipeline for a joined room ──
6116
+ case 'voice_listen_start': {
6117
+ var vlsRoom = args && args.room_id;
6118
+ if (!vlsRoom) { writeResp(id, { ok: false, output: 'voice_listen_start requires room_id' }); return; }
6119
+ if (!rooms.has(vlsRoom)) { writeResp(id, { ok: false, output: 'Not in room: ' + vlsRoom }); return; }
6120
+ _voiceListenRooms.add(vlsRoom);
6121
+ var ok = _voiceEnsureWhisper();
6122
+ if (!ok) {
6123
+ _voiceListenRooms.delete(vlsRoom);
6124
+ writeResp(id, { ok: false, output: 'Failed to start whisper — check Python + live-whisper.py path' });
6125
+ return;
6126
+ }
6127
+ writeResp(id, { ok: true, output: 'Voice listen started for ' + vlsRoom + '. Transcripts will appear in inbox/' + vlsRoom + '/voice/' });
6128
+ break;
6129
+ }
6130
+ case 'voice_listen_stop': {
6131
+ var vlsRoom2 = args && args.room_id;
6132
+ if (vlsRoom2) {
6133
+ _voiceListenRooms.delete(vlsRoom2);
6134
+ writeResp(id, { ok: true, output: 'Voice listen stopped for ' + vlsRoom2 });
6135
+ } else {
6136
+ _voiceListenRooms.clear();
6137
+ writeResp(id, { ok: true, output: 'Voice listen stopped for all rooms' });
6138
+ }
6139
+ if (_voiceListenRooms.size === 0 && _whisperProc) {
6140
+ try { _whisperProc.stdin.end(); } catch {}
6141
+ try { _whisperProc.kill(); } catch {}
6142
+ _whisperProc = null;
6143
+ }
6144
+ break;
6145
+ }
6146
+ // ── Voice: status of voice subsystem ──
6147
+ case 'voice_status': {
6148
+ writeResp(id, { ok: true, output: JSON.stringify({
6149
+ subscribed: !!_voiceSub,
6150
+ whisperRunning: !!_whisperProc,
6151
+ listeningRooms: Array.from(_voiceListenRooms),
6152
+ lastActivityMsAgo: _voiceLastActivityMs ? (Date.now() - _voiceLastActivityMs) : null,
6153
+ }, null, 2) });
6154
+ break;
6155
+ }
5831
6156
  // ── Sponsor announcement via NATS ──
5832
6157
  case 'sponsor_announce': {
5833
6158
  // Publish sponsor metadata to NATS so other OA instances can discover it
@@ -8058,6 +8383,58 @@ process.on('unhandledRejection', (reason) => {
8058
8383
  var _natsInvSub = _nc.subscribe(_natsInvSubject);
8059
8384
  dlog('NATS invoke relay listening on ' + _natsInvSubject);
8060
8385
 
8386
+ // ── Voice subscription: nexus.rooms.audio ─────────────────
8387
+ // Filters incoming voice envelopes by the rooms this daemon
8388
+ // has joined. Auto-emits voice.activity events to the room
8389
+ // inbox; if voice_listen_start has been called for that
8390
+ // room, PCM bytes are piped into the whisper child process
8391
+ // for auto-transcription.
8392
+ try {
8393
+ _voiceSub = _nc.subscribe(VOICE_SUBJECT);
8394
+ dlog('NATS voice subscription active on ' + VOICE_SUBJECT);
8395
+ (async function _voiceLoop() {
8396
+ for await (var _vm of _voiceSub) {
8397
+ try {
8398
+ var env = JSON.parse(_natsCodec.decode(_vm.data));
8399
+ if (!env || env.type !== 'voice' || !env.roomId) continue;
8400
+ // Only process audio for rooms this agent has joined —
8401
+ // ignores everyone else's chatter and keeps CPU down.
8402
+ if (!rooms.has(env.roomId)) continue;
8403
+ // Skip our own echo
8404
+ if (env.peerId && env.peerId === nexus.peerId) continue;
8405
+ _voiceLastActivityMs = Date.now();
8406
+ _voiceEmitActivity(env);
8407
+ // If whisper is active for this room, decode and pipe
8408
+ if (_voiceListenRooms.has(env.roomId) && _whisperProc && env.data) {
8409
+ var buf;
8410
+ if (env.encoding === 'float32') {
8411
+ // Float32 → PCM16 conversion so whisper gets a
8412
+ // consistent input format
8413
+ var raw = _voiceB64ToBuf(env.data);
8414
+ var f32 = new Float32Array(raw.buffer, raw.byteOffset, raw.byteLength / 4);
8415
+ buf = _voiceF32ToPcm16(f32);
8416
+ } else if (env.encoding === 'jibberlink') {
8417
+ // Jibberlink frames are encrypted data-over-audio
8418
+ // (see lib-jibberlink.ts). Skip whisper feeding —
8419
+ // those get demodulated + decrypted separately.
8420
+ continue;
8421
+ } else {
8422
+ // Default pcm16 — pass straight through
8423
+ buf = _voiceB64ToBuf(env.data);
8424
+ }
8425
+ _voiceFeedWhisper(buf);
8426
+ }
8427
+ } catch (vErr) {
8428
+ dlog('voice loop parse error: ' + (vErr.message || vErr));
8429
+ }
8430
+ }
8431
+ })().catch(function(loopErr) {
8432
+ dlog('voice loop fatal: ' + (loopErr.message || loopErr));
8433
+ });
8434
+ } catch (vsErr) {
8435
+ dlog('voice subscribe failed: ' + (vsErr.message || vsErr));
8436
+ }
8437
+
8061
8438
  (async function _natsInvokeLoop() {
8062
8439
  for await (var _nm of _natsInvSub) {
8063
8440
  try {
@@ -10093,6 +10470,32 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
10093
10470
  confidence: String(args.confidence ?? "0.7")
10094
10471
  });
10095
10472
  break;
10473
+ // ── Voice subsystem (nexus.rooms.audio transport) ──────────
10474
+ case "voice_publish":
10475
+ result = await this.sendDaemonCmd("voice_publish", {
10476
+ room_id: String(args.room_id ?? ""),
10477
+ pcm_base64: String(args.pcm_base64 ?? args.data ?? ""),
10478
+ sample_rate: String(args.sample_rate ?? "16000"),
10479
+ encoding: String(args.encoding ?? "pcm16"),
10480
+ channels: String(args.channels ?? "1")
10481
+ }, 1e4);
10482
+ break;
10483
+ case "voice_speak":
10484
+ result = await this.doVoiceSpeak(args);
10485
+ break;
10486
+ case "voice_listen_start":
10487
+ result = await this.sendDaemonCmd("voice_listen_start", { room_id: String(args.room_id ?? "") });
10488
+ break;
10489
+ case "voice_listen_stop":
10490
+ result = await this.sendDaemonCmd("voice_listen_stop", { room_id: String(args.room_id ?? "") });
10491
+ break;
10492
+ case "voice_status":
10493
+ result = await this.sendDaemonCmd("voice_status", {});
10494
+ break;
10495
+ // ── Jibberlink: encrypted data-over-audio between agents ───
10496
+ case "jibberlink_send":
10497
+ result = await this.doJibberlinkSend(args);
10498
+ break;
10096
10499
  default:
10097
10500
  return { success: false, output: "", error: `Unknown nexus action: ${action}`, durationMs: Date.now() - start2 };
10098
10501
  }
@@ -10131,7 +10534,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
10131
10534
  if (!pid)
10132
10535
  throw new Error("Nexus daemon not running. Use action 'connect' first.");
10133
10536
  }
10134
- const cmdId = randomBytes4(8).toString("hex");
10537
+ const cmdId = randomBytes5(8).toString("hex");
10135
10538
  const cmdFile = join14(this.nexusDir, "cmd.json");
10136
10539
  const respFile = join14(this.nexusDir, "resp.json");
10137
10540
  if (existsSync11(respFile))
@@ -10242,7 +10645,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
10242
10645
  // =========================================================================
10243
10646
  async doConnect(args) {
10244
10647
  await this.ensureDir();
10245
- const currentScriptHash = createHash("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
10648
+ const currentScriptHash = createHash2("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
10246
10649
  const existingPid = this.getDaemonPid();
10247
10650
  if (existingPid) {
10248
10651
  let processAlive = false;
@@ -10614,6 +11017,134 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
10614
11017
  }
10615
11018
  return this.sendDaemonCmd("send_message", args);
10616
11019
  }
11020
+ /**
11021
+ * Synthesize `text` to WAV via the system TTS (piper/espeak/ffmpeg
11022
+ * sox fallback), decode to raw 16kHz mono PCM16, chunk into 20ms
11023
+ * frames, and publish each frame to nexus.rooms.audio so other
11024
+ * agents + the nexus frontend visitors hear the agent speak.
11025
+ *
11026
+ * This is the symmetry with the existing audio_playback.speak tool,
11027
+ * but routes audio over the nexus voice subject instead of the
11028
+ * local speakers.
11029
+ */
11030
+ async doVoiceSpeak(args) {
11031
+ const text = String(args.text ?? "");
11032
+ const roomId = String(args.room_id ?? "");
11033
+ if (!text)
11034
+ throw new Error("text is required");
11035
+ if (!roomId)
11036
+ throw new Error("room_id is required");
11037
+ if (containsKeyMaterial(text)) {
11038
+ return "BLOCKED: Text contains potential key material.";
11039
+ }
11040
+ const tmpWav = join14(this.nexusDir, `voice-${Date.now()}.wav`);
11041
+ try {
11042
+ const cp2 = await import("node:child_process");
11043
+ const fsMod = await import("node:fs");
11044
+ const path5 = await import("node:path");
11045
+ let synthesized = false;
11046
+ try {
11047
+ cp2.execSync(`echo ${JSON.stringify(text)} | piper --model en_US-lessac-medium --output_file ${JSON.stringify(tmpWav)}`, {
11048
+ stdio: "pipe",
11049
+ timeout: 3e4
11050
+ });
11051
+ synthesized = fsMod.existsSync(tmpWav);
11052
+ } catch {
11053
+ }
11054
+ if (!synthesized) {
11055
+ try {
11056
+ cp2.execSync(`espeak ${JSON.stringify(text)} -w ${JSON.stringify(tmpWav)} -s 160`, {
11057
+ stdio: "pipe",
11058
+ timeout: 15e3
11059
+ });
11060
+ synthesized = fsMod.existsSync(tmpWav);
11061
+ } catch (err) {
11062
+ throw new Error(`TTS synthesis failed: ${err.message || err}`);
11063
+ }
11064
+ }
11065
+ const pcmPath = tmpWav.replace(/\.wav$/, ".pcm");
11066
+ try {
11067
+ cp2.execSync(`ffmpeg -y -i ${JSON.stringify(tmpWav)} -ac 1 -ar 16000 -f s16le ${JSON.stringify(pcmPath)}`, {
11068
+ stdio: "pipe",
11069
+ timeout: 15e3
11070
+ });
11071
+ } catch {
11072
+ const raw = fsMod.readFileSync(tmpWav);
11073
+ fsMod.writeFileSync(pcmPath, raw.slice(44));
11074
+ }
11075
+ const pcm = fsMod.readFileSync(pcmPath);
11076
+ try {
11077
+ fsMod.unlinkSync(tmpWav);
11078
+ } catch {
11079
+ }
11080
+ try {
11081
+ fsMod.unlinkSync(pcmPath);
11082
+ } catch {
11083
+ }
11084
+ const SAMPLE_RATE = 16e3;
11085
+ const FRAME_MS = 50;
11086
+ const FRAME_BYTES = Math.floor(SAMPLE_RATE * FRAME_MS / 1e3 * 2);
11087
+ const frameCount = Math.ceil(pcm.length / FRAME_BYTES);
11088
+ let published = 0;
11089
+ for (let i2 = 0; i2 < pcm.length; i2 += FRAME_BYTES) {
11090
+ const chunk = pcm.subarray(i2, Math.min(i2 + FRAME_BYTES, pcm.length));
11091
+ const b64 = chunk.toString("base64");
11092
+ await this.sendDaemonCmd("voice_publish", {
11093
+ room_id: roomId,
11094
+ pcm_base64: b64,
11095
+ sample_rate: String(SAMPLE_RATE),
11096
+ encoding: "pcm16",
11097
+ channels: "1"
11098
+ }, 5e3);
11099
+ published++;
11100
+ await new Promise((r2) => setTimeout(r2, Math.floor(FRAME_MS * 0.5)));
11101
+ }
11102
+ return `Spoke ${frameCount} frames (${(pcm.length / 1024).toFixed(1)}KB) to ${roomId}`;
11103
+ } catch (err) {
11104
+ throw new Error(`voice_speak failed: ${err.message || err}`);
11105
+ }
11106
+ }
11107
+ /**
11108
+ * Encode a byte payload under AES-GCM (per-room key), modulate it as
11109
+ * FSK over the jibberlink audio modem, and publish the resulting PCM
11110
+ * samples to the room as a voice frame with encoding='jibberlink'.
11111
+ *
11112
+ * Other agents subscribed to nexus.rooms.audio can demodulate + decrypt
11113
+ * it using the same roomId (shared key is derived from roomId + a
11114
+ * caller-supplied `secret`). Visitors in the nexus frontend simply
11115
+ * hear the characteristic chirp tones without decoding.
11116
+ */
11117
+ async doJibberlinkSend(args) {
11118
+ const roomId = String(args.room_id ?? "");
11119
+ const message2 = String(args.message ?? args.data ?? "");
11120
+ const secret = args.secret != null ? String(args.secret) : void 0;
11121
+ if (!roomId)
11122
+ throw new Error("room_id is required");
11123
+ if (!message2)
11124
+ throw new Error("message is required");
11125
+ if (containsKeyMaterial(message2)) {
11126
+ return "BLOCKED: Message contains potential key material.";
11127
+ }
11128
+ const plaintext = Buffer.from(message2, "utf8");
11129
+ if (plaintext.length > 1024) {
11130
+ throw new Error("jibberlink payload > 1KB — split into multiple frames");
11131
+ }
11132
+ const pcmF32 = encodeEncrypted(roomId, plaintext, secret);
11133
+ const pcm16 = Buffer.alloc(pcmF32.length * 2);
11134
+ for (let i2 = 0; i2 < pcmF32.length; i2++) {
11135
+ let s2 = Math.max(-1, Math.min(1, pcmF32[i2]));
11136
+ pcm16.writeInt16LE(s2 < 0 ? s2 * 32768 : s2 * 32767, i2 * 2);
11137
+ }
11138
+ const b64 = pcm16.toString("base64");
11139
+ await this.sendDaemonCmd("voice_publish", {
11140
+ room_id: roomId,
11141
+ pcm_base64: b64,
11142
+ sample_rate: "16000",
11143
+ encoding: "jibberlink",
11144
+ channels: "1"
11145
+ }, 1e4);
11146
+ return `Jibberlink frame sent to ${roomId} (${plaintext.length}B plaintext → ${pcmF32.length} samples)`;
11147
+ }
10617
11148
  async doSendDM(args) {
10618
11149
  const message2 = args.message;
10619
11150
  if (!message2)
@@ -10738,21 +11269,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
10738
11269
  let privKeyHex;
10739
11270
  try {
10740
11271
  const { privateKeyToAccount } = await import("viem/accounts");
10741
- const privKey = randomBytes4(32);
11272
+ const privKey = randomBytes5(32);
10742
11273
  privKeyHex = privKey.toString("hex");
10743
11274
  const account = privateKeyToAccount(`0x${privKeyHex}`);
10744
11275
  address = account.address;
10745
11276
  privKey.fill(0);
10746
11277
  } catch {
10747
- const privKey = randomBytes4(32);
11278
+ const privKey = randomBytes5(32);
10748
11279
  privKeyHex = privKey.toString("hex");
10749
- address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
11280
+ address = "0x" + createHash2("sha256").update(privKey).digest("hex").slice(0, 40);
10750
11281
  privKey.fill(0);
10751
11282
  }
10752
- const salt = randomBytes4(32);
11283
+ const salt = randomBytes5(32);
10753
11284
  const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
10754
- const iv = randomBytes4(16);
10755
- const cipher = createCipheriv("aes-256-gcm", key, iv);
11285
+ const iv = randomBytes5(16);
11286
+ const cipher = createCipheriv2("aes-256-gcm", key, iv);
10756
11287
  let enc = cipher.update(privKeyHex, "utf8", "hex");
10757
11288
  enc += cipher.final("hex");
10758
11289
  const x402KeyPath = join14(this.nexusDir, "x402-wallet.key");
@@ -10800,21 +11331,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
10800
11331
  let privKeyHex;
10801
11332
  try {
10802
11333
  const { privateKeyToAccount } = await import("viem/accounts");
10803
- const privKey = randomBytes4(32);
11334
+ const privKey = randomBytes5(32);
10804
11335
  privKeyHex = privKey.toString("hex");
10805
11336
  const account = privateKeyToAccount(`0x${privKeyHex}`);
10806
11337
  address = account.address;
10807
11338
  privKey.fill(0);
10808
11339
  } catch {
10809
- const privKey = randomBytes4(32);
11340
+ const privKey = randomBytes5(32);
10810
11341
  privKeyHex = privKey.toString("hex");
10811
- address = "0x" + createHash("sha256").update(privKey).digest("hex").slice(0, 40);
11342
+ address = "0x" + createHash2("sha256").update(privKey).digest("hex").slice(0, 40);
10812
11343
  privKey.fill(0);
10813
11344
  }
10814
- const salt = randomBytes4(32);
11345
+ const salt = randomBytes5(32);
10815
11346
  const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
10816
- const iv = randomBytes4(16);
10817
- const cipher = createCipheriv("aes-256-gcm", key, iv);
11347
+ const iv = randomBytes5(16);
11348
+ const cipher = createCipheriv2("aes-256-gcm", key, iv);
10818
11349
  let enc = cipher.update(privKeyHex, "utf8", "hex");
10819
11350
  enc += cipher.final("hex");
10820
11351
  const x402KeyPath = join14(this.nexusDir, "x402-wallet.key");
@@ -11120,14 +11651,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11120
11651
  throw new Error("User-managed wallet cannot spend (no private key)");
11121
11652
  const salt = Buffer.from(w.salt, "hex");
11122
11653
  const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
11123
- const decipher = createDecipheriv("aes-256-gcm", key, Buffer.from(w.iv, "hex"));
11654
+ const decipher = createDecipheriv2("aes-256-gcm", key, Buffer.from(w.iv, "hex"));
11124
11655
  decipher.setAuthTag(Buffer.from(w.authTag, "hex"));
11125
11656
  let privKeyHex = decipher.update(w.encryptedKey, "hex", "utf8");
11126
11657
  privKeyHex += decipher.final("utf8");
11127
11658
  try {
11128
11659
  const { privateKeyToAccount } = await import("viem/accounts");
11129
11660
  const account = privateKeyToAccount(`0x${privKeyHex}`);
11130
- const nonce = "0x" + randomBytes4(32).toString("hex");
11661
+ const nonce = "0x" + randomBytes5(32).toString("hex");
11131
11662
  const now = Math.floor(Date.now() / 1e3);
11132
11663
  const validAfter = now - 60;
11133
11664
  const validBefore = now + 3600;
@@ -11330,8 +11861,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
11330
11861
  } catch {
11331
11862
  }
11332
11863
  }
11333
- const nonce = randomBytes4(16).toString("hex");
11334
- const hash = createHash("sha256").update(`${modelName}:${nonce}:${Date.now()}`).digest("hex");
11864
+ const nonce = randomBytes5(16).toString("hex");
11865
+ const hash = createHash2("sha256").update(`${modelName}:${nonce}:${Date.now()}`).digest("hex");
11335
11866
  const bar = (s2) => "█".repeat(Math.round(s2 / 5)) + "░".repeat(20 - Math.round(s2 / 5));
11336
11867
  const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
11337
11868
  await this.ensureDir();
@@ -19865,7 +20396,7 @@ function createHasher(hashCons, info = {}) {
19865
20396
  Object.assign(hashC, info);
19866
20397
  return Object.freeze(hashC);
19867
20398
  }
19868
- function randomBytes5(bytesLength = 32) {
20399
+ function randomBytes6(bytesLength = 32) {
19869
20400
  const cr = typeof globalThis === "object" ? globalThis.crypto : null;
19870
20401
  if (typeof cr?.getRandomValues !== "function")
19871
20402
  throw new Error("crypto.getRandomValues must be defined");
@@ -19889,11 +20420,11 @@ var init_utils3 = __esm({
19889
20420
  });
19890
20421
 
19891
20422
  // ../node_modules/@libp2p/crypto/dist/src/random-bytes.js
19892
- function randomBytes6(length4) {
20423
+ function randomBytes7(length4) {
19893
20424
  if (isNaN(length4) || length4 <= 0) {
19894
20425
  throw new InvalidParametersError("random bytes length must be a Number bigger than 0");
19895
20426
  }
19896
- return randomBytes5(length4);
20427
+ return randomBytes6(length4);
19897
20428
  }
19898
20429
  var init_random_bytes = __esm({
19899
20430
  "../node_modules/@libp2p/crypto/dist/src/random-bytes.js"() {
@@ -22082,7 +22613,7 @@ function getWLengths(Fp, Fn) {
22082
22613
  }
22083
22614
  function ecdh(Point, ecdhOpts = {}) {
22084
22615
  const { Fn } = Point;
22085
- const randomBytes_ = ecdhOpts.randomBytes || randomBytes5;
22616
+ const randomBytes_ = ecdhOpts.randomBytes || randomBytes6;
22086
22617
  const lengths = Object.assign(getWLengths(Point.Fp, Fn), { seed: getMinHashLength(Fn.ORDER) });
22087
22618
  function isValidSecretKey(secretKey) {
22088
22619
  try {
@@ -22147,7 +22678,7 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
22147
22678
  bits2int_modN: "function"
22148
22679
  });
22149
22680
  ecdsaOpts = Object.assign({}, ecdsaOpts);
22150
- const randomBytes22 = ecdsaOpts.randomBytes || randomBytes5;
22681
+ const randomBytes23 = ecdsaOpts.randomBytes || randomBytes6;
22151
22682
  const hmac2 = ecdsaOpts.hmac || ((key, msg) => hmac(hash, key, msg));
22152
22683
  const { Fp, Fn } = Point;
22153
22684
  const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
@@ -22289,7 +22820,7 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
22289
22820
  throw new Error("invalid private key");
22290
22821
  const seedArgs = [int2octets(d2), int2octets(h1int)];
22291
22822
  if (extraEntropy != null && extraEntropy !== false) {
22292
- const e2 = extraEntropy === true ? randomBytes22(lengths.secretKey) : extraEntropy;
22823
+ const e2 = extraEntropy === true ? randomBytes23(lengths.secretKey) : extraEntropy;
22293
22824
  seedArgs.push(abytes(e2, void 0, "extraEntropy"));
22294
22825
  }
22295
22826
  const seed = concatBytes(...seedArgs);
@@ -46871,7 +47402,7 @@ var init_connection_monitor = __esm({
46871
47402
  const bs = byteStream(stream);
46872
47403
  start2 = Date.now();
46873
47404
  await Promise.all([
46874
- bs.write(randomBytes6(PING_LENGTH), {
47405
+ bs.write(randomBytes7(PING_LENGTH), {
46875
47406
  signal
46876
47407
  }),
46877
47408
  bs.read({
@@ -47383,7 +47914,7 @@ var init_random_walk = __esm({
47383
47914
  this.log("start walk");
47384
47915
  while (this.walkers > 0) {
47385
47916
  try {
47386
- const data = randomBytes6(32);
47917
+ const data = randomBytes7(32);
47387
47918
  let s2 = Date.now();
47388
47919
  for await (const peer of this.peerRouting.getClosestPeers(data, { signal })) {
47389
47920
  if (signal.aborted) {
@@ -53070,12 +53601,12 @@ async function exportToPem(privateKey, password) {
53070
53601
  });
53071
53602
  const keyBuf = keyWrapper.toBER();
53072
53603
  const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
53073
- const salt = randomBytes6(SALT_LENGTH);
53604
+ const salt = randomBytes7(SALT_LENGTH);
53074
53605
  const encryptionKey = await pbkdf2Async(sha5122, password, salt, {
53075
53606
  c: ITERATIONS,
53076
53607
  dkLen: KEY_SIZE
53077
53608
  });
53078
- const iv = randomBytes6(16);
53609
+ const iv = randomBytes7(16);
53079
53610
  const cryptoKey = await crypto14.subtle.importKey("raw", encryptionKey, "AES-CBC", false, ["encrypt"]);
53080
53611
  const encrypted = await crypto14.subtle.encrypt({
53081
53612
  name: "AES-CBC",
@@ -53373,7 +53904,7 @@ var init_keychain = __esm({
53373
53904
  const options2 = Object.assign({}, this.options);
53374
53905
  const saltLength = Math.ceil(NIST.minSaltLength / 3) * 3;
53375
53906
  if (options2.dek != null) {
53376
- options2.dek.salt = toString2(randomBytes6(saltLength), "base64");
53907
+ options2.dek.salt = toString2(randomBytes7(saltLength), "base64");
53377
53908
  }
53378
53909
  return options2;
53379
53910
  }
@@ -54864,7 +55395,7 @@ function montgomery(curveDef) {
54864
55395
  const is25519 = type === "x25519";
54865
55396
  if (!is25519 && type !== "x448")
54866
55397
  throw new Error("invalid type");
54867
- const randomBytes_ = rand || randomBytes5;
55398
+ const randomBytes_ = rand || randomBytes6;
54868
55399
  const montgomeryBits = is25519 ? 255 : 448;
54869
55400
  const fieldLen = is25519 ? 32 : 56;
54870
55401
  const Gu = is25519 ? BigInt(9) : BigInt(5);
@@ -58799,9 +59330,9 @@ var init_cookies = __esm({
58799
59330
 
58800
59331
  // ../node_modules/@libp2p/http-peer-id-auth/dist/src/utils.js
58801
59332
  function generateChallenge() {
58802
- const randomBytes22 = new Uint8Array(32);
58803
- crypto.getRandomValues(randomBytes22);
58804
- return toString2(randomBytes22, "base64urlpad");
59333
+ const randomBytes23 = new Uint8Array(32);
59334
+ crypto.getRandomValues(randomBytes23);
59335
+ return toString2(randomBytes23, "base64urlpad");
58805
59336
  }
58806
59337
  function encodeAuthParams(params) {
58807
59338
  const encodedParams = Object.entries(params).map(([key, value2]) => `${key}="${value2}"`).join(", ");
@@ -87999,7 +88530,7 @@ var require_auto = __commonJS({
87999
88530
  // ../node_modules/acme-client/src/client.js
88000
88531
  var require_client = __commonJS({
88001
88532
  "../node_modules/acme-client/src/client.js"(exports, module) {
88002
- var { createHash: createHash9 } = __require("crypto");
88533
+ var { createHash: createHash10 } = __require("crypto");
88003
88534
  var { getPemBodyAsB64u } = require_crypto();
88004
88535
  var { log: log22 } = require_logger();
88005
88536
  var HttpClient = require_http();
@@ -88310,14 +88841,14 @@ var require_client = __commonJS({
88310
88841
  */
88311
88842
  async getChallengeKeyAuthorization(challenge) {
88312
88843
  const jwk = this.http.getJwk();
88313
- const keysum = createHash9("sha256").update(JSON.stringify(jwk));
88844
+ const keysum = createHash10("sha256").update(JSON.stringify(jwk));
88314
88845
  const thumbprint = keysum.digest("base64url");
88315
88846
  const result = `${challenge.token}.${thumbprint}`;
88316
88847
  if (challenge.type === "http-01") {
88317
88848
  return result;
88318
88849
  }
88319
88850
  if (challenge.type === "dns-01") {
88320
- return createHash9("sha256").update(result).digest("base64url");
88851
+ return createHash10("sha256").update(result).digest("base64url");
88321
88852
  }
88322
88853
  if (challenge.type === "tls-alpn-01") {
88323
88854
  return result;
@@ -206664,7 +207195,7 @@ var init_refresh = __esm({
206664
207195
  if (this.routingTable.kb.localPeer == null) {
206665
207196
  throw new Error("Local peer not set");
206666
207197
  }
206667
- const randomData = randomBytes6(2);
207198
+ const randomData = randomBytes7(2);
206668
207199
  const randomUint16 = (randomData[1] << 8) + randomData[0];
206669
207200
  const key = this._makePeerId(this.routingTable.kb.localPeer.kadId, randomUint16, targetCommonPrefixLength);
206670
207201
  const multihash = decode7(key);
@@ -210841,7 +211372,7 @@ var init_ping2 = __esm({
210841
211372
  * Ping a given peer and wait for its response, getting the operation latency.
210842
211373
  */
210843
211374
  async ping(peer, options2 = {}) {
210844
- const data = randomBytes6(PING_LENGTH2);
211375
+ const data = randomBytes7(PING_LENGTH2);
210845
211376
  const stream = await this.components.connectionManager.openStream(peer, this.protocol, {
210846
211377
  runOnLimitedConnection: this.runOnLimitedConnection,
210847
211378
  ...options2
@@ -230997,7 +231528,7 @@ var require_websocket2 = __commonJS({
230997
231528
  var http6 = __require("http");
230998
231529
  var net5 = __require("net");
230999
231530
  var tls2 = __require("tls");
231000
- var { randomBytes: randomBytes22, createHash: createHash9 } = __require("crypto");
231531
+ var { randomBytes: randomBytes23, createHash: createHash10 } = __require("crypto");
231001
231532
  var { Duplex: Duplex3, Readable } = __require("stream");
231002
231533
  var { URL: URL3 } = __require("url");
231003
231534
  var PerMessageDeflate2 = require_permessage_deflate2();
@@ -231527,7 +232058,7 @@ var require_websocket2 = __commonJS({
231527
232058
  }
231528
232059
  }
231529
232060
  const defaultPort = isSecure ? 443 : 80;
231530
- const key = randomBytes22(16).toString("base64");
232061
+ const key = randomBytes23(16).toString("base64");
231531
232062
  const request = isSecure ? https4.request : http6.request;
231532
232063
  const protocolSet = /* @__PURE__ */ new Set();
231533
232064
  let perMessageDeflate;
@@ -231657,7 +232188,7 @@ var require_websocket2 = __commonJS({
231657
232188
  abortHandshake(websocket, socket, "Invalid Upgrade header");
231658
232189
  return;
231659
232190
  }
231660
- const digest3 = createHash9("sha1").update(key + GUID).digest("base64");
232191
+ const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
231661
232192
  if (res.headers["sec-websocket-accept"] !== digest3) {
231662
232193
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
231663
232194
  return;
@@ -232024,7 +232555,7 @@ var require_websocket_server = __commonJS({
232024
232555
  var EventEmitter10 = __require("events");
232025
232556
  var http6 = __require("http");
232026
232557
  var { Duplex: Duplex3 } = __require("stream");
232027
- var { createHash: createHash9 } = __require("crypto");
232558
+ var { createHash: createHash10 } = __require("crypto");
232028
232559
  var extension2 = require_extension2();
232029
232560
  var PerMessageDeflate2 = require_permessage_deflate2();
232030
232561
  var subprotocol2 = require_subprotocol();
@@ -232325,7 +232856,7 @@ var require_websocket_server = __commonJS({
232325
232856
  );
232326
232857
  }
232327
232858
  if (this._state > RUNNING) return abortHandshake(socket, 503);
232328
- const digest3 = createHash9("sha1").update(key + GUID).digest("base64");
232859
+ const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
232329
232860
  const headers = [
232330
232861
  "HTTP/1.1 101 Switching Protocols",
232331
232862
  "Upgrade: websocket",
@@ -245132,13 +245663,13 @@ Justification: ${justification || "(none provided)"}`,
245132
245663
  }
245133
245664
  const snapshot = JSON.stringify(this.selfState, null, 2);
245134
245665
  try {
245135
- const { createHash: createHash9 } = await import("node:crypto");
245666
+ const { createHash: createHash10 } = await import("node:crypto");
245136
245667
  const snapshotDir = join23(this.cwd, ".oa", "identity", "snapshots");
245137
245668
  await mkdir6(snapshotDir, { recursive: true });
245138
245669
  const version4 = this.selfState.version;
245139
245670
  const snapshotPath = join23(snapshotDir, `v${version4}.json`);
245140
245671
  await writeFile11(snapshotPath, snapshot, "utf8");
245141
- const hash = createHash9("sha256").update(snapshot).digest("hex");
245672
+ const hash = createHash10("sha256").update(snapshot).digest("hex");
245142
245673
  await writeFile11(join23(this.cwd, ".oa", "identity", "latest-hash.txt"), hash, "utf8");
245143
245674
  let ipfsCid = "";
245144
245675
  try {
@@ -245271,8 +245802,8 @@ New: ${newNarrative.slice(0, 200)}...`,
245271
245802
  }
245272
245803
  // ── Helpers ──────────────────────────────────────────────────────────────
245273
245804
  createDefaultState() {
245274
- const { createHash: createHash9 } = __require("node:crypto");
245275
- const machineId = createHash9("sha256").update(this.cwd).digest("hex").slice(0, 12);
245805
+ const { createHash: createHash10 } = __require("node:crypto");
245806
+ const machineId = createHash10("sha256").update(this.cwd).digest("hex").slice(0, 12);
245276
245807
  return {
245277
245808
  self_id: `oa-${machineId}`,
245278
245809
  version: 1,
@@ -245354,9 +245885,9 @@ New: ${newNarrative.slice(0, 200)}...`,
245354
245885
  let cid;
245355
245886
  if (this.selfState.version > prevVersion) {
245356
245887
  try {
245357
- const { createHash: createHash9 } = await import("node:crypto");
245888
+ const { createHash: createHash10 } = await import("node:crypto");
245358
245889
  const stateJson = JSON.stringify(this.selfState);
245359
- const hash = createHash9("sha256").update(stateJson).digest("hex").slice(0, 32);
245890
+ const hash = createHash10("sha256").update(stateJson).digest("hex").slice(0, 32);
245360
245891
  const cidsPath = join23(this.cwd, ".oa", "identity", "cids.json");
245361
245892
  const cidsData = { latest: "", hash, version: this.selfState.version };
245362
245893
  try {
@@ -245400,7 +245931,7 @@ import { spawn as spawn7 } from "node:child_process";
245400
245931
  import { createServer as createServer2 } from "node:net";
245401
245932
  import { join as join24 } from "node:path";
245402
245933
  import { tmpdir as tmpdir4 } from "node:os";
245403
- import { randomBytes as randomBytes8 } from "node:crypto";
245934
+ import { randomBytes as randomBytes9 } from "node:crypto";
245404
245935
  import { unlinkSync as unlinkSync3 } from "node:fs";
245405
245936
  var ReplTool;
245406
245937
  var init_repl = __esm({
@@ -245468,7 +245999,7 @@ var init_repl = __esm({
245468
245999
  if (!this.proc || this.proc.killed || this.proc.exitCode !== null) {
245469
246000
  await this.startProcess();
245470
246001
  }
245471
- const tempFile = join24(tmpdir4(), `oa-repl-ctx-${randomBytes8(6).toString("hex")}.txt`);
246002
+ const tempFile = join24(tmpdir4(), `oa-repl-ctx-${randomBytes9(6).toString("hex")}.txt`);
245472
246003
  const { writeFileSync: writeFs, unlinkSync: unlinkFs } = await import("node:fs");
245473
246004
  writeFs(tempFile, content, "utf8");
245474
246005
  const result = await this.executeCode(`with open(${JSON.stringify(tempFile)}, "r") as _f:
@@ -245668,7 +246199,7 @@ print("__OA_REPL_READY__")
245668
246199
  async startIpcServer() {
245669
246200
  if (this.ipcServer)
245670
246201
  return;
245671
- const sockId = randomBytes8(8).toString("hex");
246202
+ const sockId = randomBytes9(8).toString("hex");
245672
246203
  this.ipcPath = join24(tmpdir4(), `oa-repl-ipc-${sockId}.sock`);
245673
246204
  return new Promise((resolve39, reject) => {
245674
246205
  this.ipcServer = createServer2((conn) => {
@@ -245754,7 +246285,7 @@ print("__OA_REPL_READY__")
245754
246285
  resolve39({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
245755
246286
  return;
245756
246287
  }
245757
- const sentinel = `__OA_SENTINEL_${randomBytes8(6).toString("hex")}__`;
246288
+ const sentinel = `__OA_SENTINEL_${randomBytes9(6).toString("hex")}__`;
245758
246289
  let stdout = "";
245759
246290
  let stderr = "";
245760
246291
  let resolved = false;
@@ -250817,7 +251348,7 @@ import { execSync as execSync22, exec as execCb } from "node:child_process";
250817
251348
  import { readFile as readFile15, writeFile as writeFile17, mkdir as mkdir12 } from "node:fs/promises";
250818
251349
  import { resolve as resolve24, join as join37 } from "node:path";
250819
251350
  import { homedir as homedir10 } from "node:os";
250820
- import { randomBytes as randomBytes9 } from "node:crypto";
251351
+ import { randomBytes as randomBytes10 } from "node:crypto";
250821
251352
  function isValidCron(expr) {
250822
251353
  const parts = expr.trim().split(/\s+/);
250823
251354
  if (parts.length !== 5)
@@ -251085,7 +251616,7 @@ var init_scheduler = __esm({
251085
251616
  durationMs: performance.now() - start2
251086
251617
  };
251087
251618
  }
251088
- const id = `sched-${randomBytes9(4).toString("hex")}`;
251619
+ const id = `sched-${randomBytes10(4).toString("hex")}`;
251089
251620
  const oneShot = Boolean(args["one_shot"]);
251090
251621
  const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : void 0;
251091
251622
  const scope = String(args["scope"] ?? "local");
@@ -251244,7 +251775,7 @@ ${truncated}`, durationMs: performance.now() - start2 };
251244
251775
  // packages/execution/dist/tools/reminder.js
251245
251776
  import { readFile as readFile16, writeFile as writeFile18, mkdir as mkdir13 } from "node:fs/promises";
251246
251777
  import { resolve as resolve25, join as join38 } from "node:path";
251247
- import { randomBytes as randomBytes10 } from "node:crypto";
251778
+ import { randomBytes as randomBytes11 } from "node:crypto";
251248
251779
  function parseDueTime(due) {
251249
251780
  const lower = due.toLowerCase().trim();
251250
251781
  const now = /* @__PURE__ */ new Date();
@@ -251441,7 +251972,7 @@ var init_reminder = __esm({
251441
251972
  dueAt = parsed.isoDate;
251442
251973
  dueDescription = parsed.description;
251443
251974
  }
251444
- const id = `rem-${randomBytes10(4).toString("hex")}`;
251975
+ const id = `rem-${randomBytes11(4).toString("hex")}`;
251445
251976
  const entry = {
251446
251977
  id,
251447
251978
  message: message2,
@@ -251557,7 +252088,7 @@ var init_reminder = __esm({
251557
252088
  // packages/execution/dist/tools/agenda.js
251558
252089
  import { readFile as readFile17, writeFile as writeFile19, mkdir as mkdir14 } from "node:fs/promises";
251559
252090
  import { resolve as resolve26, join as join39 } from "node:path";
251560
- import { randomBytes as randomBytes11 } from "node:crypto";
252091
+ import { randomBytes as randomBytes12 } from "node:crypto";
251561
252092
  async function loadAttentionStore(workingDir) {
251562
252093
  const storePath = resolve26(workingDir, ".oa", "scheduled", "attention.json");
251563
252094
  try {
@@ -251760,7 +252291,7 @@ ${sections.join("\n")}`,
251760
252291
  expiresAt = target.toISOString();
251761
252292
  }
251762
252293
  }
251763
- const id = `attn-${randomBytes11(4).toString("hex")}`;
252294
+ const id = `attn-${randomBytes12(4).toString("hex")}`;
251764
252295
  const item = {
251765
252296
  id,
251766
252297
  title,
@@ -252466,7 +252997,7 @@ import { execSync as execSync25 } from "node:child_process";
252466
252997
  import { readFile as readFile18, writeFile as writeFile20, mkdir as mkdir15 } from "node:fs/promises";
252467
252998
  import { resolve as resolve28, join as join42 } from "node:path";
252468
252999
  import { homedir as homedir11 } from "node:os";
252469
- import { randomBytes as randomBytes12 } from "node:crypto";
253000
+ import { randomBytes as randomBytes13 } from "node:crypto";
252470
253001
  function isValidCron2(expr) {
252471
253002
  const parts = expr.trim().split(/\s+/);
252472
253003
  if (parts.length !== 5)
@@ -252756,7 +253287,7 @@ var init_cron_agent = __esm({
252756
253287
  durationMs: performance.now() - start2
252757
253288
  };
252758
253289
  }
252759
- const id = `cron-${randomBytes12(4).toString("hex")}`;
253290
+ const id = `cron-${randomBytes13(4).toString("hex")}`;
252760
253291
  const verifyCommand = args["verify_command"] ? String(args["verify_command"]) : void 0;
252761
253292
  const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : 0;
252762
253293
  const tags = Array.isArray(args["tags"]) ? args["tags"] : [];
@@ -253557,7 +254088,7 @@ var init_working_notes = __esm({
253557
254088
  import { existsSync as existsSync27, readFileSync as readFileSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync10, renameSync, unlinkSync as unlinkSync5, readdirSync as readdirSync6 } from "node:fs";
253558
254089
  import { join as join43 } from "node:path";
253559
254090
  import { homedir as homedir12 } from "node:os";
253560
- import { randomBytes as randomBytes13 } from "node:crypto";
254091
+ import { randomBytes as randomBytes14 } from "node:crypto";
253561
254092
  function setTodoEventPublisher(pub) {
253562
254093
  _eventPublisher = pub;
253563
254094
  }
@@ -253593,7 +254124,7 @@ function writeTodos(sessionId, incoming) {
253593
254124
  const oldById = new Map(old.map((t2) => [t2.id, t2]));
253594
254125
  const now = Date.now();
253595
254126
  const newTodos = incoming.map((t2) => {
253596
- const id = t2.id || `todo-${randomBytes13(4).toString("hex")}`;
254127
+ const id = t2.id || `todo-${randomBytes14(4).toString("hex")}`;
253597
254128
  const existing = oldById.get(id);
253598
254129
  const next = {
253599
254130
  id,
@@ -259166,7 +259697,7 @@ Audio file: ${audioFile}`,
259166
259697
 
259167
259698
  // packages/execution/dist/tools/full-sub-agent.js
259168
259699
  import { spawn as spawn14, ChildProcess } from "node:child_process";
259169
- import { randomBytes as randomBytes14 } from "node:crypto";
259700
+ import { randomBytes as randomBytes15 } from "node:crypto";
259170
259701
  function buildSubProcessArgs(opts) {
259171
259702
  const args = [];
259172
259703
  args.push(opts.task);
@@ -259194,7 +259725,7 @@ function findOaBinary3() {
259194
259725
  return "oa";
259195
259726
  }
259196
259727
  function spawnFullSubAgent(task, opts, onOutput, onComplete) {
259197
- const id = `oa-fl-${randomBytes14(2).toString("hex")}`;
259728
+ const id = `oa-fl-${randomBytes15(2).toString("hex")}`;
259198
259729
  const oaBin = findOaBinary3();
259199
259730
  const cliArgs = buildSubProcessArgs({
259200
259731
  task,
@@ -261619,7 +262150,7 @@ var init_environment_snapshot = __esm({
261619
262150
  import { execSync as execSync42 } from "node:child_process";
261620
262151
  import { existsSync as existsSync43, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readFileSync as readFileSync33, readdirSync as readdirSync10, unlinkSync as unlinkSync10 } from "node:fs";
261621
262152
  import { join as join57, basename as basename11 } from "node:path";
261622
- import { createHash as createHash2 } from "node:crypto";
262153
+ import { createHash as createHash3 } from "node:crypto";
261623
262154
  function isYouTubeUrl2(url) {
261624
262155
  return /(?:youtube\.com\/(?:watch|shorts|live|embed|v\/)|youtu\.be\/)/i.test(url);
261625
262156
  }
@@ -261647,7 +262178,7 @@ function ensureFfmpeg() {
261647
262178
  function imageHash(imagePath) {
261648
262179
  try {
261649
262180
  const data = readFileSync33(imagePath);
261650
- return createHash2("md5").update(data).digest("hex").slice(0, 12);
262181
+ return createHash3("md5").update(data).digest("hex").slice(0, 12);
261651
262182
  } catch {
261652
262183
  return "unknown";
261653
262184
  }
@@ -266900,7 +267431,7 @@ var init_toolPatternStore = __esm({
266900
267431
  import { join as join64 } from "node:path";
266901
267432
  import { mkdirSync as mkdirSync25, existsSync as existsSync48 } from "node:fs";
266902
267433
  import { randomUUID as randomUUID7 } from "node:crypto";
266903
- import { createHash as createHash3 } from "node:crypto";
267434
+ import { createHash as createHash4 } from "node:crypto";
266904
267435
  function sanitizeImportance(raw, fallback = 5) {
266905
267436
  if (typeof raw !== "number" || !Number.isFinite(raw))
266906
267437
  return fallback;
@@ -267008,7 +267539,7 @@ var init_episodeStore = __esm({
267008
267539
  insert(ep) {
267009
267540
  const id = randomUUID7();
267010
267541
  const now = Date.now();
267011
- const contentHash = createHash3("sha256").update(ep.content).digest("hex").slice(0, 16);
267542
+ const contentHash = createHash4("sha256").update(ep.content).digest("hex").slice(0, 16);
267012
267543
  const modality = ep.modality ?? "text";
267013
267544
  const rawImportance = ep.importance ?? autoImportance(ep.toolName ?? null, modality, ep.content);
267014
267545
  const importance = sanitizeImportance(rawImportance);
@@ -273920,7 +274451,7 @@ import { existsSync as existsSync50, statSync as statSync14, openSync, readSync,
273920
274451
  import { watch as fsWatch } from "node:fs";
273921
274452
  import { join as join66 } from "node:path";
273922
274453
  import { tmpdir as tmpdir17 } from "node:os";
273923
- import { randomBytes as randomBytes15 } from "node:crypto";
274454
+ import { randomBytes as randomBytes16 } from "node:crypto";
273924
274455
  var NexusAgenticBackend;
273925
274456
  var init_nexusBackend = __esm({
273926
274457
  "packages/orchestrator/dist/nexusBackend.js"() {
@@ -274068,7 +274599,7 @@ var init_nexusBackend = __esm({
274068
274599
  * Falls back to unary + word-split if streaming setup fails.
274069
274600
  */
274070
274601
  async *chatCompletionStream(request) {
274071
- const streamFile = join66(tmpdir17(), `nexus-stream-${randomBytes15(6).toString("hex")}.jsonl`);
274602
+ const streamFile = join66(tmpdir17(), `nexus-stream-${randomBytes16(6).toString("hex")}.jsonl`);
274072
274603
  writeFileSync23(streamFile, "", "utf8");
274073
274604
  const daemonArgs = {
274074
274605
  model: this.model,
@@ -274167,7 +274698,7 @@ var init_nexusBackend = __esm({
274167
274698
  }
274168
274699
  yield {
274169
274700
  type: "tool_call_delta",
274170
- toolCallId: tc.id || `call_${randomBytes15(8).toString("hex")}`,
274701
+ toolCallId: tc.id || `call_${randomBytes16(8).toString("hex")}`,
274171
274702
  toolCallName: fn.name,
274172
274703
  toolCallArgs: JSON.stringify(args)
274173
274704
  };
@@ -274263,7 +274794,7 @@ var init_nexusBackend = __esm({
274263
274794
  yield {
274264
274795
  type: "tool_call_delta",
274265
274796
  toolCallIndex: i2,
274266
- toolCallId: tc.id || `call_${randomBytes15(8).toString("hex")}`,
274797
+ toolCallId: tc.id || `call_${randomBytes16(8).toString("hex")}`,
274267
274798
  toolCallName: fn.name,
274268
274799
  toolCallArgs: JSON.stringify(args)
274269
274800
  };
@@ -279367,7 +279898,7 @@ var require_websocket3 = __commonJS({
279367
279898
  var http6 = __require("http");
279368
279899
  var net5 = __require("net");
279369
279900
  var tls2 = __require("tls");
279370
- var { randomBytes: randomBytes22, createHash: createHash9 } = __require("crypto");
279901
+ var { randomBytes: randomBytes23, createHash: createHash10 } = __require("crypto");
279371
279902
  var { Duplex: Duplex3, Readable } = __require("stream");
279372
279903
  var { URL: URL3 } = __require("url");
279373
279904
  var PerMessageDeflate2 = require_permessage_deflate3();
@@ -279897,7 +280428,7 @@ var require_websocket3 = __commonJS({
279897
280428
  }
279898
280429
  }
279899
280430
  const defaultPort = isSecure ? 443 : 80;
279900
- const key = randomBytes22(16).toString("base64");
280431
+ const key = randomBytes23(16).toString("base64");
279901
280432
  const request = isSecure ? https4.request : http6.request;
279902
280433
  const protocolSet = /* @__PURE__ */ new Set();
279903
280434
  let perMessageDeflate;
@@ -280027,7 +280558,7 @@ var require_websocket3 = __commonJS({
280027
280558
  abortHandshake(websocket, socket, "Invalid Upgrade header");
280028
280559
  return;
280029
280560
  }
280030
- const digest3 = createHash9("sha1").update(key + GUID).digest("base64");
280561
+ const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
280031
280562
  if (res.headers["sec-websocket-accept"] !== digest3) {
280032
280563
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
280033
280564
  return;
@@ -280394,7 +280925,7 @@ var require_websocket_server2 = __commonJS({
280394
280925
  var EventEmitter10 = __require("events");
280395
280926
  var http6 = __require("http");
280396
280927
  var { Duplex: Duplex3 } = __require("stream");
280397
- var { createHash: createHash9 } = __require("crypto");
280928
+ var { createHash: createHash10 } = __require("crypto");
280398
280929
  var extension2 = require_extension3();
280399
280930
  var PerMessageDeflate2 = require_permessage_deflate3();
280400
280931
  var subprotocol2 = require_subprotocol2();
@@ -280695,7 +281226,7 @@ var require_websocket_server2 = __commonJS({
280695
281226
  );
280696
281227
  }
280697
281228
  if (this._state > RUNNING) return abortHandshake(socket, 503);
280698
- const digest3 = createHash9("sha1").update(key + GUID).digest("base64");
281229
+ const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
280699
281230
  const headers = [
280700
281231
  "HTTP/1.1 101 Switching Protocols",
280701
281232
  "Upgrade: websocket",
@@ -283209,7 +283740,7 @@ var init_voice_session = __esm({
283209
283740
  import { createServer as createServer4, request as httpRequest } from "node:http";
283210
283741
  import { spawn as spawn20, exec as exec2 } from "node:child_process";
283211
283742
  import { EventEmitter as EventEmitter5 } from "node:events";
283212
- import { randomBytes as randomBytes16 } from "node:crypto";
283743
+ import { randomBytes as randomBytes17 } from "node:crypto";
283213
283744
  import { URL as URL2 } from "node:url";
283214
283745
  import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
283215
283746
  import { existsSync as existsSync53, readFileSync as readFileSync39, writeFileSync as writeFileSync26, unlinkSync as unlinkSync13, mkdirSync as mkdirSync29, readdirSync as readdirSync13, statSync as statSync15 } from "node:fs";
@@ -283409,7 +283940,7 @@ var init_expose = __esm({
283409
283940
  this._stateDir = options2.stateDir ?? null;
283410
283941
  this._fullAccess = options2.fullAccess ?? false;
283411
283942
  if (options2.authKey === void 0 || options2.authKey === "") {
283412
- this._authKey = randomBytes16(24).toString("base64url");
283943
+ this._authKey = randomBytes17(24).toString("base64url");
283413
283944
  } else {
283414
283945
  this._authKey = options2.authKey;
283415
283946
  }
@@ -284321,7 +284852,7 @@ ${this.formatConnectionInfo()}`);
284321
284852
  this._onInfo = options2.onInfo;
284322
284853
  this._onError = options2.onError;
284323
284854
  if (options2.authKey === void 0 || options2.authKey === "") {
284324
- this._authKey = randomBytes16(24).toString("base64url");
284855
+ this._authKey = randomBytes17(24).toString("base64url");
284325
284856
  } else {
284326
284857
  this._authKey = options2.authKey;
284327
284858
  }
@@ -284764,7 +285295,7 @@ var init_types = __esm({
284764
285295
  });
284765
285296
 
284766
285297
  // packages/cli/src/tui/p2p/secret-vault.ts
284767
- import { createCipheriv as createCipheriv2, createDecipheriv as createDecipheriv2, randomBytes as randomBytes17, scryptSync as scryptSync2, createHash as createHash4 } from "node:crypto";
285298
+ import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync2, createHash as createHash5 } from "node:crypto";
284768
285299
  import { readFileSync as readFileSync40, writeFileSync as writeFileSync27, existsSync as existsSync54, mkdirSync as mkdirSync30 } from "node:fs";
284769
285300
  import { dirname as dirname18 } from "node:path";
284770
285301
  var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
@@ -284965,10 +285496,10 @@ var init_secret_vault = __esm({
284965
285496
  createdAt: s2.createdAt
284966
285497
  }))
284967
285498
  );
284968
- const salt = randomBytes17(SALT_LEN);
285499
+ const salt = randomBytes18(SALT_LEN);
284969
285500
  const key = scryptSync2(passphrase, salt, KEY_LEN);
284970
- const iv = randomBytes17(IV_LEN);
284971
- const cipher = createCipheriv2(CIPHER_ALGO, key, iv);
285501
+ const iv = randomBytes18(IV_LEN);
285502
+ const cipher = createCipheriv3(CIPHER_ALGO, key, iv);
284972
285503
  const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
284973
285504
  const tag = cipher.getAuthTag();
284974
285505
  const blob = Buffer.concat([salt, iv, tag, encrypted]);
@@ -284991,7 +285522,7 @@ var init_secret_vault = __esm({
284991
285522
  const tag = blob.subarray(SALT_LEN + IV_LEN, SALT_LEN + IV_LEN + 16);
284992
285523
  const encrypted = blob.subarray(SALT_LEN + IV_LEN + 16);
284993
285524
  const key = scryptSync2(passphrase, salt, KEY_LEN);
284994
- const decipher = createDecipheriv2(CIPHER_ALGO, key, iv);
285525
+ const decipher = createDecipheriv3(CIPHER_ALGO, key, iv);
284995
285526
  decipher.setAuthTag(tag);
284996
285527
  let data;
284997
285528
  try {
@@ -285008,7 +285539,7 @@ var init_secret_vault = __esm({
285008
285539
  /** Generate a deterministic fingerprint of vault contents (for sync verification) */
285009
285540
  fingerprint() {
285010
285541
  const names = Array.from(this.secrets.keys()).sort();
285011
- const hash = createHash4("sha256");
285542
+ const hash = createHash5("sha256");
285012
285543
  for (const name10 of names) {
285013
285544
  hash.update(name10 + ":");
285014
285545
  hash.update(this.secrets.get(name10).value);
@@ -285023,7 +285554,7 @@ var init_secret_vault = __esm({
285023
285554
  // packages/cli/src/tui/p2p/peer-mesh.ts
285024
285555
  import { EventEmitter as EventEmitter6 } from "node:events";
285025
285556
  import { createServer as createServer5 } from "node:http";
285026
- import { randomBytes as randomBytes18, createHash as createHash5, generateKeyPairSync } from "node:crypto";
285557
+ import { randomBytes as randomBytes19, createHash as createHash6, generateKeyPairSync } from "node:crypto";
285027
285558
  var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
285028
285559
  var init_peer_mesh = __esm({
285029
285560
  "packages/cli/src/tui/p2p/peer-mesh.ts"() {
@@ -285040,10 +285571,10 @@ var init_peer_mesh = __esm({
285040
285571
  const { publicKey: publicKey2, privateKey } = generateKeyPairSync("ed25519");
285041
285572
  this.publicKey = publicKey2.export({ type: "spki", format: "der" });
285042
285573
  this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
285043
- this.peerId = createHash5("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
285574
+ this.peerId = createHash6("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
285044
285575
  this.capabilities = options2.capabilities;
285045
285576
  this.displayName = options2.displayName;
285046
- this._authKey = options2.authKey ?? randomBytes18(24).toString("base64url");
285577
+ this._authKey = options2.authKey ?? randomBytes19(24).toString("base64url");
285047
285578
  }
285048
285579
  /** This node's unique peer ID (hash of public key) */
285049
285580
  peerId;
@@ -285236,7 +285767,7 @@ var init_peer_mesh = __esm({
285236
285767
  if (!ws || ws.readyState !== import_websocket5.default.OPEN) {
285237
285768
  throw new Error(`Peer ${peerId} not connected`);
285238
285769
  }
285239
- const msgId = randomBytes18(8).toString("hex");
285770
+ const msgId = randomBytes19(8).toString("hex");
285240
285771
  return new Promise((resolve39, reject) => {
285241
285772
  const timeout2 = setTimeout(() => {
285242
285773
  this.pendingRequests.delete(msgId);
@@ -285452,7 +285983,7 @@ var init_peer_mesh = __esm({
285452
285983
  const msg = {
285453
285984
  type,
285454
285985
  from: this.peerId,
285455
- msgId: msgId ?? randomBytes18(8).toString("hex"),
285986
+ msgId: msgId ?? randomBytes19(8).toString("hex"),
285456
285987
  ts: (/* @__PURE__ */ new Date()).toISOString(),
285457
285988
  payload
285458
285989
  };
@@ -314607,7 +315138,7 @@ var init_disk_task_output = __esm({
314607
315138
  });
314608
315139
 
314609
315140
  // packages/cli/src/api/http.ts
314610
- import { createHash as createHash6 } from "node:crypto";
315141
+ import { createHash as createHash7 } from "node:crypto";
314611
315142
  function problemDetails(opts) {
314612
315143
  const p2 = {
314613
315144
  type: opts.type ?? "about:blank",
@@ -314670,7 +315201,7 @@ function paginated(items, page2, total) {
314670
315201
  }
314671
315202
  function computeEtag(payload) {
314672
315203
  const json = typeof payload === "string" ? payload : JSON.stringify(payload);
314673
- const hash = createHash6("sha1").update(json).digest("hex").slice(0, 16);
315204
+ const hash = createHash7("sha1").update(json).digest("hex").slice(0, 16);
314674
315205
  return `W/"${hash}"`;
314675
315206
  }
314676
315207
  function checkNotModified(req2, res, etag) {
@@ -317237,11 +317768,11 @@ async function handleAimsIncidentPost(ctx3) {
317237
317768
  }));
317238
317769
  return true;
317239
317770
  }
317240
- const { randomBytes: randomBytes22 } = await import("node:crypto");
317771
+ const { randomBytes: randomBytes23 } = await import("node:crypto");
317241
317772
  const record = await withAimsLock("incidents.json", () => {
317242
317773
  const existing = readAimsFile("incidents.json", []);
317243
317774
  const rec = {
317244
- id: `INC-${Date.now()}-${randomBytes22(4).toString("hex")}`,
317775
+ id: `INC-${Date.now()}-${randomBytes23(4).toString("hex")}`,
317245
317776
  ts: (/* @__PURE__ */ new Date()).toISOString(),
317246
317777
  raised_by: user ?? "anonymous",
317247
317778
  status: "open",
@@ -321419,7 +321950,7 @@ var init_usage_tracker = __esm({
321419
321950
  import { existsSync as existsSync80, readFileSync as readFileSync63, writeFileSync as writeFileSync41, mkdirSync as mkdirSync48, readdirSync as readdirSync27, unlinkSync as unlinkSync21 } from "node:fs";
321420
321951
  import { join as join96 } from "node:path";
321421
321952
  import { homedir as homedir34 } from "node:os";
321422
- import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes19, scryptSync as scryptSync3 } from "node:crypto";
321953
+ import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes20, scryptSync as scryptSync3 } from "node:crypto";
321423
321954
  function globalProfileDir() {
321424
321955
  return join96(homedir34(), ".open-agents", "profiles");
321425
321956
  }
@@ -321503,10 +322034,10 @@ function deleteProfile(name10, scope = "global", projectDir) {
321503
322034
  return false;
321504
322035
  }
321505
322036
  function encryptProfile(profile, password) {
321506
- const salt = randomBytes19(32);
322037
+ const salt = randomBytes20(32);
321507
322038
  const key = scryptSync3(password, salt, 32);
321508
- const iv = randomBytes19(16);
321509
- const cipher = createCipheriv3("aes-256-gcm", key, iv);
322039
+ const iv = randomBytes20(16);
322040
+ const cipher = createCipheriv4("aes-256-gcm", key, iv);
321510
322041
  const plaintext = JSON.stringify(profile);
321511
322042
  const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
321512
322043
  const tag = cipher.getAuthTag();
@@ -321525,7 +322056,7 @@ function decryptProfile(enc, password) {
321525
322056
  const salt = Buffer.from(enc.salt, "hex");
321526
322057
  const key = scryptSync3(password, salt, 32);
321527
322058
  const iv = Buffer.from(enc.iv, "hex");
321528
- const decipher = createDecipheriv3("aes-256-gcm", key, iv);
322059
+ const decipher = createDecipheriv4("aes-256-gcm", key, iv);
321529
322060
  decipher.setAuthTag(Buffer.from(enc.tag, "hex"));
321530
322061
  const decrypted = Buffer.concat([
321531
322062
  decipher.update(Buffer.from(enc.data, "hex")),
@@ -321918,7 +322449,7 @@ import { dirname as dirname28, join as join98, resolve as resolve34 } from "node
321918
322449
  import { homedir as homedir36 } from "node:os";
321919
322450
  import { spawn as spawn25, execSync as execSync55 } from "node:child_process";
321920
322451
  import { mkdirSync as mkdirSync50, readFileSync as readFileSync64, readdirSync as readdirSync28, existsSync as existsSync82, watch as fsWatch3 } from "node:fs";
321921
- import { randomBytes as randomBytes20, randomUUID as randomUUID11 } from "node:crypto";
322452
+ import { randomBytes as randomBytes21, randomUUID as randomUUID11 } from "node:crypto";
321922
322453
  function getVersion3() {
321923
322454
  try {
321924
322455
  const require3 = createRequire4(import.meta.url);
@@ -322781,7 +323312,7 @@ async function handleV1ChatCompletions(req2, res, ollamaUrl) {
322781
323312
  "Cache-Control": "no-cache",
322782
323313
  "Connection": "keep-alive"
322783
323314
  });
322784
- const chatId = `chatcmpl-${randomBytes20(12).toString("hex")}`;
323315
+ const chatId = `chatcmpl-${randomBytes21(12).toString("hex")}`;
322785
323316
  let buffer2 = "";
322786
323317
  ollamaStream(
322787
323318
  targetUrl,
@@ -322891,7 +323422,7 @@ async function handleV1ChatCompletions(req2, res, ollamaUrl) {
322891
323422
  if (ollamaResp.eval_count) metrics.totalTokensOut += ollamaResp.eval_count;
322892
323423
  if (ollamaResp.prompt_eval_count) metrics.totalTokensIn += ollamaResp.prompt_eval_count;
322893
323424
  trackTokens("local", ollamaResp.prompt_eval_count ?? 0, ollamaResp.eval_count ?? 0);
322894
- const chatId = `chatcmpl-${randomBytes20(12).toString("hex")}`;
323425
+ const chatId = `chatcmpl-${randomBytes21(12).toString("hex")}`;
322895
323426
  const responseMessage = {
322896
323427
  role: ollamaResp.message?.role ?? "assistant",
322897
323428
  content: ollamaResp.message?.content ?? ""
@@ -323623,7 +324154,7 @@ async function handleV1Run(req2, res) {
323623
324154
  return;
323624
324155
  }
323625
324156
  }
323626
- const id = `job-${randomBytes20(8).toString("hex")}`;
324157
+ const id = `job-${randomBytes21(8).toString("hex")}`;
323627
324158
  const dir = jobsDir();
323628
324159
  const workingDir = requestBody["working_directory"] || req2.headers["x-working-directory"];
323629
324160
  const isolate = requestBody["isolate"] === true;
@@ -330810,13 +331341,13 @@ ${fullInput}`;
330810
331341
  writeContent(() => renderError(errMsg));
330811
331342
  if (failureStore) {
330812
331343
  try {
330813
- const { createHash: createHash9 } = await import("node:crypto");
331344
+ const { createHash: createHash10 } = await import("node:crypto");
330814
331345
  failureStore.insert({
330815
331346
  taskId: "",
330816
331347
  sessionId: `${Date.now()}`,
330817
331348
  repoRoot,
330818
331349
  failureType: "runtime-error",
330819
- fingerprint: createHash9("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
331350
+ fingerprint: createHash10("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
330820
331351
  filePath: null,
330821
331352
  errorMessage: errMsg.slice(0, 500),
330822
331353
  context: null,
@@ -331444,7 +331975,7 @@ __export(run_exports, {
331444
331975
  import { resolve as resolve36 } from "node:path";
331445
331976
  import { spawn as spawn26 } from "node:child_process";
331446
331977
  import { mkdirSync as mkdirSync52, writeFileSync as writeFileSync45, readFileSync as readFileSync66, readdirSync as readdirSync30, existsSync as existsSync84 } from "node:fs";
331447
- import { randomBytes as randomBytes21 } from "node:crypto";
331978
+ import { randomBytes as randomBytes22 } from "node:crypto";
331448
331979
  import { join as join100 } from "node:path";
331449
331980
  function jobsDir2(repoPath) {
331450
331981
  const root = resolve36(repoPath ?? process.cwd());
@@ -331539,7 +332070,7 @@ function extractSummary(captured) {
331539
332070
  return lines.slice(-3).join(" ").slice(0, 200);
331540
332071
  }
331541
332072
  async function runBackground(task, config, opts) {
331542
- const id = `job-${randomBytes21(3).toString("hex")}`;
332073
+ const id = `job-${randomBytes22(3).toString("hex")}`;
331543
332074
  const dir = jobsDir2(opts.repoPath);
331544
332075
  const repoRoot = resolve36(opts.repoPath ?? process.cwd());
331545
332076
  const job = {
@@ -331648,7 +332179,7 @@ var init_run = __esm({
331648
332179
  import { glob as glob2 } from "glob";
331649
332180
  import ignore from "ignore";
331650
332181
  import { readFile as readFile23, stat as stat5 } from "node:fs/promises";
331651
- import { createHash as createHash8 } from "node:crypto";
332182
+ import { createHash as createHash9 } from "node:crypto";
331652
332183
  import { join as join101, relative as relative5, extname as extname12, basename as basename18 } from "node:path";
331653
332184
  var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
331654
332185
  var init_codebase_indexer = __esm({
@@ -331714,7 +332245,7 @@ var init_codebase_indexer = __esm({
331714
332245
  if (fileStat.size > this.config.maxFileSize)
331715
332246
  continue;
331716
332247
  const content = await readFile23(fullPath);
331717
- const hash = createHash8("sha256").update(content).digest("hex");
332248
+ const hash = createHash9("sha256").update(content).digest("hex");
331718
332249
  const ext = extname12(relativePath);
331719
332250
  indexed.push({
331720
332251
  path: fullPath,