@sleep2agi/agent-network 0.0.17 → 0.0.19

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
@@ -5,26 +5,34 @@ AI Agent 通信网络 — 让 AI Agent 互相发消息、派任务、协作。
5
5
  ## 安装
6
6
 
7
7
  ```bash
8
+ # 全局安装(推荐)
8
9
  npm install -g @sleep2agi/agent-network
10
+
11
+ # 或不安装,直接用 npx
12
+ npx @sleep2agi/agent-network --help
9
13
  ```
10
14
 
11
15
  ## 30 秒上手
12
16
 
13
17
  ```bash
14
18
  # 1. 配 hub(全局,一次性)
15
- anet init
19
+ npx @sleep2agi/agent-network init --hub http://YOUR_COMMHUB_IP:9200
16
20
 
17
- # 2. 配项目(下载 channel 插件 + 配 MCP)
18
- anet init project
21
+ # 2. 配项目(下载 channel 插件 + 配 MCP + 生成 CLAUDE.md
22
+ cd ~/your-project
23
+ npx @sleep2agi/agent-network init project
19
24
 
20
25
  # 3. 创建 profile(保存启动参数)
21
- anet init profile commander --alias 指挥室 --channel server:commhub
26
+ npx anet init profile commander --alias 指挥室 --channel server:commhub
27
+
28
+ # 4. 启动(新建 session)
29
+ npx anet start commander
22
30
 
23
- # 4. 启动
24
- anet start commander
31
+ # 5. 恢复上次 session
32
+ npx anet resume commander
25
33
 
26
- # 5. 查看状态
27
- anet ls
34
+ # 6. 查看状态
35
+ npx anet ls
28
36
  ```
29
37
 
30
38
  ## 为什么需要 Profile?
@@ -206,7 +214,9 @@ const { CommHub } = require('@sleep2agi/agent-network');
206
214
 
207
215
  | 版本 | 变更 |
208
216
  |------|------|
209
- | 0.0.16 | server.ts → node-server.ts,从 npm 包内 copy(不依赖 GitHub 下载) |
217
+ | 0.0.18 | node-server.ts 多路径查找,兼容 npx/global/local |
218
+ | 0.0.17 | 修复 npx 模式下路径解析 |
219
+ | 0.0.16 | server.ts → node-server.ts,从 npm 包内 copy |
210
220
  | 0.0.15 | 自动去掉 hub URL 结尾斜杠 |
211
221
  | 0.0.14 | init project 自动生成 CLAUDE.md |
212
222
  | 0.0.13 | init 交互输入后不再卡住 |
package/dist/bin/cli.js CHANGED
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import{createRequire as t}from"node:module";var p=Object.defineProperty;var c=(z)=>z;function d(z,B){this[z]=c.bind(null,B)}var l=(z,B)=>{for(var Q in B)p(z,Q,{get:B[Q],enumerable:!0,configurable:!0,set:d.bind(B,Q)})};var n=(z,B)=>()=>(z&&(B=z(z=0)),B);var w=t(import.meta.url);var j={};l(j,{default:()=>o,CommHub:()=>H});import{EventEmitter as r}from"events";import{hostname as C}from"os";var H,o;var P=n(()=>{H=class H extends r{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 Q={"Content-Type":"application/json"};if(this.token)Q.Authorization=`Bearer ${this.token}`;let X=await(await fetch(`${this.url}/mcp`,{method:"POST",headers:Q,body:JSON.stringify({jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:z,arguments:B}})})).json(),Z=X?.result?.content?.[0]?.text;return Z?JSON.parse(Z):X}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,Q="normal"){return this.call("send_task",{alias:z,task:B,priority:Q,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,Q="completed"){return this.call("reply",{task_id:z,text:B,status:Q})}async status(z,B){return this.call("report_status",{resume_id:this.resumeId,alias:this.alias,status:z,server:C(),hostname:C(),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}`,Q=this.reconnectDelay;while(this.running){try{this.sseAbort=new AbortController;let V={Accept:"text/event-stream"};if(this.token)V.Authorization=`Bearer ${this.token}`;let X=await fetch(B,{headers:V,signal:this.sseAbort.signal});if(!X.ok||!X.body){this.log(`SSE failed: ${X.status}`),await this.sleep(Q),Q=Math.min(Q*1.5,60000);continue}Q=this.reconnectDelay;let Z=X.body.getReader(),N=new TextDecoder,W="";while(this.running){let{done:Y,value:U}=await Z.read();if(Y)break;W+=N.decode(U,{stream:!0});let _=W.split(`
3
- `);W=_.pop()||"";for(let R of _){if(!R.startsWith("data: "))continue;try{let O=JSON.parse(R.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(V){if(V.name==="AbortError")break;this.emit("error",V),this.log(`SSE error: ${V.message}`)}if(this.running)this.emit("disconnected"),this.log(`SSE reconnecting in ${Q/1000}s...`),await this.sleep(Q),Q=Math.min(Q*1.5,60000)}}async processInbox(){try{let B=(await this.call("get_inbox",{alias:this.alias,limit:10}))?.messages||[];for(let Q of B)await this.call("ack_inbox",{alias:this.alias,message_id:Q.id}),this.log(`← ${Q.from_session}: ${Q.content.slice(0,60)}`),this.emit("task",Q),this.emit("message",Q)}catch(z){this.log(`inbox error: ${z.message}`)}}sleep(z){return new Promise((B)=>setTimeout(B,z))}};o=H});import{readFileSync as E,writeFileSync as K,existsSync as q,mkdirSync as G,readdirSync as S}from"fs";import{join as L}from"path";import{spawn as a}from"child_process";var $=process.argv.slice(2),A=$[0],T=process.env.HOME||process.env.USERPROFILE||"~";function y(){return L(T,".anet","config.json")}function k(){return L(process.cwd(),".anet","profiles")}function I(){let z=y();if(q(z))try{return JSON.parse(E(z,"utf-8"))}catch{}return{}}function i(z){let B=L(T,".anet");G(B,{recursive:!0}),K(L(B,"config.json"),JSON.stringify(z,null,2)+`
4
- `)}function M(z){let B=L(k(),`${z}.json`);if(q(B))try{return JSON.parse(E(B,"utf-8"))}catch{}return null}function e(z,B){let Q=k();G(Q,{recursive:!0}),K(L(Q,`${z}.json`),JSON.stringify(B,null,2)+`
5
- `)}function u(){let z=k();if(!q(z))return[];return S(z).filter((B)=>B.endsWith(".json")).map((B)=>B.replace(/\.json$/,""))}function F(){let z={_channels:[],_envs:[]};for(let B=0;B<$.length;B++){if($[B]==="--channel"&&$[B+1]){z._channels.push($[++B]);continue}if($[B]==="--env"&&$[B+1]){z._envs.push($[++B]);continue}if($[B].startsWith("--")&&$[B+1]&&!$[B+1].startsWith("--"))z[$[B].slice(2)]=$[++B]}return z}function v(){console.log(`
2
+ import{createRequire as n}from"node:module";var m=Object.defineProperty;var c=(z)=>z;function p(z,B){this[z]=c.bind(null,B)}var d=(z,B)=>{for(var Q in B)m(z,Q,{get:B[Q],enumerable:!0,configurable:!0,set:p.bind(B,Q)})};var l=(z,B)=>()=>(z&&(B=z(z=0)),B);var t=n(import.meta.url);var C={};d(C,{default:()=>o,CommHub:()=>H});import{EventEmitter as r}from"events";import{hostname as w}from"os";var H,o;var P=l(()=>{H=class H extends r{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 Q={"Content-Type":"application/json"};if(this.token)Q.Authorization=`Bearer ${this.token}`;let X=await(await fetch(`${this.url}/mcp`,{method:"POST",headers:Q,body:JSON.stringify({jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:z,arguments:B}})})).json(),Z=X?.result?.content?.[0]?.text;return Z?JSON.parse(Z):X}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,Q="normal"){return this.call("send_task",{alias:z,task:B,priority:Q,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,Q="completed"){return this.call("reply",{task_id:z,text:B,status:Q})}async status(z,B){return this.call("report_status",{resume_id:this.resumeId,alias:this.alias,status:z,server:w(),hostname:w(),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}`,Q=this.reconnectDelay;while(this.running){try{this.sseAbort=new AbortController;let V={Accept:"text/event-stream"};if(this.token)V.Authorization=`Bearer ${this.token}`;let X=await fetch(B,{headers:V,signal:this.sseAbort.signal});if(!X.ok||!X.body){this.log(`SSE failed: ${X.status}`),await this.sleep(Q),Q=Math.min(Q*1.5,60000);continue}Q=this.reconnectDelay;let Z=X.body.getReader(),N=new TextDecoder,W="";while(this.running){let{done:Y,value:U}=await Z.read();if(Y)break;W+=N.decode(U,{stream:!0});let R=W.split(`
3
+ `);W=R.pop()||"";for(let _ of R){if(!_.startsWith("data: "))continue;try{let T=JSON.parse(_.slice(6));if(T.type==="connected"){this.log("SSE connected"),this.emit("connected");continue}if(T.type==="new_task"||T.type==="new_message"||T.type==="broadcast")await this.processInbox()}catch{}}}}catch(V){if(V.name==="AbortError")break;this.emit("error",V),this.log(`SSE error: ${V.message}`)}if(this.running)this.emit("disconnected"),this.log(`SSE reconnecting in ${Q/1000}s...`),await this.sleep(Q),Q=Math.min(Q*1.5,60000)}}async processInbox(){try{let B=(await this.call("get_inbox",{alias:this.alias,limit:10}))?.messages||[];for(let Q of B)await this.call("ack_inbox",{alias:this.alias,message_id:Q.id}),this.log(`← ${Q.from_session}: ${Q.content.slice(0,60)}`),this.emit("task",Q),this.emit("message",Q)}catch(z){this.log(`inbox error: ${z.message}`)}}sleep(z){return new Promise((B)=>setTimeout(B,z))}};o=H});import{readFileSync as O,writeFileSync as K,existsSync as q,mkdirSync as G,readdirSync as b}from"fs";import{join as $}from"path";import{spawn as a}from"child_process";var L=process.argv.slice(2),A=L[0],E=process.env.HOME||process.env.USERPROFILE||"~";function S(){return $(E,".anet","config.json")}function k(){return $(process.cwd(),".anet","profiles")}function I(){let z=S();if(q(z))try{return JSON.parse(O(z,"utf-8"))}catch{}return{}}function i(z){let B=$(E,".anet");G(B,{recursive:!0}),K($(B,"config.json"),JSON.stringify(z,null,2)+`
4
+ `)}function M(z){let B=$(k(),`${z}.json`);if(q(B))try{return JSON.parse(O(B,"utf-8"))}catch{}return null}function e(z,B){let Q=k();G(Q,{recursive:!0}),K($(Q,`${z}.json`),JSON.stringify(B,null,2)+`
5
+ `)}function y(){let z=k();if(!q(z))return[];return b(z).filter((B)=>B.endsWith(".json")).map((B)=>B.replace(/\.json$/,""))}function D(){let z={_channels:[],_envs:[]};for(let B=0;B<L.length;B++){if(L[B]==="--channel"&&L[B+1]){z._channels.push(L[++B]);continue}if(L[B]==="--env"&&L[B+1]){z._envs.push(L[++B]);continue}if(L[B].startsWith("--")&&L[B+1]&&!L[B+1].startsWith("--"))z[L[B].slice(2)]=L[++B]}return z}function j(){console.log(`
6
6
  anet — AI Agent Network CLI
7
7
 
8
8
  anet init Configure hub URL (global, once)
@@ -20,11 +20,11 @@ Quick start:
20
20
  anet init profile 指挥室 --alias 指挥室 --channel server:commhub
21
21
  anet start 指挥室 # 新建
22
22
  anet resume 指挥室 # 下次恢复
23
- `)}async function s(){let z=F(),B=z.hub;if(!B)process.stdout.write("CommHub URL (e.g. http://YOUR_IP:9200): "),B=await new Promise((V)=>{process.stdin.setEncoding("utf-8"),process.stdin.once("data",(X)=>{process.stdin.unref(),V(X.toString().trim())})});if(!B)console.error("Error: hub URL required"),process.exit(1);B=B.replace(/\/+$/,"");try{let X=await(await fetch(`${B}/health`)).json();console.log(`✅ CommHub v${X.version} — ${X.sessions} sessions, ${X.sse_connections} SSE`)}catch(V){console.error(`❌ Cannot reach ${B}: ${V.message}`),process.exit(1)}let Q=I();if(Q.hub=B,z.token)Q.token=z.token;i(Q),console.log(`
24
- Saved to ${y()}`),console.log("Next: anet init project")}async function zz(){let B=I().hub;if(!B)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let Q=L(process.cwd(),".anet");G(Q,{recursive:!0});let V=L(Q,"node-server.ts");if(!q(V)){let U=new URL(".",import.meta.url).pathname,_=L(U,"..","..","src","node-server.ts");if(q(_)){let{copyFileSync:R}=await import("fs");R(_,V),console.log(" ✅ .anet/node-server.ts (from npm package)")}else try{let R=await fetch("https://raw.githubusercontent.com/sleep2agi/agent-comm-hub/main/channel/commhub-channel.ts");if(R.ok)K(V,await R.text()),console.log(" ✅ .anet/node-server.ts (downloaded)");else console.log(" ❌ Cannot find channel plugin. Copy manually from agent-comm-hub/channel/commhub-channel.ts")}catch{console.log(" Cannot find channel plugin. Copy manually from agent-comm-hub/channel/commhub-channel.ts")}}else console.log(" Channel plugin: exists");let X=L(Q,"package.json");if(!q(X)){K(X,JSON.stringify({private:!0,dependencies:{"@modelcontextprotocol/sdk":"^1.12.0"}},null,2)+`
25
- `);try{let{execSync:U}=await import("child_process");U("bun install",{cwd:Q,stdio:"pipe"}),console.log(" ✅ Dependencies installed")}catch{console.log(" ⚠️ Run: cd .anet && bun install")}}let Z=L(Q,".env");K(Z,`COMMHUB_URL=${B}
26
- `),console.log(`CommHub URL: ${B}`);let N=L(process.cwd(),".mcp.json"),W={};if(q(N))try{W=JSON.parse(E(N,"utf-8"))}catch{}if(!W.mcpServers?.commhub)W.mcpServers=W.mcpServers||{},W.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},K(N,JSON.stringify(W,null,2)+`
27
- `),console.log(".mcp.json: commhub → .anet/node-server.ts");else console.log(".mcp.json: commhub already set");let Y=L(process.cwd(),"CLAUDE.md");if(!q(Y))K(Y,`# Agent Network (CommHub)
23
+ `)}async function s(){let z=D(),B=z.hub;if(!B)process.stdout.write("CommHub URL (e.g. http://YOUR_IP:9200): "),B=await new Promise((V)=>{process.stdin.setEncoding("utf-8"),process.stdin.once("data",(X)=>{process.stdin.unref(),V(X.toString().trim())})});if(!B)console.error("Error: hub URL required"),process.exit(1);B=B.replace(/\/+$/,"");try{let X=await(await fetch(`${B}/health`)).json();console.log(`✅ CommHub v${X.version} — ${X.sessions} sessions, ${X.sse_connections} SSE`)}catch(V){console.error(`❌ Cannot reach ${B}: ${V.message}`),process.exit(1)}let Q=I();if(Q.hub=B,z.token)Q.token=z.token;i(Q),console.log(`
24
+ Saved to ${S()}`),console.log("Next: anet init project")}async function zz(){let B=I().hub;if(!B)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let Q=$(process.cwd(),".anet");G(Q,{recursive:!0});let V=$(Q,"node-server.ts");if(!q(V)){let U=[$(new URL(".",import.meta.url).pathname,"..","..","src","node-server.ts"),$(new URL(".",import.meta.url).pathname,"..","src","node-server.ts"),$(process.argv[1],"..","..","src","node-server.ts")],R=!1;for(let _ of U)if(q(_)){K(V,O(_,"utf-8")),console.log(" ✅ .anet/node-server.ts"),R=!0;break}if(!R)console.log(" ❌ Cannot find node-server.ts"),console.log(" Fix: cp $(npm root -g)/@sleep2agi/agent-network/src/node-server.ts .anet/node-server.ts")}else console.log(" Channel plugin: exists");let X=$(Q,"package.json");if(!q(X)){K(X,JSON.stringify({private:!0,dependencies:{"@modelcontextprotocol/sdk":"^1.12.0"}},null,2)+`
25
+ `);try{let{execSync:U}=await import("child_process");U("bun install",{cwd:Q,stdio:"pipe"}),console.log(" ✅ Dependencies installed")}catch{console.log(" ⚠️ Run: cd .anet && bun install")}}let Z=$(Q,".env");K(Z,`COMMHUB_URL=${B}
26
+ `),console.log(`CommHub URL: ${B}`);let N=$(process.cwd(),".mcp.json"),W={};if(q(N))try{W=JSON.parse(O(N,"utf-8"))}catch{}if(!W.mcpServers?.commhub)W.mcpServers=W.mcpServers||{},W.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},K(N,JSON.stringify(W,null,2)+`
27
+ `),console.log(".mcp.json: commhub → .anet/node-server.ts");else console.log(".mcp.json: commhub already set");let Y=$(process.cwd(),"CLAUDE.md");if(!q(Y))K(Y,`# Agent Network (CommHub)
28
28
 
29
29
  ## 通信方式
30
30
 
@@ -63,16 +63,16 @@ commhub_get_all_status()
63
63
  - 回复指挥室用 commhub_send_task(不是 commhub_reply,reply 不推送)
64
64
  - 不要猜 alias,用 get_all_status 查
65
65
  `),console.log("CLAUDE.md: created");else console.log("CLAUDE.md: already exists");console.log(`
66
- ✅ Project ready. Next: anet init profile <id> --alias <名字> --channel server:commhub`)}function Bz(){let z=$[2];if(!z)console.error("Usage: anet init profile <id> --alias <名字> [--channel ...] [--env ...]"),process.exit(1);let B=I(),Q=F(),V=Q.alias||z,X=Q.hub||B.hub;if(!X)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let Z={};for(let _ of Q._envs){let R=_.indexOf("=");if(R>0)Z[_.slice(0,R)]=_.slice(R+1)}let N={anet_version:"0.0.11",...Q.name?{name:Q.name}:{},alias:V,hub:X,channels:Q._channels.length>0?Q._channels:["server:commhub"],env:Z,flags:{dangerouslySkipPermissions:!0,...Q["teammate-mode"]?{teammateMode:Q["teammate-mode"]}:{}},...Q.resume?{resume:Q.resume}:{},...Q["resume-alias"]?{resumeAlias:Q["resume-alias"]}:{}},W=L(T,".claude","channels","commhub"),Y=process.cwd().replace(/\//g,"-"),U=L(W,Y);if(G(U,{recursive:!0}),K(L(U,".env"),`COMMHUB_ALIAS=${V}
66
+ ✅ Project ready. Next: anet init profile <id> --alias <名字> --channel server:commhub`)}function Bz(){let z=L[2];if(!z)console.error("Usage: anet init profile <id> --alias <名字> [--channel ...] [--env ...]"),process.exit(1);let B=I(),Q=D(),V=Q.alias||z,X=Q.hub||B.hub;if(!X)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let Z={};for(let R of Q._envs){let _=R.indexOf("=");if(_>0)Z[R.slice(0,_)]=R.slice(_+1)}let N={anet_version:"0.0.11",...Q.name?{name:Q.name}:{},alias:V,hub:X,channels:Q._channels.length>0?Q._channels:["server:commhub"],env:Z,flags:{dangerouslySkipPermissions:!0,...Q["teammate-mode"]?{teammateMode:Q["teammate-mode"]}:{}},...Q.resume?{resume:Q.resume}:{},...Q["resume-alias"]?{resumeAlias:Q["resume-alias"]}:{}},W=$(E,".claude","channels","commhub"),Y=process.cwd().replace(/\//g,"-"),U=$(W,Y);if(G(U,{recursive:!0}),K($(U,".env"),`COMMHUB_ALIAS=${V}
67
67
  `),e(z,N),console.log(`
68
68
  ✅ Profile "${z}" saved`),console.log(` alias: ${V}`),console.log(` channels: ${N.channels.join(", ")}`),Object.keys(Z).length)console.log(` env: ${Object.keys(Z).join(", ")}`);console.log(`
69
- Start: anet start ${z}`)}function f(z,B){let Q=M(z);if(!Q)console.error(`Profile "${z}" not found. Run: anet ls`),process.exit(1);let V={...process.env,COMMHUB_ALIAS:Q.alias};for(let[W,Y]of Object.entries(Q.env))V[W]=Y.replace(/^~/,T);let X=[];if(Q.flags.dangerouslySkipPermissions)X.push("--dangerously-skip-permissions");for(let W of Q.channels)if(W.startsWith("server:"))X.push("--dangerously-load-development-channels",W);else X.push("--channels",W);if(Q.flags.teammateMode)X.push("--teammate-mode",Q.flags.teammateMode);if(B==="resume"){let W=Q.resumeAlias||Q.name||Q.alias;X.push("--resume",W)}X.push("-n",Q.name||Q.alias),console.log(`[anet] ${B==="start"?"Starting new":"Resuming"} "${z}" (${Q.alias})...
70
- `),a("claude",X,{env:V,stdio:"inherit",shell:!0}).on("exit",(W)=>process.exit(W||0))}function b(){let z=$[1];if(!z){h("start");return}f(z,"start")}function Qz(){let z=$[1];if(!z){h("resume");return}f(z,"resume")}function h(z){let B=u();if(B.length===0){console.log("No profiles. Run: anet init profile <id> --alias <名字>");return}console.log(`
69
+ Start: anet start ${z}`)}function u(z,B){let Q=M(z);if(!Q)console.error(`Profile "${z}" not found. Run: anet ls`),process.exit(1);let V={...process.env,COMMHUB_ALIAS:Q.alias};for(let[W,Y]of Object.entries(Q.env))V[W]=Y.replace(/^~/,E);let X=[];if(Q.flags.dangerouslySkipPermissions)X.push("--dangerously-skip-permissions");for(let W of Q.channels)if(W.startsWith("server:"))X.push("--dangerously-load-development-channels",W);else X.push("--channels",W);if(Q.flags.teammateMode)X.push("--teammate-mode",Q.flags.teammateMode);if(B==="resume"){let W=Q.resumeAlias||Q.name||Q.alias;X.push("--resume",W)}X.push("-n",Q.name||Q.alias),console.log(`[anet] ${B==="start"?"Starting new":"Resuming"} "${z}" (${Q.alias})...
70
+ `),a("claude",X,{env:V,stdio:"inherit",shell:!0}).on("exit",(W)=>process.exit(W||0))}function v(){let z=L[1];if(!z){h("start");return}u(z,"start")}function Qz(){let z=L[1];if(!z){h("resume");return}u(z,"resume")}function h(z){let B=y();if(B.length===0){console.log("No profiles. Run: anet init profile <id> --alias <名字>");return}console.log(`
71
71
  Profiles:
72
72
  `);for(let Q of B){let V=M(Q);console.log(` ${Q}${V?.name?` (${V.name})`:""} → ${V?.alias} [${V?.channels.join(", ")}]`)}console.log(`
73
73
  anet ${z} <id>
74
- `)}async function Vz(){let z=u();if(z.length>0){console.log(`
74
+ `)}async function Vz(){let z=y();if(z.length>0){console.log(`
75
75
  Profiles:
76
- `);for(let W of z){let Y=M(W);console.log(` ${W}${Y?.name?` (${Y.name})`:""} → ${Y?.alias} [${Y?.channels.join(", ")}]`)}console.log()}let B=process.cwd(),Q=L(T,".claude","sessions"),V=[];if(q(Q))for(let W of S(Q).filter((Y)=>Y.endsWith(".json")))try{let Y=JSON.parse(E(L(Q,W),"utf-8"));if(Y.cwd===B)V.push(Y)}catch{}if(V.length===0&&z.length===0){console.log("No sessions or profiles in this directory."),console.log(`Get started: anet init
76
+ `);for(let W of z){let Y=M(W);console.log(` ${W}${Y?.name?` (${Y.name})`:""} → ${Y?.alias} [${Y?.channels.join(", ")}]`)}console.log()}let B=process.cwd(),Q=$(E,".claude","sessions"),V=[];if(q(Q))for(let W of b(Q).filter((Y)=>Y.endsWith(".json")))try{let Y=JSON.parse(O($(Q,W),"utf-8"));if(Y.cwd===B)V.push(Y)}catch{}if(V.length===0&&z.length===0){console.log("No sessions or profiles in this directory."),console.log(`Get started: anet init
77
77
  `);return}let X=I(),Z=[],N={};if(X.hub)try{let[W,Y]=await Promise.all([fetch(`${X.hub}/api/status`).then((U)=>U.json()),fetch(`${X.hub}/health`).then((U)=>U.json())]);Z=W.sessions||[],N=Y.sse_sessions||{}}catch{}if(V.length>0){console.log(`Sessions (${B}):
78
- `),console.log(" SESSION PID NETWORK"),console.log(" ──────────────────── ─────── ─────────────────────");for(let W of V){let Y=W.sessionId.slice(0,18),U=!1;try{process.kill(W.pid,0),U=!0}catch{}let _="(not in network)",R=B.replace(/\//g,"-"),O=L(T,".claude","channels","commhub",R,".env");if(q(O)){let D=E(O,"utf-8").match(/COMMHUB_ALIAS=(.+)/);if(D){let J=D[1].trim(),x=Z.find((m)=>m.alias===J),g=N[J]?"●":"○";_=x?`${J} ${x.status} ${g}`:`${J} (not registered)`}}console.log(` ${Y} ${(U?`${W.pid}`:`${W.pid}✕`).padEnd(7)} ${_}`)}console.log()}}async function Wz(){let z=I(),B=F(),Q=process.env.COMMHUB_URL||B.hub||z.hub||"http://127.0.0.1:9200",V=process.env.COMMHUB_ALIAS||B.alias;if(!V)console.error("Error: --alias required"),process.exit(1);let{CommHub:X}=await Promise.resolve().then(() => (P(),j)),Z=new X({url:Q,alias:V});Z.on("task",async(N)=>{console.log(`[${V}] ← ${N.from_session}: ${N.content.slice(0,100)}`),await Z.send(N.from_session,`[${V}] 收到: ${N.content.slice(0,200)}`)}),Z.on("connected",()=>console.log(`[${V}] Connected`)),Z.on("disconnected",()=>console.log(`[${V}] Reconnecting...`)),process.on("SIGINT",()=>Z.disconnect().then(()=>process.exit(0))),console.log(`[${V}] Listening on ${Q}`)}switch(A){case"init":if($[1]==="project")zz();else if($[1]==="profile")Bz();else s();break;case"start":b();break;case"resume":Qz();break;case"ls":case"list":Vz();break;case"run":Wz();break;case"--help":case"-h":case void 0:v();break;default:if(M(A))$.unshift("start"),b();else console.error(`Unknown: ${A}`),v(),process.exit(1)}
78
+ `),console.log(" SESSION PID NETWORK"),console.log(" ──────────────────── ─────── ─────────────────────");for(let W of V){let Y=W.sessionId.slice(0,18),U=!1;try{process.kill(W.pid,0),U=!0}catch{}let R="(not in network)",_=B.replace(/\//g,"-"),T=$(E,".claude","channels","commhub",_,".env");if(q(T)){let F=O(T,"utf-8").match(/COMMHUB_ALIAS=(.+)/);if(F){let J=F[1].trim(),x=Z.find((g)=>g.alias===J),f=N[J]?"●":"○";R=x?`${J} ${x.status} ${f}`:`${J} (not registered)`}}console.log(` ${Y} ${(U?`${W.pid}`:`${W.pid}✕`).padEnd(7)} ${R}`)}console.log()}}async function Wz(){let z=I(),B=D(),Q=process.env.COMMHUB_URL||B.hub||z.hub||"http://127.0.0.1:9200",V=process.env.COMMHUB_ALIAS||B.alias;if(!V)console.error("Error: --alias required"),process.exit(1);let{CommHub:X}=await Promise.resolve().then(() => (P(),C)),Z=new X({url:Q,alias:V});Z.on("task",async(N)=>{console.log(`[${V}] ← ${N.from_session}: ${N.content.slice(0,100)}`),await Z.send(N.from_session,`[${V}] 收到: ${N.content.slice(0,200)}`)}),Z.on("connected",()=>console.log(`[${V}] Connected`)),Z.on("disconnected",()=>console.log(`[${V}] Reconnecting...`)),process.on("SIGINT",()=>Z.disconnect().then(()=>process.exit(0))),console.log(`[${V}] Listening on ${Q}`)}switch(A){case"init":if(L[1]==="project")zz();else if(L[1]==="profile")Bz();else s();break;case"start":v();break;case"resume":Qz();break;case"ls":case"list":Vz();break;case"run":Wz();break;case"--help":case"-h":case void 0:j();break;default:if(M(A))L.unshift("start"),v();else console.error(`Unknown: ${A}`),j(),process.exit(1)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/agent-network",
3
- "version": "0.0.17",
3
+ "version": "0.0.19",
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",