@sleep2agi/agent-network 0.0.4 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/bin/cli.js +21 -16
  2. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- var h=Object.defineProperty;var u=(z)=>z;function g(z,B){this[z]=u.bind(null,B)}var c=(z,B)=>{for(var L in B)h(z,L,{get:B[L],enumerable:!0,configurable:!0,set:g.bind(B,L)})};var d=(z,B)=>()=>(z&&(B=z(z=0)),B);var x={};c(x,{default:()=>m,CommHub:()=>H});import{EventEmitter as f}from"events";import{hostname as D}from"os";var H,m;var A=d(()=>{H=class H extends f{url;alias;token;agent;resumeId;heartbeatInterval;reconnectDelay;heartbeatTimer;sseAbort;running=!1;constructor(z){super();if(this.url=z.url.replace(/\/$/,""),this.alias=z.alias,this.token=z.token,this.agent=z.agent||"sdk",this.resumeId=`sdk-${z.alias}-${Date.now().toString(36)}`,this.heartbeatInterval=z.heartbeatInterval??180000,this.reconnectDelay=z.reconnectDelay??3000,z.autoConnect!==!1)this.connect()}log(z){console.log(`[${new Date().toTimeString().slice(0,8)}] [commhub:${this.alias}] ${z}`)}async call(z,B){let L={"Content-Type":"application/json"};if(this.token)L.Authorization=`Bearer ${this.token}`;let R=await(await fetch(`${this.url}/mcp`,{method:"POST",headers:L,body:JSON.stringify({jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:z,arguments:B}})})).json(),W=R?.result?.content?.[0]?.text;return W?JSON.parse(W):R}async connect(){if(this.running)return;this.running=!0,await this.status("idle"),this.log("registered"),this.heartbeatTimer=setInterval(()=>{this.status("idle").catch((z)=>this.log(`heartbeat failed: ${z.message}`))},this.heartbeatInterval),this.connectSSE()}async disconnect(){if(this.running=!1,this.sseAbort?.abort(),this.heartbeatTimer)clearInterval(this.heartbeatTimer);await this.status("offline").catch(()=>{}),this.log("disconnected")}async send(z,B,L="normal"){return this.call("send_task",{alias:z,task:B,priority:L,from_session:this.alias})}async message(z,B){return this.call("send_message",{alias:z,message:B,from_session:this.alias})}async reply(z,B,L="completed"){return this.call("reply",{task_id:z,text:B,status:L})}async status(z,B){return this.call("report_status",{resume_id:this.resumeId,alias:this.alias,status:z,server:D(),hostname:D(),agent:this.agent,project_dir:process.cwd(),...B})}async getAllStatus(){return this.call("get_all_status",{})}async broadcast(z,B){return this.call("broadcast",{message:z,filter_server:B?.server,filter_status:B?.status})}async connectSSE(){let z=encodeURIComponent(this.alias),B=`${this.url}/events/${z}`,L=this.reconnectDelay;while(this.running){try{this.sseAbort=new AbortController;let Q={Accept:"text/event-stream"};if(this.token)Q.Authorization=`Bearer ${this.token}`;let R=await fetch(B,{headers:Q,signal:this.sseAbort.signal});if(!R.ok||!R.body){this.log(`SSE failed: ${R.status}`),await this.sleep(L),L=Math.min(L*1.5,60000);continue}L=this.reconnectDelay;let W=R.body.getReader(),V=new TextDecoder,X="";while(this.running){let{done:Z,value:$}=await W.read();if(Z)break;X+=V.decode($,{stream:!0});let q=X.split(`
3
- `);X=q.pop()||"";for(let J of q){if(!J.startsWith("data: "))continue;try{let O=JSON.parse(J.slice(6));if(O.type==="connected"){this.log("SSE connected"),this.emit("connected");continue}if(O.type==="new_task"||O.type==="new_message"||O.type==="broadcast")await this.processInbox()}catch{}}}}catch(Q){if(Q.name==="AbortError")break;this.emit("error",Q),this.log(`SSE error: ${Q.message}`)}if(this.running)this.emit("disconnected"),this.log(`SSE reconnecting in ${L/1000}s...`),await this.sleep(L),L=Math.min(L*1.5,60000)}}async processInbox(){try{let B=(await this.call("get_inbox",{alias:this.alias,limit:10}))?.messages||[];for(let L of B)await this.call("ack_inbox",{alias:this.alias,message_id:L.id}),this.log(`← ${L.from_session}: ${L.content.slice(0,60)}`),this.emit("task",L),this.emit("message",L)}catch(z){this.log(`inbox error: ${z.message}`)}}sleep(z){return new Promise((B)=>setTimeout(B,z))}};m=H});import{readFileSync as N,writeFileSync as _,existsSync as I,mkdirSync as K,readdirSync as p}from"fs";import{join as G}from"path";import{execSync as n,spawn as t}from"child_process";var Y=process.argv.slice(2),w=Y[0],E=process.env.HOME||"~";function C(){let z={_channels:[],_envs:[]};for(let B=1;B<Y.length;B++)if(Y[B]==="--channel"&&B+1<Y.length)z._channels.push(Y[++B]);else if(Y[B]==="--env"&&B+1<Y.length)z._envs.push(Y[++B]);else if(Y[B].startsWith("--")&&B+1<Y.length&&!Y[B+1].startsWith("--"))z[Y[B].replace(/^--/,"")]=Y[++B];return z}function U(){return G(process.cwd(),".anet","profiles")}function S(){return G(E,".anet","config.json")}function k(){let z=S();if(I(z))try{return JSON.parse(N(z,"utf-8"))}catch{}return{}}function M(z){let B=G(U(),`${z}.json`);if(I(B))try{return JSON.parse(N(B,"utf-8"))}catch{}return null}function o(z,B){let L=U();K(L,{recursive:!0}),_(G(L,`${z}.json`),JSON.stringify(B,null,2)+`
4
- `)}function F(){let z=U();if(!I(z))return[];return p(z).filter((B)=>B.endsWith(".json")).map((B)=>B.replace(/\.json$/,""))}function P(){console.log(`
2
+ var f=Object.defineProperty;var p=(z)=>z;function n(z,B){this[z]=p.bind(null,B)}var t=(z,B)=>{for(var L in B)f(z,L,{get:B[L],enumerable:!0,configurable:!0,set:n.bind(B,L)})};var l=(z,B)=>()=>(z&&(B=z(z=0)),B);var y={};t(y,{default:()=>i,CommHub:()=>U});import{EventEmitter as o}from"events";import{hostname as b}from"os";var U,i;var S=l(()=>{U=class U extends o{url;alias;token;agent;resumeId;heartbeatInterval;reconnectDelay;heartbeatTimer;sseAbort;running=!1;constructor(z){super();if(this.url=z.url.replace(/\/$/,""),this.alias=z.alias,this.token=z.token,this.agent=z.agent||"sdk",this.resumeId=`sdk-${z.alias}-${Date.now().toString(36)}`,this.heartbeatInterval=z.heartbeatInterval??180000,this.reconnectDelay=z.reconnectDelay??3000,z.autoConnect!==!1)this.connect()}log(z){console.log(`[${new Date().toTimeString().slice(0,8)}] [commhub:${this.alias}] ${z}`)}async call(z,B){let L={"Content-Type":"application/json"};if(this.token)L.Authorization=`Bearer ${this.token}`;let Y=await(await fetch(`${this.url}/mcp`,{method:"POST",headers:L,body:JSON.stringify({jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:z,arguments:B}})})).json(),X=Y?.result?.content?.[0]?.text;return X?JSON.parse(X):Y}async connect(){if(this.running)return;this.running=!0,await this.status("idle"),this.log("registered"),this.heartbeatTimer=setInterval(()=>{this.status("idle").catch((z)=>this.log(`heartbeat failed: ${z.message}`))},this.heartbeatInterval),this.connectSSE()}async disconnect(){if(this.running=!1,this.sseAbort?.abort(),this.heartbeatTimer)clearInterval(this.heartbeatTimer);await this.status("offline").catch(()=>{}),this.log("disconnected")}async send(z,B,L="normal"){return this.call("send_task",{alias:z,task:B,priority:L,from_session:this.alias})}async message(z,B){return this.call("send_message",{alias:z,message:B,from_session:this.alias})}async reply(z,B,L="completed"){return this.call("reply",{task_id:z,text:B,status:L})}async status(z,B){return this.call("report_status",{resume_id:this.resumeId,alias:this.alias,status:z,server:b(),hostname:b(),agent:this.agent,project_dir:process.cwd(),...B})}async getAllStatus(){return this.call("get_all_status",{})}async broadcast(z,B){return this.call("broadcast",{message:z,filter_server:B?.server,filter_status:B?.status})}async connectSSE(){let z=encodeURIComponent(this.alias),B=`${this.url}/events/${z}`,L=this.reconnectDelay;while(this.running){try{this.sseAbort=new AbortController;let Q={Accept:"text/event-stream"};if(this.token)Q.Authorization=`Bearer ${this.token}`;let Y=await fetch(B,{headers:Q,signal:this.sseAbort.signal});if(!Y.ok||!Y.body){this.log(`SSE failed: ${Y.status}`),await this.sleep(L),L=Math.min(L*1.5,60000);continue}L=this.reconnectDelay;let X=Y.body.getReader(),V=new TextDecoder,Z="";while(this.running){let{done:R,value:W}=await X.read();if(R)break;Z+=V.decode(W,{stream:!0});let $=Z.split(`
3
+ `);Z=$.pop()||"";for(let q of $){if(!q.startsWith("data: "))continue;try{let K=JSON.parse(q.slice(6));if(K.type==="connected"){this.log("SSE connected"),this.emit("connected");continue}if(K.type==="new_task"||K.type==="new_message"||K.type==="broadcast")await this.processInbox()}catch{}}}}catch(Q){if(Q.name==="AbortError")break;this.emit("error",Q),this.log(`SSE error: ${Q.message}`)}if(this.running)this.emit("disconnected"),this.log(`SSE reconnecting in ${L/1000}s...`),await this.sleep(L),L=Math.min(L*1.5,60000)}}async processInbox(){try{let B=(await this.call("get_inbox",{alias:this.alias,limit:10}))?.messages||[];for(let L of B)await this.call("ack_inbox",{alias:this.alias,message_id:L.id}),this.log(`← ${L.from_session}: ${L.content.slice(0,60)}`),this.emit("task",L),this.emit("message",L)}catch(z){this.log(`inbox error: ${z.message}`)}}sleep(z){return new Promise((B)=>setTimeout(B,z))}};i=U});import{readFileSync as I,writeFileSync as M,existsSync as J,mkdirSync as F,readdirSync as g}from"fs";import{join as E}from"path";import{execSync as r,spawn as a}from"child_process";var _=process.argv.slice(2),k=_[0],T=process.env.HOME||"~";function m(){let z={_channels:[],_envs:[]};for(let B=1;B<_.length;B++)if(_[B]==="--channel"&&B+1<_.length)z._channels.push(_[++B]);else if(_[B]==="--env"&&B+1<_.length)z._envs.push(_[++B]);else if(_[B].startsWith("--")&&B+1<_.length&&!_[B+1].startsWith("--"))z[_[B].replace(/^--/,"")]=_[++B];return z}function w(){return E(process.cwd(),".anet","profiles")}function c(){return E(T,".anet","config.json")}function A(){let z=c();if(J(z))try{return JSON.parse(I(z,"utf-8"))}catch{}return{}}function x(z){let B=E(w(),`${z}.json`);if(J(B))try{return JSON.parse(I(B,"utf-8"))}catch{}return null}function s(z,B){let L=w();F(L,{recursive:!0}),M(E(L,`${z}.json`),JSON.stringify(B,null,2)+`
4
+ `)}function P(){let z=w();if(!J(z))return[];return g(z).filter((B)=>B.endsWith(".json")).map((B)=>B.replace(/\.json$/,""))}function h(){console.log(`
5
5
  anet — AI Agent Network CLI
6
6
 
7
7
  Commands:
@@ -33,19 +33,24 @@ Examples:
33
33
 
34
34
  anet start commander
35
35
  anet list
36
- `)}async function l(){let z=C(),B=k(),L=z.profile,Q=z.name,R=z.alias,W=z.hub||B.hub,V=z.type||"claude-code",X=z.resume,Z=z["teammate-mode"];if(!L||!R)console.error("Error: --profile and --alias are required"),console.error("Usage: anet setup --profile hub-01 --name 指挥室 --alias 指挥室 --hub http://YOUR_IP:9200 --channel server:commhub"),process.exit(1);if(!W)console.error("Error: --hub is required (first time) or set in ~/.anet/config.json"),process.exit(1);let $={};for(let T of z._envs){let j=T.indexOf("=");if(j>0)$[T.slice(0,j)]=T.slice(j+1)}let q={...Q?{name:Q}:{},alias:R,hub:W,channels:z._channels.length>0?z._channels:["server:commhub"],env:$,flags:{dangerouslySkipPermissions:!0,...Z?{teammateMode:Z}:{}},...X?{resume:X}:{}},J=G(E,".anet");K(J,{recursive:!0});let O=k();if(O.hub=W,_(S(),JSON.stringify(O,null,2)+`
37
- `),o(L,q),console.log(`
38
- ✅ Profile "${L}" saved to .anet/profiles/${L}.json`),V==="claude-code")await i(W,R);let y=b(q);console.log(`
36
+ `)}async function e(){let z=m(),B=A(),L=z.profile,Q=z.name,Y=z.alias,X=z.hub||B.hub,V=z.type||"claude-code",Z=z.resume,R=z["teammate-mode"];if(!L||!Y)console.error("Error: --profile and --alias are required"),console.error("Usage: anet setup --profile hub-01 --name 指挥室 --alias 指挥室 --hub http://YOUR_IP:9200 --channel server:commhub"),process.exit(1);if(!X)console.error("Error: --hub is required (first time) or set in ~/.anet/config.json"),process.exit(1);let W={};for(let O of z._envs){let G=O.indexOf("=");if(G>0)W[O.slice(0,G)]=O.slice(G+1)}let $={...Q?{name:Q}:{},alias:Y,hub:X,channels:z._channels.length>0?z._channels:["server:commhub"],env:W,flags:{dangerouslySkipPermissions:!0,...R?{teammateMode:R}:{}},...Z?{resume:Z}:{}},q=E(T,".anet");F(q,{recursive:!0});let K=A();if(K.hub=X,M(c(),JSON.stringify(K,null,2)+`
37
+ `),s(L,$),console.log(`
38
+ ✅ Profile "${L}" saved to .anet/profiles/${L}.json`),V==="claude-code")await zz(X,Y);let H=d($);console.log(`
39
39
  启动命令 (anet start ${L}):
40
- ${y}
41
- `)}async function i(z,B){let L=`${E}/.claude/channels/commhub`;K(L,{recursive:!0});let Q=`${L}/server.ts`;if(!I(Q)){console.log("Downloading Channel plugin...");try{let $=await fetch("https://raw.githubusercontent.com/sleep2agi/agent-comm-hub/main/channel/server.ts");if($.ok)_(Q,await $.text()),console.log(` ✅ ${Q}`)}catch{}try{let $=await fetch("https://raw.githubusercontent.com/sleep2agi/agent-comm-hub/main/channel/package.json");if($.ok){_(`${L}/package.json`,await $.text());try{n("bun install",{cwd:L,stdio:"pipe"})}catch{}}}catch{}}let R=`${L}/.env`;if(!I(R))_(R,`COMMHUB_URL=${z}
42
- `);let W=process.cwd().replace(/\//g,"-"),V=`${L}/${W}`;K(V,{recursive:!0}),_(`${V}/.env`,`COMMHUB_ALIAS=${B}
43
- `);let X=`${E}/.claude.json`,Z={};if(I(X))try{Z=JSON.parse(N(X,"utf-8"))}catch{}if(!Z.mcpServers?.commhub)Z.mcpServers=Z.mcpServers||{},Z.mcpServers.commhub={type:"stdio",command:"bun",args:["run",Q]},_(X,JSON.stringify(Z,null,2)+`
44
- `)}function b(z){let B=[];B.push(`COMMHUB_ALIAS="${z.alias}"`);for(let[L,Q]of Object.entries(z.env))B.push(`${L}=${Q}`);if(B.push("claude"),z.flags.dangerouslySkipPermissions)B.push("--dangerously-skip-permissions");for(let L of z.channels)if(L.startsWith("server:"))B.push(`--dangerously-load-development-channels ${L}`);else B.push(`--channels ${L}`);if(z.flags.teammateMode)B.push(`--teammate-mode ${z.flags.teammateMode}`);if(z.resume)B.push(`--resume ${z.resume}`);return B.join(" ")}function v(){let z=Y[1];if(!z){let V=F();if(V.length===0)console.log("No profiles found. Create one with: anet setup --profile <name> --alias <alias> --hub <url>"),process.exit(1);console.log(`
40
+ ${H}
41
+ `)}async function zz(z,B){let L=`${T}/.claude/channels/commhub`;F(L,{recursive:!0});let Q=`${L}/server.ts`;if(!J(Q)){console.log("Downloading Channel plugin...");try{let W=await fetch("https://raw.githubusercontent.com/sleep2agi/agent-comm-hub/main/channel/server.ts");if(W.ok)M(Q,await W.text()),console.log(` ✅ ${Q}`)}catch{}try{let W=await fetch("https://raw.githubusercontent.com/sleep2agi/agent-comm-hub/main/channel/package.json");if(W.ok){M(`${L}/package.json`,await W.text());try{r("bun install",{cwd:L,stdio:"pipe"})}catch{}}}catch{}}let Y=`${L}/.env`;if(!J(Y))M(Y,`COMMHUB_URL=${z}
42
+ `);let X=process.cwd().replace(/\//g,"-"),V=`${L}/${X}`;F(V,{recursive:!0}),M(`${V}/.env`,`COMMHUB_ALIAS=${B}
43
+ `);let Z=`${T}/.claude.json`,R={};if(J(Z))try{R=JSON.parse(I(Z,"utf-8"))}catch{}if(!R.mcpServers?.commhub)R.mcpServers=R.mcpServers||{},R.mcpServers.commhub={type:"stdio",command:"bun",args:["run",Q]},M(Z,JSON.stringify(R,null,2)+`
44
+ `)}function d(z){let B=[];B.push(`COMMHUB_ALIAS="${z.alias}"`);for(let[L,Q]of Object.entries(z.env))B.push(`${L}=${Q}`);if(B.push("claude"),z.flags.dangerouslySkipPermissions)B.push("--dangerously-skip-permissions");for(let L of z.channels)if(L.startsWith("server:"))B.push(`--dangerously-load-development-channels ${L}`);else B.push(`--channels ${L}`);if(z.flags.teammateMode)B.push(`--teammate-mode ${z.flags.teammateMode}`);if(z.resume)B.push(`--resume ${z.resume}`);return B.join(" ")}function u(){let z=_[1];if(!z){let V=P();if(V.length===0)console.log("No profiles found. Create one with: anet setup --profile <name> --alias <alias> --hub <url>"),process.exit(1);console.log(`
45
45
  Available profiles:
46
- `);for(let X of V){let Z=M(X);console.log(` ${X} → alias: ${Z?.alias}, channels: ${Z?.channels.join(", ")}`)}console.log(`
46
+ `);for(let Z of V){let R=x(Z);console.log(` ${Z} → alias: ${R?.alias}, channels: ${R?.channels.join(", ")}`)}console.log(`
47
47
  Start with: anet start <profile>
48
- `);return}let B=M(z);if(!B)console.error(`Profile "${z}" not found in .anet/profiles/`),console.error(`Available: ${F().join(", ")||"(none)"}`),process.exit(1);let L=b(B);console.log(`[anet] Starting "${z}"...`),console.log(`[anet] ${L}
49
- `);let Q={...process.env,COMMHUB_ALIAS:B.alias};for(let[V,X]of Object.entries(B.env))Q[V]=X.replace(/^~/,E);let R=[];if(B.flags.dangerouslySkipPermissions)R.push("--dangerously-skip-permissions");for(let V of B.channels)if(V.startsWith("server:"))R.push("--dangerously-load-development-channels",V);else R.push("--channels",V);if(B.flags.teammateMode)R.push("--teammate-mode",B.flags.teammateMode);if(B.resume)R.push("--resume",B.resume);t("claude",R,{env:Q,stdio:"inherit",shell:!0}).on("exit",(V)=>process.exit(V||0))}function s(){let z=F();if(z.length===0){console.log("No profiles. Create one: anet setup --profile <name> --alias <alias> --hub <url>");return}console.log(`
50
- Profiles:
51
- `);for(let B of z){let L=M(B),Q=L?.channels.join(", ")||"",R=Object.keys(L?.env||{}).join(", ");if(console.log(` ${B}`),console.log(` alias: ${L?.alias} hub: ${L?.hub}`),console.log(` channels: ${Q}`),R)console.log(` env: ${R}`);if(L?.resume)console.log(` resume: ${L.resume}`);console.log()}}async function a(){let z=k(),B=C(),L=process.env.COMMHUB_URL||B.hub||z.hub||"http://127.0.0.1:9200",Q=process.env.COMMHUB_ALIAS||B.alias||z.alias;if(!Q)console.error("Error: --alias required"),process.exit(1);let{CommHub:R}=await Promise.resolve().then(() => (A(),x)),W=new R({url:L,alias:Q});W.on("task",async(V)=>{console.log(`[${Q}] ← ${V.from_session}: ${V.content.slice(0,100)}`),await W.send(V.from_session,`[${Q}] 收到: ${V.content.slice(0,200)}`)}),W.on("connected",()=>console.log(`[${Q}] Connected to ${L}`)),W.on("disconnected",()=>console.log(`[${Q}] Disconnected, reconnecting...`)),process.on("SIGINT",()=>W.disconnect().then(()=>process.exit(0))),process.on("SIGTERM",()=>W.disconnect().then(()=>process.exit(0))),console.log(`[${Q}] Listening on ${L} (Ctrl+C to quit)`)}switch(w){case"setup":l();break;case"start":v();break;case"list":s();break;case"run":a();break;case"--help":case"-h":case void 0:P();break;default:if(M(w))Y.splice(0,0,"start"),v();else console.error(`Unknown command: ${w}`),P(),process.exit(1)}
48
+ `);return}let B=x(z);if(!B)console.error(`Profile "${z}" not found in .anet/profiles/`),console.error(`Available: ${P().join(", ")||"(none)"}`),process.exit(1);let L=d(B);console.log(`[anet] Starting "${z}"...`),console.log(`[anet] ${L}
49
+ `);let Q={...process.env,COMMHUB_ALIAS:B.alias};for(let[V,Z]of Object.entries(B.env))Q[V]=Z.replace(/^~/,T);let Y=[];if(B.flags.dangerouslySkipPermissions)Y.push("--dangerously-skip-permissions");for(let V of B.channels)if(V.startsWith("server:"))Y.push("--dangerously-load-development-channels",V);else Y.push("--channels",V);if(B.flags.teammateMode)Y.push("--teammate-mode",B.flags.teammateMode);if(B.resume)Y.push("--resume",B.resume);a("claude",Y,{env:Q,stdio:"inherit",shell:!0}).on("exit",(V)=>process.exit(V||0))}async function Bz(){let z=process.cwd(),B=P();if(B.length>0){console.log(`
50
+ Profiles (.anet/profiles/):
51
+ `);for(let R of B){let W=x(R);console.log(` ${R}${W?.name?` (${W.name})`:""}`),console.log(` alias: ${W?.alias} channels: ${W?.channels.join(", ")}`),console.log()}}let L=E(T,".claude","sessions"),Q=[];if(J(L))for(let R of g(L).filter((W)=>W.endsWith(".json")))try{let W=JSON.parse(I(E(L,R),"utf-8"));if(W.cwd===z)Q.push(W)}catch{}let X=A().hub,V={};if(X)try{let W=await(await fetch(`${X}/api/status`)).json();if(W.sessions)for(let $ of W.sessions)V[$.resume_id]=$}catch{}let Z={};if(X)try{Z=(await(await fetch(`${X}/health`)).json()).sse_sessions||{}}catch{}if(Q.length>0){console.log(`Sessions in ${z}:
52
+ `),console.log(" SESSION ID PID NETWORK STATUS"),console.log(" ─────────────────── ─────── ──────────────────────────");for(let R of Q){let W=R.sessionId.slice(0,18),$="",q=!1;for(let[,O]of Object.entries(V))if(O.resume_id?.startsWith(R.sessionId.slice(0,8))){let G=O.alias||"?",v=O.status||"?",N=Z[G]?"SSE":"";$=`${G} ${v} ${N}`,q=!0;break}if(!q){let O=z.replace(/\//g,"-"),G=E(T,".claude","channels","commhub",O,".env");if(J(G)){let N=I(G,"utf-8").match(/COMMHUB_ALIAS=(.+)/);if(N){let j=N[1].trim(),C=Object.values(V).find((D)=>D.alias===j);if(C){let D=Z[j]?"SSE":"";$=`${j} ${C.status} ${D}`,q=!0}else $=`${j} (not registered)`}}}if(!q)$="(not in network)";let K=!1;try{process.kill(R.pid,0),K=!0}catch{}let H=K?`${R.pid}`:`${R.pid} ✕`;console.log(` ${W} ${H.padEnd(7)} ${$}`)}console.log()}else console.log(`
53
+ No Claude Code sessions found in ${z}
54
+ `);if(X){let R=Object.keys(Z).length,W=Object.keys(V).length;if(console.log(`Network: ${X} (${R} online / ${W} total)`),R>0){console.log(`
55
+ ALIAS STATUS SSE`),console.log(" ────────────────── ────────── ───");for(let[$,q]of Object.entries(Z)){let H=Object.values(V).find((O)=>O.alias===$)?.status||"?";console.log(` ${$.padEnd(18)} ${H.padEnd(10)} ${q>0?"●":"○"}`)}}console.log()}if(B.length===0&&Q.length===0)console.log(`Get started: anet setup --profile <id> --alias <alias> --hub <url>
56
+ `)}async function Lz(){let z=A(),B=m(),L=process.env.COMMHUB_URL||B.hub||z.hub||"http://127.0.0.1:9200",Q=process.env.COMMHUB_ALIAS||B.alias||z.alias;if(!Q)console.error("Error: --alias required"),process.exit(1);let{CommHub:Y}=await Promise.resolve().then(() => (S(),y)),X=new Y({url:L,alias:Q});X.on("task",async(V)=>{console.log(`[${Q}] ← ${V.from_session}: ${V.content.slice(0,100)}`),await X.send(V.from_session,`[${Q}] 收到: ${V.content.slice(0,200)}`)}),X.on("connected",()=>console.log(`[${Q}] Connected to ${L}`)),X.on("disconnected",()=>console.log(`[${Q}] Disconnected, reconnecting...`)),process.on("SIGINT",()=>X.disconnect().then(()=>process.exit(0))),process.on("SIGTERM",()=>X.disconnect().then(()=>process.exit(0))),console.log(`[${Q}] Listening on ${L} (Ctrl+C to quit)`)}switch(k){case"setup":e();break;case"start":u();break;case"list":case"ls":Bz();break;case"run":Lz();break;case"--help":case"-h":case void 0:h();break;default:if(x(k))_.splice(0,0,"start"),u();else console.error(`Unknown command: ${k}`),h(),process.exit(1)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/agent-network",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "AI Agent Network — Server + Client + Setup in one package. SSE real-time communication for multi-agent orchestration.",
5
5
  "type": "module",
6
6
  "main": "dist/src/client.js",