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