open-agents-ai 0.140.0 → 0.140.1
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 +259 -10
- 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 ?? ""),
|
|
@@ -40445,14 +40533,49 @@ var init_voice = __esm({
|
|
|
40445
40533
|
async drainQueue() {
|
|
40446
40534
|
this.speaking = true;
|
|
40447
40535
|
let isFirst = true;
|
|
40536
|
+
let prefetchedWav = null;
|
|
40448
40537
|
while (this.speakQueue.length > 0) {
|
|
40449
40538
|
const item = this.speakQueue.shift();
|
|
40450
40539
|
if (!isFirst) {
|
|
40451
|
-
await this.sleep(
|
|
40540
|
+
await this.sleep(120);
|
|
40452
40541
|
}
|
|
40453
40542
|
isFirst = false;
|
|
40454
40543
|
try {
|
|
40455
|
-
|
|
40544
|
+
if (this.luxttsActive) {
|
|
40545
|
+
let wavPath = null;
|
|
40546
|
+
if (prefetchedWav && prefetchedWav.item === item) {
|
|
40547
|
+
wavPath = prefetchedWav.path;
|
|
40548
|
+
prefetchedWav = null;
|
|
40549
|
+
}
|
|
40550
|
+
const nextItem = this.speakQueue[0] ?? null;
|
|
40551
|
+
let prefetchPromise = null;
|
|
40552
|
+
if (nextItem && this.luxttsActive) {
|
|
40553
|
+
prefetchPromise = this.synthesizeLuxttsWav(nextItem.text, nextItem.speedFactor);
|
|
40554
|
+
}
|
|
40555
|
+
if (!wavPath) {
|
|
40556
|
+
wavPath = await this.synthesizeLuxttsWav(item.text, item.speedFactor);
|
|
40557
|
+
}
|
|
40558
|
+
if (wavPath) {
|
|
40559
|
+
await this.postProcessAndPlayLuxtts(wavPath, item.volume, item.pitchFactor, item.stereoDelayMs);
|
|
40560
|
+
}
|
|
40561
|
+
if (prefetchPromise && nextItem) {
|
|
40562
|
+
try {
|
|
40563
|
+
const nextWav = await prefetchPromise;
|
|
40564
|
+
if (nextWav) {
|
|
40565
|
+
prefetchedWav = { path: nextWav, item: nextItem };
|
|
40566
|
+
}
|
|
40567
|
+
} catch {
|
|
40568
|
+
}
|
|
40569
|
+
}
|
|
40570
|
+
} else {
|
|
40571
|
+
await this.synthesizeAndPlay(item.text, item.volume, item.pitchFactor, item.speedFactor, item.stereoDelayMs);
|
|
40572
|
+
}
|
|
40573
|
+
} catch {
|
|
40574
|
+
}
|
|
40575
|
+
}
|
|
40576
|
+
if (prefetchedWav) {
|
|
40577
|
+
try {
|
|
40578
|
+
unlinkSync8(prefetchedWav.path);
|
|
40456
40579
|
} catch {
|
|
40457
40580
|
}
|
|
40458
40581
|
}
|
|
@@ -41151,10 +41274,19 @@ Error: ${err2 instanceof Error ? err2.message : String(err2)}`);
|
|
|
41151
41274
|
renderWarning(` Could not install system build deps: ${err instanceof Error ? err.message : String(err)}`);
|
|
41152
41275
|
}
|
|
41153
41276
|
}
|
|
41277
|
+
const isJetson = isArm && (existsSync35("/etc/nv_tegra_release") || existsSync35("/usr/local/cuda/targets/aarch64-linux") || (process.env.JETSON_L4T_VERSION ?? "") !== "");
|
|
41154
41278
|
const installSteps = isArm ? [
|
|
41155
41279
|
// ARM: install individually so we get clear error messages per package.
|
|
41156
41280
|
// ALL are fatal because LuxTTS hard-imports them (no lazy/optional imports).
|
|
41157
41281
|
{ cmd: `${pipCmd} -m pip install --quiet "setuptools<81" wheel`, fatal: true, label: "setuptools" },
|
|
41282
|
+
// Jetson: try NVIDIA's prebuilt PyTorch wheel first (has CUDA support)
|
|
41283
|
+
...isJetson ? [
|
|
41284
|
+
{ 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)" },
|
|
41285
|
+
{ cmd: `${pipCmd} -m pip install --quiet onnxruntime-gpu 2>/dev/null || true`, fatal: false, label: "onnxruntime-gpu (Jetson, optional)" }
|
|
41286
|
+
] : [
|
|
41287
|
+
// Non-Jetson ARM: standard PyTorch (CPU)
|
|
41288
|
+
{ cmd: `${pipCmd} -m pip install --quiet torch --index-url https://download.pytorch.org/whl/cpu`, fatal: true, label: "PyTorch (ARM CPU)" }
|
|
41289
|
+
],
|
|
41158
41290
|
{ cmd: `${pipCmd} -m pip install --quiet numpy`, fatal: true, label: "numpy" },
|
|
41159
41291
|
{ cmd: `${pipCmd} -m pip install --quiet huggingface_hub safetensors`, fatal: true, label: "huggingface_hub + safetensors" },
|
|
41160
41292
|
{ cmd: `${pipCmd} -m pip install --quiet "transformers<=4.57.6"`, fatal: true, label: "transformers" },
|
|
@@ -41397,17 +41529,21 @@ if __name__ == '__main__':
|
|
|
41397
41529
|
* Speed is passed natively to LuxTTS. Pitch is post-processed via resampling.
|
|
41398
41530
|
* Volume is applied via WAV sample scaling. Stereo ITD applied for depth.
|
|
41399
41531
|
*/
|
|
41400
|
-
|
|
41401
|
-
|
|
41402
|
-
|
|
41403
|
-
|
|
41532
|
+
/**
|
|
41533
|
+
* Synthesize text to a WAV file via LuxTTS daemon (synthesis only, no playback).
|
|
41534
|
+
* Returns the WAV file path or null on failure.
|
|
41535
|
+
* Used by drainQueue's pre-fetch pipeline for gapless back-to-back playback.
|
|
41536
|
+
*/
|
|
41537
|
+
async synthesizeLuxttsWav(text, speedFactor = 1) {
|
|
41538
|
+
if (!this.luxttsCloneRef || !existsSync35(this.luxttsCloneRef))
|
|
41539
|
+
return null;
|
|
41404
41540
|
const cleaned = text.replace(/\*/g, "").trim();
|
|
41405
41541
|
if (!cleaned)
|
|
41406
|
-
return;
|
|
41542
|
+
return null;
|
|
41407
41543
|
const ready = await this.ensureLuxttsDaemon();
|
|
41408
41544
|
if (!ready)
|
|
41409
|
-
return;
|
|
41410
|
-
const wavPath = join50(tmpdir9(), `oa-luxtts-${Date.now()}.wav`);
|
|
41545
|
+
return null;
|
|
41546
|
+
const wavPath = join50(tmpdir9(), `oa-luxtts-${Date.now()}-${Math.random().toString(36).slice(2, 6)}.wav`);
|
|
41411
41547
|
try {
|
|
41412
41548
|
await this.luxttsRequest({
|
|
41413
41549
|
action: "synthesize",
|
|
@@ -41417,8 +41553,15 @@ if __name__ == '__main__':
|
|
|
41417
41553
|
speed: speedFactor
|
|
41418
41554
|
});
|
|
41419
41555
|
} catch {
|
|
41420
|
-
return;
|
|
41556
|
+
return null;
|
|
41421
41557
|
}
|
|
41558
|
+
return existsSync35(wavPath) ? wavPath : null;
|
|
41559
|
+
}
|
|
41560
|
+
/**
|
|
41561
|
+
* Post-process (fade-in, volume, pitch, stereo) and play a LuxTTS WAV file.
|
|
41562
|
+
* Cleans up the WAV file after playback.
|
|
41563
|
+
*/
|
|
41564
|
+
async postProcessAndPlayLuxtts(wavPath, volume = 1, pitchFactor = 1, stereoDelayMs = 0.6) {
|
|
41422
41565
|
if (!existsSync35(wavPath))
|
|
41423
41566
|
return;
|
|
41424
41567
|
try {
|
|
@@ -41493,6 +41636,13 @@ if __name__ == '__main__':
|
|
|
41493
41636
|
} catch {
|
|
41494
41637
|
}
|
|
41495
41638
|
}
|
|
41639
|
+
/** Combined synthesize + post-process + play for LuxTTS (used by synthesizeAndPlay) */
|
|
41640
|
+
async synthesizeWithLuxtts(text, volume = 1, pitchFactor = 1, speedFactor = 1, stereoDelayMs = 0.6) {
|
|
41641
|
+
const wavPath = await this.synthesizeLuxttsWav(text, speedFactor);
|
|
41642
|
+
if (!wavPath)
|
|
41643
|
+
return;
|
|
41644
|
+
await this.postProcessAndPlayLuxtts(wavPath, volume, pitchFactor, stereoDelayMs);
|
|
41645
|
+
}
|
|
41496
41646
|
/**
|
|
41497
41647
|
* Synthesize text to WAV buffer using LuxTTS (no playback).
|
|
41498
41648
|
* Used for Telegram voice messages and WebSocket streaming.
|
|
@@ -42124,6 +42274,85 @@ async function handleSlashCommand(input, ctx) {
|
|
|
42124
42274
|
return "handled";
|
|
42125
42275
|
}
|
|
42126
42276
|
case "ipfs": {
|
|
42277
|
+
const ipfsSubCmd = (arg || "").trim().split(/\s+/);
|
|
42278
|
+
const ipfsAction = ipfsSubCmd[0]?.toLowerCase() || "";
|
|
42279
|
+
const ipfsArg = ipfsSubCmd.slice(1).join(" ");
|
|
42280
|
+
if (ipfsAction === "pin" && ipfsArg) {
|
|
42281
|
+
const cidToPin = ipfsArg.trim();
|
|
42282
|
+
if (!cidToPin.startsWith("bafy") && !cidToPin.startsWith("bafk") && !cidToPin.startsWith("Qm")) {
|
|
42283
|
+
renderWarning("Invalid CID format. Must start with bafy, bafk, or Qm");
|
|
42284
|
+
return "handled";
|
|
42285
|
+
}
|
|
42286
|
+
try {
|
|
42287
|
+
const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
|
|
42288
|
+
const nexus = new NexusTool2(ctx.repoRoot);
|
|
42289
|
+
const result = await nexus.execute({ action: "ipfs_pin", cid: cidToPin, source: "user-pin" });
|
|
42290
|
+
if (result.success) {
|
|
42291
|
+
renderInfo(`Pinned: ${cidToPin}`);
|
|
42292
|
+
} else {
|
|
42293
|
+
renderWarning(`Pin failed: ${result.output}`);
|
|
42294
|
+
}
|
|
42295
|
+
} catch (e) {
|
|
42296
|
+
renderWarning(`Pin failed: ${e.message ?? e}`);
|
|
42297
|
+
}
|
|
42298
|
+
return "handled";
|
|
42299
|
+
}
|
|
42300
|
+
if (ipfsAction === "publish") {
|
|
42301
|
+
try {
|
|
42302
|
+
const { IdentityKernelTool: IdentityKernelTool2 } = __require("@open-agents/execution");
|
|
42303
|
+
const ik = new IdentityKernelTool2(ctx.repoRoot);
|
|
42304
|
+
const result = await ik.execute({ operation: "publish_snapshot" });
|
|
42305
|
+
if (result.success) {
|
|
42306
|
+
const cidMatch = result.output.match(/CID:\s*(bafy\S+|bafk\S+)/);
|
|
42307
|
+
if (cidMatch) {
|
|
42308
|
+
safeLog(`
|
|
42309
|
+
${c2.bold("Identity Published")}`);
|
|
42310
|
+
safeLog(` CID: ${c2.bold(cidMatch[1])}`);
|
|
42311
|
+
safeLog(` ${c2.dim("Share this CID with other agents: /ipfs pin " + cidMatch[1])}
|
|
42312
|
+
`);
|
|
42313
|
+
} else {
|
|
42314
|
+
safeLog(result.output);
|
|
42315
|
+
}
|
|
42316
|
+
} else {
|
|
42317
|
+
renderWarning(result.output);
|
|
42318
|
+
}
|
|
42319
|
+
} catch (e) {
|
|
42320
|
+
renderWarning(`Publish failed: ${e.message ?? e}`);
|
|
42321
|
+
}
|
|
42322
|
+
return "handled";
|
|
42323
|
+
}
|
|
42324
|
+
if (ipfsAction === "cids" || ipfsAction === "ls" || ipfsAction === "pins") {
|
|
42325
|
+
try {
|
|
42326
|
+
const { NexusTool: NexusTool2 } = __require("@open-agents/execution");
|
|
42327
|
+
const nexus = new NexusTool2(ctx.repoRoot);
|
|
42328
|
+
const result = await nexus.execute({ action: "ipfs_ls" });
|
|
42329
|
+
if (result.success) {
|
|
42330
|
+
const data = JSON.parse(result.output);
|
|
42331
|
+
const pins = data.pins || [];
|
|
42332
|
+
if (pins.length === 0) {
|
|
42333
|
+
renderInfo("No pinned CIDs. Use /ipfs publish to publish your identity.");
|
|
42334
|
+
} else {
|
|
42335
|
+
const lines2 = [`
|
|
42336
|
+
${c2.bold("Pinned CIDs")} (${pins.length})
|
|
42337
|
+
`];
|
|
42338
|
+
for (const p of pins.slice(0, 20)) {
|
|
42339
|
+
const src = p.source ? c2.dim(` (${p.source})`) : "";
|
|
42340
|
+
const pin = p.pinned ? c2.green("pinned") : c2.yellow("registered");
|
|
42341
|
+
lines2.push(` ${pin} ${c2.bold(p.cid.slice(0, 30))}...${src}`);
|
|
42342
|
+
}
|
|
42343
|
+
if (pins.length > 20)
|
|
42344
|
+
lines2.push(` ${c2.dim(`... and ${pins.length - 20} more`)}`);
|
|
42345
|
+
lines2.push("");
|
|
42346
|
+
safeLog(lines2.join("\n"));
|
|
42347
|
+
}
|
|
42348
|
+
} else {
|
|
42349
|
+
renderWarning(result.output);
|
|
42350
|
+
}
|
|
42351
|
+
} catch (e) {
|
|
42352
|
+
renderWarning(`List failed: ${e.message ?? e}`);
|
|
42353
|
+
}
|
|
42354
|
+
return "handled";
|
|
42355
|
+
}
|
|
42127
42356
|
const lines = [];
|
|
42128
42357
|
lines.push(`
|
|
42129
42358
|
${c2.bold("IPFS / Helia Status")}
|
|
@@ -42169,6 +42398,26 @@ async function handleSlashCommand(input, ctx) {
|
|
|
42169
42398
|
lines.push(` ${c2.dim("Helia blocks:")}`);
|
|
42170
42399
|
lines.push(` Blocks: ${c2.bold(String(heliaBlocks))} Size: ${c2.bold(formatFileSize(heliaBytes))}`);
|
|
42171
42400
|
lines.push(` Backend: ${heliaBlocks > 0 ? c2.green("helia-ipfs") : c2.yellow("sha256-local (Helia not initialized)")}`);
|
|
42401
|
+
try {
|
|
42402
|
+
const statusFile = join51(ctx.repoRoot, ".oa", "nexus", "status.json");
|
|
42403
|
+
if (existsSync36(statusFile)) {
|
|
42404
|
+
const status = JSON.parse(readFileSync25(statusFile, "utf8"));
|
|
42405
|
+
if (status.peerId) {
|
|
42406
|
+
lines.push(`
|
|
42407
|
+
${c2.bold("Peer Info")}`);
|
|
42408
|
+
lines.push(` Peer ID: ${c2.bold(status.peerId.slice(0, 20))}...`);
|
|
42409
|
+
if (status.multiaddrs && status.multiaddrs.length > 0) {
|
|
42410
|
+
lines.push(` Addresses: ${status.multiaddrs.length}`);
|
|
42411
|
+
for (const addr of status.multiaddrs.slice(0, 3)) {
|
|
42412
|
+
lines.push(` ${c2.dim(addr)}`);
|
|
42413
|
+
}
|
|
42414
|
+
}
|
|
42415
|
+
}
|
|
42416
|
+
}
|
|
42417
|
+
} catch {
|
|
42418
|
+
}
|
|
42419
|
+
lines.push(`
|
|
42420
|
+
${c2.dim("Commands: /ipfs pin <CID> /ipfs publish /ipfs cids")}`);
|
|
42172
42421
|
lines.push(`
|
|
42173
42422
|
${c2.bold("Identity Kernel")}`);
|
|
42174
42423
|
const idDir = join51(ctx.repoRoot, ".oa", "identity");
|
package/package.json
CHANGED