@sleep2agi/agent-network 0.0.49 → 0.0.51

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 +44 -44
  2. package/package.json +1 -1
package/dist/bin/cli.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- var QB=Object.defineProperty;var WB=(Q)=>Q;function XB(Q,W){this[Q]=WB.bind(null,W)}var YB=(Q,W)=>{for(var B in W)QB(Q,B,{get:W[B],enumerable:!0,configurable:!0,set:XB.bind(W,B)})};var ZB=(Q,W)=>()=>(Q&&(W=Q(Q=0)),W);var m={};YB(m,{default:()=>zB,CommHub:()=>b});import{EventEmitter as $B}from"events";import{hostname as g}from"os";var b,zB;var p=ZB(()=>{b=class b extends $B{url;alias;token;agent;resumeId;heartbeatInterval;reconnectDelay;heartbeatTimer;sseAbort;running=!1;constructor(Q){super();if(this.url=Q.url.replace(/\/$/,""),this.alias=Q.alias,this.token=Q.token,this.agent=Q.agent||"sdk",this.resumeId=`sdk-${Q.alias}-${Date.now().toString(36)}`,this.heartbeatInterval=Q.heartbeatInterval??180000,this.reconnectDelay=Q.reconnectDelay??3000,Q.autoConnect!==!1)this.connect()}log(Q){console.log(`[${new Date().toTimeString().slice(0,8)}] [commhub:${this.alias}] ${Q}`)}async call(Q,W){let B={"Content-Type":"application/json",Accept:"application/json, text/event-stream"};if(this.token)B.Authorization=`Bearer ${this.token}`;let $=await(await fetch(`${this.url}/mcp`,{method:"POST",headers:B,body:JSON.stringify({jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:Q,arguments:W}})})).text(),Y=$.match(/data: (.+)/),U=Y?JSON.parse(Y[1]):JSON.parse($),Z=U?.result?.content?.[0]?.text;return Z?JSON.parse(Z):U}async connect(){if(this.running)return;this.running=!0,await this.status("idle"),this.log("registered"),this.heartbeatTimer=setInterval(()=>{this.status("idle").catch((Q)=>this.log(`heartbeat failed: ${Q.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(Q,W,B="normal"){return this.call("send_task",{alias:Q,task:W,priority:B,from_session:this.alias})}async message(Q,W){return this.call("send_message",{alias:Q,message:W,from_session:this.alias})}async reply(Q,W,B="completed"){return this.call("reply",{task_id:Q,text:W,status:B})}async status(Q,W){return this.call("report_status",{resume_id:this.resumeId,alias:this.alias,status:Q,server:g(),hostname:g(),agent:this.agent,project_dir:process.cwd(),...W})}async getAllStatus(){return this.call("get_all_status",{})}async broadcast(Q,W){return this.call("broadcast",{message:Q,filter_server:W?.server,filter_status:W?.status})}async connectSSE(){let Q=encodeURIComponent(this.alias),W=`${this.url}/events/${Q}`,B=this.reconnectDelay;while(this.running){try{this.sseAbort=new AbortController;let X={Accept:"text/event-stream"};if(this.token)X.Authorization=`Bearer ${this.token}`;let $=await fetch(W,{headers:X,signal:this.sseAbort.signal});if(!$.ok||!$.body){this.log(`SSE failed: ${$.status}`),await this.sleep(B),B=Math.min(B*1.5,60000);continue}B=this.reconnectDelay;let Y=$.body.getReader(),U=new TextDecoder,Z="";while(this.running){let{done:z,value:N}=await Y.read();if(z)break;Z+=U.decode(N,{stream:!0});let K=Z.split(`
3
- `);Z=K.pop()||"";for(let V of K){if(!V.startsWith("data: "))continue;try{let _=JSON.parse(V.slice(6));if(_.type==="connected"){this.log("SSE connected"),this.emit("connected");continue}if(_.type==="new_task"||_.type==="new_message"||_.type==="broadcast")await this.processInbox()}catch{}}}}catch(X){if(X.name==="AbortError")break;this.emit("error",X),this.log(`SSE error: ${X.message}`)}if(this.running)this.emit("disconnected"),this.log(`SSE reconnecting in ${B/1000}s...`),await this.sleep(B),B=Math.min(B*1.5,60000)}}async processInbox(){try{let W=(await this.call("get_inbox",{alias:this.alias,limit:10}))?.messages||[];for(let B of W)await this.call("ack_inbox",{alias:this.alias,message_id:B.id}),this.log(`← ${B.from_session}: ${B.content.slice(0,60)}`),this.emit("task",B),this.emit("message",B)}catch(Q){this.log(`inbox error: ${Q.message}`)}}sleep(Q){return new Promise((W)=>setTimeout(W,Q))}};zB=b});import{readFileSync as O,writeFileSync as E,existsSync as q,mkdirSync as M,readdirSync as D,statSync as w}from"fs";import{join as L}from"path";import{spawn as k,execSync as a}from"child_process";import{createInterface as KB}from"readline";var R=process.argv.slice(2),j=R[0],G=process.env.HOME||process.env.USERPROFILE||"~";function t(){return L(G,".anet","config.json")}function S(){return L(G,".anet","server","config.json")}function x(){return L(process.cwd(),".anet","nodes")}function n(){return A().token||process.env.COMMHUB_TOKEN||J().token||""}function u(Q){let W=Q||n();return W?{Authorization:`Bearer ${W}`}:{}}function J(){let Q=t();if(q(Q))try{return JSON.parse(O(Q,"utf-8"))}catch{}return{}}function i(Q){let W=L(G,".anet");M(W,{recursive:!0}),E(L(W,"config.json"),JSON.stringify(Q,null,2)+`
4
- `)}function c(){let Q=S();if(q(Q))try{return JSON.parse(O(Q,"utf-8"))}catch{}return{}}function d(Q){let W=L(G,".anet","server");M(W,{recursive:!0}),E(L(W,"config.json"),JSON.stringify(Q,null,2)+`
5
- `)}function F(Q){let W=L(x(),Q,"config.json");if(!q(W))return null;try{let B=JSON.parse(O(W,"utf-8")),X=J();return{...B,hub:B.hub||X.hub||"",token:B.token||X.token||"",env:{...B.env},flags:{...B.flags}}}catch{return null}}function v(Q,W){let B=L(x(),Q);M(B,{recursive:!0}),E(L(B,"config.json"),JSON.stringify(W,null,2)+`
6
- `)}function y(){let Q=x();if(!q(Q))return[];return D(Q).filter((W)=>q(L(Q,W,"config.json")))}function A(){let Q={_channels:[],_envs:[]};for(let W=0;W<R.length;W++){if(R[W]==="--channel"&&R[W+1]){Q._channels.push(R[++W]);continue}if(R[W]==="--env"&&R[W+1]){Q._envs.push(R[++W]);continue}if(R[W].startsWith("--")&&R[W+1]&&!R[W+1].startsWith("--"))Q[R[W].slice(2)]=R[++W]}return Q}function l(){console.log(`
2
+ var QB=Object.defineProperty;var WB=(Q)=>Q;function XB(Q,W){this[Q]=WB.bind(null,W)}var YB=(Q,W)=>{for(var B in W)QB(Q,B,{get:W[B],enumerable:!0,configurable:!0,set:XB.bind(W,B)})};var ZB=(Q,W)=>()=>(Q&&(W=Q(Q=0)),W);var m={};YB(m,{default:()=>zB,CommHub:()=>b});import{EventEmitter as $B}from"events";import{hostname as f}from"os";var b,zB;var p=ZB(()=>{b=class b extends $B{url;alias;token;agent;resumeId;heartbeatInterval;reconnectDelay;heartbeatTimer;sseAbort;running=!1;constructor(Q){super();if(this.url=Q.url.replace(/\/$/,""),this.alias=Q.alias,this.token=Q.token,this.agent=Q.agent||"sdk",this.resumeId=`sdk-${Q.alias}-${Date.now().toString(36)}`,this.heartbeatInterval=Q.heartbeatInterval??180000,this.reconnectDelay=Q.reconnectDelay??3000,Q.autoConnect!==!1)this.connect()}log(Q){console.log(`[${new Date().toTimeString().slice(0,8)}] [commhub:${this.alias}] ${Q}`)}async call(Q,W){let B={"Content-Type":"application/json",Accept:"application/json, text/event-stream"};if(this.token)B.Authorization=`Bearer ${this.token}`;let $=await(await fetch(`${this.url}/mcp`,{method:"POST",headers:B,body:JSON.stringify({jsonrpc:"2.0",id:Date.now(),method:"tools/call",params:{name:Q,arguments:W}})})).text(),Z=$.match(/data: (.+)/),z=Z?JSON.parse(Z[1]):JSON.parse($),Y=z?.result?.content?.[0]?.text;return Y?JSON.parse(Y):z}async connect(){if(this.running)return;this.running=!0,await this.status("idle"),this.log("registered"),this.heartbeatTimer=setInterval(()=>{this.status("idle").catch((Q)=>this.log(`heartbeat failed: ${Q.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(Q,W,B="normal"){return this.call("send_task",{alias:Q,task:W,priority:B,from_session:this.alias})}async message(Q,W){return this.call("send_message",{alias:Q,message:W,from_session:this.alias})}async reply(Q,W,B="completed"){return this.call("reply",{task_id:Q,text:W,status:B})}async status(Q,W){return this.call("report_status",{resume_id:this.resumeId,alias:this.alias,status:Q,server:f(),hostname:f(),agent:this.agent,project_dir:process.cwd(),...W})}async getAllStatus(){return this.call("get_all_status",{})}async broadcast(Q,W){return this.call("broadcast",{message:Q,filter_server:W?.server,filter_status:W?.status})}async connectSSE(){let Q=encodeURIComponent(this.alias),W=`${this.url}/events/${Q}`,B=this.reconnectDelay;while(this.running){try{this.sseAbort=new AbortController;let X={Accept:"text/event-stream"};if(this.token)X.Authorization=`Bearer ${this.token}`;let $=await fetch(W,{headers:X,signal:this.sseAbort.signal});if(!$.ok||!$.body){this.log(`SSE failed: ${$.status}`),await this.sleep(B),B=Math.min(B*1.5,60000);continue}B=this.reconnectDelay;let Z=$.body.getReader(),z=new TextDecoder,Y="";while(this.running){let{done:N,value:U}=await Z.read();if(N)break;Y+=z.decode(U,{stream:!0});let L=Y.split(`
3
+ `);Y=L.pop()||"";for(let E of L){if(!E.startsWith("data: "))continue;try{let V=JSON.parse(E.slice(6));if(V.type==="connected"){this.log("SSE connected"),this.emit("connected");continue}if(V.type==="new_task"||V.type==="new_message"||V.type==="broadcast")await this.processInbox()}catch{}}}}catch(X){if(X.name==="AbortError")break;this.emit("error",X),this.log(`SSE error: ${X.message}`)}if(this.running)this.emit("disconnected"),this.log(`SSE reconnecting in ${B/1000}s...`),await this.sleep(B),B=Math.min(B*1.5,60000)}}async processInbox(){try{let W=(await this.call("get_inbox",{alias:this.alias,limit:10}))?.messages||[];for(let B of W)await this.call("ack_inbox",{alias:this.alias,message_id:B.id}),this.log(`← ${B.from_session}: ${B.content.slice(0,60)}`),this.emit("task",B),this.emit("message",B)}catch(Q){this.log(`inbox error: ${Q.message}`)}}sleep(Q){return new Promise((W)=>setTimeout(W,Q))}};zB=b});import{readFileSync as O,writeFileSync as q,existsSync as _,mkdirSync as M,readdirSync as w,statSync as D}from"fs";import{join as K}from"path";import{spawn as j,execSync as r}from"child_process";import{createInterface as LB}from"readline";var R=process.argv.slice(2),k=R[0],G=process.env.HOME||process.env.USERPROFILE||"~";function t(){return K(G,".anet","config.json")}function u(){return K(G,".anet","server","config.json")}function F(){return K(process.cwd(),".anet","nodes")}function n(){return I().token||process.env.COMMHUB_TOKEN||T().token||""}function S(Q){let W=Q||n();return W?{Authorization:`Bearer ${W}`}:{}}function T(){let Q=t();if(_(Q))try{return JSON.parse(O(Q,"utf-8"))}catch{}return{}}function i(Q){let W=K(G,".anet");M(W,{recursive:!0}),q(K(W,"config.json"),JSON.stringify(Q,null,2)+`
4
+ `)}function c(){let Q=u();if(_(Q))try{return JSON.parse(O(Q,"utf-8"))}catch{}return{}}function d(Q){let W=K(G,".anet","server");M(W,{recursive:!0}),q(K(W,"config.json"),JSON.stringify(Q,null,2)+`
5
+ `)}function x(Q){let W=K(F(),Q,"config.json");if(!_(W))return null;try{let B=JSON.parse(O(W,"utf-8")),X=T();return{...B,hub:B.hub||X.hub||"",token:B.token||X.token||"",env:{...B.env},flags:{...B.flags}}}catch{return null}}function P(Q,W){let B=K(F(),Q);M(B,{recursive:!0}),q(K(B,"config.json"),JSON.stringify(W,null,2)+`
6
+ `)}function y(){let Q=F();if(!_(Q))return[];return w(Q).filter((W)=>_(K(Q,W,"config.json")))}function I(){let Q={_channels:[],_envs:[]};for(let W=0;W<R.length;W++){if(R[W]==="--channel"&&R[W+1]){Q._channels.push(R[++W]);continue}if(R[W]==="--env"&&R[W+1]){Q._envs.push(R[++W]);continue}if(R[W].startsWith("--")&&R[W+1]&&!R[W+1].startsWith("--"))Q[R[W].slice(2)]=R[++W]}return Q}function l(){console.log(`
7
7
  anet — AI Agent Network CLI
8
8
 
9
9
  anet init Configure hub URL (global, once)
@@ -23,12 +23,12 @@ Quick start:
23
23
  anet init --hub http://IP:9200
24
24
  anet start 指挥室 # Claude Code Agent
25
25
  anet start 小明 # MiniMax Agent (runtime: agent-sdk)
26
- `)}async function UB(){let Q=A(),W=Q.hub;if(!W)W=await T("CommHub URL (e.g. http://YOUR_IP:9200)");if(!W)C(),console.error("Error: hub URL required"),process.exit(1);W=W.replace(/\/+$/,"");let B=Q.token||"";if(!B)B=await T("Auth token (empty to skip)");C();try{let Y=await(await fetch(`${W}/health`,{headers:B?{Authorization:`Bearer ${B}`}:{}})).json();console.log(`✅ CommHub v${Y.version} — ${Y.sessions} sessions, ${Y.sse_connections} SSE`)}catch($){console.error(`❌ Cannot reach ${W}: ${$.message}`),process.exit(1)}let X=J();if(X.hub=W,B)X.token=B;else if(!X.token)delete X.token;i(X),console.log(`
27
- Saved to ${t()}`),console.log("Next: anet init project")}async function NB(){let Q=J(),W=Q.hub;if(!W)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let B=L(process.cwd(),".anet");M(B,{recursive:!0});let X=L(B,"node-server.ts");if(!q(X)){let V=[L(new URL(".",import.meta.url).pathname,"..","..","src","node-server.ts"),L(new URL(".",import.meta.url).pathname,"..","src","node-server.ts"),L(process.argv[1],"..","..","src","node-server.ts")],_=!1;for(let H of V)if(q(H)){E(X,O(H,"utf-8")),console.log(" ✅ .anet/node-server.ts"),_=!0;break}if(!_)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 $=L(B,"package.json");if(!q($)){E($,JSON.stringify({private:!0,dependencies:{"@modelcontextprotocol/sdk":"^1.12.0"}},null,2)+`
28
- `);try{a("bun install",{cwd:B,stdio:"pipe"}),console.log(" ✅ Dependencies installed")}catch{console.log(" ⚠️ Run: cd .anet && bun install")}}let Y=L(B,".env"),U=Q.token||"",Z=`COMMHUB_URL=${W}
29
- `;if(U)Z+=`COMMHUB_TOKEN=${U}
30
- `;E(Y,Z),console.log(`CommHub URL: ${W}${U?" (with token)":""}`);let z=L(process.cwd(),".mcp.json"),N={};if(q(z))try{N=JSON.parse(O(z,"utf-8"))}catch{}if(!N.mcpServers?.commhub)N.mcpServers=N.mcpServers||{},N.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},E(z,JSON.stringify(N,null,2)+`
31
- `),console.log(".mcp.json: commhub → .anet/node-server.ts");else console.log(".mcp.json: commhub already set");let K=L(process.cwd(),"CLAUDE.md");if(!q(K))E(K,`# Agent Network (CommHub)
26
+ `)}async function NB(){let Q=I(),W=Q.hub;if(!W)W=await J("CommHub URL (e.g. http://YOUR_IP:9200)");if(!W)v(),console.error("Error: hub URL required"),process.exit(1);W=W.replace(/\/+$/,"");let B=Q.token||"";if(!B)B=await J("Auth token (empty to skip)");v();try{let Z=await(await fetch(`${W}/health`,{headers:B?{Authorization:`Bearer ${B}`}:{}})).json();console.log(`✅ CommHub v${Z.version} — ${Z.sessions} sessions, ${Z.sse_connections} SSE`)}catch($){console.error(`❌ Cannot reach ${W}: ${$.message}`),process.exit(1)}let X=T();if(X.hub=W,B)X.token=B;else if(!X.token)delete X.token;i(X),console.log(`
27
+ Saved to ${t()}`),console.log("Next: anet init project")}async function UB(){let Q=T(),W=Q.hub;if(!W)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let B=K(process.cwd(),".anet");M(B,{recursive:!0});let X=K(B,"node-server.ts");if(!_(X)){let E=[K(new URL(".",import.meta.url).pathname,"..","..","src","node-server.ts"),K(new URL(".",import.meta.url).pathname,"..","src","node-server.ts"),K(process.argv[1],"..","..","src","node-server.ts")],V=!1;for(let H of E)if(_(H)){q(X,O(H,"utf-8")),console.log(" ✅ .anet/node-server.ts"),V=!0;break}if(!V)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 $=K(B,"package.json");if(!_($)){q($,JSON.stringify({private:!0,dependencies:{"@modelcontextprotocol/sdk":"^1.12.0"}},null,2)+`
28
+ `);try{r("bun install",{cwd:B,stdio:"pipe"}),console.log(" ✅ Dependencies installed")}catch{console.log(" ⚠️ Run: cd .anet && bun install")}}let Z=K(B,".env"),z=Q.token||"",Y=`COMMHUB_URL=${W}
29
+ `;if(z)Y+=`COMMHUB_TOKEN=${z}
30
+ `;q(Z,Y),console.log(`CommHub URL: ${W}${z?" (with token)":""}`);let N=K(process.cwd(),".mcp.json"),U={};if(_(N))try{U=JSON.parse(O(N,"utf-8"))}catch{}if(!U.mcpServers?.commhub)U.mcpServers=U.mcpServers||{},U.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},q(N,JSON.stringify(U,null,2)+`
31
+ `),console.log(".mcp.json: commhub → .anet/node-server.ts");else console.log(".mcp.json: commhub already set");let L=K(process.cwd(),"CLAUDE.md");if(!_(L))q(L,`# Agent Network (CommHub)
32
32
 
33
33
  ## 通信方式
34
34
 
@@ -67,32 +67,32 @@ commhub_get_all_status()
67
67
  - 回复指挥室用 commhub_send_task(不是 commhub_reply,reply 不推送)
68
68
  - 不要猜 alias,用 get_all_status 查
69
69
  `),console.log("CLAUDE.md: created");else console.log("CLAUDE.md: already exists");console.log(`
70
- ✅ Project ready. Next: anet init profile <id> --alias <名字> --channel server:commhub`)}function LB(){let Q=R[2];if(!Q)console.error("Usage: anet init profile <id> --alias <名字> [--channel ...] [--env ...]"),process.exit(1);let W=J(),B=A(),X=B.alias||Q,$=B.hub||W.hub;if(!$)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let Y={};for(let V of B._envs){let _=V.indexOf("=");if(_>0)Y[V.slice(0,_)]=V.slice(_+1)}let U=B.runtime||"claude-code",Z={anet_version:"0.0.24",...B.name?{name:B.name}:{},runtime:U,alias:X,hub:$,...B.model?{model:B.model}:{},...B.tools?{tools:B.tools.split(",").map((V)=>V.trim())}:{},channels:B._channels.length>0?B._channels:U==="claude-code"?["server:commhub"]:[],env:Y,flags:{dangerouslySkipPermissions:!0,...U==="claude-code"?{teammateMode:B["teammate-mode"]||"in-process"}:{},...B["max-turns"]?{maxTurns:parseInt(B["max-turns"])}:{}},...B.resume?{resume:B.resume}:{},...B["resume-alias"]?{resumeAlias:B["resume-alias"]}:{}},z=L(G,".claude","channels","commhub"),N=process.cwd().replace(/\//g,"-"),K=L(z,N);if(M(K,{recursive:!0}),E(L(K,".env"),`COMMHUB_ALIAS=${X}
71
- `),v(Q,Z),console.log(`
72
- ✅ Profile "${Q}" saved`),console.log(` alias: ${X}`),console.log(` channels: ${Z.channels.join(", ")}`),Object.keys(Y).length)console.log(` env: ${Object.keys(Y).join(", ")}`);console.log(`
73
- Start: anet start ${Q}`)}var I=null;function RB(){if(!I)I=KB({input:process.stdin,output:process.stdout});return I}function C(){if(I)I.close(),I=null}function T(Q,W){let B=W?` [${W}]`:"";return new Promise((X)=>{RB().question(`${Q}${B}: `,($)=>{X($.trim()||W||"")})})}async function VB(Q){let W=J();console.log(`
70
+ ✅ Project ready. Next: anet init profile <id> --alias <名字> --channel server:commhub`)}function KB(){let Q=R[2];if(!Q)console.error("Usage: anet init profile <id> --alias <名字> [--channel ...] [--env ...]"),process.exit(1);let W=T(),B=I(),X=B.alias||Q,$=B.hub||W.hub;if(!$)console.error("Run 'anet init' first to configure hub URL"),process.exit(1);let Z={};for(let E of B._envs){let V=E.indexOf("=");if(V>0)Z[E.slice(0,V)]=E.slice(V+1)}let z=B.runtime||"claude-code",Y={anet_version:"0.0.24",...B.name?{name:B.name}:{},runtime:z,alias:X,hub:$,...B.model?{model:B.model}:{},...B.tools?{tools:B.tools.split(",").map((E)=>E.trim())}:{},channels:B._channels.length>0?B._channels:z==="claude-code"?["server:commhub"]:[],env:Z,flags:{dangerouslySkipPermissions:!0,...z==="claude-code"?{teammateMode:B["teammate-mode"]||"in-process"}:{},...B["max-turns"]?{maxTurns:parseInt(B["max-turns"])}:{}},...B.resume?{resume:B.resume}:{},...B["resume-alias"]?{resumeAlias:B["resume-alias"]}:{}},N=K(G,".claude","channels","commhub"),U=process.cwd().replace(/\//g,"-"),L=K(N,U);if(M(L,{recursive:!0}),q(K(L,".env"),`COMMHUB_ALIAS=${X}
71
+ `),P(Q,Y),console.log(`
72
+ ✅ Profile "${Q}" saved`),console.log(` alias: ${X}`),console.log(` channels: ${Y.channels.join(", ")}`),Object.keys(Z).length)console.log(` env: ${Object.keys(Z).join(", ")}`);console.log(`
73
+ Start: anet start ${Q}`)}var A=null;function EB(){if(!A)A=LB({input:process.stdin,output:process.stdout});return A}function v(){if(A)A.close(),A=null}function J(Q,W){let B=W?` [${W}]`:"";return new Promise((X)=>{EB().question(`${Q}${B}: `,($)=>{X($.trim()||W||"")})})}async function RB(Q){let W=T();console.log(`
74
74
  Profile "${Q}" not found. Let's create it:
75
- `);let B=await T("Runtime (claude-code / agent-sdk)","claude-code"),X=await T("Alias",Q),$,Y=[],U=[],Z="";if(B==="agent-sdk")$=await T("Model","MiniMax-M2.7"),Y=(await T("Tools (comma-separated)","Read,Bash,Grep")).split(",").map((H)=>H.trim()).filter(Boolean);else U=(await T("Channels (comma-separated)","server:commhub")).split(",").map((H)=>H.trim()).filter(Boolean),Z=await T("Teammate mode","in-process");let z=await T("Extra env (K=V, comma-separated, empty to skip)"),N={};if(z)for(let _ of z.split(",")){let H=_.trim().indexOf("=");if(H>0)N[_.trim().slice(0,H)]=_.trim().slice(H+1)}let K=W.hub;if(!K)console.error(`
76
- Run 'anet init' first to configure hub URL`),process.exit(1);let V={anet_version:"0.0.23",alias:X,hub:K,runtime:B,...$?{model:$}:{},...Y.length?{tools:Y}:{},channels:U,env:N,flags:{dangerouslySkipPermissions:!0,...Z?{teammateMode:Z}:{}}};return v(Q,V),C(),console.log(`
75
+ `);let B=await J("Runtime (claude-code / agent-sdk)","claude-code"),X=await J("Alias",Q),$,Z=[],z=[],Y="";if(B==="agent-sdk")$=await J("Model","MiniMax-M2.7"),Z=(await J("Tools (comma-separated)","Read,Bash,Grep")).split(",").map((H)=>H.trim()).filter(Boolean);else z=(await J("Channels (comma-separated)","server:commhub")).split(",").map((H)=>H.trim()).filter(Boolean),Y=await J("Teammate mode","in-process");let N=await J("Extra env (K=V, comma-separated, empty to skip)"),U={};if(N)for(let V of N.split(",")){let H=V.trim().indexOf("=");if(H>0)U[V.trim().slice(0,H)]=V.trim().slice(H+1)}let L=W.hub;if(!L)console.error(`
76
+ Run 'anet init' first to configure hub URL`),process.exit(1);let E={anet_version:"0.0.23",alias:X,hub:L,runtime:B,...$?{model:$}:{},...Z.length?{tools:Z}:{},channels:z,env:U,flags:{dangerouslySkipPermissions:!0,...Y?{teammateMode:Y}:{}}};return P(Q,E),v(),console.log(`
77
77
  ✅ Profile "${Q}" saved
78
- `),V}function _B(Q){if((Q.runtime||"claude-code")!=="claude-code")return;if(!Q.channels?.some((V)=>V.includes("commhub")))return;let W=L(process.cwd(),".mcp.json"),B={};if(q(W))try{B=JSON.parse(O(W,"utf-8"))}catch{}let X=L(process.cwd(),".anet"),$=L(X,"node-server.ts"),Y=[L(new URL(".",import.meta.url).pathname,"..","..","src","node-server.ts"),L(new URL(".",import.meta.url).pathname,"..","src","node-server.ts"),L(process.argv[1],"..","..","src","node-server.ts")];for(let V of Y)if(q(V)){M(X,{recursive:!0});let _=O(V,"utf-8"),H=q($)?O($,"utf-8"):"";if(_!==H)E($,_),console.log("[anet] Updated .anet/node-server.ts");break}let U=L(X,"package.json");if(!q(U)){M(X,{recursive:!0}),E(U,JSON.stringify({private:!0,dependencies:{"@modelcontextprotocol/sdk":"^1.12.0"}},null,2)+`
79
- `);try{a("bun install",{cwd:X,stdio:"pipe"})}catch{}}if(B.mcpServers=B.mcpServers||{},!Object.keys(B.mcpServers).some((V)=>V.includes("commhub")))B.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},E(W,JSON.stringify(B,null,2)+`
80
- `),console.log("[anet] .mcp.json: added commhub");let z=L(X,".env"),N=Q.token||"",K=`COMMHUB_URL=${Q.hub||"http://127.0.0.1:9200"}
81
- `;if(N)K+=`COMMHUB_TOKEN=${N}
82
- `;E(z,K),B.mcpServers=B.mcpServers||{},B.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},E(W,JSON.stringify(B,null,2)+`
83
- `),console.log("[anet] .mcp.json: added commhub channel server")}async function o(Q,W){let B=F(Q);if(!B)B=await VB(Q);let X=B.runtime||"claude-code";console.log(`[anet] ${W==="start"?"Starting new":"Resuming"} "${Q}" (${B.alias}) [${X}]...
84
- `),_B(B);let Y=B.token||"";if(X==="agent-sdk"){let U=["@sleep2agi/agent-node","--alias",B.alias,"--hub",B.hub];if(B.model)U.push("--model",B.model);if(B.tools?.length)U.push("--tools",B.tools.join(","));if(B.flags?.maxTurns)U.push("--max-turns",String(B.flags.maxTurns));let Z={...process.env,...Y?{COMMHUB_TOKEN:Y}:{}};for(let[N,K]of Object.entries(B.env))Z[N]=K.replace(/^~/,G);k("npx",U,{env:Z,stdio:"inherit",shell:!0}).on("exit",(N)=>process.exit(N||0))}else{let U={...process.env,COMMHUB_ALIAS:B.alias,...Y?{COMMHUB_TOKEN:Y}:{}};for(let[N,K]of Object.entries(B.env))U[N]=K.replace(/^~/,G);let Z=[];if(B.flags.dangerouslySkipPermissions)Z.push("--dangerously-skip-permissions");for(let N of B.channels)if(N.startsWith("server:"))Z.push("--dangerously-load-development-channels",N);else Z.push("--channels",N);if(B.flags.teammateMode)Z.push("--teammate-mode",B.flags.teammateMode);if(W==="resume"){let N=B.resume||B.resumeAlias||B.name||B.alias;Z.push("--resume",N)}Z.push("-n",B.name||B.alias),k("claude",Z,{env:U,stdio:"inherit",shell:!0}).on("exit",(N)=>process.exit(N||0))}}async function r(){let Q=R[1];if(!Q){s("start");return}await o(Q,"start")}async function qB(){let Q=R[1];if(!Q){s("resume");return}let W=F(Q);if(!W){let B=A(),X=J(),$=B.hub||X.hub,Y=B.session;if(!Y)console.log(`Profile "${Q}" not found.
85
- `),console.log(`Quick setup: anet resume ${Q} --session <session-id>`),console.log(`Or create: anet init profile ${Q} --alias ${Q} --resume <session-id>`),process.exit(1);if(!$)console.error("Run 'anet init' first"),process.exit(1);W={runtime:"claude-code",alias:B.alias||Q,hub:$,channels:["server:commhub"],env:{},flags:{dangerouslySkipPermissions:!0,teammateMode:"in-process"},resume:Y},v(Q,W),console.log(`[anet] Created .anet/nodes/${Q}/config.json (resume: ${Y.slice(0,8)}...)
78
+ `),E}function VB(Q){if((Q.runtime||"claude-code")!=="claude-code")return;if(!Q.channels?.some((E)=>E.includes("commhub")))return;let W=K(process.cwd(),".mcp.json"),B={};if(_(W))try{B=JSON.parse(O(W,"utf-8"))}catch{}let X=K(process.cwd(),".anet"),$=K(X,"node-server.ts"),Z=[K(new URL(".",import.meta.url).pathname,"..","..","src","node-server.ts"),K(new URL(".",import.meta.url).pathname,"..","src","node-server.ts"),K(process.argv[1],"..","..","src","node-server.ts")];for(let E of Z)if(_(E)){M(X,{recursive:!0});let V=O(E,"utf-8"),H=_($)?O($,"utf-8"):"";if(V!==H)q($,V),console.log("[anet] Updated .anet/node-server.ts");break}let z=K(X,"package.json");if(!_(z)){M(X,{recursive:!0}),q(z,JSON.stringify({private:!0,dependencies:{"@modelcontextprotocol/sdk":"^1.12.0"}},null,2)+`
79
+ `);try{r("bun install",{cwd:X,stdio:"pipe"})}catch{}}if(B.mcpServers=B.mcpServers||{},!Object.keys(B.mcpServers).some((E)=>E.includes("commhub")))B.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},q(W,JSON.stringify(B,null,2)+`
80
+ `),console.log("[anet] .mcp.json: added commhub");let N=K(X,".env"),U=Q.token||"",L=`COMMHUB_URL=${Q.hub||"http://127.0.0.1:9200"}
81
+ `;if(U)L+=`COMMHUB_TOKEN=${U}
82
+ `;q(N,L),B.mcpServers=B.mcpServers||{},B.mcpServers.commhub={type:"stdio",command:"bun",args:[".anet/node-server.ts"]},q(W,JSON.stringify(B,null,2)+`
83
+ `),console.log("[anet] .mcp.json: added commhub channel server")}async function o(Q,W){let B=x(Q);if(!B)B=await RB(Q);let X=B.runtime||"claude-code";console.log(`[anet] ${W==="start"?"Starting new":"Resuming"} "${Q}" (${B.alias}) [${X}]...
84
+ `),VB(B);let Z=B.token||"";if(X==="agent-sdk"){let z=["@sleep2agi/agent-node","--alias",B.alias,"--hub",B.hub];if(B.model)z.push("--model",B.model);if(B.tools?.length)z.push("--tools",B.tools.join(","));if(B.flags?.maxTurns)z.push("--max-turns",String(B.flags.maxTurns));if(B.codexRuntime)z.push("--runtime",B.codexRuntime);if(W==="resume"&&B.resume)z.push("--session",B.resume);let Y=K(F(),Q,"channels");if(_(Y)){for(let L of w(Y))if(_(K(Y,L,".env")))z.push("--channel",`${L}:${K(Y,L)}`)}let N={...process.env,...Z?{COMMHUB_TOKEN:Z}:{}};for(let[L,E]of Object.entries(B.env))N[L]=E.replace(/^~/,G);j("npx",z,{env:N,stdio:"inherit",shell:!0}).on("exit",(L)=>process.exit(L||0))}else{let z={...process.env,COMMHUB_ALIAS:B.alias,...Z?{COMMHUB_TOKEN:Z}:{}};for(let[U,L]of Object.entries(B.env))z[U]=L.replace(/^~/,G);let Y=[];if(B.flags.dangerouslySkipPermissions)Y.push("--dangerously-skip-permissions");for(let U of B.channels)if(U.startsWith("server:"))Y.push("--dangerously-load-development-channels",U);else Y.push("--channels",U);if(B.flags.teammateMode)Y.push("--teammate-mode",B.flags.teammateMode);if(W==="resume"){let U=B.resume||B.resumeAlias||B.name||B.alias;Y.push("--resume",U)}Y.push("-n",B.name||B.alias),j("claude",Y,{env:z,stdio:"inherit",shell:!0}).on("exit",(U)=>process.exit(U||0))}}async function a(){let Q=R[1];if(!Q){s("start");return}await o(Q,"start")}async function _B(){let Q=R[1];if(!Q){s("resume");return}let W=x(Q);if(!W){let B=I(),X=T(),$=B.hub||X.hub,Z=B.session;if(!Z)console.log(`Profile "${Q}" not found.
85
+ `),console.log(`Quick setup: anet resume ${Q} --session <session-id>`),console.log(`Or create: anet init profile ${Q} --alias ${Q} --resume <session-id>`),process.exit(1);if(!$)console.error("Run 'anet init' first"),process.exit(1);W={runtime:"claude-code",alias:B.alias||Q,hub:$,channels:["server:commhub"],env:{},flags:{dangerouslySkipPermissions:!0,teammateMode:"in-process"},resume:Z},P(Q,W),console.log(`[anet] Created .anet/nodes/${Q}/config.json (resume: ${Z.slice(0,8)}...)
86
86
  `)}await o(Q,"resume")}function s(Q){let W=y();if(W.length===0){console.log("No profiles. Run: anet init profile <id> --alias <名字>");return}console.log(`
87
87
  Profiles:
88
- `);for(let B of W){let X=F(B);console.log(` ${B}${X?.name?` (${X.name})`:""} → ${X?.alias} [${X?.channels.join(", ")}]`)}console.log(`
88
+ `);for(let B of W){let X=x(B);console.log(` ${B}${X?.name?` (${X.name})`:""} → ${X?.alias} [${X?.channels.join(", ")}]`)}console.log(`
89
89
  anet ${Q} <id>
90
- `)}async function EB(){let Q=y();if(Q.length>0){console.log(`
90
+ `)}async function qB(){let Q=y();if(Q.length>0){console.log(`
91
91
  Profiles:
92
- `);for(let Z of Q){let z=F(Z);console.log(` ${Z}${z?.name?` (${z.name})`:""} → ${z?.alias} [${z?.channels.join(", ")}]`)}console.log()}let W=process.cwd(),B=L(G,".claude","sessions"),X=[];if(q(B))for(let Z of D(B).filter((z)=>z.endsWith(".json")))try{let z=JSON.parse(O(L(B,Z),"utf-8"));if(z.cwd===W)X.push(z)}catch{}if(X.length===0&&Q.length===0){console.log("No sessions or profiles in this directory."),console.log(`Get started: anet init
93
- `);return}let $=J(),Y=[],U={};if($.hub)try{let[Z,z]=await Promise.all([fetch(`${$.hub}/api/status`,{headers:u()}).then((N)=>N.json()),fetch(`${$.hub}/health`,{headers:u()}).then((N)=>N.json())]);Y=Z.sessions||[],U=z.sse_sessions||{}}catch{}if(X.length>0){console.log(`Sessions (${W}):
94
- `),console.log(" SESSION PID NETWORK"),console.log(" ──────────────────── ─────── ─────────────────────");for(let Z of X){let z=Z.sessionId.slice(0,18),N=!1;try{process.kill(Z.pid,0),N=!0}catch{}let K="(not in network)",V=W.replace(/\//g,"-"),_=L(G,".claude","channels","commhub",V,".env");if(q(_)){let h=O(_,"utf-8").match(/COMMHUB_ALIAS=(.+)/);if(h){let P=h[1].trim(),f=Y.find((BB)=>BB.alias===P),e=U[P]?"●":"○";K=f?`${P} ${f.status} ${e}`:`${P} (not registered)`}}console.log(` ${z} ${(N?`${Z.pid}`:`${Z.pid}✕`).padEnd(7)} ${K}`)}console.log()}}async function HB(){let Q=J(),W=A(),B=process.env.COMMHUB_URL||W.hub||Q.hub||"http://127.0.0.1:9200",X=process.env.COMMHUB_ALIAS||W.alias;if(!X)console.error("Error: --alias required"),process.exit(1);let{CommHub:$}=await Promise.resolve().then(() => (p(),m)),Y=new $({url:B,alias:X});Y.on("task",async(U)=>{console.log(`[${X}] ← ${U.from_session}: ${U.content.slice(0,100)}`),await Y.send(U.from_session,`[${X}] 收到: ${U.content.slice(0,200)}`)}),Y.on("connected",()=>console.log(`[${X}] Connected`)),Y.on("disconnected",()=>console.log(`[${X}] Reconnecting...`)),process.on("SIGINT",()=>Y.disconnect().then(()=>process.exit(0))),console.log(`[${X}] Listening on ${B}`)}async function OB(){let Q=R[1];if(Q==="start"){let W=A(),B=c(),X=W.port||B.port||"9200",$=W.host||B.host||"0.0.0.0",Y=W.token||B.token||n();if(!Y)Y=crypto.randomUUID().replace(/-/g,""),console.log(`[anet] Generated auth token: ${Y}`),console.log(`[anet] Save this token — agents need it to connect.
95
- `);d({port:X,host:$,token:Y});let U=J();if(!U.token)U.token=Y,i(U);console.log(`[anet] Starting CommHub Server on ${$}:${X}${Y?" (auth enabled)":""}...`);let Z={...process.env,PORT:X,HOST:$};if(Y)Z.COMMHUB_AUTH_TOKEN=Y;k("bunx",["@sleep2agi/commhub-server"],{env:Z,stdio:"inherit",shell:!0}).on("exit",(N)=>process.exit(N||0))}else if(Q==="config"){let W=A(),B=c();if(W.port)B.port=W.port;if(W.host)B.host=W.host;if(W.token)B.token=W.token;if(W.port||W.host||W.token)d(B),console.log(`Server config saved: ${S()}`);console.log(JSON.stringify(B,null,2))}else console.log(`
92
+ `);for(let Y of Q){let N=x(Y);console.log(` ${Y}${N?.name?` (${N.name})`:""} → ${N?.alias} [${N?.channels.join(", ")}]`)}console.log()}let W=process.cwd(),B=K(G,".claude","sessions"),X=[];if(_(B))for(let Y of w(B).filter((N)=>N.endsWith(".json")))try{let N=JSON.parse(O(K(B,Y),"utf-8"));if(N.cwd===W)X.push(N)}catch{}if(X.length===0&&Q.length===0){console.log("No sessions or profiles in this directory."),console.log(`Get started: anet init
93
+ `);return}let $=T(),Z=[],z={};if($.hub)try{let[Y,N]=await Promise.all([fetch(`${$.hub}/api/status`,{headers:S()}).then((U)=>U.json()),fetch(`${$.hub}/health`,{headers:S()}).then((U)=>U.json())]);Z=Y.sessions||[],z=N.sse_sessions||{}}catch{}if(X.length>0){console.log(`Sessions (${W}):
94
+ `),console.log(" SESSION PID NETWORK"),console.log(" ──────────────────── ─────── ─────────────────────");for(let Y of X){let N=Y.sessionId.slice(0,18),U=!1;try{process.kill(Y.pid,0),U=!0}catch{}let L="(not in network)",E=W.replace(/\//g,"-"),V=K(G,".claude","channels","commhub",E,".env");if(_(V)){let h=O(V,"utf-8").match(/COMMHUB_ALIAS=(.+)/);if(h){let C=h[1].trim(),g=Z.find((BB)=>BB.alias===C),e=z[C]?"●":"○";L=g?`${C} ${g.status} ${e}`:`${C} (not registered)`}}console.log(` ${N} ${(U?`${Y.pid}`:`${Y.pid}✕`).padEnd(7)} ${L}`)}console.log()}}async function HB(){let Q=T(),W=I(),B=process.env.COMMHUB_URL||W.hub||Q.hub||"http://127.0.0.1:9200",X=process.env.COMMHUB_ALIAS||W.alias;if(!X)console.error("Error: --alias required"),process.exit(1);let{CommHub:$}=await Promise.resolve().then(() => (p(),m)),Z=new $({url:B,alias:X});Z.on("task",async(z)=>{console.log(`[${X}] ← ${z.from_session}: ${z.content.slice(0,100)}`),await Z.send(z.from_session,`[${X}] 收到: ${z.content.slice(0,200)}`)}),Z.on("connected",()=>console.log(`[${X}] Connected`)),Z.on("disconnected",()=>console.log(`[${X}] Reconnecting...`)),process.on("SIGINT",()=>Z.disconnect().then(()=>process.exit(0))),console.log(`[${X}] Listening on ${B}`)}async function OB(){let Q=R[1];if(Q==="start"){let W=I(),B=c(),X=W.port||B.port||"9200",$=W.host||B.host||"0.0.0.0",Z=W.token||B.token||n();if(!Z)Z=crypto.randomUUID().replace(/-/g,""),console.log(`[anet] Generated auth token: ${Z}`),console.log(`[anet] Save this token — agents need it to connect.
95
+ `);d({port:X,host:$,token:Z});let z=T();if(!z.token)z.token=Z,i(z);console.log(`[anet] Starting CommHub Server on ${$}:${X}${Z?" (auth enabled)":""}...`);let Y={...process.env,PORT:X,HOST:$};if(Z)Y.COMMHUB_AUTH_TOKEN=Z;j("bunx",["@sleep2agi/commhub-server"],{env:Y,stdio:"inherit",shell:!0}).on("exit",(U)=>process.exit(U||0))}else if(Q==="config"){let W=I(),B=c();if(W.port)B.port=W.port;if(W.host)B.host=W.host;if(W.token)B.token=W.token;if(W.port||W.host||W.token)d(B),console.log(`Server config saved: ${u()}`);console.log(JSON.stringify(B,null,2))}else console.log(`
96
96
  anet server <command>
97
97
 
98
98
  start [options] Start CommHub Server
@@ -103,25 +103,25 @@ Options:
103
103
  --host <host> Bind address (default: 0.0.0.0)
104
104
  --token <token> Auth token
105
105
 
106
- Config: ${S()}
106
+ Config: ${u()}
107
107
  First 'anet server start' saves config, after that just 'anet server start'.
108
108
 
109
109
  Example:
110
110
  anet server start --port 9200 --token my-secret # 首次,保存配置
111
111
  anet server start # 之后直接启动
112
112
  anet server config # 查看配置
113
- `)}async function TB(){let Q=J(),B=A().hub||Q.hub;if(!B)console.error("Run 'anet init' first"),process.exit(1);let X=[];try{X=(await(await fetch(`${B}/api/status`,{headers:u()})).json()).sessions||[]}catch(z){console.error(`Cannot reach ${B}: ${z.message}`),process.exit(1)}if(X.length===0){console.log("No sessions in CommHub.");return}let $=X.filter((z)=>z.agent==="claude-code"&&z.project_dir);if($.length===0){console.log("No claude-code sessions found.");return}let Y=R[1],U=Y?$.filter((z)=>z.alias===Y):$;if(U.length===0){console.log(`No session found for "${Y}".`);return}let Z=0;for(let z of U){let N=z.project_dir,K=L(N,".anet","nodes",z.alias),V=L(K,"config.json");if(q(V)){console.log(` ⏭ ${z.alias} — already exists (${N})`);continue}if(!q(N)){console.log(` ⚠ ${z.alias} — project_dir not found: ${N}`);continue}let _={runtime:"claude-code",alias:z.alias,hub:B,channels:["server:commhub"],env:{},flags:{dangerouslySkipPermissions:!0,teammateMode:"in-process"},resume:z.resume_id};M(K,{recursive:!0}),E(V,JSON.stringify(_,null,2)+`
114
- `),console.log(` ✅ ${z.alias} → ${N}/.anet/nodes/${z.alias}/config.json`),Z++}console.log(`
115
- Imported ${Z} session(s). Use: cd <project> && anet resume <alias>`)}function JB(){let Q=R[1];if(Q==="ls"||Q==="list"||!Q){let W=process.cwd(),B=W.replace(/\//g,"-"),X=L(G,".claude","projects",B);if(!q(X)){console.log(`No sessions for ${W}`);return}let $=D(X).filter((Y)=>Y.endsWith(".jsonl")).sort((Y,U)=>{let Z=w(L(X,Y));return w(L(X,U)).mtimeMs-Z.mtimeMs});if($.length===0){console.log("No sessions.");return}console.log(`
113
+ `)}async function TB(){let Q=T(),B=I().hub||Q.hub;if(!B)console.error("Run 'anet init' first"),process.exit(1);let X=[];try{X=(await(await fetch(`${B}/api/status`,{headers:S()})).json()).sessions||[]}catch(N){console.error(`Cannot reach ${B}: ${N.message}`),process.exit(1)}if(X.length===0){console.log("No sessions in CommHub.");return}let $=X.filter((N)=>N.agent==="claude-code"&&N.project_dir);if($.length===0){console.log("No claude-code sessions found.");return}let Z=R[1],z=Z?$.filter((N)=>N.alias===Z):$;if(z.length===0){console.log(`No session found for "${Z}".`);return}let Y=0;for(let N of z){let U=N.project_dir,L=K(U,".anet","nodes",N.alias),E=K(L,"config.json");if(_(E)){console.log(` ⏭ ${N.alias} — already exists (${U})`);continue}if(!_(U)){console.log(` ⚠ ${N.alias} — project_dir not found: ${U}`);continue}let V={runtime:"claude-code",alias:N.alias,hub:B,channels:["server:commhub"],env:{},flags:{dangerouslySkipPermissions:!0,teammateMode:"in-process"},resume:N.resume_id};M(L,{recursive:!0}),q(E,JSON.stringify(V,null,2)+`
114
+ `),console.log(` ✅ ${N.alias} → ${U}/.anet/nodes/${N.alias}/config.json`),Y++}console.log(`
115
+ Imported ${Y} session(s). Use: cd <project> && anet resume <alias>`)}function JB(){let Q=R[1];if(Q==="ls"||Q==="list"||!Q){let W=process.cwd(),B=W.replace(/\//g,"-"),X=K(G,".claude","projects",B);if(!_(X)){console.log(`No sessions for ${W}`);return}let $=w(X).filter((Z)=>Z.endsWith(".jsonl")).sort((Z,z)=>{let Y=D(K(X,Z));return D(K(X,z)).mtimeMs-Y.mtimeMs});if($.length===0){console.log("No sessions.");return}console.log(`
116
116
  Sessions in ${W} (${$.length} total):
117
- `),console.log(" SESSION ID SIZE MODIFIED"),console.log(" ────────────────────────────────────── ──────── ────────────────");for(let Y of $){let U=Y.replace(".jsonl",""),Z=w(L(X,Y)),z=Z.size<1024?`${Z.size}B`:Z.size<1048576?`${(Z.size/1024).toFixed(0)}KB`:`${(Z.size/1024/1024).toFixed(1)}MB`,N=Z.mtime.toISOString().replace("T"," ").slice(0,16);console.log(` ${U} ${z.padStart(8)} ${N}`)}console.log()}else console.log(`
117
+ `),console.log(" SESSION ID SIZE MODIFIED"),console.log(" ────────────────────────────────────── ──────── ────────────────");for(let Z of $){let z=Z.replace(".jsonl",""),Y=D(K(X,Z)),N=Y.size<1024?`${Y.size}B`:Y.size<1048576?`${(Y.size/1024).toFixed(0)}KB`:`${(Y.size/1024/1024).toFixed(1)}MB`,U=Y.mtime.toISOString().replace("T"," ").slice(0,16);console.log(` ${z} ${N.padStart(8)} ${U}`)}console.log()}else console.log(`
118
118
  anet session <command>
119
119
 
120
120
  ls List Claude Code sessions in current project
121
- `)}async function MB(){let Q=R[1],W=A();if(Q==="add"){let B=R[2],X=R[3];if(!B||!X){console.log(`
121
+ `)}async function MB(){let Q=R[1],W=I();if(Q==="add"){let B=R[2],X=R[3];if(!B||!X){console.log(`
122
122
  anet channel add <type> <node-id> [options]
123
123
 
124
- Types: telegram | wechat | feishu
124
+ Types: telegram
125
125
 
126
126
  Options:
127
127
  --bot-token <token> Bot token
@@ -130,16 +130,16 @@ Options:
130
130
  Example:
131
131
  anet channel add telegram 指挥室 --bot-token 123:ABC --allow 7612221352
132
132
  anet channel add telegram 指挥室 # 交互式
133
- `);return}let $=F(X);if(!$)console.error(`Node "${X}" not found. Create it first: anet start ${X}`),process.exit(1);let Y=W["bot-token"],U=W.allow;if(!Y)Y=await T(`${B} Bot Token`);if(!U)U=await T("Allow User ID");if(C(),!Y||!U)console.error("Error: bot-token and allow required"),process.exit(1);let Z=L(x(),X,"channels",B);M(Z,{recursive:!0}),M(L(Z,"inbox"),{recursive:!0});let z=B==="telegram"?"TELEGRAM_BOT_TOKEN":B==="wechat"?"WECHAT_BOT_TOKEN":"FEISHU_BOT_TOKEN";E(L(Z,".env"),`${z}=${Y}
134
- `),E(L(Z,"access.json"),JSON.stringify({dmPolicy:"allowlist",allowFrom:[U],groups:{},pending:{}},null,2)+`
135
- `);let N=B==="telegram"?"plugin:telegram@claude-plugins-official":B==="wechat"?"plugin:wechat":"plugin:feishu",K=B==="telegram"?"TELEGRAM_STATE_DIR":B==="wechat"?"WECHAT_STATE_DIR":"FEISHU_STATE_DIR";if(!$.channels.includes(N))$.channels.push(N);$.env[K]=Z,v(X,$),console.log(`
136
- ✅ ${B} channel added to "${X}"`),console.log(` ${Z}/`),console.log(" config.json updated")}else if(Q==="ls"){let B=R[2],X=B?[B]:y(),$=!1;for(let Y of X){let U=L(x(),Y,"channels");if(!q(U))continue;let Z=D(U).filter((z)=>{try{return w(L(U,z)).isDirectory()}catch{return!1}});if(Z.length===0)continue;if(!$)console.log(`
133
+ `);return}if(B!=="telegram")console.error(`P0 only supports telegram channels. Unsupported type: ${B}`),process.exit(1);let $=x(X);if(!$){let L=T();$={runtime:"claude-code",alias:X,hub:L.hub||"",channels:["server:commhub"],env:{},flags:{dangerouslySkipPermissions:!0,teammateMode:"in-process"}},P(X,$),console.log(`[anet] Created node "${X}"`)}let Z=W["bot-token"],z=W.allow;if(!Z)Z=await J(`${B} Bot Token`);if(!z)z=await J("Allow User ID (发 @userinfobot 获取数字ID)","7612221352");if(v(),!Z||!z)console.error("Error: bot-token and allow required"),process.exit(1);let Y=K(F(),X,"channels",B);M(Y,{recursive:!0}),M(K(Y,"inbox"),{recursive:!0});let N="TELEGRAM_BOT_TOKEN";q(K(Y,".env"),`${N}=${Z}
134
+ `),q(K(Y,"access.json"),JSON.stringify({dmPolicy:"allowlist",allowFrom:[z],groups:{},pending:{}},null,2)+`
135
+ `);let U=($.runtime||"claude-code")==="agent-sdk"?`telegram:${Y}`:"plugin:telegram@claude-plugins-official";if(!$.channels.includes(U))$.channels.push(U);$.env.TELEGRAM_STATE_DIR=Y,P(X,$),console.log(`
136
+ ✅ ${B} channel added to "${X}"`),console.log(` ${Y}/`),console.log(" config.json updated")}else if(Q==="ls"){let B=R[2],X=B?[B]:y(),$=!1;for(let Z of X){let z=K(F(),Z,"channels");if(!_(z))continue;let Y=w(z).filter((N)=>{try{return D(K(z,N)).isDirectory()}catch{return!1}});if(Y.length===0)continue;if(!$)console.log(`
137
137
  Node Channels:
138
- `),$=!0;for(let z of Z){let N=L(U,z,"access.json"),K="";if(q(N))try{K=JSON.parse(O(N,"utf-8")).allowFrom?.join(", ")||""}catch{}console.log(` ${Y.padEnd(20)} ${z.padEnd(12)} allow: ${K||"(none)"}`)}}if(!$)console.log("No channels. Add one: anet channel add telegram <node-id>");console.log()}else console.log(`
138
+ `),$=!0;for(let N of Y){let U=K(z,N,"access.json"),L="";if(_(U))try{L=JSON.parse(O(U,"utf-8")).allowFrom?.join(", ")||""}catch{}console.log(` ${Z.padEnd(20)} ${N.padEnd(12)} allow: ${L||"(none)"}`)}}if(!$)console.log("No channels. Add one: anet channel add telegram <node-id>");console.log()}else console.log(`
139
139
  anet channel <command>
140
140
 
141
141
  add <type> <node-id> Add channel to a node
142
142
  ls [node-id] List channels
143
143
 
144
144
  Data: .anet/nodes/<node-id>/channels/<type>/
145
- `)}switch(j){case"init":if(R[1]==="project")NB();else if(R[1]==="profile")LB();else UB();break;case"server":OB();break;case"start":r();break;case"resume":qB();break;case"import":TB();break;case"channel":MB();break;case"session":JB();break;case"ls":case"list":EB();break;case"run":HB();break;case"-v":case"--version":case"version":{let Q=JSON.parse(O(L(new URL(".",import.meta.url).pathname,"..","..","package.json"),"utf-8"));console.log(`anet v${Q.version}`);break}case"--help":case"-h":case void 0:l();break;default:if(F(j))R.unshift("start"),r();else console.error(`Unknown: ${j}`),l(),process.exit(1)}
145
+ `)}switch(k){case"init":if(R[1]==="project")UB();else if(R[1]==="profile")KB();else NB();break;case"server":OB();break;case"start":a();break;case"resume":_B();break;case"import":TB();break;case"channel":MB();break;case"session":JB();break;case"ls":case"list":qB();break;case"run":HB();break;case"-v":case"--version":case"version":{let Q=JSON.parse(O(K(new URL(".",import.meta.url).pathname,"..","..","package.json"),"utf-8"));console.log(`anet v${Q.version}`);break}case"--help":case"-h":case void 0:l();break;default:if(x(k))R.unshift("start"),a();else console.error(`Unknown: ${k}`),l(),process.exit(1)}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleep2agi/agent-network",
3
- "version": "0.0.49",
3
+ "version": "0.0.51",
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",