open-agents-ai 0.187.227 → 0.187.229
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +699 -119
- 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
|
|
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,140 @@ 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
|
+
// DAEMON_SCRIPT is an outer template literal — any escape sequence
|
|
5871
|
+
// in code we want to appear literally in the generated file must
|
|
5872
|
+
// be double-escaped so the outer template doesn't consume it.
|
|
5873
|
+
var lines = _whisperPending.split('\\n');
|
|
5874
|
+
_whisperPending = lines.pop() || '';
|
|
5875
|
+
for (var li = 0; li < lines.length; li++) {
|
|
5876
|
+
var ln = lines[li].trim();
|
|
5877
|
+
if (!ln) continue;
|
|
5878
|
+
try {
|
|
5879
|
+
var msg = JSON.parse(ln);
|
|
5880
|
+
if (msg && msg.type === 'transcript' && msg.text) {
|
|
5881
|
+
// Write each transcript to every actively-listened room's inbox
|
|
5882
|
+
for (var roomId of _voiceListenRooms) {
|
|
5883
|
+
try {
|
|
5884
|
+
var roomInbox = pathMod.join(inboxDir, roomId, 'voice');
|
|
5885
|
+
fsMod.mkdirSync(roomInbox, { recursive: true });
|
|
5886
|
+
var fname = 'transcript-' + Date.now() + '-' + Math.random().toString(36).slice(2, 8) + '.json';
|
|
5887
|
+
fsMod.writeFileSync(pathMod.join(roomInbox, fname), JSON.stringify({
|
|
5888
|
+
type: 'voice.transcript',
|
|
5889
|
+
roomId: roomId,
|
|
5890
|
+
text: String(msg.text || '').trim(),
|
|
5891
|
+
isFinal: !!msg.isFinal,
|
|
5892
|
+
timestamp: Date.now(),
|
|
5893
|
+
}, null, 2));
|
|
5894
|
+
} catch (we) {
|
|
5895
|
+
dlog('voice: transcript write failed: ' + (we.message || we));
|
|
5896
|
+
}
|
|
5897
|
+
}
|
|
5898
|
+
}
|
|
5899
|
+
} catch { /* non-JSON whisper output — ignore */ }
|
|
5900
|
+
}
|
|
5901
|
+
});
|
|
5902
|
+
_whisperProc.stderr.on('data', function(chunk) {
|
|
5903
|
+
dlog('whisper stderr: ' + chunk.toString('utf8').slice(0, 200));
|
|
5904
|
+
});
|
|
5905
|
+
_whisperProc.on('exit', function(code) {
|
|
5906
|
+
dlog('whisper exited code=' + code);
|
|
5907
|
+
_whisperProc = null;
|
|
5908
|
+
});
|
|
5909
|
+
dlog('voice: whisper child spawned (pid=' + _whisperProc.pid + ')');
|
|
5910
|
+
return true;
|
|
5911
|
+
} catch (err) {
|
|
5912
|
+
dlog('voice: whisper spawn failed: ' + (err.message || err));
|
|
5913
|
+
_whisperProc = null;
|
|
5914
|
+
return false;
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
// Feed a PCM16 byte buffer into the whisper stdin. No-op if whisper isn't running.
|
|
5918
|
+
function _voiceFeedWhisper(buf) {
|
|
5919
|
+
if (!_whisperProc || !_whisperProc.stdin || _whisperProc.killed) return;
|
|
5920
|
+
try { _whisperProc.stdin.write(buf); } catch (err) {
|
|
5921
|
+
dlog('voice: whisper stdin write failed: ' + (err.message || err));
|
|
5922
|
+
}
|
|
5923
|
+
}
|
|
5924
|
+
// Write a compact "voice activity" event to the room inbox so the agent
|
|
5925
|
+
// sees who just spoke even when whisper isn't transcribing (no mic drain
|
|
5926
|
+
// on the laptop doing pure listening).
|
|
5927
|
+
function _voiceEmitActivity(env) {
|
|
5928
|
+
try {
|
|
5929
|
+
var pathMod2 = require('node:path');
|
|
5930
|
+
var fsMod2 = require('node:fs');
|
|
5931
|
+
var roomInbox = pathMod2.join(inboxDir, env.roomId, 'voice');
|
|
5932
|
+
fsMod2.mkdirSync(roomInbox, { recursive: true });
|
|
5933
|
+
var fname = 'activity-' + Date.now() + '-' + Math.random().toString(36).slice(2, 6) + '.json';
|
|
5934
|
+
fsMod2.writeFileSync(pathMod2.join(roomInbox, fname), JSON.stringify({
|
|
5935
|
+
type: 'voice.activity',
|
|
5936
|
+
roomId: env.roomId,
|
|
5937
|
+
peerId: env.peerId || '',
|
|
5938
|
+
agentName: env.agentName || '',
|
|
5939
|
+
seq: env.seq || 0,
|
|
5940
|
+
timestamp: env.timestamp || Date.now(),
|
|
5941
|
+
}, null, 2));
|
|
5942
|
+
} catch {}
|
|
5943
|
+
}
|
|
5944
|
+
|
|
5697
5945
|
function writeStatus(extra = {}) {
|
|
5698
5946
|
const caps = typeof nexus.getRegisteredCapabilities === 'function'
|
|
5699
5947
|
? nexus.getRegisteredCapabilities() : [];
|
|
@@ -5828,6 +6076,85 @@ async function handleCmd(cmd) {
|
|
|
5828
6076
|
writeResp(id, { ok: true, output: 'Message sent (id: ' + msgId + ')' });
|
|
5829
6077
|
break;
|
|
5830
6078
|
}
|
|
6079
|
+
// ── Voice: publish a PCM frame to a room ──
|
|
6080
|
+
// args: { room_id, pcm_base64, sample_rate?, encoding?, channels? }
|
|
6081
|
+
// Relays to nexus.rooms.audio with the same envelope the nexus
|
|
6082
|
+
// frontend decodes. Agents can call this with raw PCM bytes from
|
|
6083
|
+
// any source (TTS, mic, jibberlink modem output).
|
|
6084
|
+
case 'voice_publish': {
|
|
6085
|
+
if (!_natsConn || !_natsCodec) {
|
|
6086
|
+
writeResp(id, { ok: false, output: 'NATS not connected' });
|
|
6087
|
+
return;
|
|
6088
|
+
}
|
|
6089
|
+
if (!args || !args.room_id || !args.pcm_base64) {
|
|
6090
|
+
writeResp(id, { ok: false, output: 'voice_publish requires room_id + pcm_base64' });
|
|
6091
|
+
return;
|
|
6092
|
+
}
|
|
6093
|
+
if (!rooms.has(args.room_id)) {
|
|
6094
|
+
writeResp(id, { ok: false, output: 'Not in room: ' + args.room_id + '. Join first.' });
|
|
6095
|
+
return;
|
|
6096
|
+
}
|
|
6097
|
+
try {
|
|
6098
|
+
var vpEnv = {
|
|
6099
|
+
type: 'voice',
|
|
6100
|
+
roomId: args.room_id,
|
|
6101
|
+
peerId: nexus.peerId || '',
|
|
6102
|
+
agentName: agentName,
|
|
6103
|
+
sampleRate: parseInt(args.sample_rate, 10) || 16000,
|
|
6104
|
+
encoding: args.encoding || 'pcm16',
|
|
6105
|
+
channels: parseInt(args.channels, 10) || 1,
|
|
6106
|
+
seq: _voiceSeq++,
|
|
6107
|
+
timestamp: Date.now(),
|
|
6108
|
+
data: String(args.pcm_base64),
|
|
6109
|
+
};
|
|
6110
|
+
_natsConn.publish(VOICE_SUBJECT, _natsCodec.encode(JSON.stringify(vpEnv)));
|
|
6111
|
+
writeResp(id, { ok: true, output: 'Voice frame published to ' + args.room_id + ' (' + Math.round(args.pcm_base64.length * 0.75) + ' bytes)' });
|
|
6112
|
+
} catch (vpErr) {
|
|
6113
|
+
writeResp(id, { ok: false, output: 'voice_publish error: ' + (vpErr.message || vpErr) });
|
|
6114
|
+
}
|
|
6115
|
+
break;
|
|
6116
|
+
}
|
|
6117
|
+
// ── Voice: start/stop ASR pipeline for a joined room ──
|
|
6118
|
+
case 'voice_listen_start': {
|
|
6119
|
+
var vlsRoom = args && args.room_id;
|
|
6120
|
+
if (!vlsRoom) { writeResp(id, { ok: false, output: 'voice_listen_start requires room_id' }); return; }
|
|
6121
|
+
if (!rooms.has(vlsRoom)) { writeResp(id, { ok: false, output: 'Not in room: ' + vlsRoom }); return; }
|
|
6122
|
+
_voiceListenRooms.add(vlsRoom);
|
|
6123
|
+
var ok = _voiceEnsureWhisper();
|
|
6124
|
+
if (!ok) {
|
|
6125
|
+
_voiceListenRooms.delete(vlsRoom);
|
|
6126
|
+
writeResp(id, { ok: false, output: 'Failed to start whisper — check Python + live-whisper.py path' });
|
|
6127
|
+
return;
|
|
6128
|
+
}
|
|
6129
|
+
writeResp(id, { ok: true, output: 'Voice listen started for ' + vlsRoom + '. Transcripts will appear in inbox/' + vlsRoom + '/voice/' });
|
|
6130
|
+
break;
|
|
6131
|
+
}
|
|
6132
|
+
case 'voice_listen_stop': {
|
|
6133
|
+
var vlsRoom2 = args && args.room_id;
|
|
6134
|
+
if (vlsRoom2) {
|
|
6135
|
+
_voiceListenRooms.delete(vlsRoom2);
|
|
6136
|
+
writeResp(id, { ok: true, output: 'Voice listen stopped for ' + vlsRoom2 });
|
|
6137
|
+
} else {
|
|
6138
|
+
_voiceListenRooms.clear();
|
|
6139
|
+
writeResp(id, { ok: true, output: 'Voice listen stopped for all rooms' });
|
|
6140
|
+
}
|
|
6141
|
+
if (_voiceListenRooms.size === 0 && _whisperProc) {
|
|
6142
|
+
try { _whisperProc.stdin.end(); } catch {}
|
|
6143
|
+
try { _whisperProc.kill(); } catch {}
|
|
6144
|
+
_whisperProc = null;
|
|
6145
|
+
}
|
|
6146
|
+
break;
|
|
6147
|
+
}
|
|
6148
|
+
// ── Voice: status of voice subsystem ──
|
|
6149
|
+
case 'voice_status': {
|
|
6150
|
+
writeResp(id, { ok: true, output: JSON.stringify({
|
|
6151
|
+
subscribed: !!_voiceSub,
|
|
6152
|
+
whisperRunning: !!_whisperProc,
|
|
6153
|
+
listeningRooms: Array.from(_voiceListenRooms),
|
|
6154
|
+
lastActivityMsAgo: _voiceLastActivityMs ? (Date.now() - _voiceLastActivityMs) : null,
|
|
6155
|
+
}, null, 2) });
|
|
6156
|
+
break;
|
|
6157
|
+
}
|
|
5831
6158
|
// ── Sponsor announcement via NATS ──
|
|
5832
6159
|
case 'sponsor_announce': {
|
|
5833
6160
|
// Publish sponsor metadata to NATS so other OA instances can discover it
|
|
@@ -8058,6 +8385,58 @@ process.on('unhandledRejection', (reason) => {
|
|
|
8058
8385
|
var _natsInvSub = _nc.subscribe(_natsInvSubject);
|
|
8059
8386
|
dlog('NATS invoke relay listening on ' + _natsInvSubject);
|
|
8060
8387
|
|
|
8388
|
+
// ── Voice subscription: nexus.rooms.audio ─────────────────
|
|
8389
|
+
// Filters incoming voice envelopes by the rooms this daemon
|
|
8390
|
+
// has joined. Auto-emits voice.activity events to the room
|
|
8391
|
+
// inbox; if voice_listen_start has been called for that
|
|
8392
|
+
// room, PCM bytes are piped into the whisper child process
|
|
8393
|
+
// for auto-transcription.
|
|
8394
|
+
try {
|
|
8395
|
+
_voiceSub = _nc.subscribe(VOICE_SUBJECT);
|
|
8396
|
+
dlog('NATS voice subscription active on ' + VOICE_SUBJECT);
|
|
8397
|
+
(async function _voiceLoop() {
|
|
8398
|
+
for await (var _vm of _voiceSub) {
|
|
8399
|
+
try {
|
|
8400
|
+
var env = JSON.parse(_natsCodec.decode(_vm.data));
|
|
8401
|
+
if (!env || env.type !== 'voice' || !env.roomId) continue;
|
|
8402
|
+
// Only process audio for rooms this agent has joined —
|
|
8403
|
+
// ignores everyone else's chatter and keeps CPU down.
|
|
8404
|
+
if (!rooms.has(env.roomId)) continue;
|
|
8405
|
+
// Skip our own echo
|
|
8406
|
+
if (env.peerId && env.peerId === nexus.peerId) continue;
|
|
8407
|
+
_voiceLastActivityMs = Date.now();
|
|
8408
|
+
_voiceEmitActivity(env);
|
|
8409
|
+
// If whisper is active for this room, decode and pipe
|
|
8410
|
+
if (_voiceListenRooms.has(env.roomId) && _whisperProc && env.data) {
|
|
8411
|
+
var buf;
|
|
8412
|
+
if (env.encoding === 'float32') {
|
|
8413
|
+
// Float32 → PCM16 conversion so whisper gets a
|
|
8414
|
+
// consistent input format
|
|
8415
|
+
var raw = _voiceB64ToBuf(env.data);
|
|
8416
|
+
var f32 = new Float32Array(raw.buffer, raw.byteOffset, raw.byteLength / 4);
|
|
8417
|
+
buf = _voiceF32ToPcm16(f32);
|
|
8418
|
+
} else if (env.encoding === 'jibberlink') {
|
|
8419
|
+
// Jibberlink frames are encrypted data-over-audio
|
|
8420
|
+
// (see lib-jibberlink.ts). Skip whisper feeding —
|
|
8421
|
+
// those get demodulated + decrypted separately.
|
|
8422
|
+
continue;
|
|
8423
|
+
} else {
|
|
8424
|
+
// Default pcm16 — pass straight through
|
|
8425
|
+
buf = _voiceB64ToBuf(env.data);
|
|
8426
|
+
}
|
|
8427
|
+
_voiceFeedWhisper(buf);
|
|
8428
|
+
}
|
|
8429
|
+
} catch (vErr) {
|
|
8430
|
+
dlog('voice loop parse error: ' + (vErr.message || vErr));
|
|
8431
|
+
}
|
|
8432
|
+
}
|
|
8433
|
+
})().catch(function(loopErr) {
|
|
8434
|
+
dlog('voice loop fatal: ' + (loopErr.message || loopErr));
|
|
8435
|
+
});
|
|
8436
|
+
} catch (vsErr) {
|
|
8437
|
+
dlog('voice subscribe failed: ' + (vsErr.message || vsErr));
|
|
8438
|
+
}
|
|
8439
|
+
|
|
8061
8440
|
(async function _natsInvokeLoop() {
|
|
8062
8441
|
for await (var _nm of _natsInvSub) {
|
|
8063
8442
|
try {
|
|
@@ -10093,6 +10472,32 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
10093
10472
|
confidence: String(args.confidence ?? "0.7")
|
|
10094
10473
|
});
|
|
10095
10474
|
break;
|
|
10475
|
+
// ── Voice subsystem (nexus.rooms.audio transport) ──────────
|
|
10476
|
+
case "voice_publish":
|
|
10477
|
+
result = await this.sendDaemonCmd("voice_publish", {
|
|
10478
|
+
room_id: String(args.room_id ?? ""),
|
|
10479
|
+
pcm_base64: String(args.pcm_base64 ?? args.data ?? ""),
|
|
10480
|
+
sample_rate: String(args.sample_rate ?? "16000"),
|
|
10481
|
+
encoding: String(args.encoding ?? "pcm16"),
|
|
10482
|
+
channels: String(args.channels ?? "1")
|
|
10483
|
+
}, 1e4);
|
|
10484
|
+
break;
|
|
10485
|
+
case "voice_speak":
|
|
10486
|
+
result = await this.doVoiceSpeak(args);
|
|
10487
|
+
break;
|
|
10488
|
+
case "voice_listen_start":
|
|
10489
|
+
result = await this.sendDaemonCmd("voice_listen_start", { room_id: String(args.room_id ?? "") });
|
|
10490
|
+
break;
|
|
10491
|
+
case "voice_listen_stop":
|
|
10492
|
+
result = await this.sendDaemonCmd("voice_listen_stop", { room_id: String(args.room_id ?? "") });
|
|
10493
|
+
break;
|
|
10494
|
+
case "voice_status":
|
|
10495
|
+
result = await this.sendDaemonCmd("voice_status", {});
|
|
10496
|
+
break;
|
|
10497
|
+
// ── Jibberlink: encrypted data-over-audio between agents ───
|
|
10498
|
+
case "jibberlink_send":
|
|
10499
|
+
result = await this.doJibberlinkSend(args);
|
|
10500
|
+
break;
|
|
10096
10501
|
default:
|
|
10097
10502
|
return { success: false, output: "", error: `Unknown nexus action: ${action}`, durationMs: Date.now() - start2 };
|
|
10098
10503
|
}
|
|
@@ -10131,7 +10536,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
10131
10536
|
if (!pid)
|
|
10132
10537
|
throw new Error("Nexus daemon not running. Use action 'connect' first.");
|
|
10133
10538
|
}
|
|
10134
|
-
const cmdId =
|
|
10539
|
+
const cmdId = randomBytes5(8).toString("hex");
|
|
10135
10540
|
const cmdFile = join14(this.nexusDir, "cmd.json");
|
|
10136
10541
|
const respFile = join14(this.nexusDir, "resp.json");
|
|
10137
10542
|
if (existsSync11(respFile))
|
|
@@ -10242,7 +10647,7 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
10242
10647
|
// =========================================================================
|
|
10243
10648
|
async doConnect(args) {
|
|
10244
10649
|
await this.ensureDir();
|
|
10245
|
-
const currentScriptHash =
|
|
10650
|
+
const currentScriptHash = createHash2("sha256").update(DAEMON_SCRIPT).digest("hex").slice(0, 16);
|
|
10246
10651
|
const existingPid = this.getDaemonPid();
|
|
10247
10652
|
if (existingPid) {
|
|
10248
10653
|
let processAlive = false;
|
|
@@ -10614,6 +11019,134 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
10614
11019
|
}
|
|
10615
11020
|
return this.sendDaemonCmd("send_message", args);
|
|
10616
11021
|
}
|
|
11022
|
+
/**
|
|
11023
|
+
* Synthesize `text` to WAV via the system TTS (piper/espeak/ffmpeg
|
|
11024
|
+
* sox fallback), decode to raw 16kHz mono PCM16, chunk into 20ms
|
|
11025
|
+
* frames, and publish each frame to nexus.rooms.audio so other
|
|
11026
|
+
* agents + the nexus frontend visitors hear the agent speak.
|
|
11027
|
+
*
|
|
11028
|
+
* This is the symmetry with the existing audio_playback.speak tool,
|
|
11029
|
+
* but routes audio over the nexus voice subject instead of the
|
|
11030
|
+
* local speakers.
|
|
11031
|
+
*/
|
|
11032
|
+
async doVoiceSpeak(args) {
|
|
11033
|
+
const text = String(args.text ?? "");
|
|
11034
|
+
const roomId = String(args.room_id ?? "");
|
|
11035
|
+
if (!text)
|
|
11036
|
+
throw new Error("text is required");
|
|
11037
|
+
if (!roomId)
|
|
11038
|
+
throw new Error("room_id is required");
|
|
11039
|
+
if (containsKeyMaterial(text)) {
|
|
11040
|
+
return "BLOCKED: Text contains potential key material.";
|
|
11041
|
+
}
|
|
11042
|
+
const tmpWav = join14(this.nexusDir, `voice-${Date.now()}.wav`);
|
|
11043
|
+
try {
|
|
11044
|
+
const cp2 = await import("node:child_process");
|
|
11045
|
+
const fsMod = await import("node:fs");
|
|
11046
|
+
const path5 = await import("node:path");
|
|
11047
|
+
let synthesized = false;
|
|
11048
|
+
try {
|
|
11049
|
+
cp2.execSync(`echo ${JSON.stringify(text)} | piper --model en_US-lessac-medium --output_file ${JSON.stringify(tmpWav)}`, {
|
|
11050
|
+
stdio: "pipe",
|
|
11051
|
+
timeout: 3e4
|
|
11052
|
+
});
|
|
11053
|
+
synthesized = fsMod.existsSync(tmpWav);
|
|
11054
|
+
} catch {
|
|
11055
|
+
}
|
|
11056
|
+
if (!synthesized) {
|
|
11057
|
+
try {
|
|
11058
|
+
cp2.execSync(`espeak ${JSON.stringify(text)} -w ${JSON.stringify(tmpWav)} -s 160`, {
|
|
11059
|
+
stdio: "pipe",
|
|
11060
|
+
timeout: 15e3
|
|
11061
|
+
});
|
|
11062
|
+
synthesized = fsMod.existsSync(tmpWav);
|
|
11063
|
+
} catch (err) {
|
|
11064
|
+
throw new Error(`TTS synthesis failed: ${err.message || err}`);
|
|
11065
|
+
}
|
|
11066
|
+
}
|
|
11067
|
+
const pcmPath = tmpWav.replace(/\.wav$/, ".pcm");
|
|
11068
|
+
try {
|
|
11069
|
+
cp2.execSync(`ffmpeg -y -i ${JSON.stringify(tmpWav)} -ac 1 -ar 16000 -f s16le ${JSON.stringify(pcmPath)}`, {
|
|
11070
|
+
stdio: "pipe",
|
|
11071
|
+
timeout: 15e3
|
|
11072
|
+
});
|
|
11073
|
+
} catch {
|
|
11074
|
+
const raw = fsMod.readFileSync(tmpWav);
|
|
11075
|
+
fsMod.writeFileSync(pcmPath, raw.slice(44));
|
|
11076
|
+
}
|
|
11077
|
+
const pcm = fsMod.readFileSync(pcmPath);
|
|
11078
|
+
try {
|
|
11079
|
+
fsMod.unlinkSync(tmpWav);
|
|
11080
|
+
} catch {
|
|
11081
|
+
}
|
|
11082
|
+
try {
|
|
11083
|
+
fsMod.unlinkSync(pcmPath);
|
|
11084
|
+
} catch {
|
|
11085
|
+
}
|
|
11086
|
+
const SAMPLE_RATE = 16e3;
|
|
11087
|
+
const FRAME_MS = 50;
|
|
11088
|
+
const FRAME_BYTES = Math.floor(SAMPLE_RATE * FRAME_MS / 1e3 * 2);
|
|
11089
|
+
const frameCount = Math.ceil(pcm.length / FRAME_BYTES);
|
|
11090
|
+
let published = 0;
|
|
11091
|
+
for (let i2 = 0; i2 < pcm.length; i2 += FRAME_BYTES) {
|
|
11092
|
+
const chunk = pcm.subarray(i2, Math.min(i2 + FRAME_BYTES, pcm.length));
|
|
11093
|
+
const b64 = chunk.toString("base64");
|
|
11094
|
+
await this.sendDaemonCmd("voice_publish", {
|
|
11095
|
+
room_id: roomId,
|
|
11096
|
+
pcm_base64: b64,
|
|
11097
|
+
sample_rate: String(SAMPLE_RATE),
|
|
11098
|
+
encoding: "pcm16",
|
|
11099
|
+
channels: "1"
|
|
11100
|
+
}, 5e3);
|
|
11101
|
+
published++;
|
|
11102
|
+
await new Promise((r2) => setTimeout(r2, Math.floor(FRAME_MS * 0.5)));
|
|
11103
|
+
}
|
|
11104
|
+
return `Spoke ${frameCount} frames (${(pcm.length / 1024).toFixed(1)}KB) to ${roomId}`;
|
|
11105
|
+
} catch (err) {
|
|
11106
|
+
throw new Error(`voice_speak failed: ${err.message || err}`);
|
|
11107
|
+
}
|
|
11108
|
+
}
|
|
11109
|
+
/**
|
|
11110
|
+
* Encode a byte payload under AES-GCM (per-room key), modulate it as
|
|
11111
|
+
* FSK over the jibberlink audio modem, and publish the resulting PCM
|
|
11112
|
+
* samples to the room as a voice frame with encoding='jibberlink'.
|
|
11113
|
+
*
|
|
11114
|
+
* Other agents subscribed to nexus.rooms.audio can demodulate + decrypt
|
|
11115
|
+
* it using the same roomId (shared key is derived from roomId + a
|
|
11116
|
+
* caller-supplied `secret`). Visitors in the nexus frontend simply
|
|
11117
|
+
* hear the characteristic chirp tones without decoding.
|
|
11118
|
+
*/
|
|
11119
|
+
async doJibberlinkSend(args) {
|
|
11120
|
+
const roomId = String(args.room_id ?? "");
|
|
11121
|
+
const message2 = String(args.message ?? args.data ?? "");
|
|
11122
|
+
const secret = args.secret != null ? String(args.secret) : void 0;
|
|
11123
|
+
if (!roomId)
|
|
11124
|
+
throw new Error("room_id is required");
|
|
11125
|
+
if (!message2)
|
|
11126
|
+
throw new Error("message is required");
|
|
11127
|
+
if (containsKeyMaterial(message2)) {
|
|
11128
|
+
return "BLOCKED: Message contains potential key material.";
|
|
11129
|
+
}
|
|
11130
|
+
const plaintext = Buffer.from(message2, "utf8");
|
|
11131
|
+
if (plaintext.length > 1024) {
|
|
11132
|
+
throw new Error("jibberlink payload > 1KB — split into multiple frames");
|
|
11133
|
+
}
|
|
11134
|
+
const pcmF32 = encodeEncrypted(roomId, plaintext, secret);
|
|
11135
|
+
const pcm16 = Buffer.alloc(pcmF32.length * 2);
|
|
11136
|
+
for (let i2 = 0; i2 < pcmF32.length; i2++) {
|
|
11137
|
+
let s2 = Math.max(-1, Math.min(1, pcmF32[i2]));
|
|
11138
|
+
pcm16.writeInt16LE(s2 < 0 ? s2 * 32768 : s2 * 32767, i2 * 2);
|
|
11139
|
+
}
|
|
11140
|
+
const b64 = pcm16.toString("base64");
|
|
11141
|
+
await this.sendDaemonCmd("voice_publish", {
|
|
11142
|
+
room_id: roomId,
|
|
11143
|
+
pcm_base64: b64,
|
|
11144
|
+
sample_rate: "16000",
|
|
11145
|
+
encoding: "jibberlink",
|
|
11146
|
+
channels: "1"
|
|
11147
|
+
}, 1e4);
|
|
11148
|
+
return `Jibberlink frame sent to ${roomId} (${plaintext.length}B plaintext → ${pcmF32.length} samples)`;
|
|
11149
|
+
}
|
|
10617
11150
|
async doSendDM(args) {
|
|
10618
11151
|
const message2 = args.message;
|
|
10619
11152
|
if (!message2)
|
|
@@ -10738,21 +11271,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
10738
11271
|
let privKeyHex;
|
|
10739
11272
|
try {
|
|
10740
11273
|
const { privateKeyToAccount } = await import("viem/accounts");
|
|
10741
|
-
const privKey =
|
|
11274
|
+
const privKey = randomBytes5(32);
|
|
10742
11275
|
privKeyHex = privKey.toString("hex");
|
|
10743
11276
|
const account = privateKeyToAccount(`0x${privKeyHex}`);
|
|
10744
11277
|
address = account.address;
|
|
10745
11278
|
privKey.fill(0);
|
|
10746
11279
|
} catch {
|
|
10747
|
-
const privKey =
|
|
11280
|
+
const privKey = randomBytes5(32);
|
|
10748
11281
|
privKeyHex = privKey.toString("hex");
|
|
10749
|
-
address = "0x" +
|
|
11282
|
+
address = "0x" + createHash2("sha256").update(privKey).digest("hex").slice(0, 40);
|
|
10750
11283
|
privKey.fill(0);
|
|
10751
11284
|
}
|
|
10752
|
-
const salt =
|
|
11285
|
+
const salt = randomBytes5(32);
|
|
10753
11286
|
const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
10754
|
-
const iv =
|
|
10755
|
-
const cipher =
|
|
11287
|
+
const iv = randomBytes5(16);
|
|
11288
|
+
const cipher = createCipheriv2("aes-256-gcm", key, iv);
|
|
10756
11289
|
let enc = cipher.update(privKeyHex, "utf8", "hex");
|
|
10757
11290
|
enc += cipher.final("hex");
|
|
10758
11291
|
const x402KeyPath = join14(this.nexusDir, "x402-wallet.key");
|
|
@@ -10800,21 +11333,21 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
10800
11333
|
let privKeyHex;
|
|
10801
11334
|
try {
|
|
10802
11335
|
const { privateKeyToAccount } = await import("viem/accounts");
|
|
10803
|
-
const privKey =
|
|
11336
|
+
const privKey = randomBytes5(32);
|
|
10804
11337
|
privKeyHex = privKey.toString("hex");
|
|
10805
11338
|
const account = privateKeyToAccount(`0x${privKeyHex}`);
|
|
10806
11339
|
address = account.address;
|
|
10807
11340
|
privKey.fill(0);
|
|
10808
11341
|
} catch {
|
|
10809
|
-
const privKey =
|
|
11342
|
+
const privKey = randomBytes5(32);
|
|
10810
11343
|
privKeyHex = privKey.toString("hex");
|
|
10811
|
-
address = "0x" +
|
|
11344
|
+
address = "0x" + createHash2("sha256").update(privKey).digest("hex").slice(0, 40);
|
|
10812
11345
|
privKey.fill(0);
|
|
10813
11346
|
}
|
|
10814
|
-
const salt =
|
|
11347
|
+
const salt = randomBytes5(32);
|
|
10815
11348
|
const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
10816
|
-
const iv =
|
|
10817
|
-
const cipher =
|
|
11349
|
+
const iv = randomBytes5(16);
|
|
11350
|
+
const cipher = createCipheriv2("aes-256-gcm", key, iv);
|
|
10818
11351
|
let enc = cipher.update(privKeyHex, "utf8", "hex");
|
|
10819
11352
|
enc += cipher.final("hex");
|
|
10820
11353
|
const x402KeyPath = join14(this.nexusDir, "x402-wallet.key");
|
|
@@ -11120,14 +11653,14 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11120
11653
|
throw new Error("User-managed wallet cannot spend (no private key)");
|
|
11121
11654
|
const salt = Buffer.from(w.salt, "hex");
|
|
11122
11655
|
const key = scryptSync(`${hostname()}:${userInfo().username}:nexus-wallet`, salt, 32, { N: 16384, r: 8, p: 1 });
|
|
11123
|
-
const decipher =
|
|
11656
|
+
const decipher = createDecipheriv2("aes-256-gcm", key, Buffer.from(w.iv, "hex"));
|
|
11124
11657
|
decipher.setAuthTag(Buffer.from(w.authTag, "hex"));
|
|
11125
11658
|
let privKeyHex = decipher.update(w.encryptedKey, "hex", "utf8");
|
|
11126
11659
|
privKeyHex += decipher.final("utf8");
|
|
11127
11660
|
try {
|
|
11128
11661
|
const { privateKeyToAccount } = await import("viem/accounts");
|
|
11129
11662
|
const account = privateKeyToAccount(`0x${privKeyHex}`);
|
|
11130
|
-
const nonce = "0x" +
|
|
11663
|
+
const nonce = "0x" + randomBytes5(32).toString("hex");
|
|
11131
11664
|
const now = Math.floor(Date.now() / 1e3);
|
|
11132
11665
|
const validAfter = now - 60;
|
|
11133
11666
|
const validBefore = now + 3600;
|
|
@@ -11330,8 +11863,8 @@ process.on('SIGINT', () => process.emit('SIGTERM'));
|
|
|
11330
11863
|
} catch {
|
|
11331
11864
|
}
|
|
11332
11865
|
}
|
|
11333
|
-
const nonce =
|
|
11334
|
-
const hash =
|
|
11866
|
+
const nonce = randomBytes5(16).toString("hex");
|
|
11867
|
+
const hash = createHash2("sha256").update(`${modelName}:${nonce}:${Date.now()}`).digest("hex");
|
|
11335
11868
|
const bar = (s2) => "█".repeat(Math.round(s2 / 5)) + "░".repeat(20 - Math.round(s2 / 5));
|
|
11336
11869
|
const mem = vramMb > 24e3 ? 95 : vramMb > 16e3 ? 80 : vramMb > 8e3 ? 60 : vramMb > 0 ? 40 : 20;
|
|
11337
11870
|
await this.ensureDir();
|
|
@@ -19865,7 +20398,7 @@ function createHasher(hashCons, info = {}) {
|
|
|
19865
20398
|
Object.assign(hashC, info);
|
|
19866
20399
|
return Object.freeze(hashC);
|
|
19867
20400
|
}
|
|
19868
|
-
function
|
|
20401
|
+
function randomBytes6(bytesLength = 32) {
|
|
19869
20402
|
const cr = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
19870
20403
|
if (typeof cr?.getRandomValues !== "function")
|
|
19871
20404
|
throw new Error("crypto.getRandomValues must be defined");
|
|
@@ -19889,11 +20422,11 @@ var init_utils3 = __esm({
|
|
|
19889
20422
|
});
|
|
19890
20423
|
|
|
19891
20424
|
// ../node_modules/@libp2p/crypto/dist/src/random-bytes.js
|
|
19892
|
-
function
|
|
20425
|
+
function randomBytes7(length4) {
|
|
19893
20426
|
if (isNaN(length4) || length4 <= 0) {
|
|
19894
20427
|
throw new InvalidParametersError("random bytes length must be a Number bigger than 0");
|
|
19895
20428
|
}
|
|
19896
|
-
return
|
|
20429
|
+
return randomBytes6(length4);
|
|
19897
20430
|
}
|
|
19898
20431
|
var init_random_bytes = __esm({
|
|
19899
20432
|
"../node_modules/@libp2p/crypto/dist/src/random-bytes.js"() {
|
|
@@ -22082,7 +22615,7 @@ function getWLengths(Fp, Fn) {
|
|
|
22082
22615
|
}
|
|
22083
22616
|
function ecdh(Point, ecdhOpts = {}) {
|
|
22084
22617
|
const { Fn } = Point;
|
|
22085
|
-
const randomBytes_ = ecdhOpts.randomBytes ||
|
|
22618
|
+
const randomBytes_ = ecdhOpts.randomBytes || randomBytes6;
|
|
22086
22619
|
const lengths = Object.assign(getWLengths(Point.Fp, Fn), { seed: getMinHashLength(Fn.ORDER) });
|
|
22087
22620
|
function isValidSecretKey(secretKey) {
|
|
22088
22621
|
try {
|
|
@@ -22147,7 +22680,7 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
22147
22680
|
bits2int_modN: "function"
|
|
22148
22681
|
});
|
|
22149
22682
|
ecdsaOpts = Object.assign({}, ecdsaOpts);
|
|
22150
|
-
const
|
|
22683
|
+
const randomBytes23 = ecdsaOpts.randomBytes || randomBytes6;
|
|
22151
22684
|
const hmac2 = ecdsaOpts.hmac || ((key, msg) => hmac(hash, key, msg));
|
|
22152
22685
|
const { Fp, Fn } = Point;
|
|
22153
22686
|
const { ORDER: CURVE_ORDER, BITS: fnBits } = Fn;
|
|
@@ -22289,7 +22822,7 @@ function ecdsa(Point, hash, ecdsaOpts = {}) {
|
|
|
22289
22822
|
throw new Error("invalid private key");
|
|
22290
22823
|
const seedArgs = [int2octets(d2), int2octets(h1int)];
|
|
22291
22824
|
if (extraEntropy != null && extraEntropy !== false) {
|
|
22292
|
-
const e2 = extraEntropy === true ?
|
|
22825
|
+
const e2 = extraEntropy === true ? randomBytes23(lengths.secretKey) : extraEntropy;
|
|
22293
22826
|
seedArgs.push(abytes(e2, void 0, "extraEntropy"));
|
|
22294
22827
|
}
|
|
22295
22828
|
const seed = concatBytes(...seedArgs);
|
|
@@ -46871,7 +47404,7 @@ var init_connection_monitor = __esm({
|
|
|
46871
47404
|
const bs = byteStream(stream);
|
|
46872
47405
|
start2 = Date.now();
|
|
46873
47406
|
await Promise.all([
|
|
46874
|
-
bs.write(
|
|
47407
|
+
bs.write(randomBytes7(PING_LENGTH), {
|
|
46875
47408
|
signal
|
|
46876
47409
|
}),
|
|
46877
47410
|
bs.read({
|
|
@@ -47383,7 +47916,7 @@ var init_random_walk = __esm({
|
|
|
47383
47916
|
this.log("start walk");
|
|
47384
47917
|
while (this.walkers > 0) {
|
|
47385
47918
|
try {
|
|
47386
|
-
const data =
|
|
47919
|
+
const data = randomBytes7(32);
|
|
47387
47920
|
let s2 = Date.now();
|
|
47388
47921
|
for await (const peer of this.peerRouting.getClosestPeers(data, { signal })) {
|
|
47389
47922
|
if (signal.aborted) {
|
|
@@ -53070,12 +53603,12 @@ async function exportToPem(privateKey, password) {
|
|
|
53070
53603
|
});
|
|
53071
53604
|
const keyBuf = keyWrapper.toBER();
|
|
53072
53605
|
const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
|
|
53073
|
-
const salt =
|
|
53606
|
+
const salt = randomBytes7(SALT_LENGTH);
|
|
53074
53607
|
const encryptionKey = await pbkdf2Async(sha5122, password, salt, {
|
|
53075
53608
|
c: ITERATIONS,
|
|
53076
53609
|
dkLen: KEY_SIZE
|
|
53077
53610
|
});
|
|
53078
|
-
const iv =
|
|
53611
|
+
const iv = randomBytes7(16);
|
|
53079
53612
|
const cryptoKey = await crypto14.subtle.importKey("raw", encryptionKey, "AES-CBC", false, ["encrypt"]);
|
|
53080
53613
|
const encrypted = await crypto14.subtle.encrypt({
|
|
53081
53614
|
name: "AES-CBC",
|
|
@@ -53373,7 +53906,7 @@ var init_keychain = __esm({
|
|
|
53373
53906
|
const options2 = Object.assign({}, this.options);
|
|
53374
53907
|
const saltLength = Math.ceil(NIST.minSaltLength / 3) * 3;
|
|
53375
53908
|
if (options2.dek != null) {
|
|
53376
|
-
options2.dek.salt = toString2(
|
|
53909
|
+
options2.dek.salt = toString2(randomBytes7(saltLength), "base64");
|
|
53377
53910
|
}
|
|
53378
53911
|
return options2;
|
|
53379
53912
|
}
|
|
@@ -54864,7 +55397,7 @@ function montgomery(curveDef) {
|
|
|
54864
55397
|
const is25519 = type === "x25519";
|
|
54865
55398
|
if (!is25519 && type !== "x448")
|
|
54866
55399
|
throw new Error("invalid type");
|
|
54867
|
-
const randomBytes_ = rand ||
|
|
55400
|
+
const randomBytes_ = rand || randomBytes6;
|
|
54868
55401
|
const montgomeryBits = is25519 ? 255 : 448;
|
|
54869
55402
|
const fieldLen = is25519 ? 32 : 56;
|
|
54870
55403
|
const Gu = is25519 ? BigInt(9) : BigInt(5);
|
|
@@ -58799,9 +59332,9 @@ var init_cookies = __esm({
|
|
|
58799
59332
|
|
|
58800
59333
|
// ../node_modules/@libp2p/http-peer-id-auth/dist/src/utils.js
|
|
58801
59334
|
function generateChallenge() {
|
|
58802
|
-
const
|
|
58803
|
-
crypto.getRandomValues(
|
|
58804
|
-
return toString2(
|
|
59335
|
+
const randomBytes23 = new Uint8Array(32);
|
|
59336
|
+
crypto.getRandomValues(randomBytes23);
|
|
59337
|
+
return toString2(randomBytes23, "base64urlpad");
|
|
58805
59338
|
}
|
|
58806
59339
|
function encodeAuthParams(params) {
|
|
58807
59340
|
const encodedParams = Object.entries(params).map(([key, value2]) => `${key}="${value2}"`).join(", ");
|
|
@@ -87999,7 +88532,7 @@ var require_auto = __commonJS({
|
|
|
87999
88532
|
// ../node_modules/acme-client/src/client.js
|
|
88000
88533
|
var require_client = __commonJS({
|
|
88001
88534
|
"../node_modules/acme-client/src/client.js"(exports, module) {
|
|
88002
|
-
var { createHash:
|
|
88535
|
+
var { createHash: createHash10 } = __require("crypto");
|
|
88003
88536
|
var { getPemBodyAsB64u } = require_crypto();
|
|
88004
88537
|
var { log: log22 } = require_logger();
|
|
88005
88538
|
var HttpClient = require_http();
|
|
@@ -88310,14 +88843,14 @@ var require_client = __commonJS({
|
|
|
88310
88843
|
*/
|
|
88311
88844
|
async getChallengeKeyAuthorization(challenge) {
|
|
88312
88845
|
const jwk = this.http.getJwk();
|
|
88313
|
-
const keysum =
|
|
88846
|
+
const keysum = createHash10("sha256").update(JSON.stringify(jwk));
|
|
88314
88847
|
const thumbprint = keysum.digest("base64url");
|
|
88315
88848
|
const result = `${challenge.token}.${thumbprint}`;
|
|
88316
88849
|
if (challenge.type === "http-01") {
|
|
88317
88850
|
return result;
|
|
88318
88851
|
}
|
|
88319
88852
|
if (challenge.type === "dns-01") {
|
|
88320
|
-
return
|
|
88853
|
+
return createHash10("sha256").update(result).digest("base64url");
|
|
88321
88854
|
}
|
|
88322
88855
|
if (challenge.type === "tls-alpn-01") {
|
|
88323
88856
|
return result;
|
|
@@ -206664,7 +207197,7 @@ var init_refresh = __esm({
|
|
|
206664
207197
|
if (this.routingTable.kb.localPeer == null) {
|
|
206665
207198
|
throw new Error("Local peer not set");
|
|
206666
207199
|
}
|
|
206667
|
-
const randomData =
|
|
207200
|
+
const randomData = randomBytes7(2);
|
|
206668
207201
|
const randomUint16 = (randomData[1] << 8) + randomData[0];
|
|
206669
207202
|
const key = this._makePeerId(this.routingTable.kb.localPeer.kadId, randomUint16, targetCommonPrefixLength);
|
|
206670
207203
|
const multihash = decode7(key);
|
|
@@ -210841,7 +211374,7 @@ var init_ping2 = __esm({
|
|
|
210841
211374
|
* Ping a given peer and wait for its response, getting the operation latency.
|
|
210842
211375
|
*/
|
|
210843
211376
|
async ping(peer, options2 = {}) {
|
|
210844
|
-
const data =
|
|
211377
|
+
const data = randomBytes7(PING_LENGTH2);
|
|
210845
211378
|
const stream = await this.components.connectionManager.openStream(peer, this.protocol, {
|
|
210846
211379
|
runOnLimitedConnection: this.runOnLimitedConnection,
|
|
210847
211380
|
...options2
|
|
@@ -230997,7 +231530,7 @@ var require_websocket2 = __commonJS({
|
|
|
230997
231530
|
var http6 = __require("http");
|
|
230998
231531
|
var net5 = __require("net");
|
|
230999
231532
|
var tls2 = __require("tls");
|
|
231000
|
-
var { randomBytes:
|
|
231533
|
+
var { randomBytes: randomBytes23, createHash: createHash10 } = __require("crypto");
|
|
231001
231534
|
var { Duplex: Duplex3, Readable } = __require("stream");
|
|
231002
231535
|
var { URL: URL3 } = __require("url");
|
|
231003
231536
|
var PerMessageDeflate2 = require_permessage_deflate2();
|
|
@@ -231527,7 +232060,7 @@ var require_websocket2 = __commonJS({
|
|
|
231527
232060
|
}
|
|
231528
232061
|
}
|
|
231529
232062
|
const defaultPort = isSecure ? 443 : 80;
|
|
231530
|
-
const key =
|
|
232063
|
+
const key = randomBytes23(16).toString("base64");
|
|
231531
232064
|
const request = isSecure ? https4.request : http6.request;
|
|
231532
232065
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
231533
232066
|
let perMessageDeflate;
|
|
@@ -231657,7 +232190,7 @@ var require_websocket2 = __commonJS({
|
|
|
231657
232190
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
231658
232191
|
return;
|
|
231659
232192
|
}
|
|
231660
|
-
const digest3 =
|
|
232193
|
+
const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
|
|
231661
232194
|
if (res.headers["sec-websocket-accept"] !== digest3) {
|
|
231662
232195
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
231663
232196
|
return;
|
|
@@ -232024,7 +232557,7 @@ var require_websocket_server = __commonJS({
|
|
|
232024
232557
|
var EventEmitter10 = __require("events");
|
|
232025
232558
|
var http6 = __require("http");
|
|
232026
232559
|
var { Duplex: Duplex3 } = __require("stream");
|
|
232027
|
-
var { createHash:
|
|
232560
|
+
var { createHash: createHash10 } = __require("crypto");
|
|
232028
232561
|
var extension2 = require_extension2();
|
|
232029
232562
|
var PerMessageDeflate2 = require_permessage_deflate2();
|
|
232030
232563
|
var subprotocol2 = require_subprotocol();
|
|
@@ -232325,7 +232858,7 @@ var require_websocket_server = __commonJS({
|
|
|
232325
232858
|
);
|
|
232326
232859
|
}
|
|
232327
232860
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
232328
|
-
const digest3 =
|
|
232861
|
+
const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
|
|
232329
232862
|
const headers = [
|
|
232330
232863
|
"HTTP/1.1 101 Switching Protocols",
|
|
232331
232864
|
"Upgrade: websocket",
|
|
@@ -245132,13 +245665,13 @@ Justification: ${justification || "(none provided)"}`,
|
|
|
245132
245665
|
}
|
|
245133
245666
|
const snapshot = JSON.stringify(this.selfState, null, 2);
|
|
245134
245667
|
try {
|
|
245135
|
-
const { createHash:
|
|
245668
|
+
const { createHash: createHash10 } = await import("node:crypto");
|
|
245136
245669
|
const snapshotDir = join23(this.cwd, ".oa", "identity", "snapshots");
|
|
245137
245670
|
await mkdir6(snapshotDir, { recursive: true });
|
|
245138
245671
|
const version4 = this.selfState.version;
|
|
245139
245672
|
const snapshotPath = join23(snapshotDir, `v${version4}.json`);
|
|
245140
245673
|
await writeFile11(snapshotPath, snapshot, "utf8");
|
|
245141
|
-
const hash =
|
|
245674
|
+
const hash = createHash10("sha256").update(snapshot).digest("hex");
|
|
245142
245675
|
await writeFile11(join23(this.cwd, ".oa", "identity", "latest-hash.txt"), hash, "utf8");
|
|
245143
245676
|
let ipfsCid = "";
|
|
245144
245677
|
try {
|
|
@@ -245271,8 +245804,8 @@ New: ${newNarrative.slice(0, 200)}...`,
|
|
|
245271
245804
|
}
|
|
245272
245805
|
// ── Helpers ──────────────────────────────────────────────────────────────
|
|
245273
245806
|
createDefaultState() {
|
|
245274
|
-
const { createHash:
|
|
245275
|
-
const machineId =
|
|
245807
|
+
const { createHash: createHash10 } = __require("node:crypto");
|
|
245808
|
+
const machineId = createHash10("sha256").update(this.cwd).digest("hex").slice(0, 12);
|
|
245276
245809
|
return {
|
|
245277
245810
|
self_id: `oa-${machineId}`,
|
|
245278
245811
|
version: 1,
|
|
@@ -245354,9 +245887,9 @@ New: ${newNarrative.slice(0, 200)}...`,
|
|
|
245354
245887
|
let cid;
|
|
245355
245888
|
if (this.selfState.version > prevVersion) {
|
|
245356
245889
|
try {
|
|
245357
|
-
const { createHash:
|
|
245890
|
+
const { createHash: createHash10 } = await import("node:crypto");
|
|
245358
245891
|
const stateJson = JSON.stringify(this.selfState);
|
|
245359
|
-
const hash =
|
|
245892
|
+
const hash = createHash10("sha256").update(stateJson).digest("hex").slice(0, 32);
|
|
245360
245893
|
const cidsPath = join23(this.cwd, ".oa", "identity", "cids.json");
|
|
245361
245894
|
const cidsData = { latest: "", hash, version: this.selfState.version };
|
|
245362
245895
|
try {
|
|
@@ -245400,7 +245933,7 @@ import { spawn as spawn7 } from "node:child_process";
|
|
|
245400
245933
|
import { createServer as createServer2 } from "node:net";
|
|
245401
245934
|
import { join as join24 } from "node:path";
|
|
245402
245935
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
245403
|
-
import { randomBytes as
|
|
245936
|
+
import { randomBytes as randomBytes9 } from "node:crypto";
|
|
245404
245937
|
import { unlinkSync as unlinkSync3 } from "node:fs";
|
|
245405
245938
|
var ReplTool;
|
|
245406
245939
|
var init_repl = __esm({
|
|
@@ -245468,7 +246001,7 @@ var init_repl = __esm({
|
|
|
245468
246001
|
if (!this.proc || this.proc.killed || this.proc.exitCode !== null) {
|
|
245469
246002
|
await this.startProcess();
|
|
245470
246003
|
}
|
|
245471
|
-
const tempFile = join24(tmpdir4(), `oa-repl-ctx-${
|
|
246004
|
+
const tempFile = join24(tmpdir4(), `oa-repl-ctx-${randomBytes9(6).toString("hex")}.txt`);
|
|
245472
246005
|
const { writeFileSync: writeFs, unlinkSync: unlinkFs } = await import("node:fs");
|
|
245473
246006
|
writeFs(tempFile, content, "utf8");
|
|
245474
246007
|
const result = await this.executeCode(`with open(${JSON.stringify(tempFile)}, "r") as _f:
|
|
@@ -245668,7 +246201,7 @@ print("__OA_REPL_READY__")
|
|
|
245668
246201
|
async startIpcServer() {
|
|
245669
246202
|
if (this.ipcServer)
|
|
245670
246203
|
return;
|
|
245671
|
-
const sockId =
|
|
246204
|
+
const sockId = randomBytes9(8).toString("hex");
|
|
245672
246205
|
this.ipcPath = join24(tmpdir4(), `oa-repl-ipc-${sockId}.sock`);
|
|
245673
246206
|
return new Promise((resolve39, reject) => {
|
|
245674
246207
|
this.ipcServer = createServer2((conn) => {
|
|
@@ -245754,7 +246287,7 @@ print("__OA_REPL_READY__")
|
|
|
245754
246287
|
resolve39({ success: false, output: "REPL process not available", error: "No process", durationMs: 0 });
|
|
245755
246288
|
return;
|
|
245756
246289
|
}
|
|
245757
|
-
const sentinel = `__OA_SENTINEL_${
|
|
246290
|
+
const sentinel = `__OA_SENTINEL_${randomBytes9(6).toString("hex")}__`;
|
|
245758
246291
|
let stdout = "";
|
|
245759
246292
|
let stderr = "";
|
|
245760
246293
|
let resolved = false;
|
|
@@ -250817,7 +251350,7 @@ import { execSync as execSync22, exec as execCb } from "node:child_process";
|
|
|
250817
251350
|
import { readFile as readFile15, writeFile as writeFile17, mkdir as mkdir12 } from "node:fs/promises";
|
|
250818
251351
|
import { resolve as resolve24, join as join37 } from "node:path";
|
|
250819
251352
|
import { homedir as homedir10 } from "node:os";
|
|
250820
|
-
import { randomBytes as
|
|
251353
|
+
import { randomBytes as randomBytes10 } from "node:crypto";
|
|
250821
251354
|
function isValidCron(expr) {
|
|
250822
251355
|
const parts = expr.trim().split(/\s+/);
|
|
250823
251356
|
if (parts.length !== 5)
|
|
@@ -251085,7 +251618,7 @@ var init_scheduler = __esm({
|
|
|
251085
251618
|
durationMs: performance.now() - start2
|
|
251086
251619
|
};
|
|
251087
251620
|
}
|
|
251088
|
-
const id = `sched-${
|
|
251621
|
+
const id = `sched-${randomBytes10(4).toString("hex")}`;
|
|
251089
251622
|
const oneShot = Boolean(args["one_shot"]);
|
|
251090
251623
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : void 0;
|
|
251091
251624
|
const scope = String(args["scope"] ?? "local");
|
|
@@ -251244,7 +251777,7 @@ ${truncated}`, durationMs: performance.now() - start2 };
|
|
|
251244
251777
|
// packages/execution/dist/tools/reminder.js
|
|
251245
251778
|
import { readFile as readFile16, writeFile as writeFile18, mkdir as mkdir13 } from "node:fs/promises";
|
|
251246
251779
|
import { resolve as resolve25, join as join38 } from "node:path";
|
|
251247
|
-
import { randomBytes as
|
|
251780
|
+
import { randomBytes as randomBytes11 } from "node:crypto";
|
|
251248
251781
|
function parseDueTime(due) {
|
|
251249
251782
|
const lower = due.toLowerCase().trim();
|
|
251250
251783
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -251441,7 +251974,7 @@ var init_reminder = __esm({
|
|
|
251441
251974
|
dueAt = parsed.isoDate;
|
|
251442
251975
|
dueDescription = parsed.description;
|
|
251443
251976
|
}
|
|
251444
|
-
const id = `rem-${
|
|
251977
|
+
const id = `rem-${randomBytes11(4).toString("hex")}`;
|
|
251445
251978
|
const entry = {
|
|
251446
251979
|
id,
|
|
251447
251980
|
message: message2,
|
|
@@ -251557,7 +252090,7 @@ var init_reminder = __esm({
|
|
|
251557
252090
|
// packages/execution/dist/tools/agenda.js
|
|
251558
252091
|
import { readFile as readFile17, writeFile as writeFile19, mkdir as mkdir14 } from "node:fs/promises";
|
|
251559
252092
|
import { resolve as resolve26, join as join39 } from "node:path";
|
|
251560
|
-
import { randomBytes as
|
|
252093
|
+
import { randomBytes as randomBytes12 } from "node:crypto";
|
|
251561
252094
|
async function loadAttentionStore(workingDir) {
|
|
251562
252095
|
const storePath = resolve26(workingDir, ".oa", "scheduled", "attention.json");
|
|
251563
252096
|
try {
|
|
@@ -251760,7 +252293,7 @@ ${sections.join("\n")}`,
|
|
|
251760
252293
|
expiresAt = target.toISOString();
|
|
251761
252294
|
}
|
|
251762
252295
|
}
|
|
251763
|
-
const id = `attn-${
|
|
252296
|
+
const id = `attn-${randomBytes12(4).toString("hex")}`;
|
|
251764
252297
|
const item = {
|
|
251765
252298
|
id,
|
|
251766
252299
|
title,
|
|
@@ -252466,7 +252999,7 @@ import { execSync as execSync25 } from "node:child_process";
|
|
|
252466
252999
|
import { readFile as readFile18, writeFile as writeFile20, mkdir as mkdir15 } from "node:fs/promises";
|
|
252467
253000
|
import { resolve as resolve28, join as join42 } from "node:path";
|
|
252468
253001
|
import { homedir as homedir11 } from "node:os";
|
|
252469
|
-
import { randomBytes as
|
|
253002
|
+
import { randomBytes as randomBytes13 } from "node:crypto";
|
|
252470
253003
|
function isValidCron2(expr) {
|
|
252471
253004
|
const parts = expr.trim().split(/\s+/);
|
|
252472
253005
|
if (parts.length !== 5)
|
|
@@ -252756,7 +253289,7 @@ var init_cron_agent = __esm({
|
|
|
252756
253289
|
durationMs: performance.now() - start2
|
|
252757
253290
|
};
|
|
252758
253291
|
}
|
|
252759
|
-
const id = `cron-${
|
|
253292
|
+
const id = `cron-${randomBytes13(4).toString("hex")}`;
|
|
252760
253293
|
const verifyCommand = args["verify_command"] ? String(args["verify_command"]) : void 0;
|
|
252761
253294
|
const maxRuns = typeof args["max_runs"] === "number" ? args["max_runs"] : 0;
|
|
252762
253295
|
const tags = Array.isArray(args["tags"]) ? args["tags"] : [];
|
|
@@ -253557,7 +254090,7 @@ var init_working_notes = __esm({
|
|
|
253557
254090
|
import { existsSync as existsSync27, readFileSync as readFileSync20, writeFileSync as writeFileSync11, mkdirSync as mkdirSync10, renameSync, unlinkSync as unlinkSync5, readdirSync as readdirSync6 } from "node:fs";
|
|
253558
254091
|
import { join as join43 } from "node:path";
|
|
253559
254092
|
import { homedir as homedir12 } from "node:os";
|
|
253560
|
-
import { randomBytes as
|
|
254093
|
+
import { randomBytes as randomBytes14 } from "node:crypto";
|
|
253561
254094
|
function setTodoEventPublisher(pub) {
|
|
253562
254095
|
_eventPublisher = pub;
|
|
253563
254096
|
}
|
|
@@ -253593,7 +254126,7 @@ function writeTodos(sessionId, incoming) {
|
|
|
253593
254126
|
const oldById = new Map(old.map((t2) => [t2.id, t2]));
|
|
253594
254127
|
const now = Date.now();
|
|
253595
254128
|
const newTodos = incoming.map((t2) => {
|
|
253596
|
-
const id = t2.id || `todo-${
|
|
254129
|
+
const id = t2.id || `todo-${randomBytes14(4).toString("hex")}`;
|
|
253597
254130
|
const existing = oldById.get(id);
|
|
253598
254131
|
const next = {
|
|
253599
254132
|
id,
|
|
@@ -259166,7 +259699,7 @@ Audio file: ${audioFile}`,
|
|
|
259166
259699
|
|
|
259167
259700
|
// packages/execution/dist/tools/full-sub-agent.js
|
|
259168
259701
|
import { spawn as spawn14, ChildProcess } from "node:child_process";
|
|
259169
|
-
import { randomBytes as
|
|
259702
|
+
import { randomBytes as randomBytes15 } from "node:crypto";
|
|
259170
259703
|
function buildSubProcessArgs(opts) {
|
|
259171
259704
|
const args = [];
|
|
259172
259705
|
args.push(opts.task);
|
|
@@ -259194,7 +259727,7 @@ function findOaBinary3() {
|
|
|
259194
259727
|
return "oa";
|
|
259195
259728
|
}
|
|
259196
259729
|
function spawnFullSubAgent(task, opts, onOutput, onComplete) {
|
|
259197
|
-
const id = `oa-fl-${
|
|
259730
|
+
const id = `oa-fl-${randomBytes15(2).toString("hex")}`;
|
|
259198
259731
|
const oaBin = findOaBinary3();
|
|
259199
259732
|
const cliArgs = buildSubProcessArgs({
|
|
259200
259733
|
task,
|
|
@@ -261619,7 +262152,7 @@ var init_environment_snapshot = __esm({
|
|
|
261619
262152
|
import { execSync as execSync42 } from "node:child_process";
|
|
261620
262153
|
import { existsSync as existsSync43, mkdirSync as mkdirSync22, writeFileSync as writeFileSync20, readFileSync as readFileSync33, readdirSync as readdirSync10, unlinkSync as unlinkSync10 } from "node:fs";
|
|
261621
262154
|
import { join as join57, basename as basename11 } from "node:path";
|
|
261622
|
-
import { createHash as
|
|
262155
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
261623
262156
|
function isYouTubeUrl2(url) {
|
|
261624
262157
|
return /(?:youtube\.com\/(?:watch|shorts|live|embed|v\/)|youtu\.be\/)/i.test(url);
|
|
261625
262158
|
}
|
|
@@ -261647,7 +262180,7 @@ function ensureFfmpeg() {
|
|
|
261647
262180
|
function imageHash(imagePath) {
|
|
261648
262181
|
try {
|
|
261649
262182
|
const data = readFileSync33(imagePath);
|
|
261650
|
-
return
|
|
262183
|
+
return createHash3("md5").update(data).digest("hex").slice(0, 12);
|
|
261651
262184
|
} catch {
|
|
261652
262185
|
return "unknown";
|
|
261653
262186
|
}
|
|
@@ -266900,7 +267433,7 @@ var init_toolPatternStore = __esm({
|
|
|
266900
267433
|
import { join as join64 } from "node:path";
|
|
266901
267434
|
import { mkdirSync as mkdirSync25, existsSync as existsSync48 } from "node:fs";
|
|
266902
267435
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
266903
|
-
import { createHash as
|
|
267436
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
266904
267437
|
function sanitizeImportance(raw, fallback = 5) {
|
|
266905
267438
|
if (typeof raw !== "number" || !Number.isFinite(raw))
|
|
266906
267439
|
return fallback;
|
|
@@ -267008,7 +267541,7 @@ var init_episodeStore = __esm({
|
|
|
267008
267541
|
insert(ep) {
|
|
267009
267542
|
const id = randomUUID7();
|
|
267010
267543
|
const now = Date.now();
|
|
267011
|
-
const contentHash =
|
|
267544
|
+
const contentHash = createHash4("sha256").update(ep.content).digest("hex").slice(0, 16);
|
|
267012
267545
|
const modality = ep.modality ?? "text";
|
|
267013
267546
|
const rawImportance = ep.importance ?? autoImportance(ep.toolName ?? null, modality, ep.content);
|
|
267014
267547
|
const importance = sanitizeImportance(rawImportance);
|
|
@@ -273920,7 +274453,7 @@ import { existsSync as existsSync50, statSync as statSync14, openSync, readSync,
|
|
|
273920
274453
|
import { watch as fsWatch } from "node:fs";
|
|
273921
274454
|
import { join as join66 } from "node:path";
|
|
273922
274455
|
import { tmpdir as tmpdir17 } from "node:os";
|
|
273923
|
-
import { randomBytes as
|
|
274456
|
+
import { randomBytes as randomBytes16 } from "node:crypto";
|
|
273924
274457
|
var NexusAgenticBackend;
|
|
273925
274458
|
var init_nexusBackend = __esm({
|
|
273926
274459
|
"packages/orchestrator/dist/nexusBackend.js"() {
|
|
@@ -274068,7 +274601,7 @@ var init_nexusBackend = __esm({
|
|
|
274068
274601
|
* Falls back to unary + word-split if streaming setup fails.
|
|
274069
274602
|
*/
|
|
274070
274603
|
async *chatCompletionStream(request) {
|
|
274071
|
-
const streamFile = join66(tmpdir17(), `nexus-stream-${
|
|
274604
|
+
const streamFile = join66(tmpdir17(), `nexus-stream-${randomBytes16(6).toString("hex")}.jsonl`);
|
|
274072
274605
|
writeFileSync23(streamFile, "", "utf8");
|
|
274073
274606
|
const daemonArgs = {
|
|
274074
274607
|
model: this.model,
|
|
@@ -274167,7 +274700,7 @@ var init_nexusBackend = __esm({
|
|
|
274167
274700
|
}
|
|
274168
274701
|
yield {
|
|
274169
274702
|
type: "tool_call_delta",
|
|
274170
|
-
toolCallId: tc.id || `call_${
|
|
274703
|
+
toolCallId: tc.id || `call_${randomBytes16(8).toString("hex")}`,
|
|
274171
274704
|
toolCallName: fn.name,
|
|
274172
274705
|
toolCallArgs: JSON.stringify(args)
|
|
274173
274706
|
};
|
|
@@ -274263,7 +274796,7 @@ var init_nexusBackend = __esm({
|
|
|
274263
274796
|
yield {
|
|
274264
274797
|
type: "tool_call_delta",
|
|
274265
274798
|
toolCallIndex: i2,
|
|
274266
|
-
toolCallId: tc.id || `call_${
|
|
274799
|
+
toolCallId: tc.id || `call_${randomBytes16(8).toString("hex")}`,
|
|
274267
274800
|
toolCallName: fn.name,
|
|
274268
274801
|
toolCallArgs: JSON.stringify(args)
|
|
274269
274802
|
};
|
|
@@ -279367,7 +279900,7 @@ var require_websocket3 = __commonJS({
|
|
|
279367
279900
|
var http6 = __require("http");
|
|
279368
279901
|
var net5 = __require("net");
|
|
279369
279902
|
var tls2 = __require("tls");
|
|
279370
|
-
var { randomBytes:
|
|
279903
|
+
var { randomBytes: randomBytes23, createHash: createHash10 } = __require("crypto");
|
|
279371
279904
|
var { Duplex: Duplex3, Readable } = __require("stream");
|
|
279372
279905
|
var { URL: URL3 } = __require("url");
|
|
279373
279906
|
var PerMessageDeflate2 = require_permessage_deflate3();
|
|
@@ -279897,7 +280430,7 @@ var require_websocket3 = __commonJS({
|
|
|
279897
280430
|
}
|
|
279898
280431
|
}
|
|
279899
280432
|
const defaultPort = isSecure ? 443 : 80;
|
|
279900
|
-
const key =
|
|
280433
|
+
const key = randomBytes23(16).toString("base64");
|
|
279901
280434
|
const request = isSecure ? https4.request : http6.request;
|
|
279902
280435
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
279903
280436
|
let perMessageDeflate;
|
|
@@ -280027,7 +280560,7 @@ var require_websocket3 = __commonJS({
|
|
|
280027
280560
|
abortHandshake(websocket, socket, "Invalid Upgrade header");
|
|
280028
280561
|
return;
|
|
280029
280562
|
}
|
|
280030
|
-
const digest3 =
|
|
280563
|
+
const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
|
|
280031
280564
|
if (res.headers["sec-websocket-accept"] !== digest3) {
|
|
280032
280565
|
abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
|
|
280033
280566
|
return;
|
|
@@ -280394,7 +280927,7 @@ var require_websocket_server2 = __commonJS({
|
|
|
280394
280927
|
var EventEmitter10 = __require("events");
|
|
280395
280928
|
var http6 = __require("http");
|
|
280396
280929
|
var { Duplex: Duplex3 } = __require("stream");
|
|
280397
|
-
var { createHash:
|
|
280930
|
+
var { createHash: createHash10 } = __require("crypto");
|
|
280398
280931
|
var extension2 = require_extension3();
|
|
280399
280932
|
var PerMessageDeflate2 = require_permessage_deflate3();
|
|
280400
280933
|
var subprotocol2 = require_subprotocol2();
|
|
@@ -280695,7 +281228,7 @@ var require_websocket_server2 = __commonJS({
|
|
|
280695
281228
|
);
|
|
280696
281229
|
}
|
|
280697
281230
|
if (this._state > RUNNING) return abortHandshake(socket, 503);
|
|
280698
|
-
const digest3 =
|
|
281231
|
+
const digest3 = createHash10("sha1").update(key + GUID).digest("base64");
|
|
280699
281232
|
const headers = [
|
|
280700
281233
|
"HTTP/1.1 101 Switching Protocols",
|
|
280701
281234
|
"Upgrade: websocket",
|
|
@@ -283209,7 +283742,7 @@ var init_voice_session = __esm({
|
|
|
283209
283742
|
import { createServer as createServer4, request as httpRequest } from "node:http";
|
|
283210
283743
|
import { spawn as spawn20, exec as exec2 } from "node:child_process";
|
|
283211
283744
|
import { EventEmitter as EventEmitter5 } from "node:events";
|
|
283212
|
-
import { randomBytes as
|
|
283745
|
+
import { randomBytes as randomBytes17 } from "node:crypto";
|
|
283213
283746
|
import { URL as URL2 } from "node:url";
|
|
283214
283747
|
import { loadavg, cpus as cpus2, totalmem as totalmem2, freemem as freemem2 } from "node:os";
|
|
283215
283748
|
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 +283942,7 @@ var init_expose = __esm({
|
|
|
283409
283942
|
this._stateDir = options2.stateDir ?? null;
|
|
283410
283943
|
this._fullAccess = options2.fullAccess ?? false;
|
|
283411
283944
|
if (options2.authKey === void 0 || options2.authKey === "") {
|
|
283412
|
-
this._authKey =
|
|
283945
|
+
this._authKey = randomBytes17(24).toString("base64url");
|
|
283413
283946
|
} else {
|
|
283414
283947
|
this._authKey = options2.authKey;
|
|
283415
283948
|
}
|
|
@@ -284321,7 +284854,7 @@ ${this.formatConnectionInfo()}`);
|
|
|
284321
284854
|
this._onInfo = options2.onInfo;
|
|
284322
284855
|
this._onError = options2.onError;
|
|
284323
284856
|
if (options2.authKey === void 0 || options2.authKey === "") {
|
|
284324
|
-
this._authKey =
|
|
284857
|
+
this._authKey = randomBytes17(24).toString("base64url");
|
|
284325
284858
|
} else {
|
|
284326
284859
|
this._authKey = options2.authKey;
|
|
284327
284860
|
}
|
|
@@ -284764,7 +285297,7 @@ var init_types = __esm({
|
|
|
284764
285297
|
});
|
|
284765
285298
|
|
|
284766
285299
|
// packages/cli/src/tui/p2p/secret-vault.ts
|
|
284767
|
-
import { createCipheriv as
|
|
285300
|
+
import { createCipheriv as createCipheriv3, createDecipheriv as createDecipheriv3, randomBytes as randomBytes18, scryptSync as scryptSync2, createHash as createHash5 } from "node:crypto";
|
|
284768
285301
|
import { readFileSync as readFileSync40, writeFileSync as writeFileSync27, existsSync as existsSync54, mkdirSync as mkdirSync30 } from "node:fs";
|
|
284769
285302
|
import { dirname as dirname18 } from "node:path";
|
|
284770
285303
|
var PLACEHOLDER_PREFIX, PLACEHOLDER_SUFFIX, CIPHER_ALGO, SALT_LEN, IV_LEN, KEY_LEN, SecretVault;
|
|
@@ -284965,10 +285498,10 @@ var init_secret_vault = __esm({
|
|
|
284965
285498
|
createdAt: s2.createdAt
|
|
284966
285499
|
}))
|
|
284967
285500
|
);
|
|
284968
|
-
const salt =
|
|
285501
|
+
const salt = randomBytes18(SALT_LEN);
|
|
284969
285502
|
const key = scryptSync2(passphrase, salt, KEY_LEN);
|
|
284970
|
-
const iv =
|
|
284971
|
-
const cipher =
|
|
285503
|
+
const iv = randomBytes18(IV_LEN);
|
|
285504
|
+
const cipher = createCipheriv3(CIPHER_ALGO, key, iv);
|
|
284972
285505
|
const encrypted = Buffer.concat([cipher.update(data, "utf8"), cipher.final()]);
|
|
284973
285506
|
const tag = cipher.getAuthTag();
|
|
284974
285507
|
const blob = Buffer.concat([salt, iv, tag, encrypted]);
|
|
@@ -284991,7 +285524,7 @@ var init_secret_vault = __esm({
|
|
|
284991
285524
|
const tag = blob.subarray(SALT_LEN + IV_LEN, SALT_LEN + IV_LEN + 16);
|
|
284992
285525
|
const encrypted = blob.subarray(SALT_LEN + IV_LEN + 16);
|
|
284993
285526
|
const key = scryptSync2(passphrase, salt, KEY_LEN);
|
|
284994
|
-
const decipher =
|
|
285527
|
+
const decipher = createDecipheriv3(CIPHER_ALGO, key, iv);
|
|
284995
285528
|
decipher.setAuthTag(tag);
|
|
284996
285529
|
let data;
|
|
284997
285530
|
try {
|
|
@@ -285008,7 +285541,7 @@ var init_secret_vault = __esm({
|
|
|
285008
285541
|
/** Generate a deterministic fingerprint of vault contents (for sync verification) */
|
|
285009
285542
|
fingerprint() {
|
|
285010
285543
|
const names = Array.from(this.secrets.keys()).sort();
|
|
285011
|
-
const hash =
|
|
285544
|
+
const hash = createHash5("sha256");
|
|
285012
285545
|
for (const name10 of names) {
|
|
285013
285546
|
hash.update(name10 + ":");
|
|
285014
285547
|
hash.update(this.secrets.get(name10).value);
|
|
@@ -285023,7 +285556,7 @@ var init_secret_vault = __esm({
|
|
|
285023
285556
|
// packages/cli/src/tui/p2p/peer-mesh.ts
|
|
285024
285557
|
import { EventEmitter as EventEmitter6 } from "node:events";
|
|
285025
285558
|
import { createServer as createServer5 } from "node:http";
|
|
285026
|
-
import { randomBytes as
|
|
285559
|
+
import { randomBytes as randomBytes19, createHash as createHash6, generateKeyPairSync } from "node:crypto";
|
|
285027
285560
|
var PING_INTERVAL_MS, PEER_TIMEOUT_MS, GOSSIP_INTERVAL_MS, MAX_PEERS, PeerMesh;
|
|
285028
285561
|
var init_peer_mesh = __esm({
|
|
285029
285562
|
"packages/cli/src/tui/p2p/peer-mesh.ts"() {
|
|
@@ -285040,10 +285573,10 @@ var init_peer_mesh = __esm({
|
|
|
285040
285573
|
const { publicKey: publicKey2, privateKey } = generateKeyPairSync("ed25519");
|
|
285041
285574
|
this.publicKey = publicKey2.export({ type: "spki", format: "der" });
|
|
285042
285575
|
this.privateKey = privateKey.export({ type: "pkcs8", format: "der" });
|
|
285043
|
-
this.peerId =
|
|
285576
|
+
this.peerId = createHash6("sha256").update(this.publicKey).digest("base64url").slice(0, 22);
|
|
285044
285577
|
this.capabilities = options2.capabilities;
|
|
285045
285578
|
this.displayName = options2.displayName;
|
|
285046
|
-
this._authKey = options2.authKey ??
|
|
285579
|
+
this._authKey = options2.authKey ?? randomBytes19(24).toString("base64url");
|
|
285047
285580
|
}
|
|
285048
285581
|
/** This node's unique peer ID (hash of public key) */
|
|
285049
285582
|
peerId;
|
|
@@ -285236,7 +285769,7 @@ var init_peer_mesh = __esm({
|
|
|
285236
285769
|
if (!ws || ws.readyState !== import_websocket5.default.OPEN) {
|
|
285237
285770
|
throw new Error(`Peer ${peerId} not connected`);
|
|
285238
285771
|
}
|
|
285239
|
-
const msgId =
|
|
285772
|
+
const msgId = randomBytes19(8).toString("hex");
|
|
285240
285773
|
return new Promise((resolve39, reject) => {
|
|
285241
285774
|
const timeout2 = setTimeout(() => {
|
|
285242
285775
|
this.pendingRequests.delete(msgId);
|
|
@@ -285452,7 +285985,7 @@ var init_peer_mesh = __esm({
|
|
|
285452
285985
|
const msg = {
|
|
285453
285986
|
type,
|
|
285454
285987
|
from: this.peerId,
|
|
285455
|
-
msgId: msgId ??
|
|
285988
|
+
msgId: msgId ?? randomBytes19(8).toString("hex"),
|
|
285456
285989
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
285457
285990
|
payload
|
|
285458
285991
|
};
|
|
@@ -289057,6 +289590,14 @@ var init_status_bar = __esm({
|
|
|
289057
289590
|
_contentScrollOffset = 0;
|
|
289058
289591
|
// 0 = live (bottom), >0 = scrolled back
|
|
289059
289592
|
_contentMaxLines = 1e4;
|
|
289593
|
+
// Partial-line accumulator for the buffered-write layer. Stream output
|
|
289594
|
+
// arrives in chunks (one per syntax-highlighted token) and a single
|
|
289595
|
+
// logical line can span many writes. If we naively push each chunk to
|
|
289596
|
+
// _contentLines, scroll-back replay fragments the line across rows and
|
|
289597
|
+
// "injects" extra newlines between pieces. Instead, everything up to the
|
|
289598
|
+
// last \n goes into _contentLines (as complete lines), and the trailing
|
|
289599
|
+
// partial stays in _inProgressLine until the next \n arrives.
|
|
289600
|
+
_inProgressLine = "";
|
|
289060
289601
|
/** Auto-scroll to live when new content arrives (disabled when user scrolls back) */
|
|
289061
289602
|
_autoScroll = true;
|
|
289062
289603
|
/** Cached click region for the spacer button */
|
|
@@ -290247,8 +290788,15 @@ var init_status_bar = __esm({
|
|
|
290247
290788
|
const fh = this._currentFooterHeight;
|
|
290248
290789
|
const footerStart = termRows() - fh + 1;
|
|
290249
290790
|
if (row >= footerStart) return;
|
|
290250
|
-
if (type === "press"
|
|
290251
|
-
this.
|
|
290791
|
+
if (type === "press") {
|
|
290792
|
+
this._textSelection.onMousePress(row, col);
|
|
290793
|
+
this.repaintContent();
|
|
290794
|
+
} else if (type === "drag") {
|
|
290795
|
+
this._textSelection.onMouseDrag(row, col);
|
|
290796
|
+
this.repaintContent();
|
|
290797
|
+
} else if (type === "release") {
|
|
290798
|
+
this._textSelection.onMouseRelease(row, col);
|
|
290799
|
+
this.repaintContent();
|
|
290252
290800
|
}
|
|
290253
290801
|
}
|
|
290254
290802
|
/** Copy current selection to clipboard. Returns true if copied. */
|
|
@@ -290590,11 +291138,21 @@ var init_status_bar = __esm({
|
|
|
290590
291138
|
if (typeof chunk === "string") text = chunk;
|
|
290591
291139
|
else if (Buffer.isBuffer(chunk)) text = chunk.toString();
|
|
290592
291140
|
else text = String(chunk);
|
|
290593
|
-
const lines = text.split("\n");
|
|
290594
291141
|
if (self2._bufferContent && !isOverlayActive()) {
|
|
290595
|
-
|
|
290596
|
-
|
|
290597
|
-
|
|
291142
|
+
const combined = self2._inProgressLine + text;
|
|
291143
|
+
const lastNl = combined.lastIndexOf("\n");
|
|
291144
|
+
if (lastNl < 0) {
|
|
291145
|
+
self2._inProgressLine = combined;
|
|
291146
|
+
} else {
|
|
291147
|
+
const completed = combined.slice(0, lastNl);
|
|
291148
|
+
self2._inProgressLine = combined.slice(lastNl + 1);
|
|
291149
|
+
const completeLines = completed.split("\n");
|
|
291150
|
+
for (const line of completeLines) {
|
|
291151
|
+
const visible = line.replace(/\x1B\[[0-9;]*[A-Za-z]/g, "");
|
|
291152
|
+
if (line.length === 0 || visible.length > 0) {
|
|
291153
|
+
self2.bufferContentLine(line);
|
|
291154
|
+
}
|
|
291155
|
+
}
|
|
290598
291156
|
}
|
|
290599
291157
|
}
|
|
290600
291158
|
if (typeof chunk === "string") {
|
|
@@ -290627,6 +291185,11 @@ ${CONTENT_BG_SEQ}`);
|
|
|
290627
291185
|
if (!this.active) return;
|
|
290628
291186
|
this.writeDepth = Math.max(0, this.writeDepth - 1);
|
|
290629
291187
|
if (this.writeDepth === 0) {
|
|
291188
|
+
if (this._inProgressLine.length > 0) {
|
|
291189
|
+
const visible = this._inProgressLine.replace(/\x1B\[[0-9;]*[A-Za-z]/g, "");
|
|
291190
|
+
if (visible.length > 0) this.bufferContentLine(this._inProgressLine);
|
|
291191
|
+
this._inProgressLine = "";
|
|
291192
|
+
}
|
|
290630
291193
|
this._bufferContent = false;
|
|
290631
291194
|
if (this._origWrite) {
|
|
290632
291195
|
try {
|
|
@@ -290783,12 +291346,19 @@ ${CONTENT_BG_SEQ}`);
|
|
|
290783
291346
|
let buf = "\x1B[?2026h";
|
|
290784
291347
|
buf += "\x1B7";
|
|
290785
291348
|
buf += "\x1B[?25l";
|
|
291349
|
+
const selRanges = this._textSelection.hasSelection ? this._textSelection.getSelectedRanges() : [];
|
|
291350
|
+
const selByBufferIdx = /* @__PURE__ */ new Map();
|
|
291351
|
+
for (const r2 of selRanges) selByBufferIdx.set(r2.bufferIdx, { startCol: r2.startCol, endCol: r2.endCol });
|
|
290786
291352
|
for (let row = 0; row < h; row++) {
|
|
290787
291353
|
const lineIdx = startIdx + row;
|
|
290788
291354
|
let line = lineIdx < totalLines ? this._contentLines[lineIdx] : "";
|
|
290789
291355
|
const screenRow = this.scrollRegionTop + row;
|
|
290790
291356
|
if (screenRow < headerSafeFloor) continue;
|
|
290791
291357
|
line = line.replace(/\x1B\[0m/g, `\x1B[0m${CONTENT_BG_SEQ}`);
|
|
291358
|
+
const sel = selByBufferIdx.get(lineIdx);
|
|
291359
|
+
if (sel) {
|
|
291360
|
+
line = TextSelection.applyHighlight(line, sel.startCol, sel.endCol);
|
|
291361
|
+
}
|
|
290792
291362
|
buf += `\x1B[${screenRow};1H${CONTENT_BG_SEQ}\x1B[2K${line}`;
|
|
290793
291363
|
}
|
|
290794
291364
|
const L = layout();
|
|
@@ -314607,7 +315177,7 @@ var init_disk_task_output = __esm({
|
|
|
314607
315177
|
});
|
|
314608
315178
|
|
|
314609
315179
|
// packages/cli/src/api/http.ts
|
|
314610
|
-
import { createHash as
|
|
315180
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
314611
315181
|
function problemDetails(opts) {
|
|
314612
315182
|
const p2 = {
|
|
314613
315183
|
type: opts.type ?? "about:blank",
|
|
@@ -314670,7 +315240,7 @@ function paginated(items, page2, total) {
|
|
|
314670
315240
|
}
|
|
314671
315241
|
function computeEtag(payload) {
|
|
314672
315242
|
const json = typeof payload === "string" ? payload : JSON.stringify(payload);
|
|
314673
|
-
const hash =
|
|
315243
|
+
const hash = createHash7("sha1").update(json).digest("hex").slice(0, 16);
|
|
314674
315244
|
return `W/"${hash}"`;
|
|
314675
315245
|
}
|
|
314676
315246
|
function checkNotModified(req2, res, etag) {
|
|
@@ -317237,11 +317807,11 @@ async function handleAimsIncidentPost(ctx3) {
|
|
|
317237
317807
|
}));
|
|
317238
317808
|
return true;
|
|
317239
317809
|
}
|
|
317240
|
-
const { randomBytes:
|
|
317810
|
+
const { randomBytes: randomBytes23 } = await import("node:crypto");
|
|
317241
317811
|
const record = await withAimsLock("incidents.json", () => {
|
|
317242
317812
|
const existing = readAimsFile("incidents.json", []);
|
|
317243
317813
|
const rec = {
|
|
317244
|
-
id: `INC-${Date.now()}-${
|
|
317814
|
+
id: `INC-${Date.now()}-${randomBytes23(4).toString("hex")}`,
|
|
317245
317815
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
317246
317816
|
raised_by: user ?? "anonymous",
|
|
317247
317817
|
status: "open",
|
|
@@ -321419,7 +321989,7 @@ var init_usage_tracker = __esm({
|
|
|
321419
321989
|
import { existsSync as existsSync80, readFileSync as readFileSync63, writeFileSync as writeFileSync41, mkdirSync as mkdirSync48, readdirSync as readdirSync27, unlinkSync as unlinkSync21 } from "node:fs";
|
|
321420
321990
|
import { join as join96 } from "node:path";
|
|
321421
321991
|
import { homedir as homedir34 } from "node:os";
|
|
321422
|
-
import { createCipheriv as
|
|
321992
|
+
import { createCipheriv as createCipheriv4, createDecipheriv as createDecipheriv4, randomBytes as randomBytes20, scryptSync as scryptSync3 } from "node:crypto";
|
|
321423
321993
|
function globalProfileDir() {
|
|
321424
321994
|
return join96(homedir34(), ".open-agents", "profiles");
|
|
321425
321995
|
}
|
|
@@ -321503,10 +322073,10 @@ function deleteProfile(name10, scope = "global", projectDir) {
|
|
|
321503
322073
|
return false;
|
|
321504
322074
|
}
|
|
321505
322075
|
function encryptProfile(profile, password) {
|
|
321506
|
-
const salt =
|
|
322076
|
+
const salt = randomBytes20(32);
|
|
321507
322077
|
const key = scryptSync3(password, salt, 32);
|
|
321508
|
-
const iv =
|
|
321509
|
-
const cipher =
|
|
322078
|
+
const iv = randomBytes20(16);
|
|
322079
|
+
const cipher = createCipheriv4("aes-256-gcm", key, iv);
|
|
321510
322080
|
const plaintext = JSON.stringify(profile);
|
|
321511
322081
|
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
|
321512
322082
|
const tag = cipher.getAuthTag();
|
|
@@ -321525,7 +322095,7 @@ function decryptProfile(enc, password) {
|
|
|
321525
322095
|
const salt = Buffer.from(enc.salt, "hex");
|
|
321526
322096
|
const key = scryptSync3(password, salt, 32);
|
|
321527
322097
|
const iv = Buffer.from(enc.iv, "hex");
|
|
321528
|
-
const decipher =
|
|
322098
|
+
const decipher = createDecipheriv4("aes-256-gcm", key, iv);
|
|
321529
322099
|
decipher.setAuthTag(Buffer.from(enc.tag, "hex"));
|
|
321530
322100
|
const decrypted = Buffer.concat([
|
|
321531
322101
|
decipher.update(Buffer.from(enc.data, "hex")),
|
|
@@ -321918,7 +322488,7 @@ import { dirname as dirname28, join as join98, resolve as resolve34 } from "node
|
|
|
321918
322488
|
import { homedir as homedir36 } from "node:os";
|
|
321919
322489
|
import { spawn as spawn25, execSync as execSync55 } from "node:child_process";
|
|
321920
322490
|
import { mkdirSync as mkdirSync50, readFileSync as readFileSync64, readdirSync as readdirSync28, existsSync as existsSync82, watch as fsWatch3 } from "node:fs";
|
|
321921
|
-
import { randomBytes as
|
|
322491
|
+
import { randomBytes as randomBytes21, randomUUID as randomUUID11 } from "node:crypto";
|
|
321922
322492
|
function getVersion3() {
|
|
321923
322493
|
try {
|
|
321924
322494
|
const require3 = createRequire4(import.meta.url);
|
|
@@ -322781,7 +323351,7 @@ async function handleV1ChatCompletions(req2, res, ollamaUrl) {
|
|
|
322781
323351
|
"Cache-Control": "no-cache",
|
|
322782
323352
|
"Connection": "keep-alive"
|
|
322783
323353
|
});
|
|
322784
|
-
const chatId = `chatcmpl-${
|
|
323354
|
+
const chatId = `chatcmpl-${randomBytes21(12).toString("hex")}`;
|
|
322785
323355
|
let buffer2 = "";
|
|
322786
323356
|
ollamaStream(
|
|
322787
323357
|
targetUrl,
|
|
@@ -322891,7 +323461,7 @@ async function handleV1ChatCompletions(req2, res, ollamaUrl) {
|
|
|
322891
323461
|
if (ollamaResp.eval_count) metrics.totalTokensOut += ollamaResp.eval_count;
|
|
322892
323462
|
if (ollamaResp.prompt_eval_count) metrics.totalTokensIn += ollamaResp.prompt_eval_count;
|
|
322893
323463
|
trackTokens("local", ollamaResp.prompt_eval_count ?? 0, ollamaResp.eval_count ?? 0);
|
|
322894
|
-
const chatId = `chatcmpl-${
|
|
323464
|
+
const chatId = `chatcmpl-${randomBytes21(12).toString("hex")}`;
|
|
322895
323465
|
const responseMessage = {
|
|
322896
323466
|
role: ollamaResp.message?.role ?? "assistant",
|
|
322897
323467
|
content: ollamaResp.message?.content ?? ""
|
|
@@ -323623,7 +324193,7 @@ async function handleV1Run(req2, res) {
|
|
|
323623
324193
|
return;
|
|
323624
324194
|
}
|
|
323625
324195
|
}
|
|
323626
|
-
const id = `job-${
|
|
324196
|
+
const id = `job-${randomBytes21(8).toString("hex")}`;
|
|
323627
324197
|
const dir = jobsDir();
|
|
323628
324198
|
const workingDir = requestBody["working_directory"] || req2.headers["x-working-directory"];
|
|
323629
324199
|
const isolate = requestBody["isolate"] === true;
|
|
@@ -328626,7 +329196,17 @@ Rationale: ${proposal.rationale}${provenanceNote}`;
|
|
|
328626
329196
|
statusBar.setNexusStatus("disconnected");
|
|
328627
329197
|
}
|
|
328628
329198
|
};
|
|
328629
|
-
_tryNexusConnect(1)
|
|
329199
|
+
_tryNexusConnect(1).catch((err) => {
|
|
329200
|
+
try {
|
|
329201
|
+
statusBar.setNexusStatus("disconnected");
|
|
329202
|
+
} catch {
|
|
329203
|
+
}
|
|
329204
|
+
try {
|
|
329205
|
+
const msg = err?.message || String(err);
|
|
329206
|
+
writeContent(() => renderWarning(`Nexus startup: ${msg.slice(0, 160)}`));
|
|
329207
|
+
} catch {
|
|
329208
|
+
}
|
|
329209
|
+
});
|
|
328630
329210
|
} catch {
|
|
328631
329211
|
}
|
|
328632
329212
|
try {
|
|
@@ -330810,13 +331390,13 @@ ${fullInput}`;
|
|
|
330810
331390
|
writeContent(() => renderError(errMsg));
|
|
330811
331391
|
if (failureStore) {
|
|
330812
331392
|
try {
|
|
330813
|
-
const { createHash:
|
|
331393
|
+
const { createHash: createHash10 } = await import("node:crypto");
|
|
330814
331394
|
failureStore.insert({
|
|
330815
331395
|
taskId: "",
|
|
330816
331396
|
sessionId: `${Date.now()}`,
|
|
330817
331397
|
repoRoot,
|
|
330818
331398
|
failureType: "runtime-error",
|
|
330819
|
-
fingerprint:
|
|
331399
|
+
fingerprint: createHash10("sha256").update(errMsg.slice(0, 200)).digest("hex").slice(0, 16),
|
|
330820
331400
|
filePath: null,
|
|
330821
331401
|
errorMessage: errMsg.slice(0, 500),
|
|
330822
331402
|
context: null,
|
|
@@ -331444,7 +332024,7 @@ __export(run_exports, {
|
|
|
331444
332024
|
import { resolve as resolve36 } from "node:path";
|
|
331445
332025
|
import { spawn as spawn26 } from "node:child_process";
|
|
331446
332026
|
import { mkdirSync as mkdirSync52, writeFileSync as writeFileSync45, readFileSync as readFileSync66, readdirSync as readdirSync30, existsSync as existsSync84 } from "node:fs";
|
|
331447
|
-
import { randomBytes as
|
|
332027
|
+
import { randomBytes as randomBytes22 } from "node:crypto";
|
|
331448
332028
|
import { join as join100 } from "node:path";
|
|
331449
332029
|
function jobsDir2(repoPath) {
|
|
331450
332030
|
const root = resolve36(repoPath ?? process.cwd());
|
|
@@ -331539,7 +332119,7 @@ function extractSummary(captured) {
|
|
|
331539
332119
|
return lines.slice(-3).join(" ").slice(0, 200);
|
|
331540
332120
|
}
|
|
331541
332121
|
async function runBackground(task, config, opts) {
|
|
331542
|
-
const id = `job-${
|
|
332122
|
+
const id = `job-${randomBytes22(3).toString("hex")}`;
|
|
331543
332123
|
const dir = jobsDir2(opts.repoPath);
|
|
331544
332124
|
const repoRoot = resolve36(opts.repoPath ?? process.cwd());
|
|
331545
332125
|
const job = {
|
|
@@ -331648,7 +332228,7 @@ var init_run = __esm({
|
|
|
331648
332228
|
import { glob as glob2 } from "glob";
|
|
331649
332229
|
import ignore from "ignore";
|
|
331650
332230
|
import { readFile as readFile23, stat as stat5 } from "node:fs/promises";
|
|
331651
|
-
import { createHash as
|
|
332231
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
331652
332232
|
import { join as join101, relative as relative5, extname as extname12, basename as basename18 } from "node:path";
|
|
331653
332233
|
var DEFAULT_EXCLUDE, LANGUAGE_MAP, CodebaseIndexer;
|
|
331654
332234
|
var init_codebase_indexer = __esm({
|
|
@@ -331714,7 +332294,7 @@ var init_codebase_indexer = __esm({
|
|
|
331714
332294
|
if (fileStat.size > this.config.maxFileSize)
|
|
331715
332295
|
continue;
|
|
331716
332296
|
const content = await readFile23(fullPath);
|
|
331717
|
-
const hash =
|
|
332297
|
+
const hash = createHash9("sha256").update(content).digest("hex");
|
|
331718
332298
|
const ext = extname12(relativePath);
|
|
331719
332299
|
indexed.push({
|
|
331720
332300
|
path: fullPath,
|