@nekzus/liop 2.0.0-alpha.2 → 2.0.0-alpha.4

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/README.md CHANGED
@@ -49,7 +49,7 @@ This fundamentally solves the data privacy, bandwidth, and latency challenges of
49
49
  ## Installation
50
50
 
51
51
  ```bash
52
- npm install @nekzus/liop
52
+ npm install @nekzus/liop@latest
53
53
  ```
54
54
 
55
55
  > **Requirements:** Node.js ≥ 20.0. The SDK uses `node:crypto`, `node:vm`, and `piscina` (worker threads) internally.
@@ -58,7 +58,7 @@ npm install @nekzus/liop
58
58
 
59
59
  ## LIOP Agent (CLI)
60
60
 
61
- The SDK includes a zero-config agent (`liop-agent`) designed to bridge the Logic-Injection-on-Origin Protocol with local AI clients like **Claude Desktop**.
61
+ The SDK includes a zero-config agent CLI (`liop`) designed to bridge the Logic-Injection-on-Origin Protocol with local AI clients like **Claude Desktop**.
62
62
 
63
63
  ### Installation & Run
64
64
 
@@ -66,23 +66,28 @@ You can run the agent directly using `npx` (recommended) or install it globally:
66
66
 
67
67
  ```bash
68
68
  # Run instantly
69
- npx @nekzus/liop
69
+ npx @nekzus/liop@latest
70
70
 
71
71
  # Or install globally
72
- npm install -g @nekzus/liop
73
- liop-agent
72
+ npm install -g @nekzus/liop@latest
73
+ liop
74
74
  ```
75
75
 
76
76
  ### 🤖 Claude Desktop Configuration
77
77
 
78
- To use the Neural Mesh inside Claude Desktop, update your `claude_desktop_config.json` (typically found in `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
78
+ To integrate LIOP into Claude Desktop, update your `claude_desktop_config.json` (typically found in `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
79
79
 
80
80
  ```json
81
81
  {
82
82
  "mcpServers": {
83
- "liop-agent": {
83
+ "liop": {
84
84
  "command": "npx",
85
- "args": ["-y", "@nekzus/liop"]
85
+ "args": ["-y", "@nekzus/liop@latest"],
86
+ "env": {
87
+ "LIOP_NEXUS_URL": "http://your-nexus-host:3000",
88
+ "LIOP_LOG_LEVEL": "info",
89
+ "NODE_OPTIONS": "--use-system-ca"
90
+ }
86
91
  }
87
92
  }
88
93
  }
@@ -95,7 +100,7 @@ The agent automatically manages your P2P identity:
95
100
  - **Identity Path**: `~/.liop/identity.json`. This file contains your unique PeerID. Keep it safe if you want to maintain a consistent identity in the mesh.
96
101
  - **Bootstrap Nodes**: By default, the agent connects to the **LIOP Alpha Nexus**. You can provide custom bootstrap addresses as CLI arguments:
97
102
  ```bash
98
- npx @nekzus/liop /ip4/1.2.3.4/tcp/4001/p2p/PEER_ID
103
+ npx @nekzus/liop@latest /ip4/1.2.3.4/tcp/4001/p2p/PEER_ID
99
104
  ```
100
105
 
101
106
  ---
@@ -198,7 +203,11 @@ new LiopServer(
198
203
  forbiddenKeys?: string[]; // Keys stripped from outgoing responses
199
204
  enableNerScanning?: boolean; // NLP entity detection via compromise (default: false)
200
205
  rateLimit?: { // Sliding window rate limiter per tool
201
- maxPerWindow?: number; // Max calls per window (default: 30)
206
+ maxPerWindow?: number; // Max calls per window (default: 15)
207
+ windowMs?: number; // Window duration in ms (default: 60000)
208
+ };
209
+ globalRateLimit?: { // Cross-tool aggregate rate limiter
210
+ maxPerWindow?: number; // Max total calls per window (default: 40)
202
211
  windowMs?: number; // Window duration in ms (default: 60000)
203
212
  };
204
213
  };
@@ -260,20 +269,21 @@ await bridge.connect();
260
269
  ```
261
270
  ┌───────────────────────────────────────────────────────────┐
262
271
  │ Layer 1: Guardian AST (Zero-Time Static Analysis) │
263
- Blocks: require, import(), fs, eval, fetch, process,
264
- global, __proto__, XMLHttpRequest 128 import cap
272
+ 14-function WASI allowlist • 128 import cap Blocks
273
+ require, import(), fs, eval, fetch, __proto__
265
274
  ├───────────────────────────────────────────────────────────┤
266
275
  │ Layer 2: WASI Sandbox (V8 Isolate) │
267
276
  │ 25 poisoned globals (incl. Date, TypedArrays) • │
268
277
  │ CPU Fuel limits • 5s timeout • maxHeapMb (64MB default) │
278
+ │ Object.freeze() on 6 core prototypes │
269
279
  ├───────────────────────────────────────────────────────────┤
270
- │ Layer 3: Prototype Pollution Defense
271
- Object.freeze() on 6 core prototypes (Object, Array,
272
- String, Number, Boolean, Function) inside sandbox IIFE
280
+ │ Layer 3: Taint Analyzer (IFC — Static)
281
+ Acorn AST 3-pass analysis blocks PII side-channels:
282
+ charCodeAt, boolean inference, arithmetic derivation
273
283
  ├───────────────────────────────────────────────────────────┤
274
284
  │ Layer 4: PII Shield (Egress Filter) │
275
- Scans output for Email, SSN, Credit Card, IP, IBAN,
276
- Passport MRZ Strips forbidden keys • NER opt-in
285
+ 4-stage pipeline: exact key fuzzy key pattern
286
+ validators (Luhn, IBAN Mod-97) NER (compromise)
277
287
  ├───────────────────────────────────────────────────────────┤
278
288
  │ Layer 5: Aggregation-First Policy │
279
289
  │ Blocks raw row export • maxOutputRows (default: 10) • │
@@ -281,7 +291,7 @@ await bridge.connect();
281
291
  ├───────────────────────────────────────────────────────────┤
282
292
  │ Layer 6: ZK-Receipt (Integrity Verification) │
283
293
  │ SHA-256 ImageID + HMAC-SHA256 Seal (Kyber768-derived) │
284
- LiopMcpBridge verifies before forwarding to LLM
294
+ Timing-safe verification LiopMcpBridge auto-verifies
285
295
  └───────────────────────────────────────────────────────────┘
286
296
  ```
287
297
 
@@ -331,9 +341,10 @@ The following shows a complete Logic-Injection-on-Origin execution cycle (handle
331
341
  2. LiopServer receives the payload via tools/call (JSON-RPC or direct)
332
342
  3. Guardian AST inspects for sandbox escapes (zero-time heuristic analysis)
333
343
  4. Code executes inside a V8 isolate with CPU fuel limits (no Node.js globals)
334
- 5. PII Shield scans output for forbidden data and keys
335
- 6. ZK-Receipt generated (SHA-256 logic hash + SHA-512 seal)
336
- 7. Result + receipt returned to the LLM (raw data never exposed)
344
+ 5. Taint Analyzer blocks PII side-channel derivation (charCodeAt, boolean inference)
345
+ 6. PII Shield scans output for forbidden data and keys
346
+ 7. ZK-Receipt generated (SHA-256 ImageID + HMAC-SHA256 seal)
347
+ 8. Result + receipt returned to the LLM (raw data never exposed)
337
348
  ```
338
349
 
339
350
  ### Data Dictionary & Zero-Shot Autonomy
@@ -414,11 +425,11 @@ await server.connectToMesh();
414
425
 
415
426
  This package is continuously tested across multiple platforms and Node.js versions via CI/CD:
416
427
 
417
- - **227+ tests** spanning unit, integration, conformance, adversarial, and crossnet suites
428
+ - **259+ tests** spanning unit, integration, conformance, adversarial, and crossnet suites
418
429
  - **Multi-OS matrix:** Ubuntu, Windows, macOS
419
- - **Node.js versions:** 22.x, 24.x
430
+ - **Node.js versions:** 20.x, 22.x
420
431
  - **Code quality:** Enforced by [Biome.js](https://biomejs.dev/) (linting + formatting)
421
- - **Security:** Verified defense-in-depth architecture — see [Security Architecture](https://nekzus-32.mintlify.app/typescript-sdk/security)
432
+ - **Security:** Verified 6-layer defense-in-depth architecture — see [Security Architecture](https://nekzus-32.mintlify.app/typescript-sdk/security)
422
433
 
423
434
  > To run tests locally or contribute, clone the [repository](https://github.com/Nekzus/LIOP) and follow the [Contributing Guide](https://github.com/Nekzus/LIOP/blob/main/CONTRIBUTING.md).
424
435
 
package/dist/bin/agent.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import {f as f$1}from'../chunk-X6FJATUE.js';import {g}from'../chunk-4ABAFG44.js';import'../chunk-UVTEJYHN.js';import'../chunk-ANFXJGMP.js';import'../chunk-DBXGYHKY.js';import'../chunk-HM77MWB6.js';import'../chunk-RWRRBYG4.js';import {a as a$1}from'../chunk-PPCOS2NU.js';import {a}from'../chunk-S6RJHZV2.js';import*as p from'fs';import*as $ from'os';import*as f from'path';import {multiaddr}from'@multiformats/multiaddr';async function b(t){try{let c=t.endsWith("/health")?t:`${t}/health`,u=await fetch(c,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!u.ok)return null;let e=await u.json();if(!e.mesh?.multiaddrs?.length||!e.mesh?.peerId)return null;let l=e.mesh.multiaddrs.find(r=>r.includes("/tcp/")&&!r.includes("/ws")&&!r.includes("/ip4/127.0.0.1/"));if(!l)return null;let o=R(l);if(!o||o===l){let r=new URL(t).hostname;o=l.replace(/\/ip4\/[^/]+/,`/ip4/${r}`);}return o?(o+=o.includes("/p2p/")?"":`/p2p/${e.mesh.peerId}`,o):null}catch{return null}}function P(t){let c=t.trim(),u=/\/ip4\/172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}/,e=/\/ip4\/127\.0\.0\.1/,l=/\/ip4\/192\.168\.[0-9]{1,3}\.[0-9]{1,3}/;if(u.test(c)||e.test(c)||l.test(c)){let o="127.0.0.1",r=c.replace(u,`/ip4/${o}`).replace(e,`/ip4/${o}`).replace(l,`/ip4/${o}`);return r!==c&&a.info(`[LIOP-Agent] \u{1F504} Local Routing Hack \u2192 Forced 127.0.0.1: ${r}`),r}return c}function R(t){return t.includes("/ip4/172.20.0.10")?t.replace(/\/ip4\/172\.20\.0\.10\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13001"):t.includes("/ip4/172.20.0.11")?t.replace(/\/ip4\/172\.20\.0\.11\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13003"):t.includes("/ip4/172.20.0.12")?t.replace(/\/ip4\/172\.20\.0\.12\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13004"):t.includes("/ip4/172.20.0.13")?t.replace(/\/ip4\/172\.20\.0\.13\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13005"):t.includes("/ip4/127.0.0.1/tcp/4000")||t.includes("/ip4/127.0.0.1/tcp/3000")?null:t}async function x(){let t=new Date().toISOString();a.info(`[LIOP-Agent] \u{1F680} Version 1.2.0-alpha.9 | Build: ${t}`);let c=f.join($.homedir(),".liop"),u=f.join(c,"identity.json");p.existsSync(c)||p.mkdirSync(c,{recursive:true});let e=[],l=process.argv.slice(2);if(l.length>0&&(e=l.filter(n=>n.startsWith("/"))),e.length===0){let n=[];if(process.env.LIOP_BOOTSTRAP_FILE){let s=f.resolve(process.env.LIOP_BOOTSTRAP_FILE);if(p.existsSync(s)){let a=p.readFileSync(s,"utf8").trim();a&&e.push(P(a));}}n.push(process.cwd(),f.join(process.cwd(),"tests/infra/nexus-data"),c,f.join(f.dirname(new URL(import.meta.url).pathname).replace(/^\/([A-Z]:)/,"$1"),"../../tests/infra/nexus-data"));for(let s of n)try{if(p.existsSync(s)){let m=p.readdirSync(s).filter(g=>g.endsWith(".multiaddr"));for(let g of m){let T=f.join(s,g),S=p.readFileSync(T,"utf8").trim();if(S){let y=P(S);e.includes(y)||(e.push(y),a.info(`[LIOP-Agent] \u2705 Loaded beacon: ${g} from ${s}`));}}if(e.length>0)break}}catch{}}if(process.env.LIOP_NEXUS_URL){let n=process.env.LIOP_NEXUS_URL;a.info(`[LIOP-Agent] \u{1F310} Running parallel discovery from: ${n} (Sources Found: ${e.length})`);let s=await b(n);if(s){let a$1=P(s);e.includes(a$1)||(e.push(a$1),a.info(`[LIOP-Agent] \u2705 Added bootstrap from URL discovery: ${a$1}`));}}e.length===0&&process.env.LIOP_BOOTSTRAP&&e.push(process.env.LIOP_BOOTSTRAP.trim()),e.length===0&&e.push("/ip4/127.0.0.1/tcp/13001/p2p/12D3KooWD8FUFdnLQzzLFNdicsaTknM5cpD7os9sK9NWVSVABJMD"),e=e.filter(n=>{try{return multiaddr(n),!0}catch{return a.warn(`[LIOP-Agent] Ignoring invalid bootstrap multiaddr: ${n}`),false}}),e.length===0&&(a.info("[LIOP-Agent] No bootstrap nodes configured. Operating in standalone mode."),a.info("[LIOP-Agent] Pass a multiaddr as argument or create 'nexus.multiaddr' file."));let o=new f$1({name:"@nekzus/liop-agent",version:"1.0.0"});o.enableZeroShotAutonomy();let r=new a$1({identityPath:u,bootstrapNodes:e,addressMapper:R});await r.start();let d=new g(o,r);d.onToolsChanged=()=>{process.stdout.write(`{"jsonrpc":"2.0","method":"notifications/tools/list_changed"}
2
+ import {f}from'../chunk-FW6CICSY.js';import {g}from'../chunk-7MAGL6ON.js';import'../chunk-UVTEJYHN.js';import'../chunk-ANFXJGMP.js';import'../chunk-DBXGYHKY.js';import'../chunk-HM77MWB6.js';import'../chunk-RWRRBYG4.js';import {a as a$1}from'../chunk-PPCOS2NU.js';import {a}from'../chunk-S6RJHZV2.js';import*as l from'fs';import*as _ from'os';import*as d from'path';import {multiaddr}from'@multiformats/multiaddr';async function x(t){try{let c=t.endsWith("/health")?t:`${t}/health`,u=await fetch(c,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!u.ok)return null;let e=await u.json();if(!e.mesh?.multiaddrs?.length||!e.mesh?.peerId)return null;let p=e.mesh.multiaddrs.find(a=>a.includes("/tcp/")&&!a.includes("/ws")&&!a.includes("/ip4/127.0.0.1/"));if(!p)return null;let i=process.env.NODE_ENV==="development"||process.env.NODE_ENV==="test"?N(p):p;if(!i||i===p){let a=new URL(t).hostname;i=p.replace(/\/ip4\/[^/]+/,`/ip4/${a}`);}return i?(i+=i.includes("/p2p/")?"":`/p2p/${e.mesh.peerId}`,i):null}catch{return null}}function P(t){let c=t.trim(),u=/\/ip4\/172\.(1[6-9]|2[0-9]|3[0-1])\.[0-9]{1,3}\.[0-9]{1,3}/,e=/\/ip4\/127\.0\.0\.1/,p=/\/ip4\/192\.168\.[0-9]{1,3}\.[0-9]{1,3}/;if(u.test(c)||e.test(c)||p.test(c)){let f="127.0.0.1",i=c.replace(u,`/ip4/${f}`).replace(e,`/ip4/${f}`).replace(p,`/ip4/${f}`);return i!==c&&a.info(`[LIOP-Agent] \u{1F504} Local Routing Hack \u2192 Forced 127.0.0.1: ${i}`),i}return c}function N(t){return t.includes("/ip4/172.20.0.10")?t.replace(/\/ip4\/172\.20\.0\.10\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13001"):t.includes("/ip4/172.20.0.11")?t.replace(/\/ip4\/172\.20\.0\.11\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13003"):t.includes("/ip4/172.20.0.12")?t.replace(/\/ip4\/172\.20\.0\.12\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13004"):t.includes("/ip4/172.20.0.13")?t.replace(/\/ip4\/172\.20\.0\.13\/tcp\/[0-9]+/,"/ip4/127.0.0.1/tcp/13005"):t.includes("/ip4/127.0.0.1/tcp/4000")||t.includes("/ip4/127.0.0.1/tcp/3000")?null:t}async function E(){if((process.platform==="win32"||process.platform==="darwin")&&!process.execArgv.includes("--use-system-ca")&&!(process.env.NODE_OPTIONS??"").includes("--use-system-ca")){let{spawn:s}=await import('child_process'),n=s(process.execPath,["--use-system-ca",...process.argv.slice(1)],{stdio:"inherit",env:process.env});n.on("exit",r=>process.exit(r??1)),n.on("error",()=>process.exit(1)),await new Promise(()=>{});return}let t=new Date().toISOString();a.info(`[LIOP-Agent] \u{1F680} Version 1.2.0-alpha.9 | Build: ${t}`);let c=d.join(_.homedir(),".liop"),u=d.join(c,"identity.json");l.existsSync(c)||l.mkdirSync(c,{recursive:true});let e=[],p=process.argv.slice(2);if(p.length>0&&(e=p.filter(s=>s.startsWith("/"))),e.length===0){let s=[];if(process.env.LIOP_BOOTSTRAP_FILE){a.warn("LIOP_BOOTSTRAP_FILE is deprecated and will be removed in the next major version. Use LIOP_NEXUS_URL for Auto-Discovery instead.");let n=d.resolve(process.env.LIOP_BOOTSTRAP_FILE);if(l.existsSync(n)){let r=l.readFileSync(n,"utf8").trim();r&&e.push(P(r));}}s.push(process.cwd(),d.join(process.cwd(),"tests/infra/nexus-data"),c,d.join(d.dirname(new URL(import.meta.url).pathname).replace(/^\/([A-Z]:)/,"$1"),"../../tests/infra/nexus-data"));for(let n of s)try{if(l.existsSync(n)){let h=l.readdirSync(n).filter(g=>g.endsWith(".multiaddr"));for(let g of h){let T=d.join(n,g),I=l.readFileSync(T,"utf8").trim();if(I){let S=P(I);e.includes(S)||(e.push(S),a.info(`[LIOP-Agent] \u2705 Loaded beacon: ${g} from ${n}`));}}if(e.length>0)break}}catch{}}if(process.env.LIOP_NEXUS_URL){let s=process.env.LIOP_NEXUS_URL;a.info(`[LIOP-Agent] \u{1F310} Running parallel discovery from: ${s} (Sources Found: ${e.length})`);let n=await x(s);if(n){let r=P(n);e.includes(r)||(e.push(r),a.info(`[LIOP-Agent] \u2705 Added bootstrap from URL discovery: ${r}`));}}e.length===0&&process.env.LIOP_BOOTSTRAP&&e.push(process.env.LIOP_BOOTSTRAP.trim()),e.length===0&&e.push("/ip4/127.0.0.1/tcp/13001/p2p/12D3KooWD8FUFdnLQzzLFNdicsaTknM5cpD7os9sK9NWVSVABJMD"),e=e.filter(s=>{try{return multiaddr(s),!0}catch{return a.warn(`[LIOP-Agent] Ignoring invalid bootstrap multiaddr: ${s}`),false}}),e.length===0&&(a.info("[LIOP-Agent] No bootstrap nodes configured. Operating in standalone mode."),a.info("[LIOP-Agent] Pass a multiaddr as argument or create 'nexus.multiaddr' file."));let f$1=new f({name:"@nekzus/liop",version:"1.0.0"});f$1.enableZeroShotAutonomy();let i=new a$1({identityPath:u,bootstrapNodes:e,addressMapper:process.env.NODE_ENV==="development"||process.env.NODE_ENV==="test"?N:void 0});await i.start();let a$2=new g(f$1,i);a$2.onToolsChanged=()=>{process.stdout.write(`{"jsonrpc":"2.0","method":"notifications/tools/list_changed"}
3
3
  `),process.stdout.write(`{"jsonrpc":"2.0","method":"notifications/resources/list_changed"}
4
- `);},setTimeout(()=>{let n=r.getRoutingTableSize?.()||0;a.info(`[LIOP-Agent] Warm-up complete. Routing Table size: ${n}`),d.refreshManifestCache(true).catch(()=>{});},2e3);let L=1e4,_=12e4,h=L,I=()=>{setTimeout(async()=>{let n=d.getCacheSize();await d.refreshManifestCache(true).catch(()=>{});let s=d.getCacheSize();s!==n?(h=L,a.info(`[LIOP-Agent] Topology change detected (${n} \u2192 ${s}). Resetting poll to ${L/1e3}s.`)):h=Math.min(Math.round(h*1.5),_),I();},h);};I();let O=(await import('readline')).createInterface({input:process.stdin,terminal:false});process.stdout.on("error",n=>{n.code==="EPIPE"&&process.exit(0);}),O.on("line",async n=>{let s=n.trim();if(s)try{let a=JSON.parse(s);if(a.method){let m=await d.dispatch(a);m&&process.stdout.write(`${JSON.stringify(m)}
5
- `);}}catch{}}),O.on("close",()=>{process.exit(0);}),a.info("[LIOP-Agent] Guarding Claude Desktop via STDIO."),a.info(`[LIOP-Agent] P2P Mesh: Joined (${e.length} bootstraps)`),a.info("[LIOP-Agent] Tool discovery: Dynamic via /liop/manifest/1.0.0"),process.on("SIGINT",async()=>{await r.stop(),process.exit(0);});}x().catch(t=>{a.error(`[LIOP-Agent] Fatal Error: ${t.message}`),process.exit(1);});//# sourceMappingURL=agent.js.map
4
+ `);},setTimeout(()=>{let s=i.getRoutingTableSize?.()||0;a.info(`[LIOP-Agent] Warm-up complete. Routing Table size: ${s}`),a$2.refreshManifestCache(true).catch(()=>{});},2e3);let O=1e4,R=12e4,m=O,v=()=>{setTimeout(async()=>{let s=a$2.getCacheSize();await a$2.refreshManifestCache(true).catch(()=>{});let n=a$2.getCacheSize();n!==s?(m=O,a.info(`[LIOP-Agent] Topology change detected (${s} \u2192 ${n}). Resetting poll to ${O/1e3}s.`)):m=Math.min(Math.round(m*1.5),R),v();},m);};v();let L=(await import('readline')).createInterface({input:process.stdin,terminal:false});process.stdout.on("error",s=>{s.code==="EPIPE"&&process.exit(0);}),L.on("line",async s=>{let n=s.trim();if(n)try{let r=JSON.parse(n);if(r.method){let h=await a$2.dispatch(r);h&&process.stdout.write(`${JSON.stringify(h)}
5
+ `);}}catch{}}),L.on("close",()=>{process.exit(0);}),a.info("[LIOP-Agent] Guarding Claude Desktop via STDIO."),a.info(`[LIOP-Agent] P2P Mesh: Joined (${e.length} bootstraps)`),a.info("[LIOP-Agent] Tool discovery: Dynamic via /liop/manifest/1.0.0"),process.on("SIGINT",async()=>{await i.stop(),process.exit(0);});}E().catch(t=>{a.error(`[LIOP-Agent] Fatal Error: ${t.message}`),process.exit(1);});//# sourceMappingURL=agent.js.map
6
6
  //# sourceMappingURL=agent.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/agent.ts"],"names":["resolveBootstrapFromUrl","url","healthUrl","response","data","tcpAddr","a","resolved","industrialAddressMapper","urlHost","normalizeBootstrap","addr","trimmed","dockerIpRegex","loopbackRegex","physicalIpRegex","targetIp","normalized","log","main","buildTime","liopDir","identityPath","bootstrapNodes","args","searchDirs","filePath","dir","multiaddrFiles","f","file","nexusUrl","multiaddr","liopServer","LiopServer","meshNode","MeshNode","router","LiopMcpRouter","rtSize","POLL_BASE_MS","POLL_MAX_MS","pollIntervalMs","scheduleAdaptivePoll","prevSize","newSize","rl","err","line","request"],"mappings":"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","file":"agent.js","sourcesContent":["#!/usr/bin/env node\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { multiaddr } from \"@multiformats/multiaddr\";\nimport { LiopMcpRouter } from \"../gateway/router.js\";\nimport { MeshNode } from \"../mesh/index.js\";\nimport { LiopServer } from \"../server/index.js\";\nimport type { McpRequest } from \"../types.js\";\nimport { log } from \"../utils/logger.js\";\n\n/**\n * Resolves a full libp2p multiaddr (with PeerID) from a LIOP node's\n * HTTP health endpoint. This enables zero-config bootstrap — users\n * only need to provide a URL, not a cryptographic PeerID.\n *\n * @param url - HTTP URL of a LIOP node's health endpoint (e.g. \"http://host:3000\")\n * @returns Full multiaddr string with PeerID, or null if resolution fails\n */\nasync function resolveBootstrapFromUrl(url: string): Promise<string | null> {\n\ttry {\n\t\tconst healthUrl = url.endsWith(\"/health\") ? url : `${url}/health`;\n\t\tconst response = await fetch(healthUrl, {\n\t\t\theaders: { Accept: \"application/json\" },\n\t\t\tsignal: AbortSignal.timeout(10000), // Increased to 10s\n\t\t});\n\t\tif (!response.ok) return null;\n\n\t\tconst data = await response.json();\n\t\tif (!data.mesh?.multiaddrs?.length || !data.mesh?.peerId) return null;\n\n\t\t// Find TCP multiaddr (prefer non-websocket for stability)\n\t\tconst tcpAddr = data.mesh.multiaddrs.find(\n\t\t\t(a: string) =>\n\t\t\t\ta.includes(\"/tcp/\") &&\n\t\t\t\t!a.includes(\"/ws\") &&\n\t\t\t\t!a.includes(\"/ip4/127.0.0.1/\"),\n\t\t);\n\t\tif (!tcpAddr) return null;\n\n\t\t// Rewrite internal Docker IP using industrial mapper if available\n\t\tlet resolved = industrialAddressMapper(tcpAddr);\n\t\tif (!resolved || resolved === tcpAddr) {\n\t\t\tconst urlHost = new URL(url).hostname;\n\t\t\tresolved = tcpAddr.replace(/\\/ip4\\/[^/]+/, `/ip4/${urlHost}`);\n\t\t}\n\n\t\tif (!resolved) return null;\n\n\t\tresolved += resolved.includes(\"/p2p/\") ? \"\" : `/p2p/${data.mesh.peerId}`;\n\n\t\treturn resolved;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Normalizes a bootstrap multiaddr string.\n * If the address contains a Docker bridge IP (172.16-31.x.x) or Loopback (127.0.0.1),\n * rewrites it to the host accessible via LIOP_NEXUS_URL (e.g. WSL2 IP).\n * This is critical when WSL2 mirror-mode networking is broken.\n */\nfunction normalizeBootstrap(addr: string): string {\n\tconst trimmed = addr.trim();\n\t// Remap Docker bridge IPs and ANY external physical IPs to 127.0.0.1\n\t// because Test-NetConnection confirmed 127.0.0.1 is the only reliable path to Docker ports.\n\tconst dockerIpRegex =\n\t\t/\\/ip4\\/172\\.(1[6-9]|2[0-9]|3[0-1])\\.[0-9]{1,3}\\.[0-9]{1,3}/;\n\tconst loopbackRegex = /\\/ip4\\/127\\.0\\.0\\.1/;\n\tconst physicalIpRegex = /\\/ip4\\/192\\.168\\.[0-9]{1,3}\\.[0-9]{1,3}/;\n\n\tif (\n\t\tdockerIpRegex.test(trimmed) ||\n\t\tloopbackRegex.test(trimmed) ||\n\t\tphysicalIpRegex.test(trimmed)\n\t) {\n\t\tconst targetIp = \"127.0.0.1\";\n\t\tconst normalized = trimmed\n\t\t\t.replace(dockerIpRegex, `/ip4/${targetIp}`)\n\t\t\t.replace(loopbackRegex, `/ip4/${targetIp}`)\n\t\t\t.replace(physicalIpRegex, `/ip4/${targetIp}`);\n\n\t\tif (normalized !== trimmed) {\n\t\t\tlog.info(\n\t\t\t\t`[LIOP-Agent] 🔄 Local Routing Hack → Forced 127.0.0.1: ${normalized}`,\n\t\t\t);\n\t\t}\n\t\treturn normalized;\n\t}\n\n\treturn trimmed;\n}\n\n/**\n * industrialAddressMapper\n *\n * Mapea IPs internas de Docker a puertos industriales mapeados en el Host.\n * Nexus (172.20.0.10) -> 13001\n * Vault (172.20.0.11) -> 13003\n * Bank (172.20.0.12) -> 13004\n * Oracle(172.20.0.13) -> 13005\n */\nfunction industrialAddressMapper(addr: string): string | null {\n\tif (addr.includes(\"/ip4/172.20.0.10\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.10\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13001\",\n\t\t);\n\tif (addr.includes(\"/ip4/172.20.0.11\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.11\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13003\",\n\t\t);\n\tif (addr.includes(\"/ip4/172.20.0.12\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.12\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13004\",\n\t\t);\n\tif (addr.includes(\"/ip4/172.20.0.13\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.13\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13005\",\n\t\t);\n\n\t// Drop container-internal loopbacks to prevent the Host Agent from dialing itself or conflicting ports\n\tif (\n\t\taddr.includes(\"/ip4/127.0.0.1/tcp/4000\") ||\n\t\taddr.includes(\"/ip4/127.0.0.1/tcp/3000\")\n\t) {\n\t\treturn null;\n\t}\n\n\treturn addr;\n}\n\n/**\n * LIOP Agent (Zero-Config CLI)\n *\n * Secure Logic-on-Origin gateway for Claude Desktop.\n * Communicates via STDIO / JSON-RPC.\n *\n * All tool discovery is DYNAMIC via the /liop/manifest/1.0.0 protocol.\n * No hardcoded tools, PeerIDs, or port mappings.\n */\nasync function main() {\n\tconst buildTime = new Date().toISOString();\n\tlog.info(`[LIOP-Agent] 🚀 Version 1.2.0-alpha.9 | Build: ${buildTime}`);\n\n\tconst liopDir = path.join(os.homedir(), \".liop\");\n\tconst identityPath = path.join(liopDir, \"identity.json\");\n\n\tif (!fs.existsSync(liopDir)) {\n\t\tfs.mkdirSync(liopDir, { recursive: true });\n\t}\n\n\t// 1. Determine Bootstrap Nodes (Zero-Config Discovery)\n\tlet bootstrapNodes: string[] = [];\n\n\t// Command line arguments take precedence\n\tconst args = process.argv.slice(2);\n\tif (args.length > 0) {\n\t\tbootstrapNodes = args.filter((a) => a.startsWith(\"/\"));\n\t}\n\n\t// Priority 1: Physical Beacons (Industrial Pattern) - DETERMINISTIC & INSTANT\n\tif (bootstrapNodes.length === 0) {\n\t\tconst searchDirs = [];\n\n\t\t// Priority 1.1: Explicit file from environment variable\n\t\tif (process.env.LIOP_BOOTSTRAP_FILE) {\n\t\t\tconst filePath = path.resolve(process.env.LIOP_BOOTSTRAP_FILE);\n\t\t\tif (fs.existsSync(filePath)) {\n\t\t\t\tconst addr = fs.readFileSync(filePath, \"utf8\").trim();\n\t\t\t\tif (addr) bootstrapNodes.push(normalizeBootstrap(addr));\n\t\t\t}\n\t\t}\n\n\t\t// Priority 1.2: Traditional locations (Scan for all *.multiaddr)\n\t\tsearchDirs.push(\n\t\t\tprocess.cwd(),\n\t\t\tpath.join(process.cwd(), \"tests/infra/nexus-data\"),\n\t\t\tliopDir,\n\t\t\tpath.join(\n\t\t\t\tpath\n\t\t\t\t\t.dirname(new URL(import.meta.url).pathname)\n\t\t\t\t\t.replace(/^\\/([A-Z]:)/, \"$1\"),\n\t\t\t\t\"../../tests/infra/nexus-data\",\n\t\t\t),\n\t\t);\n\n\t\tfor (const dir of searchDirs) {\n\t\t\ttry {\n\t\t\t\tif (fs.existsSync(dir)) {\n\t\t\t\t\tconst files = fs.readdirSync(dir);\n\t\t\t\t\tconst multiaddrFiles = files.filter((f) => f.endsWith(\".multiaddr\"));\n\n\t\t\t\t\tfor (const file of multiaddrFiles) {\n\t\t\t\t\t\tconst filePath = path.join(dir, file);\n\t\t\t\t\t\tconst addr = fs.readFileSync(filePath, \"utf8\").trim();\n\t\t\t\t\t\tif (addr) {\n\t\t\t\t\t\t\tconst normalized = normalizeBootstrap(addr);\n\t\t\t\t\t\t\tif (!bootstrapNodes.includes(normalized)) {\n\t\t\t\t\t\t\t\tbootstrapNodes.push(normalized);\n\t\t\t\t\t\t\t\tlog.info(`[LIOP-Agent] ✅ Loaded beacon: ${file} from ${dir}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If we found any beacons in this directory, we consider discovery successful for this layer\n\t\t\t\t\tif (bootstrapNodes.length > 0) break;\n\t\t\t\t}\n\t\t\t} catch (_e) {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\t}\n\t}\n\n\t// Priority 2: Auto-Discovery via NEXUS URL (Aggressive Parallel Discovery)\n\tif (process.env.LIOP_NEXUS_URL) {\n\t\tconst nexusUrl = process.env.LIOP_NEXUS_URL;\n\t\tlog.info(\n\t\t\t`[LIOP-Agent] 🌐 Running parallel discovery from: ${nexusUrl} (Sources Found: ${bootstrapNodes.length})`,\n\t\t);\n\n\t\tconst resolved = await resolveBootstrapFromUrl(nexusUrl);\n\t\tif (resolved) {\n\t\t\tconst normalized = normalizeBootstrap(resolved);\n\t\t\tif (!bootstrapNodes.includes(normalized)) {\n\t\t\t\tbootstrapNodes.push(normalized);\n\t\t\t\tlog.info(\n\t\t\t\t\t`[LIOP-Agent] ✅ Added bootstrap from URL discovery: ${normalized}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Priority 3: Environment variable (direct multiaddr)\n\tif (bootstrapNodes.length === 0 && process.env.LIOP_BOOTSTRAP) {\n\t\tbootstrapNodes.push(process.env.LIOP_BOOTSTRAP.trim());\n\t}\n\n\t// Final fallback: local Nexus bootstrap for demo environments.\n\t// Avoid injecting stale static peer IDs when discovery already found valid peers.\n\tif (bootstrapNodes.length === 0) {\n\t\tbootstrapNodes.push(\n\t\t\t\"/ip4/127.0.0.1/tcp/13001/p2p/12D3KooWD8FUFdnLQzzLFNdicsaTknM5cpD7os9sK9NWVSVABJMD\",\n\t\t);\n\t}\n\n\t// Sanitize/validate all candidate multiaddrs so malformed PeerIDs don't crash startup.\n\tbootstrapNodes = bootstrapNodes.filter((addr) => {\n\t\ttry {\n\t\t\tmultiaddr(addr);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tlog.warn(`[LIOP-Agent] Ignoring invalid bootstrap multiaddr: ${addr}`);\n\t\t\treturn false;\n\t\t}\n\t});\n\n\t// If no bootstrap nodes found, the agent operates in standalone mode.\n\t// It will only serve local tools until peers are discovered.\n\tif (bootstrapNodes.length === 0) {\n\t\tlog.info(\n\t\t\t\"[LIOP-Agent] No bootstrap nodes configured. Operating in standalone mode.\",\n\t\t);\n\t\tlog.info(\n\t\t\t\"[LIOP-Agent] Pass a multiaddr as argument or create 'nexus.multiaddr' file.\",\n\t\t);\n\t}\n\n\t// Initialize local server node (lightweight, no tools registered locally)\n\tconst liopServer = new LiopServer({\n\t\tname: \"@nekzus/liop-agent\",\n\t\tversion: \"1.0.0\",\n\t});\n\n\t// Enable Zero-Shot Autonomy (Industrial Prompt Injection)\n\tliopServer.enableZeroShotAutonomy();\n\n\t// 2. Mesh Node Configuration\n\tconst meshNode = new MeshNode({\n\t\tidentityPath: identityPath,\n\t\tbootstrapNodes: bootstrapNodes,\n\t\taddressMapper: industrialAddressMapper,\n\t});\n\n\t// Start P2P Mesh\n\tawait meshNode.start();\n\n\t// 3. Initialize the Dynamic Router\n\t// No hardcoded tools — all discovery happens via liop:manifest protocol\n\tconst router = new LiopMcpRouter(liopServer, meshNode);\n\n\t// Proactive Notification to Claude Desktop when tools/resources are discovered dynamically\n\trouter.onToolsChanged = () => {\n\t\tprocess.stdout.write(\n\t\t\t`{\"jsonrpc\":\"2.0\",\"method\":\"notifications/tools/list_changed\"}\\n`,\n\t\t);\n\t\tprocess.stdout.write(\n\t\t\t`{\"jsonrpc\":\"2.0\",\"method\":\"notifications/resources/list_changed\"}\\n`,\n\t\t);\n\t};\n\n\t// Initial warming period (2s) then Adaptive Background Discovery\n\t// Polls DHT for new nodes and triggers onToolsChanged when topology shifts.\n\t// Uses exponential backoff to reduce polling load on stable meshes.\n\tsetTimeout(() => {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: access internal for telemetry\n\t\tconst rtSize = (meshNode as any).getRoutingTableSize?.() || 0;\n\t\tlog.info(`[LIOP-Agent] Warm-up complete. Routing Table size: ${rtSize}`);\n\t\trouter.refreshManifestCache(true).catch(() => {});\n\t}, 2000);\n\n\tconst POLL_BASE_MS = 10_000;\n\tconst POLL_MAX_MS = 120_000;\n\tlet pollIntervalMs = POLL_BASE_MS;\n\n\tconst scheduleAdaptivePoll = () => {\n\t\tsetTimeout(async () => {\n\t\t\tconst prevSize = router.getCacheSize();\n\t\t\tawait router.refreshManifestCache(true).catch(() => {});\n\t\t\tconst newSize = router.getCacheSize();\n\n\t\t\tif (newSize !== prevSize) {\n\t\t\t\t// Topology changed — reset to aggressive polling\n\t\t\t\tpollIntervalMs = POLL_BASE_MS;\n\t\t\t\tlog.info(\n\t\t\t\t\t`[LIOP-Agent] Topology change detected (${prevSize} → ${newSize}). Resetting poll to ${POLL_BASE_MS / 1000}s.`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Stable — relax polling interval (factor 1.5)\n\t\t\t\tpollIntervalMs = Math.min(\n\t\t\t\t\tMath.round(pollIntervalMs * 1.5),\n\t\t\t\t\tPOLL_MAX_MS,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscheduleAdaptivePoll();\n\t\t}, pollIntervalMs);\n\t};\n\n\tscheduleAdaptivePoll();\n\n\t// 4. STDIO Transport — Buffered Line Reader\n\t// Uses readline to guarantee complete JSON-RPC messages before parsing.\n\t// Raw stdin.on(\"data\") can fragment large payloads across multiple chunks.\n\tconst readline = await import(\"node:readline\");\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\tterminal: false,\n\t});\n\n\tprocess.stdout.on(\"error\", (err: Error & { code?: string }) => {\n\t\tif (err.code === \"EPIPE\") {\n\t\t\tprocess.exit(0); // Graceful exit when Claude Desktop disconnects\n\t\t}\n\t});\n\n\trl.on(\"line\", async (line) => {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) return;\n\n\t\ttry {\n\t\t\tconst request = JSON.parse(trimmed) as McpRequest;\n\t\t\tif (request.method) {\n\t\t\t\tconst response = await router.dispatch(request);\n\t\t\t\tif (response) {\n\t\t\t\t\tprocess.stdout.write(`${JSON.stringify(response)}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (_err) {\n\t\t\t// Silent catch for binary noise or malformed lines\n\t\t}\n\t});\n\n\trl.on(\"close\", () => {\n\t\tprocess.exit(0);\n\t});\n\n\t// Status directed only to stderr\n\tlog.info(`[LIOP-Agent] Guarding Claude Desktop via STDIO.`);\n\tlog.info(\n\t\t`[LIOP-Agent] P2P Mesh: Joined (${bootstrapNodes.length} bootstraps)`,\n\t);\n\tlog.info(\"[LIOP-Agent] Tool discovery: Dynamic via /liop/manifest/1.0.0\");\n\n\tprocess.on(\"SIGINT\", async () => {\n\t\tawait meshNode.stop();\n\t\tprocess.exit(0);\n\t});\n}\n\nmain().catch((err) => {\n\tlog.error(`[LIOP-Agent] Fatal Error: ${err.message}`);\n\tprocess.exit(1);\n});\n"]}
1
+ {"version":3,"sources":["../../src/bin/agent.ts"],"names":["resolveBootstrapFromUrl","url","healthUrl","response","data","tcpAddr","resolved","industrialAddressMapper","urlHost","normalizeBootstrap","addr","trimmed","dockerIpRegex","loopbackRegex","physicalIpRegex","targetIp","normalized","log","main","spawn","child","code","buildTime","liopDir","identityPath","bootstrapNodes","args","a","searchDirs","filePath","dir","multiaddrFiles","f","file","nexusUrl","multiaddr","liopServer","LiopServer","meshNode","MeshNode","router","LiopMcpRouter","rtSize","POLL_BASE_MS","POLL_MAX_MS","pollIntervalMs","scheduleAdaptivePoll","prevSize","newSize","rl","err","line","request"],"mappings":"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","file":"agent.js","sourcesContent":["#!/usr/bin/env node\nimport * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { multiaddr } from \"@multiformats/multiaddr\";\nimport { LiopMcpRouter } from \"../gateway/router.js\";\nimport { MeshNode } from \"../mesh/index.js\";\nimport { LiopServer } from \"../server/index.js\";\nimport type { McpRequest } from \"../types.js\";\nimport { log } from \"../utils/logger.js\";\n\n/**\n * Resolves a full libp2p multiaddr (with PeerID) from a LIOP node's\n * HTTP health endpoint. This enables zero-config bootstrap — users\n * only need to provide a URL, not a cryptographic PeerID.\n *\n * @param url - HTTP URL of a LIOP node's health endpoint (e.g. \"http://host:3000\")\n * @returns Full multiaddr string with PeerID, or null if resolution fails\n */\nasync function resolveBootstrapFromUrl(url: string): Promise<string | null> {\n\ttry {\n\t\tconst healthUrl = url.endsWith(\"/health\") ? url : `${url}/health`;\n\t\tconst response = await fetch(healthUrl, {\n\t\t\theaders: { Accept: \"application/json\" },\n\t\t\tsignal: AbortSignal.timeout(10000), // Increased to 10s\n\t\t});\n\t\tif (!response.ok) return null;\n\n\t\tconst data = await response.json();\n\t\tif (!data.mesh?.multiaddrs?.length || !data.mesh?.peerId) return null;\n\n\t\t// Find TCP multiaddr (prefer non-websocket for stability)\n\t\tconst tcpAddr = data.mesh.multiaddrs.find(\n\t\t\t(a: string) =>\n\t\t\t\ta.includes(\"/tcp/\") &&\n\t\t\t\t!a.includes(\"/ws\") &&\n\t\t\t\t!a.includes(\"/ip4/127.0.0.1/\"),\n\t\t);\n\t\tif (!tcpAddr) return null;\n\n\t\t// Rewrite internal Docker IP using development mapper if available\n\t\tconst isDevMode =\n\t\t\tprocess.env.NODE_ENV === \"development\" || process.env.NODE_ENV === \"test\";\n\t\tlet resolved = isDevMode ? industrialAddressMapper(tcpAddr) : tcpAddr;\n\t\tif (!resolved || resolved === tcpAddr) {\n\t\t\tconst urlHost = new URL(url).hostname;\n\t\t\tresolved = tcpAddr.replace(/\\/ip4\\/[^/]+/, `/ip4/${urlHost}`);\n\t\t}\n\n\t\tif (!resolved) return null;\n\n\t\tresolved += resolved.includes(\"/p2p/\") ? \"\" : `/p2p/${data.mesh.peerId}`;\n\n\t\treturn resolved;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Normalizes a bootstrap multiaddr string.\n * If the address contains a Docker bridge IP (172.16-31.x.x) or Loopback (127.0.0.1),\n * rewrites it to the host accessible via LIOP_NEXUS_URL (e.g. WSL2 IP).\n * This is critical when WSL2 mirror-mode networking is broken.\n */\nfunction normalizeBootstrap(addr: string): string {\n\tconst trimmed = addr.trim();\n\t// Remap Docker bridge IPs and ANY external physical IPs to 127.0.0.1\n\t// because Test-NetConnection confirmed 127.0.0.1 is the only reliable path to Docker ports.\n\tconst dockerIpRegex =\n\t\t/\\/ip4\\/172\\.(1[6-9]|2[0-9]|3[0-1])\\.[0-9]{1,3}\\.[0-9]{1,3}/;\n\tconst loopbackRegex = /\\/ip4\\/127\\.0\\.0\\.1/;\n\tconst physicalIpRegex = /\\/ip4\\/192\\.168\\.[0-9]{1,3}\\.[0-9]{1,3}/;\n\n\tif (\n\t\tdockerIpRegex.test(trimmed) ||\n\t\tloopbackRegex.test(trimmed) ||\n\t\tphysicalIpRegex.test(trimmed)\n\t) {\n\t\tconst targetIp = \"127.0.0.1\";\n\t\tconst normalized = trimmed\n\t\t\t.replace(dockerIpRegex, `/ip4/${targetIp}`)\n\t\t\t.replace(loopbackRegex, `/ip4/${targetIp}`)\n\t\t\t.replace(physicalIpRegex, `/ip4/${targetIp}`);\n\n\t\tif (normalized !== trimmed) {\n\t\t\tlog.info(\n\t\t\t\t`[LIOP-Agent] 🔄 Local Routing Hack → Forced 127.0.0.1: ${normalized}`,\n\t\t\t);\n\t\t}\n\t\treturn normalized;\n\t}\n\n\treturn trimmed;\n}\n\n/**\n * industrialAddressMapper (DEVELOPMENT ONLY)\n *\n * Maps Docker-internal IPs to host-published ports for local demo environments.\n * This function is ONLY active when NODE_ENV is \"development\" or \"test\".\n * In production, it is completely bypassed.\n *\n * Nexus (172.20.0.10) -> 13001\n * Vault (172.20.0.11) -> 13003\n * Bank (172.20.0.12) -> 13004\n * Oracle(172.20.0.13) -> 13005\n */\nfunction industrialAddressMapper(addr: string): string | null {\n\tif (addr.includes(\"/ip4/172.20.0.10\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.10\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13001\",\n\t\t);\n\tif (addr.includes(\"/ip4/172.20.0.11\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.11\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13003\",\n\t\t);\n\tif (addr.includes(\"/ip4/172.20.0.12\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.12\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13004\",\n\t\t);\n\tif (addr.includes(\"/ip4/172.20.0.13\"))\n\t\treturn addr.replace(\n\t\t\t/\\/ip4\\/172\\.20\\.0\\.13\\/tcp\\/[0-9]+/,\n\t\t\t\"/ip4/127.0.0.1/tcp/13005\",\n\t\t);\n\n\t// Drop container-internal loopbacks to prevent the Host Agent from dialing itself or conflicting ports\n\tif (\n\t\taddr.includes(\"/ip4/127.0.0.1/tcp/4000\") ||\n\t\taddr.includes(\"/ip4/127.0.0.1/tcp/3000\")\n\t) {\n\t\treturn null;\n\t}\n\n\treturn addr;\n}\n\n/**\n * LIOP Agent (Zero-Config CLI)\n *\n * Secure Logic-on-Origin gateway for Claude Desktop.\n * Communicates via STDIO / JSON-RPC.\n *\n * All tool discovery is DYNAMIC via the /liop/manifest/1.0.0 protocol.\n * No hardcoded tools, PeerIDs, or port mappings.\n */\nasync function main() {\n\t// Auto-Relaunch: Ensure system CA certificates are loaded for TLS compatibility.\n\t// Corporate proxies (Cloudflare WARP, Zscaler) inject custom root CAs into the\n\t// OS certificate store. Node.js ignores these by default, causing UNABLE_TO_VERIFY_LEAF_SIGNATURE.\n\t// Pattern: if --use-system-ca is not active, re-spawn with the flag transparently.\n\t// stdio: \"inherit\" ensures Claude Desktop's JSON-RPC pipe is passed through cleanly.\n\tif (\n\t\t(process.platform === \"win32\" || process.platform === \"darwin\") &&\n\t\t!process.execArgv.includes(\"--use-system-ca\") &&\n\t\t!(process.env.NODE_OPTIONS ?? \"\").includes(\"--use-system-ca\")\n\t) {\n\t\tconst { spawn } = await import(\"node:child_process\");\n\t\tconst child = spawn(\n\t\t\tprocess.execPath,\n\t\t\t[\"--use-system-ca\", ...process.argv.slice(1)],\n\t\t\t{ stdio: \"inherit\", env: process.env },\n\t\t);\n\t\tchild.on(\"exit\", (code) => process.exit(code ?? 1));\n\t\tchild.on(\"error\", () => process.exit(1));\n\t\t// Block parent — child handles all I/O from here\n\t\tawait new Promise(() => {});\n\t\treturn;\n\t}\n\n\tconst buildTime = new Date().toISOString();\n\tlog.info(`[LIOP-Agent] 🚀 Version 1.2.0-alpha.9 | Build: ${buildTime}`);\n\n\tconst liopDir = path.join(os.homedir(), \".liop\");\n\tconst identityPath = path.join(liopDir, \"identity.json\");\n\n\tif (!fs.existsSync(liopDir)) {\n\t\tfs.mkdirSync(liopDir, { recursive: true });\n\t}\n\n\t// 1. Determine Bootstrap Nodes (Zero-Config Discovery)\n\tlet bootstrapNodes: string[] = [];\n\n\t// Command line arguments take precedence\n\tconst args = process.argv.slice(2);\n\tif (args.length > 0) {\n\t\tbootstrapNodes = args.filter((a) => a.startsWith(\"/\"));\n\t}\n\n\t// Priority 1: Physical Beacons (Industrial Pattern) - DETERMINISTIC & INSTANT\n\tif (bootstrapNodes.length === 0) {\n\t\tconst searchDirs = [];\n\n\t\t// Priority 1.1: Explicit file from environment variable\n\t\tif (process.env.LIOP_BOOTSTRAP_FILE) {\n\t\t\tlog.warn(\n\t\t\t\t\"LIOP_BOOTSTRAP_FILE is deprecated and will be removed in the next major version. \" +\n\t\t\t\t\t\"Use LIOP_NEXUS_URL for Auto-Discovery instead.\",\n\t\t\t);\n\t\t\tconst filePath = path.resolve(process.env.LIOP_BOOTSTRAP_FILE);\n\t\t\tif (fs.existsSync(filePath)) {\n\t\t\t\tconst addr = fs.readFileSync(filePath, \"utf8\").trim();\n\t\t\t\tif (addr) bootstrapNodes.push(normalizeBootstrap(addr));\n\t\t\t}\n\t\t}\n\n\t\t// Priority 1.2: Traditional locations (Scan for all *.multiaddr)\n\t\tsearchDirs.push(\n\t\t\tprocess.cwd(),\n\t\t\tpath.join(process.cwd(), \"tests/infra/nexus-data\"),\n\t\t\tliopDir,\n\t\t\tpath.join(\n\t\t\t\tpath\n\t\t\t\t\t.dirname(new URL(import.meta.url).pathname)\n\t\t\t\t\t.replace(/^\\/([A-Z]:)/, \"$1\"),\n\t\t\t\t\"../../tests/infra/nexus-data\",\n\t\t\t),\n\t\t);\n\n\t\tfor (const dir of searchDirs) {\n\t\t\ttry {\n\t\t\t\tif (fs.existsSync(dir)) {\n\t\t\t\t\tconst files = fs.readdirSync(dir);\n\t\t\t\t\tconst multiaddrFiles = files.filter((f) => f.endsWith(\".multiaddr\"));\n\n\t\t\t\t\tfor (const file of multiaddrFiles) {\n\t\t\t\t\t\tconst filePath = path.join(dir, file);\n\t\t\t\t\t\tconst addr = fs.readFileSync(filePath, \"utf8\").trim();\n\t\t\t\t\t\tif (addr) {\n\t\t\t\t\t\t\tconst normalized = normalizeBootstrap(addr);\n\t\t\t\t\t\t\tif (!bootstrapNodes.includes(normalized)) {\n\t\t\t\t\t\t\t\tbootstrapNodes.push(normalized);\n\t\t\t\t\t\t\t\tlog.info(`[LIOP-Agent] ✅ Loaded beacon: ${file} from ${dir}`);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t// If we found any beacons in this directory, we consider discovery successful for this layer\n\t\t\t\t\tif (bootstrapNodes.length > 0) break;\n\t\t\t\t}\n\t\t\t} catch (_e) {\n\t\t\t\t/* ignore */\n\t\t\t}\n\t\t}\n\t}\n\n\t// Priority 2: Auto-Discovery via NEXUS URL (Aggressive Parallel Discovery)\n\tif (process.env.LIOP_NEXUS_URL) {\n\t\tconst nexusUrl = process.env.LIOP_NEXUS_URL;\n\t\tlog.info(\n\t\t\t`[LIOP-Agent] 🌐 Running parallel discovery from: ${nexusUrl} (Sources Found: ${bootstrapNodes.length})`,\n\t\t);\n\n\t\tconst resolved = await resolveBootstrapFromUrl(nexusUrl);\n\t\tif (resolved) {\n\t\t\tconst normalized = normalizeBootstrap(resolved);\n\t\t\tif (!bootstrapNodes.includes(normalized)) {\n\t\t\t\tbootstrapNodes.push(normalized);\n\t\t\t\tlog.info(\n\t\t\t\t\t`[LIOP-Agent] ✅ Added bootstrap from URL discovery: ${normalized}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Priority 3: Environment variable (direct multiaddr)\n\tif (bootstrapNodes.length === 0 && process.env.LIOP_BOOTSTRAP) {\n\t\tbootstrapNodes.push(process.env.LIOP_BOOTSTRAP.trim());\n\t}\n\n\t// Final fallback: local Nexus bootstrap for demo environments.\n\t// Avoid injecting stale static peer IDs when discovery already found valid peers.\n\tif (bootstrapNodes.length === 0) {\n\t\tbootstrapNodes.push(\n\t\t\t\"/ip4/127.0.0.1/tcp/13001/p2p/12D3KooWD8FUFdnLQzzLFNdicsaTknM5cpD7os9sK9NWVSVABJMD\",\n\t\t);\n\t}\n\n\t// Sanitize/validate all candidate multiaddrs so malformed PeerIDs don't crash startup.\n\tbootstrapNodes = bootstrapNodes.filter((addr) => {\n\t\ttry {\n\t\t\tmultiaddr(addr);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\tlog.warn(`[LIOP-Agent] Ignoring invalid bootstrap multiaddr: ${addr}`);\n\t\t\treturn false;\n\t\t}\n\t});\n\n\t// If no bootstrap nodes found, the agent operates in standalone mode.\n\t// It will only serve local tools until peers are discovered.\n\tif (bootstrapNodes.length === 0) {\n\t\tlog.info(\n\t\t\t\"[LIOP-Agent] No bootstrap nodes configured. Operating in standalone mode.\",\n\t\t);\n\t\tlog.info(\n\t\t\t\"[LIOP-Agent] Pass a multiaddr as argument or create 'nexus.multiaddr' file.\",\n\t\t);\n\t}\n\n\t// Initialize local server node (lightweight, no tools registered locally)\n\tconst liopServer = new LiopServer({\n\t\tname: \"@nekzus/liop\",\n\t\tversion: \"1.0.0\",\n\t});\n\n\t// Enable Zero-Shot Autonomy (Industrial Prompt Injection)\n\tliopServer.enableZeroShotAutonomy();\n\n\t// 2. Mesh Node Configuration\n\tconst meshNode = new MeshNode({\n\t\tidentityPath: identityPath,\n\t\tbootstrapNodes: bootstrapNodes,\n\t\taddressMapper:\n\t\t\tprocess.env.NODE_ENV === \"development\" || process.env.NODE_ENV === \"test\"\n\t\t\t\t? industrialAddressMapper\n\t\t\t\t: undefined,\n\t});\n\n\t// Start P2P Mesh\n\tawait meshNode.start();\n\n\t// 3. Initialize the Dynamic Router\n\t// No hardcoded tools — all discovery happens via liop:manifest protocol\n\tconst router = new LiopMcpRouter(liopServer, meshNode);\n\n\t// Proactive Notification to Claude Desktop when tools/resources are discovered dynamically\n\trouter.onToolsChanged = () => {\n\t\tprocess.stdout.write(\n\t\t\t`{\"jsonrpc\":\"2.0\",\"method\":\"notifications/tools/list_changed\"}\\n`,\n\t\t);\n\t\tprocess.stdout.write(\n\t\t\t`{\"jsonrpc\":\"2.0\",\"method\":\"notifications/resources/list_changed\"}\\n`,\n\t\t);\n\t};\n\n\t// Initial warming period (2s) then Adaptive Background Discovery\n\t// Polls DHT for new nodes and triggers onToolsChanged when topology shifts.\n\t// Uses exponential backoff to reduce polling load on stable meshes.\n\tsetTimeout(() => {\n\t\t// biome-ignore lint/suspicious/noExplicitAny: access internal for telemetry\n\t\tconst rtSize = (meshNode as any).getRoutingTableSize?.() || 0;\n\t\tlog.info(`[LIOP-Agent] Warm-up complete. Routing Table size: ${rtSize}`);\n\t\trouter.refreshManifestCache(true).catch(() => {});\n\t}, 2000);\n\n\tconst POLL_BASE_MS = 10_000;\n\tconst POLL_MAX_MS = 120_000;\n\tlet pollIntervalMs = POLL_BASE_MS;\n\n\tconst scheduleAdaptivePoll = () => {\n\t\tsetTimeout(async () => {\n\t\t\tconst prevSize = router.getCacheSize();\n\t\t\tawait router.refreshManifestCache(true).catch(() => {});\n\t\t\tconst newSize = router.getCacheSize();\n\n\t\t\tif (newSize !== prevSize) {\n\t\t\t\t// Topology changed — reset to aggressive polling\n\t\t\t\tpollIntervalMs = POLL_BASE_MS;\n\t\t\t\tlog.info(\n\t\t\t\t\t`[LIOP-Agent] Topology change detected (${prevSize} → ${newSize}). Resetting poll to ${POLL_BASE_MS / 1000}s.`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\t// Stable — relax polling interval (factor 1.5)\n\t\t\t\tpollIntervalMs = Math.min(\n\t\t\t\t\tMath.round(pollIntervalMs * 1.5),\n\t\t\t\t\tPOLL_MAX_MS,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tscheduleAdaptivePoll();\n\t\t}, pollIntervalMs);\n\t};\n\n\tscheduleAdaptivePoll();\n\n\t// 4. STDIO Transport — Buffered Line Reader\n\t// Uses readline to guarantee complete JSON-RPC messages before parsing.\n\t// Raw stdin.on(\"data\") can fragment large payloads across multiple chunks.\n\tconst readline = await import(\"node:readline\");\n\tconst rl = readline.createInterface({\n\t\tinput: process.stdin,\n\t\tterminal: false,\n\t});\n\n\tprocess.stdout.on(\"error\", (err: Error & { code?: string }) => {\n\t\tif (err.code === \"EPIPE\") {\n\t\t\tprocess.exit(0); // Graceful exit when Claude Desktop disconnects\n\t\t}\n\t});\n\n\trl.on(\"line\", async (line) => {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) return;\n\n\t\ttry {\n\t\t\tconst request = JSON.parse(trimmed) as McpRequest;\n\t\t\tif (request.method) {\n\t\t\t\tconst response = await router.dispatch(request);\n\t\t\t\tif (response) {\n\t\t\t\t\tprocess.stdout.write(`${JSON.stringify(response)}\\n`);\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (_err) {\n\t\t\t// Silent catch for binary noise or malformed lines\n\t\t}\n\t});\n\n\trl.on(\"close\", () => {\n\t\tprocess.exit(0);\n\t});\n\n\t// Status directed only to stderr\n\tlog.info(`[LIOP-Agent] Guarding Claude Desktop via STDIO.`);\n\tlog.info(\n\t\t`[LIOP-Agent] P2P Mesh: Joined (${bootstrapNodes.length} bootstraps)`,\n\t);\n\tlog.info(\"[LIOP-Agent] Tool discovery: Dynamic via /liop/manifest/1.0.0\");\n\n\tprocess.on(\"SIGINT\", async () => {\n\t\tawait meshNode.stop();\n\t\tprocess.exit(0);\n\t});\n}\n\nmain().catch((err) => {\n\tlog.error(`[LIOP-Agent] Fatal Error: ${err.message}`);\n\tprocess.exit(1);\n});\n"]}
package/dist/bridge.js CHANGED
@@ -1,2 +1,2 @@
1
- export{b as LiopMcpBridge,a as LiopStreamBridge}from'./chunk-XLVRRGOX.js';import'./chunk-S6RJHZV2.js';//# sourceMappingURL=bridge.js.map
1
+ export{b as LiopMcpBridge,a as LiopStreamBridge}from'./chunk-LYULZHZO.js';import'./chunk-S6RJHZV2.js';//# sourceMappingURL=bridge.js.map
2
2
  //# sourceMappingURL=bridge.js.map
@@ -0,0 +1,33 @@
1
+ import {a as a$1}from'./chunk-UVTEJYHN.js';import {a as a$3}from'./chunk-DBXGYHKY.js';import {a as a$2,c}from'./chunk-HM77MWB6.js';import {a}from'./chunk-S6RJHZV2.js';import {metrics}from'@opentelemetry/api';import*as w from'crypto';var C=class{name="o200k_base";countFn;constructor(e,r){this.countFn=e,r&&r(1e4);}countTokens(e){return e.length===0?0:this.countFn(e)}},R=class{name="heuristic (chars/4)";countTokens(e){return e.length===0?0:Math.ceil(e.length/4)}};async function B(){try{let y=await import('gpt-tokenizer'),e=new C(y.countTokens,y.setMergeCacheSize);return a.debug("[LIOP-Economy] Token estimator initialized: o200k_base"),e}catch{return a.info("[LIOP-Economy] gpt-tokenizer unavailable, falling back to heuristic estimator"),new R}}function U(){return new R}var H="@nekzus/liop",J="1.2.0-alpha.9",q=[1,4,16,64,256,1024,4096,16384,65536,262144,1048576,4194304,16777216,67108864],Q=[.01,.02,.04,.08,.16,.32,.64,1.28,2.56,5.12,10.24,20.48,40.96,81.92],N=class{tokenUsage;operationDuration;active=false;constructor(){try{let e=metrics.getMeter(H,J);this.tokenUsage=e.createHistogram("gen_ai.client.token.usage",{description:"Number of tokens used in LIOP Logic-on-Origin operations",unit:"{token}",advice:{explicitBucketBoundaries:q}}),this.operationDuration=e.createHistogram("gen_ai.client.operation.duration",{description:"Duration of LIOP operations",unit:"s",advice:{explicitBucketBoundaries:Q}}),this.active=!0,a.debug("[LIOP-OTel] gen_ai.* metrics bridge initialized");}catch(e){a.debug(`[LIOP-OTel] Bridge disabled: ${e instanceof Error?e.message:String(e)}`);let r={record:()=>{}};this.tokenUsage=r,this.operationDuration=r;}}recordTokens(e,r,s,n){this.tokenUsage.record(e,{"gen_ai.system":"liop","gen_ai.operation.name":s,"gen_ai.token.type":r,"gen_ai.request.model":"liop-mesh",...n?{"liop.tool.name":n}:{}});}recordDuration(e,r,s){this.operationDuration.record(e/1e3,{"gen_ai.system":"liop","gen_ai.operation.name":r,...s?{"error.type":s}:{}});}isActive(){return this.active}};var W={tools_list:"chat",tool_call:"execute_tool",resource_read:"chat",resource_list:"chat",prompt_get:"chat",prompt_list:"chat",diagnostic:"chat"},I=class y{static instance=null;operations=[];sessionId;startedAt;estimator;otelBridge;constructor(){this.sessionId=crypto.randomUUID(),this.startedAt=Date.now(),this.estimator=U(),this.otelBridge=new N,this.initRealEstimator();}initRealEstimator(){B().then(e=>{this.estimator=e;}).catch(()=>{});}static getInstance(){return y.instance||(y.instance=new y),y.instance}countTokens(e){try{return this.estimator.countTokens(e)}catch{return Math.ceil(e.length/4)}}record(e){let r={...e,timestamp:Date.now()};this.operations.push(r);try{let s=W[e.type]||"chat";e.estimatedInputTokens>0&&this.otelBridge.recordTokens(e.estimatedInputTokens,"input",s,e.toolName),e.estimatedOutputTokens>0&&this.otelBridge.recordTokens(e.estimatedOutputTokens,"output",s,e.toolName),e.durationMs!==void 0&&this.otelBridge.recordDuration(e.durationMs,s);}catch{}}estimateTokens(e){return this.countTokens(e)}getReport(){return {sessionId:this.sessionId,operations:[...this.operations],totalInputTokens:this.operations.reduce((e,r)=>e+r.estimatedInputTokens,0),totalOutputTokens:this.operations.reduce((e,r)=>e+r.estimatedOutputTokens,0),estimatorName:this.estimator.name,sessionUptimeMs:Date.now()-this.startedAt}}getPerToolReport(){let e=new Map;for(let r of this.operations){let s=r.toolName||r.method,n=e.get(s)||{input:0,output:0,calls:0,avgDurationMs:0},t=n.avgDurationMs*n.calls+(r.durationMs||0),o=n.calls+1;e.set(s,{input:n.input+r.estimatedInputTokens,output:n.output+r.estimatedOutputTokens,calls:o,avgDurationMs:o>0?t/o:0});}return e}formatStatusBlock(){let e=this.getReport();if(e.operations.length===0)return "";let r=this.formatUptime(e.sessionUptimeMs),s=e.totalInputTokens+e.totalOutputTokens,n=new Map;for(let p of e.operations){let h=p.type,d=n.get(h)||{count:0,input:0,output:0};n.set(h,{count:d.count+1,input:d.input+p.estimatedInputTokens,output:d.output+p.estimatedOutputTokens});}let t=Array.from(n.entries()),o=t.map(([p,h],d)=>{let P=d===t.length-1?"\u2502 \u2514\u2500":"\u2502 \u251C\u2500",S=h.output>0?` / ${h.output.toLocaleString()} out`:"";return `${P} ${p} \xD7${h.count} \u2192 ${h.input.toLocaleString()} in${S}`}),c=this.getPerToolReport(),u=Array.from(c.entries()).filter(([p])=>p!=="tools/list"&&p!=="LiopMeshStatus"),i=[];u.length>0&&(i.push("\u251C\u2500 By Tool:"),u.forEach(([p,h],d)=>{let P=d===u.length-1?"\u2502 \u2514\u2500":"\u2502 \u251C\u2500",S=h.output>0?` / ${h.output.toLocaleString()} out`:"",v=h.avgDurationMs>0?` ~${Math.round(h.avgDurationMs)}ms`:"";i.push(`${P} ${p}: ${h.input.toLocaleString()} in${S} (\xD7${h.calls})${v}`);}));let f=e.operations.filter(p=>p.durationMs!==void 0),m=f.length>0?Math.round(f.reduce((p,h)=>p+(h.durationMs||0),0)/f.length):0,a=this.otelBridge.isActive()?"gen_ai.client.token.usage \u2192 active":"disabled";return [`
2
+ Token Economy:`,`\u251C\u2500 Session: ${e.sessionId.slice(0,8)} (${r})`,`\u251C\u2500 Estimator: ${e.estimatorName}`,`\u251C\u2500 Operations: ${e.operations.length}`,...o,`\u251C\u2500 Total: ${e.totalInputTokens.toLocaleString()} in / ${e.totalOutputTokens.toLocaleString()} out (${s.toLocaleString()} combined)`,...i,...m>0?[`\u251C\u2500 Avg Latency: ${m}ms`]:[],`\u2514\u2500 OTel: ${a}`].join(`
3
+ `)}formatUptime(e){let r=Math.floor(e/1e3);if(r<60)return `${r}s`;let s=Math.floor(r/60),n=r%60;if(s<60)return `${s}m ${n}s`;let t=Math.floor(s/60),o=s%60;return `${t}h ${o}m`}reset(){this.operations=[];}static destroy(){y.instance=null;}};function M(){let y=process.env.LIOP_MCP_COMPACT_TOOL_DESCRIPTIONS?.toLowerCase().trim();return !(y==="0"||y==="false"||y==="no")}function b(y){let e=y,r=[`
4
+
5
+ [LIOP-PROTO-V1:`,`\r
6
+ \r
7
+ [LIOP-PROTO-V1:`,`
8
+ [LIOP-PROTO-V1:`];for(let s of r){let n=e.indexOf(s);if(n!==-1){e=e.slice(0,n);break}}return e.trimEnd()}var z=300,$=5,F=class y{constructor(e,r=null,s=50051){this.liopServer=e;this.meshNode=r;this.defaultRpcPort=s;this.meshNode&&(this.meshNode.registerManifestHandler(()=>{let n=this.liopServer.listTools().map(o=>({name:o.name,description:o.description,inputSchema:o.inputSchema})),t=this.liopServer.listResources().map(o=>({name:o.name,uri:o.uri,description:o.description,mimeType:o.mimeType}));return {peerId:this.meshNode?.getPeerId()||"unknown",grpcPort:this.defaultRpcPort,tools:[...n],resources:t,serverInfo:this.liopServer.getServerInfo()}}),this.meshNode.announceManifest().catch(n=>{a.info(`[LIOP-Router] Failed to announce manifest: ${n instanceof Error?n.message:String(n)}`);})),process.env.LIOP_DIAGNOSTIC_LEVEL==="full"&&process.stderr.write(`\u26A0\uFE0F [LIOP-Security] Diagnostic level set to FULL \u2014 PeerIDs and network topology are exposed. Do NOT use in production.
9
+ `);}manifestCache=new Map;currentDiscovery=null;verifier=new a$1;onToolsChanged;manifestFailureState=new Map;static MANIFEST_FAILURE_BASE_COOLDOWN_MS=15e3;static MANIFEST_FAILURE_MAX_COOLDOWN_MS=5*6e4;static MANIFEST_SKIP_LOG_THROTTLE_MS=3e4;shouldSkipManifestQuery(e){let r=this.manifestFailureState.get(e);if(!r)return false;let s=Date.now();return s>=r.cooldownUntil?false:(s-r.lastSkipLogAt>y.MANIFEST_SKIP_LOG_THROTTLE_MS&&(a.info(`[LIOP-Router] Skipping manifest query for ${e} during cooldown (${Math.ceil((r.cooldownUntil-s)/1e3)}s remaining)`),r.lastSkipLogAt=s),true)}recordManifestQuerySuccess(e){this.manifestFailureState.delete(e);}recordManifestQueryFailure(e){let r=Date.now(),n=(this.manifestFailureState.get(e)?.failures||0)+1,t=Math.min(y.MANIFEST_FAILURE_BASE_COOLDOWN_MS*2**Math.max(0,n-1),y.MANIFEST_FAILURE_MAX_COOLDOWN_MS);this.manifestFailureState.set(e,{failures:n,cooldownUntil:r+t,lastSkipLogAt:0});}async dispatch(e){let{method:r,params:s,id:n}=e;switch(a.info(`[LIOP-Router] Processing: ${r}`),r){case "initialize":return {jsonrpc:"2.0",id:n,result:{protocolVersion:"2025-11-25",capabilities:{tools:{listChanged:true},resources:{listChanged:true},prompts:{listChanged:true}},serverInfo:this.liopServer.getServerInfo()}};case "notifications/initialized":return this.kickDiscoveryAfterInitialized().catch(()=>{}),null;case "notifications/cancelled":return null;case "ping":return {jsonrpc:"2.0",id:n,result:{}};case "tools/list":{let t=this.liopServer.listTools(),o=await this.getRemoteTools(),c=M()?t.map(l=>({...l,description:b(l.description??"")})):t;a.info(`[LIOP-Router] tools/list: ${t.length} local, ${o.length} remote tools found`);let i=[{name:"LiopMeshStatus",description:"LiopMeshStatus: Returns the current dynamic diagnostic status of the Zero-Trust Neural Mesh.",inputSchema:{type:"object",properties:{},additionalProperties:false}},...c,...o],f=I.getInstance(),m=JSON.stringify(i),a$1=JSON.stringify({tools:i});return f.record({type:"tools_list",method:"tools/list",estimatedInputTokens:f.countTokens(m),estimatedOutputTokens:f.countTokens(a$1)}),{jsonrpc:"2.0",id:n,result:{tools:i}}}case "tools/call":return this.transcodeMcpToLiop(n,s);case "resources/list":{let t=this.liopServer.listResources(),o=await this.getRemoteResources(),c=[...t,...o],u=I.getInstance(),i=JSON.stringify(c);return u.record({type:"resource_list",method:"resources/list",estimatedInputTokens:0,estimatedOutputTokens:u.countTokens(i)}),{jsonrpc:"2.0",id:n,result:{resources:c}}}case "resources/read":{let t=s;if(!t?.uri)return {jsonrpc:"2.0",id:n,error:{code:-32602,message:"Missing resource uri"}};try{let o=Date.now(),c=await this.liopServer.readResource(t.uri),u=I.getInstance(),i=JSON.stringify(c);return u.record({type:"resource_read",method:"resources/read",toolName:t.uri,estimatedInputTokens:u.countTokens(t.uri),estimatedOutputTokens:u.countTokens(i),durationMs:Date.now()-o}),{jsonrpc:"2.0",id:n,result:c}}catch(o){let c=t.uri;for(let{manifest:u}of this.manifestCache.values()){let i=u.resources.find(f=>f.uri===c);if(i)return a.info(`[LIOP-Router] Resolved resource ${c} from cache (Peer: ${u.peerId})`),{jsonrpc:"2.0",id:n,result:{contents:[{uri:i.uri,mimeType:i.mimeType||"text/plain",text:i.text||i.description||"No content provided"}]}}}return {jsonrpc:"2.0",id:n,error:{code:-32e3,message:o instanceof Error?o.message:String(o)}}}}case "prompts/list":{let t=this.liopServer.listPrompts(),o=I.getInstance(),c=JSON.stringify(t);return o.record({type:"prompt_list",method:"prompts/list",estimatedInputTokens:0,estimatedOutputTokens:o.countTokens(c)}),{jsonrpc:"2.0",id:n,result:{prompts:t}}}case "prompts/get":{let t=s;if(!t?.name)return {jsonrpc:"2.0",id:n,error:{code:-32602,message:"Missing prompt name"}};try{let o=Date.now(),c=await this.liopServer.getPrompt({name:t.name,arguments:t.arguments||{}}),u=I.getInstance(),i=JSON.stringify({name:t.name,arguments:t.arguments}),f=JSON.stringify(c);return u.record({type:"prompt_get",method:"prompts/get",toolName:t.name,estimatedInputTokens:u.countTokens(i),estimatedOutputTokens:u.countTokens(f),durationMs:Date.now()-o}),{jsonrpc:"2.0",id:n,result:c}}catch(o){return {jsonrpc:"2.0",id:n,error:{code:-32e3,message:o instanceof Error?o.message:String(o)}}}}default:return {jsonrpc:"2.0",id:n,error:{code:-32601,message:`Method not found: ${r}`}}}}kickDiscoveryAfterInitialized(){return (async()=>{await new Promise(e=>setTimeout(e,250)),await Promise.race([this.refreshManifestCache(true),new Promise(e=>setTimeout(e,15e3))]).catch(()=>{});})()}async refreshManifestCache(e=false){if(this.meshNode){if(this.currentDiscovery)return this.currentDiscovery;if(!e&&this.manifestCache.size>0){let r=Date.now();if(Array.from(this.manifestCache.values()).every(({cachedAt:n})=>r-n<z*1e3))return}return this.currentDiscovery=(async()=>{try{let r=Array.from(this.manifestCache.values()).reduce((a,{manifest:l})=>a+l.tools.length,0);if(this.manifestCache.size===0)for(let a$1=0;a$1<3;a$1++){if((this.meshNode.node?.getConnections().length||0)>0){a.info("[LIOP-Router] P2P Connection established. Starting discovery...");break}a.info(`[LIOP-Router] Waiting for P2P connections (attempt ${a$1+1}/10)...`),await new Promise(p=>setTimeout(p,1e3));}let s=[],n=this.manifestCache.size===0?5:1;for(let a$1=0;a$1<n;a$1++){for(let d=0;d<$;d++){s=await this.meshNode?.discoverManifestProviders()||[];let P=this.meshNode?.getPeerId();if(s.filter(v=>v!==P).length>0)break;d<$-1&&(a.info(`[LIOP-Router] DHT discovery attempt ${d+1}/${$}...`),await new Promise(v=>setTimeout(v,1e3)));}let l=this.meshNode.node?.getConnections().map(d=>d.remotePeer.toString())||[];l.length>0&&(s=Array.from(new Set([...s,...l])));let p=this.meshNode?.getPeerId();if(s.filter(d=>d!==p).length>0)break;a$1<n-1&&(a.info(`[LIOP-Router] Initial discovery failed (0 providers). Retrying in 1s (${a$1+1}/${n})...`),await new Promise(d=>setTimeout(d,1e3)));}if(s.length===0){a.info("[LIOP-Router] No manifest providers found after all attempts.");return}e||a.info(`[LIOP-Router] Discovered ${s.length} candidate manifest providers`);let t=new Set((this.meshNode.node?.getConnections?.()||[]).map(a=>a.remotePeer.toString()));s=[...s].sort((a,l)=>{let p=t.has(a)?1:0;return (t.has(l)?1:0)-p});let o=0,c=0,u=!1,i=this.meshNode?.getPeerId(),f=s.filter(a=>{if(!this.meshNode||a===i||this.shouldSkipManifestQuery(a))return !1;let l=this.manifestCache.get(a);return l&&Date.now()-l.cachedAt<z*1e3?(o++,!1):!0}),m=await Promise.allSettled(f.map(async a$1=>this.meshNode?(a.info(`[LIOP-Router] Querying manifest from: ${a$1}`),{peerId:a$1,manifest:await this.meshNode.queryManifest(a$1)}):null));for(let a$1 of m)if(a$1.status==="fulfilled"&&a$1.value?.manifest){let{peerId:l,manifest:p}=a$1.value;this.manifestCache.set(l,{manifest:p,cachedAt:Date.now()}),this.recordManifestQuerySuccess(l),u=!0,o++,a.info(`[LIOP-Router] Manifest received from ${l} (${p.tools.length} tools)`);}else a$1.status==="fulfilled"&&a$1.value?(this.recordManifestQueryFailure(a$1.value.peerId),c++,a.info(`[LIOP-Router] Manifest query returned NULL for ${a$1.value.peerId}`)):a$1.status==="rejected"&&(c++,a.info("[LIOP-Router] Fatal error querying manifest:",a$1.reason instanceof Error?a$1.reason.message:String(a$1.reason)));this._discoveryStats={candidates:s.length,success:o,failures:c,lastDiscovery:Date.now()},u&&Array.from(this.manifestCache.values()).reduce((l,{manifest:p})=>l+p.tools.length,0)!==r&&this.onToolsChanged&&(process.stderr.write(`[LIOP-Router] Mesh topology updated! Emitting notifications/tools/list_changed.
10
+ `),this.onToolsChanged());}finally{this.currentDiscovery=null;}})(),this.currentDiscovery}}getCacheSize(){return this.manifestCache.size}async getRemoteTools(){let e=Number.parseInt(process.env.LIOP_EXPECTED_PROVIDERS??"1",10);if(this.manifestCache.size<e&&this.meshNode){let t=Number.parseInt(process.env.LIOP_INITIAL_DISCOVERY_TIMEOUT_MS??"8000",10),o=Number.isFinite(t)&&t>0?t:12e3,c=Date.now()+o,u=0,i=-1;for(;Date.now()<c&&!(this.manifestCache.size>=e||(await Promise.race([this.refreshManifestCache(true),new Promise(f=>setTimeout(f,3e3))]).catch(()=>{}),this.manifestCache.size>=e));){if(this.manifestCache.size===i){if(u++,u>=3&&this.manifestCache.size>0){a.info(`[LIOP-Router] Provider count stabilized at ${this.manifestCache.size}/${e}. Proceeding with available mesh.`);break}}else u=0,i=this.manifestCache.size;await new Promise(f=>setTimeout(f,1e3));}this.manifestCache.size<e&&(a.info(`[LIOP-Router] \u26A0\uFE0F Mesh partially available: ${this.manifestCache.size}/${e} providers. Some tools may be unavailable. Check Docker containers.`),this.refreshManifestCache(true).catch(()=>{}));}let r=[],s=new Set,n=new Set(this.liopServer.listTools().map(t=>t.name));for(let[t,{manifest:o}]of this.manifestCache.entries())for(let c of o.tools){if(c.name==="LiopMeshStatus")continue;let u=c.name;(s.has(c.name)||n.has(c.name))&&(u=`${c.name}_${t.slice(-4)}`),s.add(u);let i=o.serverInfo?.name||"Unknown Provider",f=c.description||`Remote tool from ${i}`,m={name:u,description:M()?b(f):f,inputSchema:c.inputSchema||{type:"object",properties:{}}};typeof m.inputSchema=="object"&&!m.inputSchema.type&&(m.inputSchema.type="object"),typeof m.inputSchema=="object"&&!m.inputSchema.properties&&(m.inputSchema.properties={});let a="";o.taxonomy&&(a=`
11
+ [LIOP-DOMAIN: ${o.taxonomy.domain}]`);let l=m.inputSchema.properties||{},p="";!M()&&l.payload&&(p=`
12
+ [REQUIRES: LIOP-PROTO-V1 ENVELOPE]`),!M()&&m.description.includes("STRICT SCHEMA ADHERENCE")&&(m.description=m.description.replace("STRICT SCHEMA ADHERENCE:","[INDUSTRIAL-REQUISITE] STRICT SCHEMA ADHERENCE (MANDATORY):"));let h=M()?`
13
+ (Peer: ${t.slice(-8)})${a}`:`
14
+ (Origin: ${t.slice(-8)})${a}${p}`;m.description=`${m.description}${h}`,r.push(m);}return r}async getRemoteResources(){this.currentDiscovery||this.refreshManifestCache(true).catch(()=>{});let e=[],r=new Set(this.liopServer.listResources().map(s=>s.uri));for(let[s,{manifest:n}]of this.manifestCache.entries())for(let t of n.resources)if(!r.has(t.uri)){let o={...t},c=n.serverInfo?.name||"Unknown Provider",u="";n.taxonomy&&(u=`
15
+
16
+ [LIOP Zero-Trust Blueprint]
17
+ Domain: ${n.taxonomy.domain}
18
+ Clearance Tier: ${n.taxonomy.clearanceTier}`,n.taxonomy.executionTypes&&n.taxonomy.executionTypes.length>0&&(u+=`
19
+ Execution Types: ${n.taxonomy.executionTypes.join(", ")}`));let i=`
20
+
21
+ [LIOP Zero-Trust Origin]
22
+ Provider: ${c}
23
+ Network ID: ${s}${u}`;o.uri.startsWith("liop://schema/")?(o.name=`[SCHEMA] ${o.name}`,o.description=`[CRITICAL SCHEMA] ${o.description||"Data Dictionary for Zero-Shot Autonomy"}${i}`):o.description=o.description?`${o.description}${i}`:i.trim(),e.push(o),r.add(t.uri);}return e}resolveManifestTarget(e){for(let[s,{manifest:n}]of this.manifestCache.entries())if(n.tools.find(o=>o.name===e))return {peerId:s,originalToolName:e};let r=e.split("_");if(r.length>1){let s=r.pop(),n=r.join("_");for(let[t,{manifest:o}]of this.manifestCache.entries())if(t.endsWith(s||"")&&o.tools.find(u=>u.name===n))return {peerId:t,originalToolName:n}}return null}redactPeerId(e){return (process.env.LIOP_DIAGNOSTIC_LEVEL||"redacted")==="full"?e:`***${e.slice(-8)}`}async transcodeMcpToLiop(e,r){let s=r.name;if(s==="LiopMeshStatus"){this.refreshManifestCache(true).catch(()=>{});let t=this._discoveryStats||{candidates:0,success:0,failures:0},o=this.manifestCache.size,c=this.meshNode?"Active":"Offline",u=Array.from(this.manifestCache.values()).reduce((T,{manifest:k})=>T+k.tools.length,0),i=this.meshNode?this.meshNode.node?.getConnections().length:0,f=this.meshNode&&this.meshNode.config?.bootstrapNodes?this.meshNode.config.bootstrapNodes:[],m=f.length,l=(process.env.LIOP_DIAGNOSTIC_LEVEL||"redacted")!=="minimal",p=l?f.map(T=>{let k=T.split("/"),L=k[k.length-1];return ` \u2022 ${L?L.slice(-8):"Unknown"} (bootstrap)`}).join(`
24
+ `):"",h=this.meshNode?this.meshNode.getRoutingTableSize():0,d=this.meshNode?.getPeerId()||"Offline",P=d==="Offline"?d:this.redactPeerId(d),S=Array.from(this.manifestCache.entries()).flatMap(([T,{manifest:k}])=>k.tools.map(L=>` \u2022 ${L.name} (from origin: ${this.redactPeerId(T)})`)).join(`
25
+ `),v=[`LIOP Mesh Status: ${c==="Active"?"Active":"Offline"}`,`Local Agent Identity: ${P}`,`Network: ${i} Conns | ${h} Mesh Nodes | ${m} Bootstraps`,l&&m>0?`
26
+ Active Bootstraps:
27
+ ${p}
28
+ `:"",`Discovery: ${t.candidates} Candidates | ${t.success} OK | ${t.failures} FAIL`,`Tooling: ${o} Providers | ${u} Total Remote Tools`,u>0?`
29
+ Discovered Remote Tools (Zero-Trust Origins):
30
+ ${S}`:`
31
+ No remote tools discovered yet.`,I.getInstance().formatStatusBlock()].filter(T=>T!=="").join(`
32
+ `),O=I.getInstance();return O.record({type:"diagnostic",method:"tools/call",toolName:"LiopMeshStatus",estimatedInputTokens:0,estimatedOutputTokens:O.countTokens(v)}),{jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:v}]}}}let n=this.liopServer.listTools().some(t=>t.name===s);if(!n&&this.meshNode){let t=this.resolveManifestTarget(s);if(t||(await this.refreshManifestCache(),t=this.resolveManifestTarget(s)),t)return a.info(`[LIOP-Router] Resolved ${s} via manifest cache (Peer: ${t.peerId}, Original: ${t.originalToolName})`),this.routeToRemoteProvider(e,t.originalToolName,t.peerId,r);let o=[];for(let c=0;c<3&&(o=await this.meshNode.findProviders(s),!(o.length>0));c++)c<2&&await new Promise(u=>setTimeout(u,1e3));if(o.length>0)return this.routeToRemoteProvider(e,s,o[0],r)}if(n)try{let t=Date.now(),o=await this.liopServer.callTool({name:s,arguments:r.arguments||{}}),c=I.getInstance(),u=JSON.stringify(r.arguments||{}),i=JSON.stringify(o);return c.record({type:"tool_call",method:"tools/call",toolName:s,estimatedInputTokens:c.countTokens(u),estimatedOutputTokens:c.countTokens(i),durationMs:Date.now()-t}),{jsonrpc:"2.0",id:e,result:o}}catch(t){return {jsonrpc:"2.0",id:e,error:{code:-32e3,message:t instanceof Error?t.message:String(t)}}}return {jsonrpc:"2.0",id:e,error:{code:-32002,message:`No provider found for tool: ${s}. Ensure the provider node is active and connected to the mesh.`}}}async routeToRemoteProvider(e,r,s,n){if(!this.meshNode)return {jsonrpc:"2.0",id:e,error:{code:-32603,message:"Mesh Node inactive"}};let t=this.manifestCache.get(s),o=this.defaultRpcPort;if(t)o=t.manifest.grpcPort;else {let l=await this.meshNode.queryManifest(s);l&&(o=l.grpcPort,this.manifestCache.set(s,{manifest:l,cachedAt:Date.now()}),t=this.manifestCache.get(s));}if((process.env.NODE_ENV==="development"||process.env.NODE_ENV==="test")&&t&&process.env.LIOP_USE_PUBLISHED_GRPC_PORTS==="1"){let l=t.manifest.serverInfo?.name?.toLowerCase()||"";l.includes("vault")?o=13011:l.includes("bank")?o=13021:l.includes("oracle")&&(o=13031);}let u=await this.meshNode.resolvePeer(s),i=null,f=await import('os'),m=Object.values(f.networkInterfaces()).flat().filter(l=>l?.family==="IPv4").map(l=>l?.address);for(let l of u){let p=l.split("/"),h=p.indexOf("ip4");if(h!==-1){let d=p[h+1];if(d==="127.0.0.1"||m.includes(d)){i=`127.0.0.1:${o}`;break}i||(i=`${d}:${o}`);}}i||(i=`127.0.0.1:${o}`),a.info(`[LIOP-Router] Dynamic route: ${r} -> ${i} (PeerID: ${s})`);let a$1=new a$2.LogicMesh(i,c());return this.performTranscoding(e,a$1,r,n,s)}async performTranscoding(e,r,s,n,t){let o=s,c=this.meshNode?await this.meshNode.sign(Buffer.from(o)):Buffer.from([]),u=Date.now();return new Promise(i=>{r.negotiateIntent({agent_did:`did:liop:${this.meshNode?.getPeerId()||"mcp-proxy"}`,capability_hash:o,proof_of_intent:c},async(f,m)=>{if(f||!m.accepted)return i({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:`PQC Handshake Failed: ${f?.message||"Rejected"}`}],isError:true}});let{ciphertext:a,sharedSecret:l}=await a$3.encapsulateAsymmetric(m.kyber_public_key),p=JSON.stringify(n.arguments||{}),h=`return { "__liop_proxy_tool": "${s}", "__liop_proxy_args": ${p} };`,d=w.randomBytes(12),P=this.encryptWithNonce(Buffer.from(h),l,d),S=r.executeLogic({session_token:m.session_token,wasm_binary:new Uint8Array(P),inputs:{},pqc_ciphertext:a,aes_nonce:d}),v="",O=null;S.on("data",T=>{v+=T.semantic_evidence,O=T;}),S.on("end",async()=>{try{if(O&&!await this.verifier.verifyZkReceipt(Buffer.from(h),Buffer.from(O.cryptographic_proof).toString("hex"),Buffer.from(O.zk_receipt)))return i({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:"SECURITY ALERT: Remote response failed cryptographic integrity audit."}],isError:!0}});let T=JSON.parse(v),k=I.getInstance();k.record({type:"tool_call",method:"tools/call",toolName:s,peerId:t,estimatedInputTokens:k.countTokens(p),estimatedOutputTokens:k.countTokens(v),durationMs:Date.now()-u}),i({jsonrpc:"2.0",id:e,result:T});}catch{i({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:v}]}});}}),S.on("error",T=>i({jsonrpc:"2.0",id:e,result:{content:[{type:"text",text:`LIOP gRPC Error: ${T.message}`}],isError:true}}));});})}encryptWithNonce(e,r,s){let n=w.createCipheriv("aes-256-gcm",r,s),t=Buffer.concat([n.update(e),n.final()]);return Buffer.concat([t,n.getAuthTag()])}};export{C as a,R as b,B as c,U as d,N as e,I as f,F as g};//# sourceMappingURL=chunk-7MAGL6ON.js.map
33
+ //# sourceMappingURL=chunk-7MAGL6ON.js.map