@sleep2agi/agent-network 2.2.21 → 2.2.22-preview.0
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 +1 -0
- package/dist/bin/cli.js +1 -1
- package/dist/src/client.js +1 -1
- package/dist/src/im/feishu/adapter.d.ts +29 -0
- package/dist/src/im/feishu/bridge.d.ts +67 -0
- package/dist/src/im/feishu/config.d.ts +34 -0
- package/dist/src/im/feishu/index.d.ts +14 -0
- package/dist/src/im/feishu/worker.d.ts +2 -0
- package/dist/src/im/feishu/worker.js +11 -0
- package/dist/src/node-server.js +1 -1
- package/package.json +4 -3
package/dist/src/client.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
function a0_0x3c0a(){const _0x18320d=['disconnected','parse','toTimeString','Authorization','processInbox','SSE\x20connected','sseAbort','application/json','/mcp','token','8qmmfUl','message','task','normal','new_task','s...','call','read','109800ZoQiIC','heartbeatTimer','offline','reply','match','/events/','SSE\x20error:\x20','new_message','pop','ack_inbox','send_reply','completed','tools/call','126040amGDUq','heartbeat\x20failed:\x20','7ZkRfnV','replace','alias','agent','disconnect','SSE\x20failed:\x20','cwd','AbortError','name','connect','log','min','slice','status','from_session','decode','idle','abort','sleep','144jvUlWP','server','catch','resumeId','text','registered','46890roTArF','connectSSE','connected','type','heartbeatInterval','data:\x20','error',']\x20[commhub:','url','running','getAllStatus','Bearer\x20','55dlqHgN','527136whyMIO','emit','2.0','startsWith','SSE\x20reconnecting\x20in\x20','report_status','application/json,\x20text/event-stream','content','body','378608nxHcyX','get_all_status','3YgnhsJ','now','405099DuaOwd','getReader','reconnectDelay','10436gcOXoF','send'];a0_0x3c0a=function(){return _0x18320d;};return a0_0x3c0a();}function a0_0x5f44(_0x479a0e,_0x55cc72){_0x479a0e=_0x479a0e-0xb4;const _0x3c0a=a0_0x3c0a();let _0x5f4449=_0x3c0a[_0x479a0e];return _0x5f4449;}const a0_0x19de2f=a0_0x5f44;(function(_0x4735d8,_0x3931e8){const _0x280533=a0_0x5f44,_0x43e2ca=_0x4735d8();while(!![]){try{const _0x1d6546=parseInt(_0x280533(0xd4))/0x1*(-parseInt(_0x280533(0xd9))/0x2)+-parseInt(_0x280533(0xed))/0x3*(-parseInt(_0x280533(0xe5))/0x4)+-parseInt(_0x280533(0xbc))/0x5*(-parseInt(_0x280533(0xb6))/0x6)+parseInt(_0x280533(0xfc))/0x7*(parseInt(_0x280533(0xd2))/0x8)+parseInt(_0x280533(0xd6))/0x9+-parseInt(_0x280533(0xfa))/0xa+-parseInt(_0x280533(0xc8))/0xb*(parseInt(_0x280533(0xc9))/0xc);if(_0x1d6546===_0x3931e8)break;else _0x43e2ca['push'](_0x43e2ca['shift']());}catch(_0x5e7c99){_0x43e2ca['push'](_0x43e2ca['shift']());}}}(a0_0x3c0a,0x22d77));import{EventEmitter as a0_0xa82c8b}from'events';import{hostname as a0_0x229639}from'os';class T extends a0_0xa82c8b{[a0_0x19de2f(0xc4)];['alias'];[a0_0x19de2f(0xe4)];[a0_0x19de2f(0xff)];['resumeId'];['heartbeatInterval'];[a0_0x19de2f(0xd8)];[a0_0x19de2f(0xee)];['sseAbort'];[a0_0x19de2f(0xc5)]=!0x1;constructor(_0x2a5ce4){const _0x53a421=a0_0x19de2f;super();if(this['url']=_0x2a5ce4[_0x53a421(0xc4)][_0x53a421(0xfd)](/\/$/,''),this[_0x53a421(0xfe)]=_0x2a5ce4[_0x53a421(0xfe)],this[_0x53a421(0xe4)]=_0x2a5ce4['token'],this['agent']=_0x2a5ce4['agent']||'sdk',this[_0x53a421(0xb9)]='sdk-'+_0x2a5ce4[_0x53a421(0xfe)]+'-'+Date[_0x53a421(0xd5)]()['toString'](0x24),this['heartbeatInterval']=_0x2a5ce4['heartbeatInterval']??0x2bf20,this[_0x53a421(0xd8)]=_0x2a5ce4[_0x53a421(0xd8)]??0xbb8,_0x2a5ce4['autoConnect']!==!0x1)this[_0x53a421(0x105)]();}['log'](_0x1fb884){const _0x143538=a0_0x19de2f;console[_0x143538(0x106)]('['+new Date()[_0x143538(0xdd)]()[_0x143538(0x108)](0x0,0x8)+_0x143538(0xc3)+this[_0x143538(0xfe)]+']\x20'+_0x1fb884);}async['call'](_0x38b8f4,_0x23d64b){const _0x246f6e=a0_0x19de2f;let _0x13600b={'Content-Type':_0x246f6e(0xe2),'Accept':_0x246f6e(0xcf)};if(this[_0x246f6e(0xe4)])_0x13600b[_0x246f6e(0xde)]=_0x246f6e(0xc7)+this[_0x246f6e(0xe4)];let _0x3b5c03=await(await fetch(this[_0x246f6e(0xc4)]+_0x246f6e(0xe3),{'method':'POST','headers':_0x13600b,'body':JSON['stringify']({'jsonrpc':_0x246f6e(0xcb),'id':Date[_0x246f6e(0xd5)](),'method':_0x246f6e(0xf9),'params':{'name':_0x38b8f4,'arguments':_0x23d64b}})}))['text'](),_0x41c425=_0x3b5c03[_0x246f6e(0xf1)](/data: (.+)/),_0x490945=_0x41c425?JSON['parse'](_0x41c425[0x1]):JSON['parse'](_0x3b5c03),_0x47ccbc=_0x490945?.['result']?.[_0x246f6e(0xd0)]?.[0x0]?.[_0x246f6e(0xba)];return _0x47ccbc?JSON[_0x246f6e(0xdc)](_0x47ccbc):_0x490945;}async['connect'](){const _0x2ba586=a0_0x19de2f;if(this['running'])return;this['running']=!0x0,await this[_0x2ba586(0x109)]('idle'),this[_0x2ba586(0x106)](_0x2ba586(0xbb)),this[_0x2ba586(0xee)]=setInterval(()=>{const _0x23192e=_0x2ba586;this['status'](_0x23192e(0x10c))[_0x23192e(0xb8)](_0xe84d8f=>this[_0x23192e(0x106)](_0x23192e(0xfb)+_0xe84d8f[_0x23192e(0xe6)]));},this[_0x2ba586(0xc0)]),this[_0x2ba586(0xbd)]();}async[a0_0x19de2f(0x100)](){const _0x16a264=a0_0x19de2f;if(this[_0x16a264(0xc5)]=!0x1,this[_0x16a264(0xe1)]?.[_0x16a264(0xb4)](),this[_0x16a264(0xee)])clearInterval(this[_0x16a264(0xee)]);await this[_0x16a264(0x109)](_0x16a264(0xef))['catch'](()=>{}),this[_0x16a264(0x106)]('disconnected');}async[a0_0x19de2f(0xda)](_0x5dc68a,_0x426bfe,_0xed8d8b=a0_0x19de2f(0xe8)){const _0xec2b8b=a0_0x19de2f;return this[_0xec2b8b(0xeb)]('send_task',{'alias':_0x5dc68a,'task':_0x426bfe,'priority':_0xed8d8b,'from_session':this[_0xec2b8b(0xfe)]});}async[a0_0x19de2f(0xe6)](_0x2a099d,_0x1871d5){const _0xaeda6a=a0_0x19de2f;return this[_0xaeda6a(0xeb)]('send_message',{'alias':_0x2a099d,'message':_0x1871d5,'from_session':this[_0xaeda6a(0xfe)]});}async[a0_0x19de2f(0xf0)](_0x3b085f,_0x31c15b,_0x2aef4e=a0_0x19de2f(0xf8)){const _0xf555e0=a0_0x19de2f;return this['call'](_0xf555e0(0xf7),{'in_reply_to':_0x3b085f,'text':_0x31c15b,'status':_0x2aef4e});}async[a0_0x19de2f(0x109)](_0x165753,_0xe3bac3){const _0x3f4566=a0_0x19de2f;return this['call'](_0x3f4566(0xce),{'resume_id':this[_0x3f4566(0xb9)],'alias':this[_0x3f4566(0xfe)],'status':_0x165753,'server':a0_0x229639(),'hostname':a0_0x229639(),'agent':this[_0x3f4566(0xff)],'project_dir':process[_0x3f4566(0x102)](),..._0xe3bac3});}async[a0_0x19de2f(0xc6)](){const _0xeaa3e2=a0_0x19de2f;return this[_0xeaa3e2(0xeb)](_0xeaa3e2(0xd3),{});}async['broadcast'](_0x1c68a1,_0x1a0194){const _0x2de29c=a0_0x19de2f;return this[_0x2de29c(0xeb)]('broadcast',{'message':_0x1c68a1,'filter_server':_0x1a0194?.[_0x2de29c(0xb7)],'filter_status':_0x1a0194?.[_0x2de29c(0x109)]});}async[a0_0x19de2f(0xbd)](){const _0x630883=a0_0x19de2f;let _0x5bbe35=encodeURIComponent(this[_0x630883(0xfe)]),_0x51db15=this[_0x630883(0xc4)]+_0x630883(0xf2)+_0x5bbe35,_0x3b130a=this['reconnectDelay'];while(this[_0x630883(0xc5)]){try{this[_0x630883(0xe1)]=new AbortController();let _0x3f206c={'Accept':'text/event-stream'};if(this['token'])_0x3f206c[_0x630883(0xde)]='Bearer\x20'+this[_0x630883(0xe4)];let _0x5d2deb=await fetch(_0x51db15,{'headers':_0x3f206c,'signal':this[_0x630883(0xe1)]['signal']});if(!_0x5d2deb['ok']||!_0x5d2deb['body']){this['log'](_0x630883(0x101)+_0x5d2deb[_0x630883(0x109)]),await this[_0x630883(0xb5)](_0x3b130a),_0x3b130a=Math[_0x630883(0x107)](_0x3b130a*1.5,0xea60);continue;}_0x3b130a=this[_0x630883(0xd8)];let _0x26fad9=_0x5d2deb[_0x630883(0xd1)][_0x630883(0xd7)](),_0x521933=new TextDecoder(),_0x22b29a='';while(this[_0x630883(0xc5)]){let {done:_0x1130b3,value:_0x9d8dcf}=await _0x26fad9[_0x630883(0xec)]();if(_0x1130b3)break;_0x22b29a+=_0x521933[_0x630883(0x10b)](_0x9d8dcf,{'stream':!0x0});let _0xbd133e=_0x22b29a['split']('\x0a');_0x22b29a=_0xbd133e[_0x630883(0xf5)]()||'';for(let _0x1bfab5 of _0xbd133e){if(!_0x1bfab5[_0x630883(0xcc)](_0x630883(0xc1)))continue;try{let _0x4149fd=JSON[_0x630883(0xdc)](_0x1bfab5[_0x630883(0x108)](0x6));if(_0x4149fd[_0x630883(0xbf)]===_0x630883(0xbe)){this[_0x630883(0x106)](_0x630883(0xe0)),this[_0x630883(0xca)](_0x630883(0xbe));continue;}if(_0x4149fd['type']===_0x630883(0xe9)||_0x4149fd[_0x630883(0xbf)]===_0x630883(0xf4)||_0x4149fd[_0x630883(0xbf)]==='broadcast')await this[_0x630883(0xdf)]();}catch{}}}}catch(_0x1b97f7){if(_0x1b97f7[_0x630883(0x104)]===_0x630883(0x103))break;this[_0x630883(0xca)](_0x630883(0xc2),_0x1b97f7),this[_0x630883(0x106)](_0x630883(0xf3)+_0x1b97f7[_0x630883(0xe6)]);}if(this['running'])this['emit'](_0x630883(0xdb)),this['log'](_0x630883(0xcd)+_0x3b130a/0x3e8+_0x630883(0xea)),await this[_0x630883(0xb5)](_0x3b130a),_0x3b130a=Math[_0x630883(0x107)](_0x3b130a*1.5,0xea60);}}async[a0_0x19de2f(0xdf)](){const _0x3a1a95=a0_0x19de2f;try{let _0x100eb3=(await this[_0x3a1a95(0xeb)]('get_inbox',{'alias':this['alias'],'limit':0xa}))?.['messages']||[];for(let _0x15126d of _0x100eb3)await this['call'](_0x3a1a95(0xf6),{'alias':this[_0x3a1a95(0xfe)],'message_id':_0x15126d['id']}),this[_0x3a1a95(0x106)]('←\x20'+_0x15126d[_0x3a1a95(0x10a)]+':\x20'+_0x15126d['content'][_0x3a1a95(0x108)](0x0,0x3c)),this[_0x3a1a95(0xca)](_0x3a1a95(0xe7),_0x15126d),this[_0x3a1a95(0xca)](_0x3a1a95(0xe6),_0x15126d);}catch(_0x211980){this[_0x3a1a95(0x106)]('inbox\x20error:\x20'+_0x211980['message']);}}[a0_0x19de2f(0xb5)](_0x540ad5){return new Promise(_0x1edbad=>setTimeout(_0x1edbad,_0x540ad5));}}var $=T;export{$ as default,T as CommHub};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { IMAdapter, IMAdapterHealth, IMChannelConfig, IMConversationRef, IMIngressMode, NormalizedIMEvent, NormalizedIMMessage } from "../types.js";
|
|
2
|
+
type OnEventHandler = (event: NormalizedIMEvent) => Promise<void>;
|
|
3
|
+
export declare class FeishuAdapter implements IMAdapter {
|
|
4
|
+
readonly platform = "feishu";
|
|
5
|
+
readonly ingressMode: IMIngressMode;
|
|
6
|
+
private feishuConfig;
|
|
7
|
+
private connectionName;
|
|
8
|
+
private client;
|
|
9
|
+
private wsClient;
|
|
10
|
+
/**
|
|
11
|
+
* The bot's own open_id, resolved at init() via /open-apis/bot/v3/info.
|
|
12
|
+
* Used to detect real @bot mentions (vs any mention) in group messages.
|
|
13
|
+
* Falls back to null on lookup failure — `mentioned` then degrades to the
|
|
14
|
+
* naive `mentions.length > 0` check.
|
|
15
|
+
*/
|
|
16
|
+
private botOpenId;
|
|
17
|
+
/** Where to persist downloaded inbound media (M5c). */
|
|
18
|
+
private mediaDir;
|
|
19
|
+
private health_;
|
|
20
|
+
init(config: IMChannelConfig): Promise<void>;
|
|
21
|
+
start(onEvent: OnEventHandler): Promise<void>;
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
send(message: NormalizedIMMessage): Promise<{
|
|
24
|
+
messageId: string;
|
|
25
|
+
}>;
|
|
26
|
+
edit(_target: IMConversationRef, messageId: string, message: NormalizedIMMessage): Promise<void>;
|
|
27
|
+
health(): IMAdapterHealth;
|
|
28
|
+
}
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-020 §2.5 / RFC-002 §2.2 — Feishu bridge worker.
|
|
3
|
+
*
|
|
4
|
+
* Entry point spawned by agent-node when a node profile has `channels.feishu`
|
|
5
|
+
* enabled. Per Vincent 2026-06-24 decision, the first-cut is the simplified
|
|
6
|
+
* "agent-node direct bridge" model, not the full commhub-gateway:
|
|
7
|
+
*
|
|
8
|
+
* - This worker owns the FeishuAdapter and its WSClient connection.
|
|
9
|
+
* - Inbound IM event → access whitelist gate → forward to agent-node's main
|
|
10
|
+
* `think()` via parent IPC.
|
|
11
|
+
* - think() result → adapter.send() back to the originating conversation.
|
|
12
|
+
*
|
|
13
|
+
* Differences vs RFC-020 §2.5 full commhub-gateway path:
|
|
14
|
+
* - No separate gateway ntok_ / dedicated commhub alias.
|
|
15
|
+
* - IM messages do NOT pass through commhub task dispatch.
|
|
16
|
+
* - Feishu messages do NOT appear in Dashboard topology / Chat.
|
|
17
|
+
*
|
|
18
|
+
* The full §2.9 path (meta_json columns, SSE passthrough, persisted
|
|
19
|
+
* IMCorrelationStore) lands as the follow-up PR after this demo ships
|
|
20
|
+
* — tracked in #182.
|
|
21
|
+
*
|
|
22
|
+
* Milestones:
|
|
23
|
+
* M1: worker entry scaffold.
|
|
24
|
+
* M2: adapter + WSClient wiring with a noop event handler.
|
|
25
|
+
* M3 (this file): IPC contract for the think() round-trip — when running
|
|
26
|
+
* as a forked child the bridge auto-uses `process.send` /
|
|
27
|
+
* `process.on("message")`; standalone, it falls back to a
|
|
28
|
+
* stderr logger so the inbound path stays observable.
|
|
29
|
+
* M4: agent-node spawn integration (fork(this) wired by agent-node).
|
|
30
|
+
* M5: group @bot trigger refinement, image up/down, Docker smoke.
|
|
31
|
+
*/
|
|
32
|
+
import type { NormalizedIMEvent } from "../types.js";
|
|
33
|
+
import { FeishuAdapter } from "./adapter.js";
|
|
34
|
+
export interface FeishuBridgeOptions {
|
|
35
|
+
/** Absolute path to `.anet/nodes/<node>/channels/feishu/`. */
|
|
36
|
+
channelDir: string;
|
|
37
|
+
/** Node alias — used for audit log + IPC framing. */
|
|
38
|
+
nodeAlias: string;
|
|
39
|
+
/**
|
|
40
|
+
* Optional inbound event sink for tests or custom integrations. When omitted
|
|
41
|
+
* the bridge picks an automatic strategy:
|
|
42
|
+
* - IPC handler when `process.send` exists (i.e. running as a forked
|
|
43
|
+
* child of agent-node).
|
|
44
|
+
* - stderr logger otherwise (standalone smoke debugging).
|
|
45
|
+
*/
|
|
46
|
+
onEvent?: (event: NormalizedIMEvent) => Promise<void>;
|
|
47
|
+
}
|
|
48
|
+
/** Bridge → parent: inbound IM event ready for think(). */
|
|
49
|
+
export interface BridgeIncomingEnvelope {
|
|
50
|
+
type: "event";
|
|
51
|
+
event: NormalizedIMEvent;
|
|
52
|
+
}
|
|
53
|
+
/** Parent → bridge: agent reply text for a previously-forwarded event. */
|
|
54
|
+
export interface BridgeReplyEnvelope {
|
|
55
|
+
type: "reply";
|
|
56
|
+
/** Echoes the originating event's idempotencyKey. */
|
|
57
|
+
eventKey: string;
|
|
58
|
+
text: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wire and start the Feishu bridge. Resolves once the underlying WSClient is
|
|
62
|
+
* connected and the EventDispatcher is registered.
|
|
63
|
+
*/
|
|
64
|
+
export declare function startFeishuBridge(opts: FeishuBridgeOptions): Promise<FeishuAdapter>;
|
|
65
|
+
export { FeishuAdapter } from "./adapter.js";
|
|
66
|
+
export { loadFeishuChannelConfig } from "./config.js";
|
|
67
|
+
export type { FeishuAccessList, FeishuChannelConfig, FeishuChannelEnv, } from "./config.js";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface FeishuChannelEnv {
|
|
2
|
+
FEISHU_APP_ID: string;
|
|
3
|
+
FEISHU_APP_SECRET: string;
|
|
4
|
+
}
|
|
5
|
+
export interface FeishuAccessList {
|
|
6
|
+
/** Feishu open_ids permitted to DM the bot. */
|
|
7
|
+
allowFrom: string[];
|
|
8
|
+
/** Feishu chat_ids the bot is permitted to listen in. */
|
|
9
|
+
allowChats: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface FeishuChannelConfig {
|
|
12
|
+
appId: string;
|
|
13
|
+
appSecret: string;
|
|
14
|
+
access: FeishuAccessList;
|
|
15
|
+
/** RFC-020 §4.3 group trigger policy. Default `mention`. */
|
|
16
|
+
groupPolicy: "mention" | "command" | "all" | "observe";
|
|
17
|
+
/** Send a "⏳ 处理中…" placeholder before agent reply (RFC-020 §4.2). */
|
|
18
|
+
ackPlaceholder: boolean;
|
|
19
|
+
/** Persist redacted raw payload to local audit log (RFC-020 §2.3 / §12.10). */
|
|
20
|
+
auditRaw: boolean;
|
|
21
|
+
/** Per-task timeout in ms; default 5 min (RFC-020 §4.5). */
|
|
22
|
+
taskTimeoutMs: number;
|
|
23
|
+
/**
|
|
24
|
+
* Absolute path to the channel directory. The adapter writes downloaded
|
|
25
|
+
* inbound media to `<channelDir>/media/` (M5c). Populated by the loader so
|
|
26
|
+
* callers do not have to thread it separately.
|
|
27
|
+
*/
|
|
28
|
+
channelDir: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Load Feishu channel config from a node's channels/feishu directory.
|
|
32
|
+
* Throws if required secrets are missing.
|
|
33
|
+
*/
|
|
34
|
+
export declare function loadFeishuChannelConfig(channelDir: string): FeishuChannelConfig;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC-020 §3.1 — Feishu (Lark) IM channel public surface.
|
|
3
|
+
*
|
|
4
|
+
* - `FeishuAdapter` — IMAdapter implementation backed by `@larksuiteoapi/node-sdk` WSClient.
|
|
5
|
+
* - `startFeishuBridge` — entry point spawned by agent-node for SDK runtimes.
|
|
6
|
+
* - `loadFeishuChannelConfig` — loader for `.anet/nodes/<node>/channels/feishu/`.
|
|
7
|
+
*
|
|
8
|
+
* Tracking: issues #179 (parent RFC), #182 (P0 tracker).
|
|
9
|
+
*/
|
|
10
|
+
export { FeishuAdapter } from "./adapter.js";
|
|
11
|
+
export { startFeishuBridge } from "./bridge.js";
|
|
12
|
+
export type { FeishuBridgeOptions } from "./bridge.js";
|
|
13
|
+
export { loadFeishuChannelConfig } from "./config.js";
|
|
14
|
+
export type { FeishuAccessList, FeishuChannelConfig, FeishuChannelEnv, } from "./config.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import*as B from"@larksuiteoapi/node-sdk";import T from"node:crypto";import{existsSync as C,mkdirSync as M,readFileSync as S,writeFileSync as F}from"node:fs";import{join as O}from"node:path";import{Readable as x}from"node:stream";class N{platform="feishu";ingressMode="socket";feishuConfig=null;connectionName="";client=null;wsClient=null;botOpenId=null;mediaDir=null;health_={connected:!1,lastEventAt:null,lastError:null};async init(Q){if(Q.platform!=="feishu")throw Error(`FeishuAdapter.init: expected platform "feishu", got "${Q.platform}"`);let J=Q.platformConfig;if(!J?.appId||!J?.appSecret)throw Error("FeishuAdapter.init: appId / appSecret missing in platformConfig");this.feishuConfig=J,this.connectionName=Q.connectionName,this.client=new B.Client({appId:J.appId,appSecret:J.appSecret,disableTokenCache:!1}),this.botOpenId=await D(this.client),this.mediaDir=J.channelDir?O(J.channelDir,"media"):null}async start(Q){if(!this.feishuConfig||!this.client)throw Error("FeishuAdapter.start: call init() first");let{appId:J,appSecret:V,access:X,groupPolicy:Z}=this.feishuConfig,$=this.connectionName,Y=this.botOpenId,G=this.mediaDir,W=this.client,U=new B.EventDispatcher({});U.register({"im.message.receive_v1":async(R)=>{try{this.health_={...this.health_,lastEventAt:Date.now()};let H=k(R,$,Y);if(!H)return;await E(R,H,W,G);let q=I(H,X,Z);if(!q.allow){L("deny",H,q.reason);return}await Q(H)}catch(H){let q=H instanceof Error?H.message:String(H);this.health_={...this.health_,lastError:q},L("error",null,q)}}}),this.wsClient=new B.WSClient({appId:J,appSecret:V,loggerLevel:B.LoggerLevel.warn}),await this.wsClient.start({eventDispatcher:U}),this.health_={...this.health_,connected:!0,lastError:null}}async stop(){this.health_={...this.health_,connected:!1},this.wsClient=null,this.client=null,this.feishuConfig=null}async send(Q){if(!this.client)throw Error("FeishuAdapter.send: call init() first");let J,V;if(Q.imagePath){let G=await P(this.client,Q.imagePath);if(!G)throw Error(`FeishuAdapter.send: image upload failed for ${Q.imagePath}`);J="image",V=JSON.stringify({image_key:G})}else{let G=Q.text??Q.markdown;if(!G)throw Error("FeishuAdapter.send: requires text, markdown, or imagePath");J="text",V=JSON.stringify({text:G})}let X=Q.replyToMessageId??Q.target.threadRootId;if(X){let W=(await this.client.im.message.reply({path:{message_id:X},data:{msg_type:J,content:V}}))?.data?.message_id;if(!W)throw Error("FeishuAdapter.send: reply returned no message_id");return{messageId:W}}let Z=Q.target.conversationType==="dm"?"open_id":"chat_id",Y=(await this.client.im.message.create({params:{receive_id_type:Z},data:{receive_id:Q.target.conversationId,msg_type:J,content:V}}))?.data?.message_id;if(!Y)throw Error("FeishuAdapter.send: create returned no message_id");return{messageId:Y}}async edit(Q,J,V){if(!this.client)throw Error("FeishuAdapter.edit: call init() first");let X=V.text??V.markdown;if(!X)throw Error("FeishuAdapter.edit: M3 supports text only");await this.client.im.message.update({path:{message_id:J},data:{msg_type:"text",content:JSON.stringify({text:X})}})}health(){return{...this.health_}}}function k(Q,J,V){let X=Q,Z=X?.message,$=X?.sender,Y=$?.sender_id?.open_id;if(!Z||!Y)return null;let G;if(Z.message_type==="text")try{G=JSON.parse(Z.content).text}catch{G=Z.content}else if(Z.message_type==="file")try{G=`[文件: ${JSON.parse(Z.content).file_name??"unknown"}]`}catch{G="[文件]"}else if(Z.message_type==="sticker")G="[表情]";else if(Z.message_type==="image")G=void 0;else return null;let W=Z.chat_type==="group"?"group":"dm",U=Array.isArray(Z.mentions)?Z.mentions:[],R=V?U.some((q)=>q?.id?.open_id===V):U.length>0,H=`${J}#feishu`;return{platform:"feishu",connectionId:H,tenantId:$?.tenant_key,conversation:{platform:"feishu",conversationId:Z.chat_id,conversationType:W,threadRootId:Z.root_id},sender:{id:Y},messageId:Z.message_id,mentioned:R,content:G?{text:G}:{},receivedAt:Date.now(),idempotencyKey:`feishu:${H}:${Z.message_id}`}}async function E(Q,J,V,X){if(!V||!X)return;let $=Q?.message;if(!$||$.message_type!=="image")return;let Y;try{Y=JSON.parse($.content).image_key}catch{return}if(!Y||!$.message_id)return;let G=await b(V,$.message_id,Y,X);if(G)J.content={...J.content,images:[G]}}async function b(Q,J,V,X){try{let Z=await Q.im.messageResource.get({path:{message_id:J,file_key:V},params:{type:"image"}});if(!Z)return null;let $=Z,Y=[];await new Promise((U,R)=>{$.on("data",(H)=>Y.push(Buffer.from(H))),$.on("end",()=>U()),$.on("error",(H)=>R(H))}),M(X,{recursive:!0});let G=`img_${Date.now()}_${T.randomBytes(4).toString("hex")}.png`,W=O(X,G);return F(W,Buffer.concat(Y)),W}catch{return null}}async function P(Q,J){try{if(!C(J))return null;let V=S(J),X=x.from(V);return(await Q.im.image.create({data:{image_type:"message",image:X}}))?.image_key??null}catch{return null}}async function D(Q){try{let V=await Q.request({method:"GET",url:"/open-apis/bot/v3/info"});return V?.bot?.open_id??V?.data?.bot?.open_id??null}catch{return null}}function I(Q,J,V){if(Q.conversation.conversationType==="dm")return J.allowFrom.includes(Q.sender.id)?{allow:!0,reason:""}:{allow:!1,reason:"sender not in allowFrom (dm)"};if(!J.allowChats.includes(Q.conversation.conversationId))return{allow:!1,reason:"chat not in allowChats"};if(V==="all")return{allow:!0,reason:""};if(V==="observe")return{allow:!1,reason:"groupPolicy=observe — chat in allowChats but no trigger"};if(Q.mentioned)return{allow:!0,reason:""};return{allow:!1,reason:`groupPolicy=${V} requires @bot mention (not mentioned)`}}function L(Q,J,V){let X=new Date().toISOString(),Z=J?`${J.conversation.conversationType}:${J.conversation.conversationId}`:"?",$=J?J.sender.id:"?";process.stderr.write(`[${X}] [feishu:audit] ${Q} from=${$} conv=${Z} — ${V}
|
|
3
|
+
`)}import{existsSync as _,readFileSync as z}from"node:fs";import{join as K}from"node:path";function A(Q){let J=w(K(Q,".env")),V=J.FEISHU_APP_ID,X=J.FEISHU_APP_SECRET;if(!V||!X)throw Error(`feishu channel: FEISHU_APP_ID / FEISHU_APP_SECRET missing in ${Q}/.env`);let Z=y(K(Q,"access.json"));return{appId:V,appSecret:X,access:Z,groupPolicy:"mention",ackPlaceholder:!0,auditRaw:!1,taskTimeoutMs:300000,channelDir:Q}}function w(Q){if(!_(Q))return{};let J={};for(let V of z(Q,"utf-8").split(/\r?\n/)){let X=V.trim();if(!X||X.startsWith("#"))continue;let Z=X.indexOf("=");if(Z<0)continue;let $=X.slice(0,Z).trim(),Y=X.slice(Z+1).trim().replace(/^["']|["']$/g,"");J[$]=Y}return J}function y(Q){if(!_(Q))return{allowFrom:[],allowChats:[]};try{let J=JSON.parse(z(Q,"utf-8"));return{allowFrom:Array.isArray(J.allowFrom)?J.allowFrom:[],allowChats:Array.isArray(J.allowChats)?J.allowChats:[]}}catch{return{allowFrom:[],allowChats:[]}}}var u=900000,f=120000;async function j(Q){let J=A(Q.channelDir),V=new N;await V.init({platform:"feishu",connectionName:Q.nodeAlias,ingressMode:"socket",groupPolicy:J.groupPolicy,ackPlaceholder:J.ackPlaceholder,auditRaw:J.auditRaw,taskTimeoutMs:J.taskTimeoutMs,platformConfig:J});let X=J.taskTimeoutMs||u,Z=Q.onEvent??p(V,X);return await V.start(h(Z)),V}function h(Q){let J=new Map;return async(V)=>{let X=Date.now();if(J.size>200){for(let[Z,$]of J)if(X-$>f)J.delete(Z)}if(J.has(V.idempotencyKey)){process.stderr.write(`[feishu:bridge] dedup drop ${V.idempotencyKey}
|
|
4
|
+
`);return}J.set(V.idempotencyKey,X),await Q(V)}}function p(Q,J){if(typeof process.send==="function")return v(Q,J);return m}function v(Q,J){if(typeof process.send!=="function")throw Error("createIPCEventHandler: parent process.send unavailable (not forked)");let V=new Map;return process.on("message",(X)=>{if(!l(X))return;let Z=V.get(X.eventKey);if(!Z)return;V.delete(X.eventKey);let{text:$,eventKey:Y}=X;(async()=>{try{await Q.send({target:Z.conversation,text:$,replyToMessageId:Z.messageId,correlation:{taskId:Y}})}catch(G){let W=G instanceof Error?G.message:String(G);process.stderr.write(`[feishu:bridge] reply send failed: ${W}
|
|
5
|
+
`)}})()}),async(X)=>{V.set(X.idempotencyKey,X),setTimeout(()=>{if(!V.has(X.idempotencyKey))return;V.delete(X.idempotencyKey),(async()=>{try{await Q.send({target:X.conversation,text:"[处理超时,任务可能仍在后台运行]",replyToMessageId:X.messageId,correlation:{taskId:X.idempotencyKey}}),process.stderr.write(`[feishu:bridge] timeout-notify sent for ${X.idempotencyKey} after ${J}ms
|
|
6
|
+
`)}catch($){let Y=$ instanceof Error?$.message:String($);process.stderr.write(`[feishu:bridge] timeout-notify send failed: ${Y}
|
|
7
|
+
`)}})()},J);let Z={type:"event",event:X};process.send(Z)}}function l(Q){if(!Q||typeof Q!=="object")return!1;let J=Q;return J.type==="reply"&&typeof J.eventKey==="string"&&typeof J.text==="string"}async function m(Q){process.stderr.write(`[feishu:bridge] event from=${Q.sender.id} conv=${Q.conversation.conversationType}:${Q.conversation.conversationId} mentioned=${Q.mentioned} text=${(Q.content.text??"").slice(0,80)}
|
|
8
|
+
`)}function c(Q){let J={};for(let V=0;V<Q.length;V++){let X=Q[V],Z=Q[V+1];if(X==="--channel-dir"&&Z)J.channelDir=Z,V++;else if(X==="--node-alias"&&Z)J.nodeAlias=Z,V++}return J}async function d(){let Q=c(process.argv.slice(2));if(!Q.channelDir||!Q.nodeAlias)process.stderr.write(`usage: feishu-worker --channel-dir <path> --node-alias <alias>
|
|
9
|
+
`),process.exit(2);try{await j({channelDir:Q.channelDir,nodeAlias:Q.nodeAlias}),process.stderr.write(`[feishu:worker] bridge online — node=${Q.nodeAlias} dir=${Q.channelDir} ipc=${typeof process.send==="function"?"yes":"no"}
|
|
10
|
+
`)}catch(J){let V=J instanceof Error?J.stack??J.message:String(J);process.stderr.write(`[feishu:worker] startup failed: ${V}
|
|
11
|
+
`),process.exit(1)}}d();
|
package/dist/src/node-server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
const a0_0x5076e2=a0_0xcb2a;(function(_0x1ff7ba,_0x45c8c6){const _0x2a0d38=a0_0xcb2a,_0x1de4e0=_0x1ff7ba();while(!![]){try{const _0x11b957=parseInt(_0x2a0d38(0x187))/0x1+-parseInt(_0x2a0d38(0x20c))/0x2+parseInt(_0x2a0d38(0x1be))/0x3*(parseInt(_0x2a0d38(0x193))/0x4)+parseInt(_0x2a0d38(0x1bc))/0x5+-parseInt(_0x2a0d38(0x1a8))/0x6+parseInt(_0x2a0d38(0x1bf))/0x7+-parseInt(_0x2a0d38(0x1e9))/0x8*(parseInt(_0x2a0d38(0x19e))/0x9);if(_0x11b957===_0x45c8c6)break;else _0x1de4e0['push'](_0x1de4e0['shift']());}catch(_0x1796b5){_0x1de4e0['push'](_0x1de4e0['shift']());}}}(a0_0x4f30,0xf25fd));import{readFileSync as a0_0x5ecebf,existsSync as a0_0x223d03}from'fs';import{randomUUID as a0_0xc5b628}from'crypto';import{join as a0_0x39926c}from'path';import{hostname as a0_0xd90332}from'os';import{execSync as a0_0x42eb80}from'child_process';import{Server as a0_0x50fcc5}from'@modelcontextprotocol/sdk/server/index.js';function a0_0xcb2a(_0x49e910,_0x1feaba){_0x49e910=_0x49e910-0x17d;const _0x4f3097=a0_0x4f30();let _0xcb2a6d=_0x4f3097[_0x49e910];return _0xcb2a6d;}import{StdioServerTransport as a0_0x1557d3}from'@modelcontextprotocol/sdk/server/stdio.js';import{ListToolsRequestSchema as a0_0x413e24,CallToolRequestSchema as a0_0x1b81a8}from'@modelcontextprotocol/sdk/types.js';function I(_0x52512d){const _0x5d5d1b=a0_0xcb2a;if(!a0_0x223d03(_0x52512d))return;for(let _0x4eabd6 of a0_0x5ecebf(_0x52512d,_0x5d5d1b(0x213))[_0x5d5d1b(0x18a)]('\x0a')){let _0x3bc212=_0x4eabd6[_0x5d5d1b(0x1ae)]();if(!_0x3bc212||_0x3bc212[_0x5d5d1b(0x216)]('#'))continue;let _0x5e302c=_0x3bc212[_0x5d5d1b(0x1e3)]('=');if(_0x5e302c<0x0)continue;let _0x2792f2=_0x3bc212[_0x5d5d1b(0x1a2)](0x0,_0x5e302c)['trim'](),_0x26e716=_0x3bc212[_0x5d5d1b(0x1a2)](_0x5e302c+0x1)[_0x5d5d1b(0x1ae)]()[_0x5d5d1b(0x1c4)](/^["']|["']$/g,'');if(!process.env[_0x2792f2])process.env[_0x2792f2]=_0x26e716;}}var L=process.env.HOME||'~',U=a0_0x39926c(L,'.claude/channels/commhub');I(a0_0x39926c(U,a0_0x5076e2(0x1c5)));var v=process[a0_0x5076e2(0x19a)]()[a0_0x5076e2(0x1c4)](/\//g,'-');I(a0_0x39926c(U,v,'.env'));function d(){const _0x37f15b=a0_0x5076e2;try{return a0_0x42eb80(_0x37f15b(0x17e),{'encoding':_0x37f15b(0x213),'timeout':0x7d0})['trim']();}catch{return'';}}function m(){const _0x239593=a0_0x5076e2;try{let _0x20a067=a0_0x39926c(L,_0x239593(0x212),_0x239593(0x1af));if(a0_0x223d03(_0x20a067))return JSON[_0x239593(0x1d9)](a0_0x5ecebf(_0x20a067,_0x239593(0x213)));}catch{}return{};}var u=m(),j=process.env.COMMHUB_URL||u['hub']||a0_0x5076e2(0x1db),f=process.env.COMMHUB_TMUX||d();function r(){const _0x3e2bb4=a0_0x5076e2;if(process.env.COMMHUB_ALIAS&&process.env.COMMHUB_ALIAS[_0x3e2bb4(0x1ae)]())return process.env.COMMHUB_ALIAS[_0x3e2bb4(0x1ae)]();return process['stderr'][_0x3e2bb4(0x200)](_0x3e2bb4(0x201)+(_0x3e2bb4(0x1ee)+(f||_0x3e2bb4(0x17f))+'\x20/\x20hostname='+a0_0xd90332()+_0x3e2bb4(0x1f4))),_0x3e2bb4(0x180)+process['pid'];}var G=r(),K=process.env.COMMHUB_RESUME_ID||process.env.CLAUDE_RESUME_ID||a0_0xc5b628(),F=process.env.COMMHUB_TOKEN||u[a0_0x5076e2(0x188)]||'';function W(_0x2c52b0){const _0x2a738c=a0_0x5076e2;let _0x3eeeaf=new Date()[_0x2a738c(0x215)]()[_0x2a738c(0x1a2)](0x0,0x8);process[_0x2a738c(0x1ca)][_0x2a738c(0x200)]('['+_0x3eeeaf+']\x20[commhub]\x20'+_0x2c52b0+'\x0a');}function N(_0x59a12c){return new Promise(_0x40f87a=>setTimeout(_0x40f87a,_0x59a12c));}W(a0_0x5076e2(0x18b)+j+a0_0x5076e2(0x1dd)+G+a0_0x5076e2(0x1c3)+K[a0_0x5076e2(0x1a2)](0x0,0x8)+a0_0x5076e2(0x1e2)+(f||a0_0x5076e2(0x1c8))+a0_0x5076e2(0x1cd)+process[a0_0x5076e2(0x19a)]()+'\x20PROJECT_ENV='+v);var D=new Map(),x=new a0_0x50fcc5({'name':a0_0x5076e2(0x1d3),'version':'0.3.0'},{'capabilities':{'experimental':{'claude/channel':{}},'tools':{}},'instructions':[a0_0x5076e2(0x1da),a0_0x5076e2(0x1b7),'Reply\x20using\x20the\x20commhub_reply\x20tool\x20to\x20report\x20status\x20or\x20results\x20back.',a0_0x5076e2(0x1b3),'Session\x20alias:\x20'+G][a0_0x5076e2(0x190)]('\x0a')});x['setRequestHandler'](a0_0x413e24,async()=>({'tools':[{'name':a0_0x5076e2(0x20d),'description':a0_0x5076e2(0x1ac),'inputSchema':{'type':a0_0x5076e2(0x219),'properties':{'task_id':{'type':a0_0x5076e2(0x1de),'description':a0_0x5076e2(0x1b9)},'text':{'type':a0_0x5076e2(0x1de),'description':'Reply\x20text\x20/\x20result\x20summary'},'status':{'type':a0_0x5076e2(0x1de),'enum':['completed','failed',a0_0x5076e2(0x1fa),a0_0x5076e2(0x1e8),'error',a0_0x5076e2(0x1b0)],'description':a0_0x5076e2(0x218)}},'required':[a0_0x5076e2(0x1f7)]}},{'name':a0_0x5076e2(0x1b6),'description':'Update\x20this\x20session\x27s\x20status\x20in\x20CommHub\x20(working/idle/blocked/error).\x20Returns\x20inbox_count.','inputSchema':{'type':a0_0x5076e2(0x219),'properties':{'status':{'type':a0_0x5076e2(0x1de),'enum':[a0_0x5076e2(0x1d7),'idle','blocked','error']},'task':{'type':a0_0x5076e2(0x1de),'description':a0_0x5076e2(0x1f2)},'progress':{'type':a0_0x5076e2(0x1c0),'description':a0_0x5076e2(0x1fd)}},'required':[a0_0x5076e2(0x182)]}},{'name':a0_0x5076e2(0x1bb),'description':a0_0x5076e2(0x1ce),'inputSchema':{'type':a0_0x5076e2(0x219),'properties':{'alias':{'type':a0_0x5076e2(0x1de),'description':a0_0x5076e2(0x199)},'task':{'type':a0_0x5076e2(0x1de),'description':a0_0x5076e2(0x1b5)},'priority':{'type':a0_0x5076e2(0x1de),'enum':[a0_0x5076e2(0x181),a0_0x5076e2(0x19f),a0_0x5076e2(0x1a7)],'description':a0_0x5076e2(0x1a9)}},'required':['alias',a0_0x5076e2(0x1d2)]}},{'name':a0_0x5076e2(0x20b),'description':a0_0x5076e2(0x1d8),'inputSchema':{'type':a0_0x5076e2(0x219),'properties':{'alias':{'type':a0_0x5076e2(0x1de),'description':a0_0x5076e2(0x199)},'message':{'type':a0_0x5076e2(0x1de),'description':a0_0x5076e2(0x1ef)}},'required':[a0_0x5076e2(0x1bd),a0_0x5076e2(0x1f5)]}},{'name':a0_0x5076e2(0x1d1),'description':'Get\x20status\x20of\x20all\x20sessions\x20from\x20CommHub.','inputSchema':{'type':a0_0x5076e2(0x219),'properties':{}}}]}));async function Y(_0x18f641,_0x2bb795){const _0x49a02f=a0_0x5076e2;let _0x293398=await fetch(j+_0x49a02f(0x198),{'method':_0x49a02f(0x1e4),'headers':{'Content-Type':_0x49a02f(0x1e0),'Accept':_0x49a02f(0x18f),...F?{'Authorization':'Bearer\x20'+F}:{}},'body':JSON[_0x49a02f(0x1aa)]({'jsonrpc':_0x49a02f(0x206),'id':0x1,'method':_0x49a02f(0x208),'params':{'protocolVersion':_0x49a02f(0x1fc),'capabilities':{},'clientInfo':{'name':_0x49a02f(0x1d3),'version':_0x49a02f(0x19c)}}})});if(!_0x293398['ok']){let _0xaf1e8a=await _0x293398[_0x49a02f(0x1f7)]();return W(_0x49a02f(0x1a4)+_0x293398[_0x49a02f(0x182)]+'\x20'+_0xaf1e8a[_0x49a02f(0x1a2)](0x0,0x64)),{'ok':!0x1,'error':_0x49a02f(0x189)+_0x293398[_0x49a02f(0x182)]};}await _0x293398[_0x49a02f(0x1f7)]();let _0x3d0eac=(await(await fetch(j+'/mcp',{'method':'POST','headers':{'Content-Type':_0x49a02f(0x1e0),'Accept':_0x49a02f(0x18f),...F?{'Authorization':_0x49a02f(0x185)+F}:{}},'body':JSON['stringify']({'jsonrpc':_0x49a02f(0x206),'id':0x2,'method':_0x49a02f(0x207),'params':{'name':_0x18f641,'arguments':_0x2bb795}})}))['text']())[_0x49a02f(0x18a)]('\x0a')['find'](_0x5a8366=>_0x5a8366[_0x49a02f(0x216)]('data:\x20'));if(_0x3d0eac){let _0x25ec7f=JSON[_0x49a02f(0x1d9)](_0x3d0eac['slice'](0x6));return _0x25ec7f?.['result']?.['content']?.[0x0]?.[_0x49a02f(0x1f7)]?JSON[_0x49a02f(0x1d9)](_0x25ec7f[_0x49a02f(0x1b4)][_0x49a02f(0x194)][0x0][_0x49a02f(0x1f7)]):_0x25ec7f;}return{'ok':!0x1,'error':'no\x20response'};}x[a0_0x5076e2(0x1ed)](a0_0x1b81a8,async _0x5a4113=>{const _0x35244f=a0_0x5076e2;let {name:_0x217d86,arguments:_0x4fc3a1}=_0x5a4113['params'];if(_0x217d86==='commhub_reply'){let {task_id:_0x51d966,text:_0x2b9be9,status:_0x49c71d}=_0x4fc3a1;if(_0x49c71d===_0x35244f(0x1c6)||_0x49c71d==='failed'||_0x49c71d===_0x35244f(0x1fa)){let _0x45495b=_0x49c71d===_0x35244f(0x1c6)?_0x35244f(0x1d6):_0x49c71d,_0x82167f=_0x51d966?D['get'](_0x51d966)||_0x35244f(0x1e6):_0x35244f(0x1e6),_0xeb2e05=await Y(_0x35244f(0x196),{'alias':_0x82167f,'text':_0x2b9be9,'in_reply_to':_0x51d966||void 0x0,'status':_0x45495b,'from_session':G});if(_0x51d966)D[_0x35244f(0x1e1)](_0x51d966);return{'content':[{'type':_0x35244f(0x1f7),'text':JSON[_0x35244f(0x1aa)](_0xeb2e05)}]};}let _0x4031c2=await Y(_0x35244f(0x1df),{'resume_id':K,'alias':G,'status':_0x49c71d===_0x35244f(0x1e8)?_0x35244f(0x1e8):_0x49c71d==='error'?'error':_0x35244f(0x1d7),'task':_0x2b9be9['slice'](0x0,0xc8),'output':_0x2b9be9});return{'content':[{'type':_0x35244f(0x1f7),'text':JSON[_0x35244f(0x1aa)](_0x4031c2)}]};}if(_0x217d86===_0x35244f(0x1b6)){let {status:_0x59e42d,task:_0x4390fb,progress:_0x24edd2}=_0x4fc3a1,_0x58978b=await Y(_0x35244f(0x1df),{'resume_id':K,'alias':G,'status':_0x59e42d,'task':_0x4390fb,'progress':_0x24edd2});return{'content':[{'type':_0x35244f(0x1f7),'text':JSON[_0x35244f(0x1aa)](_0x58978b)}]};}if(_0x217d86===_0x35244f(0x1bb)){let {alias:_0x2cabad,task:_0x54b3a5,priority:_0x4a6c93}=_0x4fc3a1,_0x3219c6=await Y(_0x35244f(0x1a5),{'alias':_0x2cabad,'task':_0x54b3a5,'priority':_0x4a6c93||_0x35244f(0x19f),'from_session':G});return{'content':[{'type':'text','text':JSON[_0x35244f(0x1aa)](_0x3219c6)}]};}if(_0x217d86===_0x35244f(0x20b)){let {alias:_0x11beda,message:_0x1b537d}=_0x4fc3a1,_0x2e04df=await Y(_0x35244f(0x1a3),{'alias':_0x11beda,'message':_0x1b537d,'from_session':G});return{'content':[{'type':_0x35244f(0x1f7),'text':JSON['stringify'](_0x2e04df)}]};}if(_0x217d86===_0x35244f(0x1d1)){let _0x50201a=await Y('get_all_status',{});return{'content':[{'type':_0x35244f(0x1f7),'text':JSON[_0x35244f(0x1aa)](_0x50201a)}]};}return{'content':[{'type':_0x35244f(0x1f7),'text':JSON[_0x35244f(0x1aa)]({'error':_0x35244f(0x1fb)})}]};});var O=0x3e8,R=0x7530,T=0x36ee80;async function l(){const _0x2aa51e=a0_0x5076e2;try{await Y(_0x2aa51e(0x1df),{'resume_id':K,'alias':G,'status':'idle','server':a0_0xd90332(),'hostname':a0_0xd90332(),'agent':_0x2aa51e(0x197),'project_dir':process[_0x2aa51e(0x19a)](),'tmux_name':f||void 0x0}),W('re-registered\x20as\x20\x22'+G+'\x22\x20after\x20SSE\x20reconnect');}catch(_0x1c398c){W('re-register\x20failed:\x20'+_0x1c398c);}}async function o(){const _0x1f926a=a0_0x5076e2;let _0x38935c=j+_0x1f926a(0x1b8)+encodeURIComponent(G),_0x22b7e8={};if(F)_0x22b7e8[_0x1f926a(0x1dc)]=_0x1f926a(0x185)+F;W(_0x1f926a(0x1b2)+_0x38935c);let _0x5e9dc3=O,_0x3032ba=!0x0,_0x216e07=null;while(!0x0){try{let _0x26a6c4=await fetch(_0x38935c,{'headers':_0x22b7e8});if(!_0x26a6c4['ok']){if(W('SSE\x20error:\x20'+_0x26a6c4[_0x1f926a(0x182)]+'\x20'+_0x26a6c4[_0x1f926a(0x1cc)]),_0x216e07=_0x216e07??Date['now'](),Date[_0x1f926a(0x1d0)]()-_0x216e07>T){W(_0x1f926a(0x19b)+j+_0x1f926a(0x1d5));return;}await N(_0x5e9dc3),_0x5e9dc3=Math[_0x1f926a(0x1b1)](_0x5e9dc3*0x2,R);continue;}let _0x175e39=_0x26a6c4[_0x1f926a(0x18c)][_0x1f926a(0x195)](),_0x95196c=new TextDecoder(),_0x2aaa5b='';_0x5e9dc3=O;while(!0x0){let {done:_0x4299fd,value:_0x1d271d}=await _0x175e39[_0x1f926a(0x1ff)]();if(_0x4299fd)break;_0x2aaa5b+=_0x95196c[_0x1f926a(0x1ab)](_0x1d271d,{'stream':!0x0});let _0x3be6c3=_0x2aaa5b[_0x1f926a(0x18a)]('\x0a\x0a');_0x2aaa5b=_0x3be6c3['pop']()||'';for(let _0x9c542b of _0x3be6c3){let _0x514789=_0x9c542b[_0x1f926a(0x18a)]('\x0a')[_0x1f926a(0x1e5)](_0x27d550=>_0x27d550[_0x1f926a(0x216)](_0x1f926a(0x19d)));if(!_0x514789)continue;try{let _0x5321c7=JSON[_0x1f926a(0x1d9)](_0x514789['slice'](0x6));if(await a(_0x5321c7),_0x5321c7[_0x1f926a(0x1cb)]===_0x1f926a(0x1c1)){if(_0x216e07=null,!_0x3032ba)await l();_0x3032ba=!0x1;}}catch(_0x42e762){W('parse\x20error:\x20'+_0x42e762);}}}W(_0x1f926a(0x1fe));}catch(_0x3ecd77){W(_0x1f926a(0x1a0)+_0x3ecd77);}if(_0x216e07=_0x216e07??Date[_0x1f926a(0x1d0)](),Date[_0x1f926a(0x1d0)]()-_0x216e07>T){W(_0x1f926a(0x19b)+j+_0x1f926a(0x1d5));return;}await N(_0x5e9dc3),_0x5e9dc3=Math[_0x1f926a(0x1b1)](_0x5e9dc3*0x2,R);}}async function a(_0x480a41){const _0x44013a=a0_0x5076e2;if(_0x480a41[_0x44013a(0x1cb)]===_0x44013a(0x1c1)){W(_0x44013a(0x17d)+G+'\x22');return;}if(_0x480a41[_0x44013a(0x1cb)]===_0x44013a(0x1f6)){if(W(_0x44013a(0x204)+_0x480a41[_0x44013a(0x183)]+':\x20'+_0x480a41[_0x44013a(0x1f5)][_0x44013a(0x1a2)](0x0,0x3c)),await x[_0x44013a(0x211)]({'method':'notifications/claude/channel','params':{'content':_0x480a41['message'],'meta':{'sender':_0x480a41[_0x44013a(0x183)]||'hub','sender_id':_0x44013a(0x214),'user':_0x480a41[_0x44013a(0x183)]||'hub','priority':'normal'}}}),_0x480a41[_0x44013a(0x186)])await Y('ack_inbox',{'alias':G,'message_id':_0x480a41['message_id']});return;}if(_0x480a41[_0x44013a(0x1cb)]===_0x44013a(0x1a1)||_0x480a41[_0x44013a(0x1cb)]==='broadcast'){W('←\x20'+_0x480a41[_0x44013a(0x1cb)]+_0x44013a(0x1ec)+_0x480a41[_0x44013a(0x1f0)]+_0x44013a(0x1f3)+(_0x480a41[_0x44013a(0x1a6)]||_0x44013a(0x19f)));let _0x47a122=await Y(_0x44013a(0x217),{'alias':G,'limit':0x5});if(_0x47a122?.['ok']&&_0x47a122[_0x44013a(0x191)]?.[_0x44013a(0x18d)]>0x0)for(let _0x572b3a of _0x47a122[_0x44013a(0x191)]){let _0x46e61c={'sender':_0x572b3a[_0x44013a(0x210)]||_0x44013a(0x1e6),'sender_id':'commhub','user':_0x572b3a[_0x44013a(0x210)]||'hub','task_id':_0x572b3a['id'],'priority':_0x572b3a[_0x44013a(0x1a6)]||'normal'};D[_0x44013a(0x1c2)](_0x572b3a['id'],_0x572b3a['from_session']||'hub'),await x[_0x44013a(0x211)]({'method':_0x44013a(0x20f),'params':{'content':_0x572b3a[_0x44013a(0x194)],'meta':_0x46e61c}}),W(_0x44013a(0x1ea)+_0x572b3a['id']['slice'](0x0,0x8)+_0x44013a(0x184)+_0x572b3a['from_session']+':\x20'+_0x572b3a[_0x44013a(0x194)][_0x44013a(0x1a2)](0x0,0x3c)),await Y(_0x44013a(0x1ad),{'alias':G,'message_id':_0x572b3a['id']});}}}async function n(){const _0x16f298=a0_0x5076e2;let _0x1b92ea=new a0_0x1557d3();await x[_0x16f298(0x1e7)](_0x1b92ea),W(_0x16f298(0x1eb)),W(_0x16f298(0x1d4)),o()[_0x16f298(0x1c9)](_0x2b0bf7=>W(_0x16f298(0x205)+_0x2b0bf7)),Y(_0x16f298(0x1df),{'resume_id':K,'alias':G,'status':_0x16f298(0x1ba),'server':a0_0xd90332(),'hostname':a0_0xd90332(),'agent':_0x16f298(0x197),'project_dir':process[_0x16f298(0x19a)](),'tmux_name':f||void 0x0})[_0x16f298(0x203)](()=>W(_0x16f298(0x1cf)+G+'\x22\x20('+K[_0x16f298(0x1a2)](0x0,0x8)+')'))[_0x16f298(0x1c9)](_0x429164=>W('warning:\x20could\x20not\x20register:\x20'+_0x429164)),setInterval(()=>{const _0x32c2e6=_0x16f298;Y(_0x32c2e6(0x1df),{'resume_id':K,'alias':G,'status':_0x32c2e6(0x1ba),'server':a0_0xd90332(),'hostname':a0_0xd90332(),'agent':_0x32c2e6(0x197),'project_dir':process[_0x32c2e6(0x19a)](),'tmux_name':f||void 0x0})[_0x32c2e6(0x1c9)](_0x1b2e41=>W(_0x32c2e6(0x18e)+_0x1b2e41));},0x2bf20),W(_0x16f298(0x202));}function a0_0x4f30(){const _0xfc2e80=['registered\x20as\x20\x22','now','commhub_get_all_status','task','commhub-channel','starting\x20SSE\x20listener...',')\x20—\x20放弃自动重连。手动\x20anet\x20node\x20start\x20恢复。','replied','working','Send\x20a\x20message\x20to\x20another\x20session\x20(no\x20task\x20lifecycle,\x20just\x20chat).\x20Use\x20for\x20replies\x20and\x20status\x20updates.','parse','Messages\x20from\x20CommHub\x20arrive\x20as\x20<channel\x20source=\x22commhub\x22\x20task_id=\x22...\x22\x20priority=\x22...\x22\x20from=\x22...\x22>','http://127.0.0.1:9200','Authorization','\x20ALIAS=','string','report_status','application/json','delete','...\x20TMUX=','indexOf','POST','find','hub','connect','blocked','836704oXLVpb','→\x20injected\x20task\x20','MCP\x20stdio\x20connected',':\x20inbox_count=','setRequestHandler','would\x20mis-attribute.\x20Refusing\x20to\x20guess\x20from\x20TMUX_NAME=','Message\x20content','inbox_count','shutting\x20down,\x20reporting\x20offline...','Current\x20task\x20description','\x20priority=','.\x20Restart\x20node\x20via\x20`anet\x20node\x20start\x20<alias>`\x20so\x20the\x20env\x20is\x20set\x20explicitly\x20(#203).\x0a','message','new_message','text','offline','SIGTERM','cancelled','unknown\x20tool','2025-03-26','Progress\x200-100','SSE\x20stream\x20ended,\x20reconnecting...','read','write','[commhub]\x20WARN:\x20COMMHUB_ALIAS\x20env\x20var\x20is\x20unset\x20—\x20outbound\x20from_session\x20','ready\x20—\x20waiting\x20for\x20events','then','←\x20message\x20from\x20','SSE\x20fatal:\x20','2.0','tools/call','initialize','stdin','fatal:\x20','commhub_send_message','2985078cxWUKQ','commhub_reply','exit','notifications/claude/channel','from_session','notification','.anet','utf-8','commhub','toTimeString','startsWith','get_inbox','Task\x20outcome:\x20completed/failed/cancelled\x20for\x20final\x20results,\x20blocked/error/in_progress\x20for\x20status\x20updates','object','SSE\x20connected\x20as\x20\x22','tmux\x20display-message\x20-p\x20\x27#S\x27','(none)','unattributed-','high','status','from','\x20from\x20','Bearer\x20','message_id','1492761CGcvUf','token','init\x20failed:\x20','split','ENV:\x20URL=','body','length','heartbeat\x20failed:\x20','application/json,\x20text/event-stream','join','messages','SIGINT','155132IFGRnC','content','getReader','send_reply','claude-code','/mcp','Target\x20session\x20alias','cwd','SSE\x20连续\x20>1h\x20连不上\x20hub\x20(','0.3.0','data:\x20','45ZsiXqX','normal','SSE\x20connection\x20error:\x20','new_task','slice','send_message','CommHub\x20init\x20failed:\x20','send_task','priority','low','8605344aldfDZ','Priority\x20(default:\x20normal)','stringify','decode','Reply\x20to\x20a\x20CommHub\x20task\x20—\x20report\x20completion\x20or\x20send\x20a\x20message\x20back\x20to\x20the\x20hub.','ack_inbox','trim','config.json','in_progress','min','connecting\x20to\x20','You\x20can\x20also\x20use\x20commhub_report_status\x20to\x20update\x20your\x20session\x20status.','result','Task\x20content','commhub_report_status','These\x20are\x20tasks\x20dispatched\x20by\x20the\x20hub\x20or\x20other\x20sessions\x20via\x20the\x20CommHub\x20Server.','/events/','The\x20task_id\x20from\x20the\x20channel\x20message\x20(or\x20\x27hub\x27\x20for\x20general)','idle','commhub_send_task','1600665IiZdjD','alias','117khKxEA','7819259dGKgfR','number','connected','set','\x20RESUME_ID=','replace','.env','completed','end','none','catch','stderr','type','statusText','\x20CWD=','Send\x20a\x20task\x20to\x20another\x20session\x20via\x20CommHub.'];a0_0x4f30=function(){return _0xfc2e80;};return a0_0x4f30();}n()[a0_0x5076e2(0x1c9)](_0x162fd2=>{const _0xe1dee7=a0_0x5076e2;W(_0xe1dee7(0x20a)+_0x162fd2),process[_0xe1dee7(0x20e)](0x1);});async function b(){const _0x25952a=a0_0x5076e2;W(_0x25952a(0x1f1)),await Y(_0x25952a(0x1df),{'resume_id':K,'alias':G,'status':_0x25952a(0x1f8),'task':'session\x20disconnected'})[_0x25952a(0x1c9)](()=>{}),process[_0x25952a(0x20e)](0x0);}process[a0_0x5076e2(0x209)]['on'](a0_0x5076e2(0x1c7),()=>b()),process['on'](a0_0x5076e2(0x1f9),()=>b()),process['on'](a0_0x5076e2(0x192),()=>b());
|
|
2
|
+
const a0_0x46492c=a0_0x4ca9;(function(_0x13f52c,_0x5c868a){const _0x291654=a0_0x4ca9,_0x331d56=_0x13f52c();while(!![]){try{const _0x345745=-parseInt(_0x291654(0x136))/0x1*(-parseInt(_0x291654(0x173))/0x2)+parseInt(_0x291654(0x140))/0x3*(parseInt(_0x291654(0xe8))/0x4)+-parseInt(_0x291654(0x110))/0x5*(parseInt(_0x291654(0x16a))/0x6)+-parseInt(_0x291654(0x157))/0x7*(parseInt(_0x291654(0x138))/0x8)+parseInt(_0x291654(0x132))/0x9*(-parseInt(_0x291654(0xf9))/0xa)+parseInt(_0x291654(0x14a))/0xb+parseInt(_0x291654(0x16b))/0xc;if(_0x345745===_0x5c868a)break;else _0x331d56['push'](_0x331d56['shift']());}catch(_0x37b189){_0x331d56['push'](_0x331d56['shift']());}}}(a0_0x225b,0xb5055));import{readFileSync as a0_0x4cc358,existsSync as a0_0x364285}from'fs';import{randomUUID as a0_0x17c95e}from'crypto';import{join as a0_0x2175ac}from'path';import{hostname as a0_0x47b9f6}from'os';import{execSync as a0_0xd3af48}from'child_process';import{Server as a0_0x38247c}from'@modelcontextprotocol/sdk/server/index.js';import{StdioServerTransport as a0_0x281413}from'@modelcontextprotocol/sdk/server/stdio.js';import{ListToolsRequestSchema as a0_0xbb978b,CallToolRequestSchema as a0_0xbc40e}from'@modelcontextprotocol/sdk/types.js';function I(_0x2007b8){const _0x21657b=a0_0x4ca9;if(!a0_0x364285(_0x2007b8))return;for(let _0x55b4bf of a0_0x4cc358(_0x2007b8,_0x21657b(0x142))[_0x21657b(0x134)]('\x0a')){let _0x459e7e=_0x55b4bf['trim']();if(!_0x459e7e||_0x459e7e[_0x21657b(0xf7)]('#'))continue;let _0x2e0941=_0x459e7e[_0x21657b(0x13a)]('=');if(_0x2e0941<0x0)continue;let _0x543e9f=_0x459e7e[_0x21657b(0xe6)](0x0,_0x2e0941)[_0x21657b(0x15d)](),_0x304ea7=_0x459e7e[_0x21657b(0xe6)](_0x2e0941+0x1)['trim']()[_0x21657b(0x12e)](/^["']|["']$/g,'');if(!process.env[_0x543e9f])process.env[_0x543e9f]=_0x304ea7;}}var L=process.env.HOME||'~',U=a0_0x2175ac(L,'.claude/channels/commhub');I(a0_0x2175ac(U,a0_0x46492c(0x107)));function a0_0x225b(){const _0x3c0b11=['Reply\x20text\x20/\x20result\x20summary','exit','.anet','(none)','init\x20failed:\x20','Update\x20this\x20session\x27s\x20status\x20in\x20CommHub\x20(working/idle/blocked/error).\x20Returns\x20inbox_count.','data:\x20','completed','Task\x20content','now','.env','stdin','broadcast','SSE\x20stream\x20ended,\x20reconnecting...','message_id','Progress\x200-100','/mcp','connect','SIGINT','5ToOGqo','Target\x20session\x20alias','Message\x20content','failed','SSE\x20fatal:\x20','text','Get\x20status\x20of\x20all\x20sessions\x20from\x20CommHub.','→\x20injected\x20task\x20','re-registered\x20as\x20\x22','http://127.0.0.1:9200','commhub','from','Send\x20a\x20message\x20to\x20another\x20session\x20(no\x20task\x20lifecycle,\x20just\x20chat).\x20Use\x20for\x20replies\x20and\x20status\x20updates.','working','notification','token','in_progress','get_all_status','[commhub]\x20WARN:\x20COMMHUB_ALIAS\x20env\x20var\x20is\x20unset\x20—\x20outbound\x20from_session\x20','messages','status','message','connected','hub','unattributed-','from_session','starting\x20SSE\x20listener...','\x20ALIAS=','Task\x20outcome:\x20completed/failed/cancelled\x20for\x20final\x20results,\x20blocked/error/in_progress\x20for\x20status\x20updates','\x22\x20(','replace','commhub_send_task','read','cancelled','123399VRgvix','You\x20can\x20also\x20use\x20commhub_report_status\x20to\x20update\x20your\x20session\x20status.','split','stderr','838RAUPqu','\x20PROJECT_ENV=','16896sGKjTf','stringify','indexOf','0.3.0','set','would\x20mis-attribute.\x20Refusing\x20to\x20guess\x20from\x20TMUX_NAME=','object','idle','6EHSArw','normal','utf-8','min','send_message','Send\x20a\x20task\x20to\x20another\x20session\x20via\x20CommHub.','heartbeat\x20failed:\x20','then','...\x20TMUX=','high','11567479aDeLmi','replied','ack_inbox','send_reply','SSE\x20connected\x20as\x20\x22','2.0','offline','session\x20disconnected','Reply\x20to\x20a\x20CommHub\x20task\x20—\x20report\x20completion\x20or\x20send\x20a\x20message\x20back\x20to\x20the\x20hub.','config.json',':\x20inbox_count=','cwd','POST','4151KkYcZP','no\x20response','pid','claude-code','type','warning:\x20could\x20not\x20register:\x20','trim','commhub_report_status','Session\x20alias:\x20','setRequestHandler','.\x20Restart\x20node\x20via\x20`anet\x20node\x20start\x20<alias>`\x20so\x20the\x20env\x20is\x20set\x20explicitly\x20(#203).\x0a','CommHub\x20init\x20failed:\x20','new_task','ENV:\x20URL=','priority','notifications/claude/channel','Reply\x20using\x20the\x20commhub_reply\x20tool\x20to\x20report\x20status\x20or\x20results\x20back.','body','SSE\x20error:\x20','8720886yPdaYp','6878256IvjNSO','statusText','report_status','delete','low','get_inbox','fatal:\x20','write','3026fIyJlP','catch','blocked','commhub-channel','content','\x20from\x20','none','pop','parse','initialize','send_task','result','alias','length','commhub_send_message','join','error','getReader','slice','string','1136796uyRnmN','Messages\x20from\x20CommHub\x20arrive\x20as\x20<channel\x20source=\x22commhub\x22\x20task_id=\x22...\x22\x20priority=\x22...\x22\x20from=\x22...\x22>','inbox_count','application/json','commhub_get_all_status','SSE\x20connection\x20error:\x20','task','The\x20task_id\x20from\x20the\x20channel\x20message\x20(or\x20\x27hub\x27\x20for\x20general)','new_message','shutting\x20down,\x20reporting\x20offline...','\x22\x20after\x20SSE\x20reconnect','SSE\x20连续\x20>1h\x20连不上\x20hub\x20(','application/json,\x20text/event-stream',']\x20[commhub]\x20',')\x20—\x20放弃自动重连。手动\x20anet\x20node\x20start\x20恢复。','startsWith','\x20RESUME_ID=','10eLJDGU','end','find','Bearer\x20'];a0_0x225b=function(){return _0x3c0b11;};return a0_0x225b();}var v=process[a0_0x46492c(0x155)]()['replace'](/\//g,'-');I(a0_0x2175ac(U,v,'.env'));function d(){const _0x4cb4d8=a0_0x46492c;try{return a0_0xd3af48('tmux\x20display-message\x20-p\x20\x27#S\x27',{'encoding':_0x4cb4d8(0x142),'timeout':0x7d0})[_0x4cb4d8(0x15d)]();}catch{return'';}}function a0_0x4ca9(_0x28b5e1,_0x5344b9){_0x28b5e1=_0x28b5e1-0xd7;const _0x225bda=a0_0x225b();let _0x4ca966=_0x225bda[_0x28b5e1];return _0x4ca966;}function m(){const _0x263cde=a0_0x46492c;try{let _0x3cea15=a0_0x2175ac(L,_0x263cde(0xff),_0x263cde(0x153));if(a0_0x364285(_0x3cea15))return JSON[_0x263cde(0xdc)](a0_0x4cc358(_0x3cea15,_0x263cde(0x142)));}catch{}return{};}var u=m(),j=process.env.COMMHUB_URL||u['hub']||a0_0x46492c(0x119),f=process.env.COMMHUB_TMUX||d();function r(){const _0x10646a=a0_0x46492c;if(process.env.COMMHUB_ALIAS&&process.env.COMMHUB_ALIAS['trim']())return process.env.COMMHUB_ALIAS[_0x10646a(0x15d)]();return process[_0x10646a(0x135)][_0x10646a(0x172)](_0x10646a(0x122)+(_0x10646a(0x13d)+(f||_0x10646a(0x100))+'\x20/\x20hostname='+a0_0x47b9f6()+_0x10646a(0x161))),_0x10646a(0x128)+process[_0x10646a(0x159)];}var G=r(),K=process.env.COMMHUB_RESUME_ID||process.env.CLAUDE_RESUME_ID||a0_0x17c95e(),F=process.env.COMMHUB_TOKEN||u[a0_0x46492c(0x11f)]||'';function W(_0x4df2d4){const _0x264c10=a0_0x46492c;let _0x2cf643=new Date()['toTimeString']()[_0x264c10(0xe6)](0x0,0x8);process[_0x264c10(0x135)][_0x264c10(0x172)]('['+_0x2cf643+_0x264c10(0xf5)+_0x4df2d4+'\x0a');}function N(_0x44b101){return new Promise(_0x48e1e3=>setTimeout(_0x48e1e3,_0x44b101));}W(a0_0x46492c(0x164)+j+a0_0x46492c(0x12b)+G+a0_0x46492c(0xf8)+K['slice'](0x0,0x8)+a0_0x46492c(0x148)+(f||a0_0x46492c(0xda))+'\x20CWD='+process['cwd']()+a0_0x46492c(0x137)+v);var D=new Map(),x=new a0_0x38247c({'name':a0_0x46492c(0xd7),'version':'0.3.0'},{'capabilities':{'experimental':{'claude/channel':{}},'tools':{}},'instructions':[a0_0x46492c(0xe9),'These\x20are\x20tasks\x20dispatched\x20by\x20the\x20hub\x20or\x20other\x20sessions\x20via\x20the\x20CommHub\x20Server.',a0_0x46492c(0x167),a0_0x46492c(0x133),a0_0x46492c(0x15f)+G][a0_0x46492c(0xe3)]('\x0a')});x[a0_0x46492c(0x160)](a0_0xbb978b,async()=>({'tools':[{'name':'commhub_reply','description':a0_0x46492c(0x152),'inputSchema':{'type':a0_0x46492c(0x13e),'properties':{'task_id':{'type':'string','description':a0_0x46492c(0xef)},'text':{'type':a0_0x46492c(0xe7),'description':a0_0x46492c(0xfd)},'status':{'type':a0_0x46492c(0xe7),'enum':[a0_0x46492c(0x104),a0_0x46492c(0x113),a0_0x46492c(0x131),a0_0x46492c(0x175),a0_0x46492c(0xe4),a0_0x46492c(0x120)],'description':a0_0x46492c(0x12c)}},'required':[a0_0x46492c(0x115)]}},{'name':a0_0x46492c(0x15e),'description':a0_0x46492c(0x102),'inputSchema':{'type':'object','properties':{'status':{'type':a0_0x46492c(0xe7),'enum':[a0_0x46492c(0x11d),a0_0x46492c(0x13f),a0_0x46492c(0x175),a0_0x46492c(0xe4)]},'task':{'type':'string','description':'Current\x20task\x20description'},'progress':{'type':'number','description':a0_0x46492c(0x10c)}},'required':[a0_0x46492c(0x124)]}},{'name':a0_0x46492c(0x12f),'description':a0_0x46492c(0x145),'inputSchema':{'type':'object','properties':{'alias':{'type':a0_0x46492c(0xe7),'description':'Target\x20session\x20alias'},'task':{'type':a0_0x46492c(0xe7),'description':a0_0x46492c(0x105)},'priority':{'type':a0_0x46492c(0xe7),'enum':[a0_0x46492c(0x149),a0_0x46492c(0x141),a0_0x46492c(0x16f)],'description':'Priority\x20(default:\x20normal)'}},'required':[a0_0x46492c(0xe0),a0_0x46492c(0xee)]}},{'name':a0_0x46492c(0xe2),'description':a0_0x46492c(0x11c),'inputSchema':{'type':a0_0x46492c(0x13e),'properties':{'alias':{'type':'string','description':a0_0x46492c(0x111)},'message':{'type':a0_0x46492c(0xe7),'description':a0_0x46492c(0x112)}},'required':['alias','message']}},{'name':'commhub_get_all_status','description':a0_0x46492c(0x116),'inputSchema':{'type':'object','properties':{}}}]}));async function Y(_0x5ddb0d,_0x3739ef){const _0xefb32c=a0_0x46492c;let _0x19925f=await fetch(j+'/mcp',{'method':'POST','headers':{'Content-Type':_0xefb32c(0xeb),'Accept':_0xefb32c(0xf4),...F?{'Authorization':_0xefb32c(0xfc)+F}:{}},'body':JSON[_0xefb32c(0x139)]({'jsonrpc':'2.0','id':0x1,'method':_0xefb32c(0xdd),'params':{'protocolVersion':'2025-03-26','capabilities':{},'clientInfo':{'name':_0xefb32c(0xd7),'version':_0xefb32c(0x13b)}}})});if(!_0x19925f['ok']){let _0x251074=await _0x19925f[_0xefb32c(0x115)]();return W(_0xefb32c(0x162)+_0x19925f[_0xefb32c(0x124)]+'\x20'+_0x251074[_0xefb32c(0xe6)](0x0,0x64)),{'ok':!0x1,'error':_0xefb32c(0x101)+_0x19925f[_0xefb32c(0x124)]};}await _0x19925f[_0xefb32c(0x115)]();let _0x5ed084=(await(await fetch(j+_0xefb32c(0x10d),{'method':_0xefb32c(0x156),'headers':{'Content-Type':_0xefb32c(0xeb),'Accept':_0xefb32c(0xf4),...F?{'Authorization':_0xefb32c(0xfc)+F}:{}},'body':JSON['stringify']({'jsonrpc':_0xefb32c(0x14f),'id':0x2,'method':'tools/call','params':{'name':_0x5ddb0d,'arguments':_0x3739ef}})}))[_0xefb32c(0x115)]())[_0xefb32c(0x134)]('\x0a')[_0xefb32c(0xfb)](_0x3b90be=>_0x3b90be['startsWith'](_0xefb32c(0x103)));if(_0x5ed084){let _0x83a4be=JSON[_0xefb32c(0xdc)](_0x5ed084['slice'](0x6));return _0x83a4be?.[_0xefb32c(0xdf)]?.[_0xefb32c(0xd8)]?.[0x0]?.[_0xefb32c(0x115)]?JSON['parse'](_0x83a4be[_0xefb32c(0xdf)][_0xefb32c(0xd8)][0x0][_0xefb32c(0x115)]):_0x83a4be;}return{'ok':!0x1,'error':_0xefb32c(0x158)};}x[a0_0x46492c(0x160)](a0_0xbc40e,async _0x492646=>{const _0x18116a=a0_0x46492c;let {name:_0x4fa7d7,arguments:_0x4c2a80}=_0x492646['params'];if(_0x4fa7d7==='commhub_reply'){let {task_id:_0xf56c28,text:_0x11dc7e,status:_0x479744}=_0x4c2a80;if(_0x479744==='completed'||_0x479744==='failed'||_0x479744==='cancelled'){let _0x5019ff=_0x479744==='completed'?_0x18116a(0x14b):_0x479744,_0x1e2a40=_0xf56c28?D['get'](_0xf56c28)||'hub':_0x18116a(0x127),_0x2698cb=await Y(_0x18116a(0x14d),{'alias':_0x1e2a40,'text':_0x11dc7e,'in_reply_to':_0xf56c28||void 0x0,'status':_0x5019ff,'from_session':G});if(_0xf56c28)D[_0x18116a(0x16e)](_0xf56c28);return{'content':[{'type':'text','text':JSON[_0x18116a(0x139)](_0x2698cb)}]};}let _0x470863=await Y(_0x18116a(0x16d),{'resume_id':K,'alias':G,'status':_0x479744==='blocked'?_0x18116a(0x175):_0x479744===_0x18116a(0xe4)?_0x18116a(0xe4):_0x18116a(0x11d),'task':_0x11dc7e[_0x18116a(0xe6)](0x0,0xc8),'output':_0x11dc7e});return{'content':[{'type':_0x18116a(0x115),'text':JSON[_0x18116a(0x139)](_0x470863)}]};}if(_0x4fa7d7===_0x18116a(0x15e)){let {status:_0x185d45,task:_0x4b0482,progress:_0x5ec4d4}=_0x4c2a80,_0x1ed774=await Y('report_status',{'resume_id':K,'alias':G,'status':_0x185d45,'task':_0x4b0482,'progress':_0x5ec4d4});return{'content':[{'type':'text','text':JSON[_0x18116a(0x139)](_0x1ed774)}]};}if(_0x4fa7d7===_0x18116a(0x12f)){let {alias:_0x43748a,task:_0x6b379b,priority:_0x12e710}=_0x4c2a80,_0x2f86fb=await Y(_0x18116a(0xde),{'alias':_0x43748a,'task':_0x6b379b,'priority':_0x12e710||_0x18116a(0x141),'from_session':G});return{'content':[{'type':_0x18116a(0x115),'text':JSON['stringify'](_0x2f86fb)}]};}if(_0x4fa7d7==='commhub_send_message'){let {alias:_0x103f32,message:_0x421998}=_0x4c2a80,_0x5b0e0d=await Y(_0x18116a(0x144),{'alias':_0x103f32,'message':_0x421998,'from_session':G});return{'content':[{'type':'text','text':JSON[_0x18116a(0x139)](_0x5b0e0d)}]};}if(_0x4fa7d7===_0x18116a(0xec)){let _0x50ef26=await Y(_0x18116a(0x121),{});return{'content':[{'type':'text','text':JSON[_0x18116a(0x139)](_0x50ef26)}]};}return{'content':[{'type':_0x18116a(0x115),'text':JSON[_0x18116a(0x139)]({'error':'unknown\x20tool'})}]};});var O=0x3e8,R=0x7530,T=0x36ee80;async function l(){const _0x1a10bf=a0_0x46492c;try{await Y(_0x1a10bf(0x16d),{'resume_id':K,'alias':G,'status':_0x1a10bf(0x13f),'server':a0_0x47b9f6(),'hostname':a0_0x47b9f6(),'agent':_0x1a10bf(0x15a),'project_dir':process[_0x1a10bf(0x155)](),'tmux_name':f||void 0x0}),W(_0x1a10bf(0x118)+G+_0x1a10bf(0xf2));}catch(_0x3f522d){W('re-register\x20failed:\x20'+_0x3f522d);}}async function o(){const _0x10c8d0=a0_0x46492c;let _0x344bd2=j+'/events/'+encodeURIComponent(G),_0x4850f1={};if(F)_0x4850f1['Authorization']=_0x10c8d0(0xfc)+F;W('connecting\x20to\x20'+_0x344bd2);let _0x1fc06f=O,_0x3b9dc9=!0x0,_0xfc7937=null;while(!0x0){try{let _0x345098=await fetch(_0x344bd2,{'headers':_0x4850f1});if(!_0x345098['ok']){if(W(_0x10c8d0(0x169)+_0x345098[_0x10c8d0(0x124)]+'\x20'+_0x345098[_0x10c8d0(0x16c)]),_0xfc7937=_0xfc7937??Date['now'](),Date[_0x10c8d0(0x106)]()-_0xfc7937>T){W(_0x10c8d0(0xf3)+j+_0x10c8d0(0xf6));return;}await N(_0x1fc06f),_0x1fc06f=Math['min'](_0x1fc06f*0x2,R);continue;}let _0x37008c=_0x345098[_0x10c8d0(0x168)][_0x10c8d0(0xe5)](),_0x3bd0fc=new TextDecoder(),_0xf98715='';_0x1fc06f=O;while(!0x0){let {done:_0x1437f7,value:_0x25c25b}=await _0x37008c[_0x10c8d0(0x130)]();if(_0x1437f7)break;_0xf98715+=_0x3bd0fc['decode'](_0x25c25b,{'stream':!0x0});let _0x145d17=_0xf98715[_0x10c8d0(0x134)]('\x0a\x0a');_0xf98715=_0x145d17[_0x10c8d0(0xdb)]()||'';for(let _0x173303 of _0x145d17){let _0x127596=_0x173303[_0x10c8d0(0x134)]('\x0a')[_0x10c8d0(0xfb)](_0x32c918=>_0x32c918[_0x10c8d0(0xf7)](_0x10c8d0(0x103)));if(!_0x127596)continue;try{let _0x50aebb=JSON[_0x10c8d0(0xdc)](_0x127596[_0x10c8d0(0xe6)](0x6));if(await a(_0x50aebb),_0x50aebb[_0x10c8d0(0x15b)]===_0x10c8d0(0x126)){if(_0xfc7937=null,!_0x3b9dc9)await l();_0x3b9dc9=!0x1;}}catch(_0x56b3fc){W('parse\x20error:\x20'+_0x56b3fc);}}}W(_0x10c8d0(0x10a));}catch(_0x468a93){W(_0x10c8d0(0xed)+_0x468a93);}if(_0xfc7937=_0xfc7937??Date['now'](),Date[_0x10c8d0(0x106)]()-_0xfc7937>T){W(_0x10c8d0(0xf3)+j+_0x10c8d0(0xf6));return;}await N(_0x1fc06f),_0x1fc06f=Math[_0x10c8d0(0x143)](_0x1fc06f*0x2,R);}}async function a(_0xe8eb58){const _0x1cd076=a0_0x46492c;if(_0xe8eb58[_0x1cd076(0x15b)]===_0x1cd076(0x126)){W(_0x1cd076(0x14e)+G+'\x22');return;}if(_0xe8eb58[_0x1cd076(0x15b)]===_0x1cd076(0xf0)){if(W('←\x20message\x20from\x20'+_0xe8eb58['from']+':\x20'+_0xe8eb58[_0x1cd076(0x125)]['slice'](0x0,0x3c)),await x[_0x1cd076(0x11e)]({'method':_0x1cd076(0x166),'params':{'content':_0xe8eb58[_0x1cd076(0x125)],'meta':{'sender':_0xe8eb58[_0x1cd076(0x11b)]||_0x1cd076(0x127),'sender_id':_0x1cd076(0x11a),'user':_0xe8eb58['from']||_0x1cd076(0x127),'priority':_0x1cd076(0x141)}}}),_0xe8eb58[_0x1cd076(0x10b)])await Y(_0x1cd076(0x14c),{'alias':G,'message_id':_0xe8eb58['message_id']});return;}if(_0xe8eb58['type']===_0x1cd076(0x163)||_0xe8eb58['type']===_0x1cd076(0x109)){W('←\x20'+_0xe8eb58[_0x1cd076(0x15b)]+_0x1cd076(0x154)+_0xe8eb58[_0x1cd076(0xea)]+'\x20priority='+(_0xe8eb58[_0x1cd076(0x165)]||_0x1cd076(0x141)));let _0x38ff0c=await Y(_0x1cd076(0x170),{'alias':G,'limit':0x5});if(_0x38ff0c?.['ok']&&_0x38ff0c[_0x1cd076(0x123)]?.[_0x1cd076(0xe1)]>0x0)for(let _0x39dd38 of _0x38ff0c[_0x1cd076(0x123)]){let _0x17a599={'sender':_0x39dd38[_0x1cd076(0x129)]||_0x1cd076(0x127),'sender_id':_0x1cd076(0x11a),'user':_0x39dd38[_0x1cd076(0x129)]||_0x1cd076(0x127),'task_id':_0x39dd38['id'],'priority':_0x39dd38[_0x1cd076(0x165)]||'normal'};D[_0x1cd076(0x13c)](_0x39dd38['id'],_0x39dd38['from_session']||_0x1cd076(0x127)),await x['notification']({'method':'notifications/claude/channel','params':{'content':_0x39dd38[_0x1cd076(0xd8)],'meta':_0x17a599}}),W(_0x1cd076(0x117)+_0x39dd38['id'][_0x1cd076(0xe6)](0x0,0x8)+_0x1cd076(0xd9)+_0x39dd38['from_session']+':\x20'+_0x39dd38['content'][_0x1cd076(0xe6)](0x0,0x3c)),await Y(_0x1cd076(0x14c),{'alias':G,'message_id':_0x39dd38['id']});}}}async function n(){const _0xcd959=a0_0x46492c;let _0x2396e9=new a0_0x281413();await x[_0xcd959(0x10e)](_0x2396e9),W('MCP\x20stdio\x20connected'),W(_0xcd959(0x12a)),o()['catch'](_0x5ad11f=>W(_0xcd959(0x114)+_0x5ad11f)),Y(_0xcd959(0x16d),{'resume_id':K,'alias':G,'status':'idle','server':a0_0x47b9f6(),'hostname':a0_0x47b9f6(),'agent':'claude-code','project_dir':process[_0xcd959(0x155)](),'tmux_name':f||void 0x0})[_0xcd959(0x147)](()=>W('registered\x20as\x20\x22'+G+_0xcd959(0x12d)+K[_0xcd959(0xe6)](0x0,0x8)+')'))['catch'](_0x1be390=>W(_0xcd959(0x15c)+_0x1be390)),setInterval(()=>{const _0x1b5722=_0xcd959;Y(_0x1b5722(0x16d),{'resume_id':K,'alias':G,'status':_0x1b5722(0x13f),'server':a0_0x47b9f6(),'hostname':a0_0x47b9f6(),'agent':'claude-code','project_dir':process['cwd'](),'tmux_name':f||void 0x0})[_0x1b5722(0x174)](_0x34d0b1=>W(_0x1b5722(0x146)+_0x34d0b1));},0x2bf20),W('ready\x20—\x20waiting\x20for\x20events');}n()[a0_0x46492c(0x174)](_0xbbcab7=>{const _0x1eb077=a0_0x46492c;W(_0x1eb077(0x171)+_0xbbcab7),process[_0x1eb077(0xfe)](0x1);});async function b(){const _0x2bc112=a0_0x46492c;W(_0x2bc112(0xf1)),await Y(_0x2bc112(0x16d),{'resume_id':K,'alias':G,'status':_0x2bc112(0x150),'task':_0x2bc112(0x151)})['catch'](()=>{}),process[_0x2bc112(0xfe)](0x0);}process[a0_0x46492c(0x108)]['on'](a0_0x46492c(0xfa),()=>b()),process['on']('SIGTERM',()=>b()),process['on'](a0_0x46492c(0x10f),()=>b());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sleep2agi/agent-network",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.22-preview.0",
|
|
4
4
|
"description": "AI Agent Network CLI — Local-first multi-agent orchestration across 4 runtimes (Claude Code CLI / Claude Agent SDK / Codex SDK / Grok Build ACP) and 8+ LLM providers (Anthropic / OpenAI / xAI Grok / MiniMax / DeepSeek / GLM / Kimi / InternLM / Xiaomi MiMo / OpenRouter). Apache 2.0.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/client.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
21
|
"typecheck": "tsc --noEmit",
|
|
22
|
-
"build": "bun build src/client.ts --outdir dist/src --target node --minify && bun build bin/cli.ts --outdir dist/bin --target node --minify --external @sleep2agi/commhub-server --external bun:sqlite --external '../../server/*' && bun build src/node-server.ts --outdir dist/src --target node --minify --external @modelcontextprotocol/sdk && tsc --emitDeclarationOnly --declaration --outDir dist && npx javascript-obfuscator dist/bin/cli.js --output dist/bin/cli.js --compact true --string-array true --string-array-encoding base64 && npx javascript-obfuscator dist/src/client.js --output dist/src/client.js --compact true --string-array true && npx javascript-obfuscator dist/src/node-server.js --output dist/src/node-server.js --compact true --string-array true",
|
|
22
|
+
"build": "bun build src/client.ts --outdir dist/src --target node --minify && bun build bin/cli.ts --outdir dist/bin --target node --minify --external @sleep2agi/commhub-server --external bun:sqlite --external '../../server/*' && bun build src/node-server.ts --outdir dist/src --target node --minify --external @modelcontextprotocol/sdk && bun build src/im/feishu/worker.ts --outdir dist/src/im/feishu --target node --minify --external @larksuiteoapi/node-sdk && tsc --emitDeclarationOnly --declaration --outDir dist && npx javascript-obfuscator dist/bin/cli.js --output dist/bin/cli.js --compact true --string-array true --string-array-encoding base64 && npx javascript-obfuscator dist/src/client.js --output dist/src/client.js --compact true --string-array true && npx javascript-obfuscator dist/src/node-server.js --output dist/src/node-server.js --compact true --string-array true",
|
|
23
23
|
"prepublishOnly": "npm run build"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
@@ -63,7 +63,8 @@
|
|
|
63
63
|
"node": ">=22.13.0"
|
|
64
64
|
},
|
|
65
65
|
"dependencies": {
|
|
66
|
-
"@inquirer/prompts": "^8.4.3"
|
|
66
|
+
"@inquirer/prompts": "^8.4.3",
|
|
67
|
+
"@larksuiteoapi/node-sdk": "^1.42.0"
|
|
67
68
|
},
|
|
68
69
|
"devDependencies": {
|
|
69
70
|
"@modelcontextprotocol/sdk": "^1.12.0",
|