@sleep2agi/agent-network 2.3.0-preview.127 → 2.3.0-preview.129

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.
@@ -0,0 +1,47 @@
1
+ export type RevokeOutcome =
2
+ /** 服务端已撤销 */
3
+ {
4
+ kind: "revoked";
5
+ tokenId: string;
6
+ }
7
+ /** Hub 回 401:这个 token 在服务端本来就无效了(过期/已撤/改过密码),没东西可撤 */
8
+ | {
9
+ kind: "already_invalid";
10
+ }
11
+ /** 不是登录会话(显式 API 令牌 / 节点令牌):按设计不撤,仍有效 */
12
+ | {
13
+ kind: "not_a_session";
14
+ tokenId?: string;
15
+ }
16
+ /** Hub 没有 /api/auth/sessions(早于 #2114 的旧版本 → 404) */
17
+ | {
18
+ kind: "unsupported";
19
+ status: number;
20
+ }
21
+ /** 连不上 Hub(DNS / 拒绝连接 / 超时) */
22
+ | {
23
+ kind: "unreachable";
24
+ error: string;
25
+ }
26
+ /** 其他意外响应 */
27
+ | {
28
+ kind: "failed";
29
+ status?: number;
30
+ error: string;
31
+ };
32
+ export type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
33
+ export declare function normalizeHubUrl(url: string): string;
34
+ export declare function sameHub(a?: string | null, b?: string | null): boolean;
35
+ /** 本地登录态字段。hub 不在里面:退出登录不等于忘掉 Hub 地址。 */
36
+ export declare const LOCAL_CREDENTIAL_KEYS: readonly ["token", "user", "network_id", "network_name"];
37
+ export declare function clearLocalCredentials(gc: Record<string, any>): Record<string, any>;
38
+ /** 在 `hub` 上撤销 `token` 所代表的登录会话。只把 token 发给 `hub` 本身。 */
39
+ export declare function revokeCurrentLoginSession(hub: string, token: string, opts?: {
40
+ fetchImpl?: FetchLike;
41
+ timeoutMs?: number;
42
+ }): Promise<RevokeOutcome>;
43
+ /** 把撤销结果翻成给人看的行。`ok=false` 表示服务端令牌**仍然有效**,调用方按警告打印。 */
44
+ export declare function describeRevokeOutcome(o: RevokeOutcome, hub: string): {
45
+ ok: boolean;
46
+ lines: string[];
47
+ };
@@ -0,0 +1,11 @@
1
+ export declare const ANET_EXIT: {
2
+ readonly OK: 0;
3
+ readonly FAILURE: 1;
4
+ readonly USAGE: 2;
5
+ };
6
+ /** 命令打印了错误、不再继续 —— 记下失败码,让 main() 的终结器用它退出。 */
7
+ export declare function markFailed(): void;
8
+ /** 用法错误(缺参数 / 未知子命令 / 非法取值)。 */
9
+ export declare function markUsageError(): void;
10
+ /** main() 正常返回后的退出码:命令记下过的码,没记过就是 0。 */
11
+ export declare function finalExitCode(): number;
@@ -1 +1 @@
1
- const a0_0x418f2e=a0_0x4ae2;(function(_0x414e82,_0x3d2a95){const _0x1fe9b1=a0_0x4ae2,_0x2ef0e9=_0x414e82();while(!![]){try{const _0x2ca167=parseInt(_0x1fe9b1(0x1d4))/0x1*(parseInt(_0x1fe9b1(0x20d))/0x2)+-parseInt(_0x1fe9b1(0x1da))/0x3+-parseInt(_0x1fe9b1(0x20b))/0x4*(-parseInt(_0x1fe9b1(0x249))/0x5)+-parseInt(_0x1fe9b1(0x1d7))/0x6*(-parseInt(_0x1fe9b1(0x1de))/0x7)+parseInt(_0x1fe9b1(0x202))/0x8+-parseInt(_0x1fe9b1(0x21d))/0x9*(-parseInt(_0x1fe9b1(0x23e))/0xa)+-parseInt(_0x1fe9b1(0x1e0))/0xb;if(_0x2ca167===_0x3d2a95)break;else _0x2ef0e9['push'](_0x2ef0e9['shift']());}catch(_0x1461ff){_0x2ef0e9['push'](_0x2ef0e9['shift']());}}}(a0_0x2db5,0xaddbc));import{EventEmitter as a0_0x3c33ac}from'events';import{hostname as a0_0x40011f}from'os';function a0_0x4ae2(_0x3930bf,_0x142388){_0x3930bf=_0x3930bf-0x1c6;const _0x2db522=a0_0x2db5();let _0x4ae244=_0x2db522[_0x3930bf];return _0x4ae244;}var K=/(?:atok|ntok|utok|ghp|github_pat)_[A-Za-z0-9_-]+|Bearer\s+\S+/gi,L=(_0x23311b,_0x20dbfb)=>(_0x23311b??_0x20dbfb)[a0_0x418f2e(0x228)](/[\r\n\x00-\x1f\x7f]/g,'\x20')[a0_0x418f2e(0x1df)](0x0,0xf0);function N(_0x2d4533){const _0x56d695=a0_0x418f2e;return(_0x2d4533 instanceof Error?_0x2d4533['message']:String(_0x2d4533??_0x56d695(0x1cf)))[_0x56d695(0x228)](K,_0x56d695(0x1f3))[_0x56d695(0x228)](/[\r\n\x00-\x1f\x7f]/g,'\x20')[_0x56d695(0x1df)](0x0,0xf0);}function O(_0x6c81c,_0x2d75d4=process.env.ANET_TASK_TRACE_FORMAT===a0_0x418f2e(0x234)){const _0x1021a1=a0_0x418f2e;if(_0x2d75d4)return JSON[_0x1021a1(0x224)](_0x6c81c);let _0x27bc4e=L(_0x6c81c[_0x1021a1(0x1f4)],_0x1021a1(0x244)),_0x3e07be=L(_0x6c81c['task_id'],_0x1021a1(0x226)),_0x58e920=_0x6c81c[_0x1021a1(0x1f9)]?_0x1021a1(0x203)+_0x6c81c[_0x1021a1(0x1f9)]+':'+(_0x6c81c['error_message']??''):'';return _0x1021a1(0x20f)+_0x6c81c[_0x1021a1(0x200)]+_0x1021a1(0x23d)+L(_0x6c81c[_0x1021a1(0x240)],'<unknown>')+_0x1021a1(0x1c6)+L(_0x6c81c[_0x1021a1(0x1d2)],_0x1021a1(0x23b))+'\x20task_id='+_0x3e07be+_0x1021a1(0x1e3)+_0x27bc4e+_0x1021a1(0x1f7)+L(_0x6c81c[_0x1021a1(0x227)],_0x1021a1(0x23b))+_0x1021a1(0x1d8)+_0x6c81c['transport']+_0x1021a1(0x1d3)+_0x6c81c[_0x1021a1(0x1cb)]+_0x1021a1(0x1fa)+_0x6c81c[_0x1021a1(0x212)]+_0x58e920;}function U(_0x5da40b){const _0xde4c72=a0_0x418f2e;return{'event':{'sending':_0xde4c72(0x1f5),'delivered':'task.send.delivered','failed':_0xde4c72(0x23f),'acked':_0xde4c72(0x1ea),'started':_0xde4c72(0x235),'replied':_0xde4c72(0x245),'expired':_0xde4c72(0x209)}[_0x5da40b[_0xde4c72(0x200)]],..._0x5da40b};}function j(_0x3382f6){const _0x4bb307=a0_0x418f2e;let _0xa879f7=_0x3382f6?.[_0x4bb307(0x1fc)]||_0x3382f6?.[_0x4bb307(0x206)]||_0x3382f6?.['id'];if(_0xa879f7)return String(_0xa879f7);let _0x526c45=_0x3382f6?.['content']?.[0x0]?.[_0x4bb307(0x243)];if(typeof _0x526c45!==_0x4bb307(0x1cd))return null;try{let _0x38e9e5=JSON[_0x4bb307(0x1e7)](_0x526c45);return _0x38e9e5?.[_0x4bb307(0x1fc)]||_0x38e9e5?.[_0x4bb307(0x206)]||_0x38e9e5?.['id']||null;}catch{return null;}}async function X(_0x386454,_0x10c3cc){const _0x139d5f=a0_0x418f2e;let _0x2ee677=_0x10c3cc[_0x139d5f(0x1d6)]??Date[_0x139d5f(0x1d6)],_0x19f050=_0x2ee677(),_0x444823=(_0x4f91f3,_0x42141b,_0x2f6f23,_0x5d2fa8)=>{const _0x4f467f=_0x139d5f;_0x10c3cc['log'](O(U({'from_alias':_0x386454[_0x4f467f(0x1d0)],'to_alias':_0x386454[_0x4f467f(0x207)],'task_id':_0x42141b,'parent_task_id':_0x386454[_0x4f467f(0x1ec)],'network_id':_0x386454[_0x4f467f(0x21f)],'transport':_0x386454['transport'],'status':_0x4f91f3,'duration_ms':_0x2ee677()-_0x19f050,'lifecycle_tracking':_0x386454[_0x4f467f(0x1e8)],..._0x2f6f23!==void 0x0?{'error_code':_0x5d2fa8||'send_failed','error_message':N(_0x2f6f23)}:{}})));};_0x444823(_0x139d5f(0x218),null);try{let _0x5815d1=await _0x10c3cc[_0x139d5f(0x20a)](),_0x459d3f=j(_0x5815d1);if(_0x459d3f)_0x444823(_0x139d5f(0x237),_0x459d3f);else{if(_0x5815d1?.['ok']===!0x1||_0x5815d1?.['error'])_0x444823(_0x139d5f(0x213),_0x459d3f,_0x5815d1?.[_0x139d5f(0x220)]||_0x139d5f(0x246),'send_rejected');else _0x444823(_0x139d5f(0x213),null,_0x139d5f(0x236),_0x139d5f(0x1e4));}return _0x5815d1;}catch(_0x20ded1){throw _0x444823('failed',null,_0x20ded1,_0x139d5f(0x22a)),_0x20ded1;}}async function Y(_0x5961f6,_0x88fc19){const _0x461eac=a0_0x418f2e;return X({'fromAlias':_0x5961f6[_0x461eac(0x1d0)],'toAlias':_0x5961f6[_0x461eac(0x21e)],'parentTaskId':_0x5961f6['parentTaskId']||null,'networkId':_0x5961f6['networkId']||null,'transport':_0x461eac(0x22b),'lifecycleTracking':_0x461eac(0x214)},_0x88fc19);}function a0_0x2db5(){const _0x3a0e0f=['messages','text/event-stream','Bearer\x20','<unknown>','task','\x20from=','10pnJlVW','task.send.failed','from_alias','completed','reconnectDelay','text','<missing>','task.replied','CommHub\x20rejected\x20task','offline','application/json,\x20text/event-stream','65uZhAJs','broadcast','/mcp','\x20to=','split','reply','application/json','tools/call','duration_ms','registered','string','2.0','unknown\x20error','fromAlias','result','to_alias','\x20duration_ms=','661LfXISq','connected','now','25320dRyDcN','\x20transport=','from_session','2154669prVdpi','SSE\x20reconnecting\x20in\x20','new_task','SSE\x20failed:\x20','679NlqOne','slice','25173676ewFqvC','inbox\x20error:\x20','connect','\x20parent_task_id=','missing_task_id','getReader','running','parse','lifecycleTracking','body','task.ack','token','parentTaskId','decode','report_status',']\x20[commhub:','idle','agent','/events/','[REDACTED]','parent_task_id','task.send.start','sleep','\x20network_id=','connectSSE','error_code','\x20lifecycle=','match','task_id','send_message','abort','sseAbort','status','log','4078728BXYJXT','\x20error=','call','cwd','message_id','toAlias','url','task.expired','send','413032guJolz','catch','2932Tunygv','message','[commhub:task]\x20','emit','type','lifecycle_tracking','failed','not_tracked','send_task','heartbeatTimer','data:\x20','sending','disconnected','heartbeatInterval','autoConnect','content','4394718tSvqSZ','alias','networkId','error','min','SSE\x20connected','Authorization','stringify','new_message','<pending>','network_id','replace','server','send_failed','mcp_http','resumeId','sdk-','sdk','normal','toString','pop','AbortError','processInbox','json','task.started','CommHub\x20response\x20omitted\x20task_id','delivered'];a0_0x2db5=function(){return _0x3a0e0f;};return a0_0x2db5();}class $ extends a0_0x3c33ac{[a0_0x418f2e(0x208)];['alias'];['token'];[a0_0x418f2e(0x1f1)];[a0_0x418f2e(0x22c)];[a0_0x418f2e(0x21a)];['reconnectDelay'];[a0_0x418f2e(0x216)];[a0_0x418f2e(0x1ff)];[a0_0x418f2e(0x1e6)]=!0x1;constructor(_0x29c6f7){const _0x477eab=a0_0x418f2e;super();if(this['url']=_0x29c6f7[_0x477eab(0x208)][_0x477eab(0x228)](/\/$/,''),this[_0x477eab(0x21e)]=_0x29c6f7['alias'],this['token']=_0x29c6f7[_0x477eab(0x1eb)],this[_0x477eab(0x1f1)]=_0x29c6f7[_0x477eab(0x1f1)]||_0x477eab(0x22e),this[_0x477eab(0x22c)]=_0x477eab(0x22d)+_0x29c6f7[_0x477eab(0x21e)]+'-'+Date[_0x477eab(0x1d6)]()[_0x477eab(0x230)](0x24),this['heartbeatInterval']=_0x29c6f7[_0x477eab(0x21a)]??0x2bf20,this[_0x477eab(0x242)]=_0x29c6f7[_0x477eab(0x242)]??0xbb8,_0x29c6f7[_0x477eab(0x21b)]!==!0x1)this[_0x477eab(0x1e2)]();}[a0_0x418f2e(0x201)](_0x35d769){const _0xe987d=a0_0x418f2e;console[_0xe987d(0x201)]('['+new Date()['toTimeString']()['slice'](0x0,0x8)+_0xe987d(0x1ef)+this['alias']+']\x20'+_0x35d769);}async[a0_0x418f2e(0x204)](_0x140740,_0x11398c){const _0x230cb2=a0_0x418f2e;let _0x198aff={'Content-Type':_0x230cb2(0x1c9),'Accept':_0x230cb2(0x248)};if(this[_0x230cb2(0x1eb)])_0x198aff[_0x230cb2(0x223)]='Bearer\x20'+this['token'];let _0x5b37eb=await(await fetch(this[_0x230cb2(0x208)]+_0x230cb2(0x24b),{'method':'POST','headers':_0x198aff,'body':JSON[_0x230cb2(0x224)]({'jsonrpc':_0x230cb2(0x1ce),'id':Date['now'](),'method':_0x230cb2(0x1ca),'params':{'name':_0x140740,'arguments':_0x11398c}})}))['text'](),_0x2f2793=_0x5b37eb[_0x230cb2(0x1fb)](/data: (.+)/),_0x3a401=_0x2f2793?JSON[_0x230cb2(0x1e7)](_0x2f2793[0x1]):JSON[_0x230cb2(0x1e7)](_0x5b37eb),_0x1ebb0a=_0x3a401?.[_0x230cb2(0x1d1)]?.[_0x230cb2(0x21c)]?.[0x0]?.[_0x230cb2(0x243)];return _0x1ebb0a?JSON[_0x230cb2(0x1e7)](_0x1ebb0a):_0x3a401;}async[a0_0x418f2e(0x1e2)](){const _0x3f30ec=a0_0x418f2e;if(this[_0x3f30ec(0x1e6)])return;this['running']=!0x0,await this['status'](_0x3f30ec(0x1f0)),this[_0x3f30ec(0x201)](_0x3f30ec(0x1cc)),this['heartbeatTimer']=setInterval(()=>{const _0x58c58c=_0x3f30ec;this[_0x58c58c(0x200)](_0x58c58c(0x1f0))[_0x58c58c(0x20c)](_0x13c4a7=>this[_0x58c58c(0x201)]('heartbeat\x20failed:\x20'+_0x13c4a7[_0x58c58c(0x20e)]));},this[_0x3f30ec(0x21a)]),this[_0x3f30ec(0x1f8)]();}async['disconnect'](){const _0x1cf5d2=a0_0x418f2e;if(this[_0x1cf5d2(0x1e6)]=!0x1,this[_0x1cf5d2(0x1ff)]?.[_0x1cf5d2(0x1fe)](),this['heartbeatTimer'])clearInterval(this['heartbeatTimer']);await this['status'](_0x1cf5d2(0x247))[_0x1cf5d2(0x20c)](()=>{}),this[_0x1cf5d2(0x201)]('disconnected');}async['send'](_0x25c32e,_0x21d1e5,_0x5a7e01=a0_0x418f2e(0x22f)){const _0x2da13b=a0_0x418f2e;return Y({'alias':_0x25c32e,'fromAlias':this[_0x2da13b(0x21e)]},{'log':_0x43f255=>console[_0x2da13b(0x201)](_0x43f255),'send':()=>this[_0x2da13b(0x204)](_0x2da13b(0x215),{'alias':_0x25c32e,'task':_0x21d1e5,'priority':_0x5a7e01,'from_session':this['alias']})});}async['message'](_0x2f067f,_0x4b4378){const _0x1b6958=a0_0x418f2e;return this[_0x1b6958(0x204)](_0x1b6958(0x1fd),{'alias':_0x2f067f,'message':_0x4b4378,'from_session':this[_0x1b6958(0x21e)]});}async[a0_0x418f2e(0x1c8)](_0x9cdd79,_0x4f727d,_0x2d6efc=a0_0x418f2e(0x241)){const _0x29e572=a0_0x418f2e;return this[_0x29e572(0x204)]('send_reply',{'in_reply_to':_0x9cdd79,'text':_0x4f727d,'status':_0x2d6efc});}async[a0_0x418f2e(0x200)](_0x146675,_0x236f0b){const _0x555737=a0_0x418f2e;return this['call'](_0x555737(0x1ee),{'resume_id':this[_0x555737(0x22c)],'alias':this['alias'],'status':_0x146675,'server':a0_0x40011f(),'hostname':a0_0x40011f(),'agent':this[_0x555737(0x1f1)],'project_dir':process[_0x555737(0x205)](),..._0x236f0b});}async['getAllStatus'](){const _0x32b6e7=a0_0x418f2e;return this[_0x32b6e7(0x204)]('get_all_status',{});}async[a0_0x418f2e(0x24a)](_0x1d2d68,_0x43f8fd){const _0x5174d8=a0_0x418f2e;return this[_0x5174d8(0x204)](_0x5174d8(0x24a),{'message':_0x1d2d68,'filter_server':_0x43f8fd?.[_0x5174d8(0x229)],'filter_status':_0x43f8fd?.[_0x5174d8(0x200)]});}async[a0_0x418f2e(0x1f8)](){const _0x57c991=a0_0x418f2e;let _0x25fb9e=encodeURIComponent(this['alias']),_0x38dc04=this[_0x57c991(0x208)]+_0x57c991(0x1f2)+_0x25fb9e,_0x451857=this[_0x57c991(0x242)];while(this[_0x57c991(0x1e6)]){try{this[_0x57c991(0x1ff)]=new AbortController();let _0x5cbed6={'Accept':_0x57c991(0x239)};if(this[_0x57c991(0x1eb)])_0x5cbed6['Authorization']=_0x57c991(0x23a)+this['token'];let _0x3101d8=await fetch(_0x38dc04,{'headers':_0x5cbed6,'signal':this[_0x57c991(0x1ff)]['signal']});if(!_0x3101d8['ok']||!_0x3101d8['body']){this['log'](_0x57c991(0x1dd)+_0x3101d8[_0x57c991(0x200)]),await this['sleep'](_0x451857),_0x451857=Math[_0x57c991(0x221)](_0x451857*1.5,0xea60);continue;}_0x451857=this['reconnectDelay'];let _0x1702c4=_0x3101d8[_0x57c991(0x1e9)][_0x57c991(0x1e5)](),_0x4e4ec8=new TextDecoder(),_0x24a903='';while(this[_0x57c991(0x1e6)]){let {done:_0x1838ba,value:_0x362820}=await _0x1702c4['read']();if(_0x1838ba)break;_0x24a903+=_0x4e4ec8[_0x57c991(0x1ed)](_0x362820,{'stream':!0x0});let _0x440a29=_0x24a903[_0x57c991(0x1c7)]('\x0a');_0x24a903=_0x440a29[_0x57c991(0x231)]()||'';for(let _0x2973ff of _0x440a29){if(!_0x2973ff['startsWith'](_0x57c991(0x217)))continue;try{let _0x236248=JSON[_0x57c991(0x1e7)](_0x2973ff['slice'](0x6));if(_0x236248[_0x57c991(0x211)]==='connected'){this['log'](_0x57c991(0x222)),this[_0x57c991(0x210)](_0x57c991(0x1d5));continue;}if(_0x236248[_0x57c991(0x211)]===_0x57c991(0x1dc)||_0x236248['type']===_0x57c991(0x225)||_0x236248[_0x57c991(0x211)]===_0x57c991(0x24a))await this[_0x57c991(0x233)]();}catch{}}}}catch(_0x4ee57e){if(_0x4ee57e['name']===_0x57c991(0x232))break;this[_0x57c991(0x210)](_0x57c991(0x220),_0x4ee57e),this[_0x57c991(0x201)]('SSE\x20error:\x20'+_0x4ee57e[_0x57c991(0x20e)]);}if(this['running'])this[_0x57c991(0x210)](_0x57c991(0x219)),this['log'](_0x57c991(0x1db)+_0x451857/0x3e8+'s...'),await this[_0x57c991(0x1f6)](_0x451857),_0x451857=Math['min'](_0x451857*1.5,0xea60);}}async[a0_0x418f2e(0x233)](){const _0x144cdb=a0_0x418f2e;try{let _0x12793b=(await this['call']('get_inbox',{'alias':this[_0x144cdb(0x21e)],'limit':0xa}))?.[_0x144cdb(0x238)]||[];for(let _0x486355 of _0x12793b)await this[_0x144cdb(0x204)]('ack_inbox',{'alias':this[_0x144cdb(0x21e)],'message_id':_0x486355['id']}),this[_0x144cdb(0x201)]('←\x20'+_0x486355[_0x144cdb(0x1d9)]+':\x20'+_0x486355[_0x144cdb(0x21c)][_0x144cdb(0x1df)](0x0,0x3c)),this['emit'](_0x144cdb(0x23c),_0x486355),this[_0x144cdb(0x210)](_0x144cdb(0x20e),_0x486355);}catch(_0x329f2e){this[_0x144cdb(0x201)](_0x144cdb(0x1e1)+_0x329f2e[_0x144cdb(0x20e)]);}}[a0_0x418f2e(0x1f6)](_0x47d15c){return new Promise(_0x3c0ed9=>setTimeout(_0x3c0ed9,_0x47d15c));}}var F=$;export{F as default,$ as CommHub};
1
+ const a0_0x5d395c=a0_0x5553;(function(_0x2049ca,_0x45eabd){const _0x5edff4=a0_0x5553,_0x2471e0=_0x2049ca();while(!![]){try{const _0x18c5b8=-parseInt(_0x5edff4(0x1b0))/0x1+parseInt(_0x5edff4(0x169))/0x2+parseInt(_0x5edff4(0x199))/0x3*(-parseInt(_0x5edff4(0x1b2))/0x4)+-parseInt(_0x5edff4(0x1ab))/0x5+-parseInt(_0x5edff4(0x17b))/0x6+parseInt(_0x5edff4(0x1ba))/0x7*(parseInt(_0x5edff4(0x187))/0x8)+-parseInt(_0x5edff4(0x1b1))/0x9*(-parseInt(_0x5edff4(0x19e))/0xa);if(_0x18c5b8===_0x45eabd)break;else _0x2471e0['push'](_0x2471e0['shift']());}catch(_0x148236){_0x2471e0['push'](_0x2471e0['shift']());}}}(a0_0x38f4,0xe213f));import{EventEmitter as a0_0x196e24}from'events';import{hostname as a0_0x5b7e5c}from'os';var K=/(?:atok|ntok|utok|ghp|github_pat)_[A-Za-z0-9_-]+|Bearer\s+\S+/gi,L=(_0x54381c,_0x6b108)=>(_0x54381c??_0x6b108)[a0_0x5d395c(0x192)](/[\r\n\x00-\x1f\x7f]/g,'\x20')[a0_0x5d395c(0x18f)](0x0,0xf0);function N(_0x2204ec){const _0x1642f2=a0_0x5d395c;return(_0x2204ec instanceof Error?_0x2204ec['message']:String(_0x2204ec??_0x1642f2(0x1aa)))[_0x1642f2(0x192)](K,'[REDACTED]')[_0x1642f2(0x192)](/[\r\n\x00-\x1f\x7f]/g,'\x20')[_0x1642f2(0x18f)](0x0,0xf0);}function O(_0x21bbe4,_0x33c7b2=process.env.ANET_TASK_TRACE_FORMAT===a0_0x5d395c(0x196)){const _0x1a3ab8=a0_0x5d395c;if(_0x33c7b2)return JSON[_0x1a3ab8(0x195)](_0x21bbe4);let _0xc75d90=L(_0x21bbe4[_0x1a3ab8(0x1d8)],'<missing>'),_0x56665e=L(_0x21bbe4[_0x1a3ab8(0x1ce)],_0x1a3ab8(0x17e)),_0xf61e8d=_0x21bbe4['error_code']?_0x1a3ab8(0x185)+_0x21bbe4[_0x1a3ab8(0x18e)]+':'+(_0x21bbe4[_0x1a3ab8(0x1d9)]??''):'';return _0x1a3ab8(0x190)+_0x21bbe4[_0x1a3ab8(0x17d)]+_0x1a3ab8(0x179)+L(_0x21bbe4[_0x1a3ab8(0x16c)],'<unknown>')+_0x1a3ab8(0x1b3)+L(_0x21bbe4[_0x1a3ab8(0x163)],'<unknown>')+_0x1a3ab8(0x186)+_0x56665e+_0x1a3ab8(0x1df)+_0xc75d90+_0x1a3ab8(0x181)+L(_0x21bbe4[_0x1a3ab8(0x1cc)],_0x1a3ab8(0x1c3))+_0x1a3ab8(0x1cf)+_0x21bbe4[_0x1a3ab8(0x171)]+_0x1a3ab8(0x17c)+_0x21bbe4[_0x1a3ab8(0x1a4)]+'\x20lifecycle='+_0x21bbe4[_0x1a3ab8(0x176)]+_0xf61e8d;}function a0_0x5553(_0x28fb70,_0x5144cc){_0x28fb70=_0x28fb70-0x163;const _0x38f4d2=a0_0x38f4();let _0x55531b=_0x38f4d2[_0x28fb70];return _0x55531b;}function U(_0x1f7330){const _0x324411=a0_0x5d395c;return{'event':{'sending':_0x324411(0x174),'delivered':_0x324411(0x188),'failed':_0x324411(0x1da),'acked':'task.ack','started':_0x324411(0x18d),'replied':'task.replied','expired':_0x324411(0x1c2)}[_0x1f7330[_0x324411(0x17d)]],..._0x1f7330};}function j(_0x564ff4){const _0x5208d0=a0_0x5d395c;let _0x14e6f6=_0x564ff4?.[_0x5208d0(0x1ce)]||_0x564ff4?.[_0x5208d0(0x16a)]||_0x564ff4?.['id'];if(_0x14e6f6)return String(_0x14e6f6);let _0x304575=_0x564ff4?.['content']?.[0x0]?.[_0x5208d0(0x1e1)];if(typeof _0x304575!==_0x5208d0(0x1e3))return null;try{let _0x8ad82=JSON['parse'](_0x304575);return _0x8ad82?.[_0x5208d0(0x1ce)]||_0x8ad82?.[_0x5208d0(0x16a)]||_0x8ad82?.['id']||null;}catch{return null;}}function a0_0x38f4(){const _0x361af7=['parse','startsWith','heartbeatInterval','application/json','duration_ms','send','2.0','min','autoConnect','tools/call','unknown\x20error','3541230QDcQyA','resumeId','mcp_http','toString','running','974262jYDCvE','5382TjTgOX','4xlNYrn','\x20to=','content','emit','catch','alias','message','send_message','7pfAgSh','text/event-stream','sdk-','not_tracked','new_message','type','processInbox','heartbeatTimer','task.expired','<unknown>','SSE\x20reconnecting\x20in\x20','token','fromAlias','name','new_task','broadcast','CommHub\x20response\x20omitted\x20task_id','registered','network_id','networkId','task_id','\x20transport=','connectSSE','reply','url','lifecycleTracking','server','sleep','signal','normal','parent_task_id','error_message','task.send.failed','report_status','idle','decode','body','\x20parent_task_id=','pop','text','read','string','Authorization','match','to_alias','reconnectDelay','send_failed','offline','disconnect','sending','50194yPEaKY','message_id','POST','from_alias','log','SSE\x20error:\x20','AbortError','connected','transport','cwd','abort','task.send.start','data:\x20','lifecycle_tracking','call','application/json,\x20text/event-stream','\x20from=','agent','256128nShGLQ','\x20duration_ms=','status','<pending>','now','SSE\x20connected','\x20network_id=','getReader','heartbeat\x20failed:\x20','get_all_status','\x20error=','\x20task_id=','12239320xOiFiK','task.send.delivered','s...','parentTaskId','error','ack_inbox','task.started','error_code','slice','[commhub:task]\x20','disconnected','replace','SSE\x20failed:\x20','sseAbort','stringify','json','from_session','connect','4897425SLXthQ','/mcp','result','Bearer\x20','completed','45630EFmfdp','send_reply'];a0_0x38f4=function(){return _0x361af7;};return a0_0x38f4();}async function X(_0x227264,_0x542aa6){const _0x1104a9=a0_0x5d395c;let _0x33c353=_0x542aa6[_0x1104a9(0x17f)]??Date['now'],_0x44ce08=_0x33c353(),_0x3816d3=(_0xb09f31,_0x5d10bd,_0xdabd1a,_0x403648)=>{const _0xd96912=_0x1104a9;_0x542aa6[_0xd96912(0x16d)](O(U({'from_alias':_0x227264[_0xd96912(0x1c6)],'to_alias':_0x227264['toAlias'],'task_id':_0x5d10bd,'parent_task_id':_0x227264['parentTaskId'],'network_id':_0x227264[_0xd96912(0x1cd)],'transport':_0x227264[_0xd96912(0x171)],'status':_0xb09f31,'duration_ms':_0x33c353()-_0x44ce08,'lifecycle_tracking':_0x227264[_0xd96912(0x1d3)],..._0xdabd1a!==void 0x0?{'error_code':_0x403648||'send_failed','error_message':N(_0xdabd1a)}:{}})));};_0x3816d3(_0x1104a9(0x168),null);try{let _0x3d7961=await _0x542aa6[_0x1104a9(0x1a5)](),_0x5aa0a2=j(_0x3d7961);if(_0x5aa0a2)_0x3816d3('delivered',_0x5aa0a2);else{if(_0x3d7961?.['ok']===!0x1||_0x3d7961?.[_0x1104a9(0x18b)])_0x3816d3('failed',_0x5aa0a2,_0x3d7961?.[_0x1104a9(0x18b)]||'CommHub\x20rejected\x20task','send_rejected');else _0x3816d3('failed',null,_0x1104a9(0x1ca),'missing_task_id');}return _0x3d7961;}catch(_0x4b74a5){throw _0x3816d3('failed',null,_0x4b74a5,_0x1104a9(0x165)),_0x4b74a5;}}async function Y(_0x157924,_0x25771c){const _0x13f564=a0_0x5d395c;return X({'fromAlias':_0x157924['fromAlias'],'toAlias':_0x157924['alias'],'parentTaskId':_0x157924[_0x13f564(0x18a)]||null,'networkId':_0x157924[_0x13f564(0x1cd)]||null,'transport':_0x13f564(0x1ad),'lifecycleTracking':_0x13f564(0x1bd)},_0x25771c);}class $ extends a0_0x196e24{['url'];[a0_0x5d395c(0x1b7)];[a0_0x5d395c(0x1c5)];['agent'];[a0_0x5d395c(0x1ac)];[a0_0x5d395c(0x1a2)];[a0_0x5d395c(0x164)];[a0_0x5d395c(0x1c1)];[a0_0x5d395c(0x194)];[a0_0x5d395c(0x1af)]=!0x1;constructor(_0x5e6142){const _0xc215d=a0_0x5d395c;super();if(this['url']=_0x5e6142[_0xc215d(0x1d2)][_0xc215d(0x192)](/\/$/,''),this['alias']=_0x5e6142[_0xc215d(0x1b7)],this[_0xc215d(0x1c5)]=_0x5e6142[_0xc215d(0x1c5)],this[_0xc215d(0x17a)]=_0x5e6142[_0xc215d(0x17a)]||'sdk',this[_0xc215d(0x1ac)]=_0xc215d(0x1bc)+_0x5e6142['alias']+'-'+Date[_0xc215d(0x17f)]()[_0xc215d(0x1ae)](0x24),this['heartbeatInterval']=_0x5e6142[_0xc215d(0x1a2)]??0x2bf20,this['reconnectDelay']=_0x5e6142[_0xc215d(0x164)]??0xbb8,_0x5e6142[_0xc215d(0x1a8)]!==!0x1)this['connect']();}['log'](_0x1d34cb){const _0x45bdee=a0_0x5d395c;console[_0x45bdee(0x16d)]('['+new Date()['toTimeString']()[_0x45bdee(0x18f)](0x0,0x8)+']\x20[commhub:'+this[_0x45bdee(0x1b7)]+']\x20'+_0x1d34cb);}async[a0_0x5d395c(0x177)](_0x1a0154,_0x3b160d){const _0x4d2c71=a0_0x5d395c;let _0xf4fc88={'Content-Type':_0x4d2c71(0x1a3),'Accept':_0x4d2c71(0x178)};if(this[_0x4d2c71(0x1c5)])_0xf4fc88[_0x4d2c71(0x1e4)]=_0x4d2c71(0x19c)+this['token'];let _0x42ebbe=await(await fetch(this[_0x4d2c71(0x1d2)]+_0x4d2c71(0x19a),{'method':_0x4d2c71(0x16b),'headers':_0xf4fc88,'body':JSON[_0x4d2c71(0x195)]({'jsonrpc':_0x4d2c71(0x1a6),'id':Date[_0x4d2c71(0x17f)](),'method':_0x4d2c71(0x1a9),'params':{'name':_0x1a0154,'arguments':_0x3b160d}})}))[_0x4d2c71(0x1e1)](),_0x5caac1=_0x42ebbe[_0x4d2c71(0x1e5)](/data: (.+)/),_0x14b072=_0x5caac1?JSON[_0x4d2c71(0x1a0)](_0x5caac1[0x1]):JSON[_0x4d2c71(0x1a0)](_0x42ebbe),_0x3af791=_0x14b072?.[_0x4d2c71(0x19b)]?.[_0x4d2c71(0x1b4)]?.[0x0]?.['text'];return _0x3af791?JSON[_0x4d2c71(0x1a0)](_0x3af791):_0x14b072;}async[a0_0x5d395c(0x198)](){const _0x899f13=a0_0x5d395c;if(this['running'])return;this['running']=!0x0,await this[_0x899f13(0x17d)]('idle'),this[_0x899f13(0x16d)](_0x899f13(0x1cb)),this[_0x899f13(0x1c1)]=setInterval(()=>{const _0x4436a8=_0x899f13;this[_0x4436a8(0x17d)](_0x4436a8(0x1dc))['catch'](_0x2f87ed=>this['log'](_0x4436a8(0x183)+_0x2f87ed[_0x4436a8(0x1b8)]));},this[_0x899f13(0x1a2)]),this[_0x899f13(0x1d0)]();}async[a0_0x5d395c(0x167)](){const _0x18c883=a0_0x5d395c;if(this[_0x18c883(0x1af)]=!0x1,this[_0x18c883(0x194)]?.[_0x18c883(0x173)](),this[_0x18c883(0x1c1)])clearInterval(this[_0x18c883(0x1c1)]);await this[_0x18c883(0x17d)](_0x18c883(0x166))[_0x18c883(0x1b6)](()=>{}),this[_0x18c883(0x16d)](_0x18c883(0x191));}async[a0_0x5d395c(0x1a5)](_0x53e91e,_0xd68458,_0x48fc90=a0_0x5d395c(0x1d7)){const _0xa50331=a0_0x5d395c;return Y({'alias':_0x53e91e,'fromAlias':this[_0xa50331(0x1b7)]},{'log':_0x4839ab=>console[_0xa50331(0x16d)](_0x4839ab),'send':()=>this['call']('send_task',{'alias':_0x53e91e,'task':_0xd68458,'priority':_0x48fc90,'from_session':this[_0xa50331(0x1b7)]})});}async[a0_0x5d395c(0x1b8)](_0x172e70,_0x505ebd){const _0x4b7164=a0_0x5d395c;return this['call'](_0x4b7164(0x1b9),{'alias':_0x172e70,'message':_0x505ebd,'from_session':this[_0x4b7164(0x1b7)]});}async[a0_0x5d395c(0x1d1)](_0x44b682,_0x5bf4ec,_0x3e3ce6=a0_0x5d395c(0x19d)){const _0x911d70=a0_0x5d395c;return this[_0x911d70(0x177)](_0x911d70(0x19f),{'in_reply_to':_0x44b682,'text':_0x5bf4ec,'status':_0x3e3ce6});}async[a0_0x5d395c(0x17d)](_0x3338bf,_0x259bd1){const _0x682eba=a0_0x5d395c;return this[_0x682eba(0x177)](_0x682eba(0x1db),{'resume_id':this['resumeId'],'alias':this[_0x682eba(0x1b7)],'status':_0x3338bf,'server':a0_0x5b7e5c(),'hostname':a0_0x5b7e5c(),'agent':this['agent'],'project_dir':process[_0x682eba(0x172)](),..._0x259bd1});}async['getAllStatus'](){const _0x58c547=a0_0x5d395c;return this['call'](_0x58c547(0x184),{});}async[a0_0x5d395c(0x1c9)](_0x2ed343,_0x25013a){const _0xed2a02=a0_0x5d395c;return this[_0xed2a02(0x177)](_0xed2a02(0x1c9),{'message':_0x2ed343,'filter_server':_0x25013a?.[_0xed2a02(0x1d4)],'filter_status':_0x25013a?.[_0xed2a02(0x17d)]});}async[a0_0x5d395c(0x1d0)](){const _0x98b085=a0_0x5d395c;let _0x47bf8c=encodeURIComponent(this[_0x98b085(0x1b7)]),_0x52d331=this[_0x98b085(0x1d2)]+'/events/'+_0x47bf8c,_0x32c263=this['reconnectDelay'];while(this[_0x98b085(0x1af)]){try{this[_0x98b085(0x194)]=new AbortController();let _0xd60ecb={'Accept':_0x98b085(0x1bb)};if(this[_0x98b085(0x1c5)])_0xd60ecb['Authorization']=_0x98b085(0x19c)+this[_0x98b085(0x1c5)];let _0x1dc686=await fetch(_0x52d331,{'headers':_0xd60ecb,'signal':this['sseAbort'][_0x98b085(0x1d6)]});if(!_0x1dc686['ok']||!_0x1dc686[_0x98b085(0x1de)]){this[_0x98b085(0x16d)](_0x98b085(0x193)+_0x1dc686[_0x98b085(0x17d)]),await this['sleep'](_0x32c263),_0x32c263=Math[_0x98b085(0x1a7)](_0x32c263*1.5,0xea60);continue;}_0x32c263=this[_0x98b085(0x164)];let _0x5bcd85=_0x1dc686[_0x98b085(0x1de)][_0x98b085(0x182)](),_0x46969d=new TextDecoder(),_0x3ca111='';while(this[_0x98b085(0x1af)]){let {done:_0x5ce54d,value:_0xa65cee}=await _0x5bcd85[_0x98b085(0x1e2)]();if(_0x5ce54d)break;_0x3ca111+=_0x46969d[_0x98b085(0x1dd)](_0xa65cee,{'stream':!0x0});let _0x48a351=_0x3ca111['split']('\x0a');_0x3ca111=_0x48a351[_0x98b085(0x1e0)]()||'';for(let _0x27fb53 of _0x48a351){if(!_0x27fb53[_0x98b085(0x1a1)](_0x98b085(0x175)))continue;try{let _0x854c9e=JSON[_0x98b085(0x1a0)](_0x27fb53[_0x98b085(0x18f)](0x6));if(_0x854c9e[_0x98b085(0x1bf)]===_0x98b085(0x170)){this[_0x98b085(0x16d)](_0x98b085(0x180)),this[_0x98b085(0x1b5)](_0x98b085(0x170));continue;}if(_0x854c9e['type']===_0x98b085(0x1c8)||_0x854c9e[_0x98b085(0x1bf)]===_0x98b085(0x1be)||_0x854c9e[_0x98b085(0x1bf)]==='broadcast')await this[_0x98b085(0x1c0)]();}catch{}}}}catch(_0x3a1159){if(_0x3a1159[_0x98b085(0x1c7)]===_0x98b085(0x16f))break;this['emit']('error',_0x3a1159),this[_0x98b085(0x16d)](_0x98b085(0x16e)+_0x3a1159[_0x98b085(0x1b8)]);}if(this['running'])this['emit'](_0x98b085(0x191)),this['log'](_0x98b085(0x1c4)+_0x32c263/0x3e8+_0x98b085(0x189)),await this[_0x98b085(0x1d5)](_0x32c263),_0x32c263=Math['min'](_0x32c263*1.5,0xea60);}}async[a0_0x5d395c(0x1c0)](){const _0x5db871=a0_0x5d395c;try{let _0x5dc358=(await this[_0x5db871(0x177)]('get_inbox',{'alias':this['alias'],'limit':0xa}))?.['messages']||[];for(let _0x2f6677 of _0x5dc358)await this['call'](_0x5db871(0x18c),{'alias':this['alias'],'message_id':_0x2f6677['id']}),this[_0x5db871(0x16d)]('←\x20'+_0x2f6677[_0x5db871(0x197)]+':\x20'+_0x2f6677[_0x5db871(0x1b4)][_0x5db871(0x18f)](0x0,0x3c)),this[_0x5db871(0x1b5)]('task',_0x2f6677),this[_0x5db871(0x1b5)](_0x5db871(0x1b8),_0x2f6677);}catch(_0x23305c){this[_0x5db871(0x16d)]('inbox\x20error:\x20'+_0x23305c[_0x5db871(0x1b8)]);}}[a0_0x5d395c(0x1d5)](_0x1bcda6){return new Promise(_0x1e628f=>setTimeout(_0x1e628f,_0x1bcda6));}}var F=$;export{F as default,$ as CommHub};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * #512 — which model a codex co-presence start runs on, and why.
3
+ *
4
+ * Order: explicit `--model` flag > the node's own config (`model` in
5
+ * .anet/nodes/<id>/config.json, written by `anet node create --model` /
6
+ * `anet node edit --model`) > DEFAULT_CODEX_MODEL.
7
+ *
8
+ * The bug this replaces: the start path computed `opts.model || DEFAULT`
9
+ * where `opts.model` was ONLY the CLI flag, so every start that did not
10
+ * repeat `--model` — the plain `anet node start <name>`, the boot sweep, and
11
+ * `anet node codex start|restart|resume` (which re-invoke `node start`
12
+ * without `--model`) — silently put the node on the default.
13
+ *
14
+ * One resolved value feeds all three pieces (app-server `-c model=`, the
15
+ * thread/resume `model` override, TUI `-m`), so they cannot disagree.
16
+ */
17
+ export type CodexModelSource = "flag" | "node-config" | "default";
18
+ export interface ResolvedCodexModel {
19
+ model: string;
20
+ source: CodexModelSource;
21
+ }
22
+ export declare function resolveCodexCopresenceModel(flagModel: unknown, nodeConfigModel: unknown, fallback?: string): ResolvedCodexModel;
23
+ export declare function describeCodexModelSource(r: ResolvedCodexModel): string;
@@ -17,7 +17,22 @@ export declare function quiesceThenSnapshot<T>(quiesce: () => Promise<void>, sna
17
17
  * exact thread back with persisted history. This is deliberately stricter
18
18
  * than accepting a successful thread/resume RPC response. */
19
19
  export declare function verifyCodexThreadHistory(method: "thread/start" | "thread/resume", expectedThreadId: string, readResult: unknown, now?: Date): CodexRecoveryVerification;
20
- export declare function resumeAndVerifyCodexThread(threadId: string, request: (method: string, params: Record<string, unknown>) => Promise<unknown>): Promise<CodexRecoveryVerification>;
20
+ /**
21
+ * #512 — `model` is the node's resolved model. It MUST ride on thread/resume:
22
+ * measured on codex 0.155 (Docker), a resume without it puts the thread back on
23
+ * the model recorded in the rollout's last turn_context and ignores the
24
+ * app-server's `-c model=`. This launcher is the first client to load the
25
+ * thread, and once loaded, later resumes without a model (the bridge's) keep
26
+ * whatever the first one set — so this is the request that decides the model
27
+ * for every subsequent turn: the configured model wins over the thread's
28
+ * recorded one.
29
+ *
30
+ * Returns the model the app-server reports for the resumed thread (if any) so
31
+ * the caller can say which model the session is actually on.
32
+ */
33
+ export declare function resumeAndVerifyCodexThread(threadId: string, request: (method: string, params: Record<string, unknown>) => Promise<unknown>, model?: string): Promise<CodexRecoveryVerification & {
34
+ resumedModel?: string;
35
+ }>;
21
36
  /** Private, node-local recovery point. config-recovery.json is deliberately
22
37
  * redacted non-credential audit/recovery metadata, not an identity backup.
23
38
  * Identity recovery relies on leaving the original node config and CODEX_HOME
@@ -0,0 +1,74 @@
1
+ export type ProbeName = "proc" | "ss" | "lsof" | "netstat";
2
+ /** null = 这条探针在本机跑不了(没有 /proc、没装 ss …);数组 = 跑了,这些 PID 在监听。 */
3
+ export interface SocketProbeResult {
4
+ pids: number[];
5
+ /** 端口确实被监听、但属主 PID 读不到(别的用户的进程)。 */
6
+ unresolved?: number;
7
+ }
8
+ export interface HubPidRecord {
9
+ pid: number;
10
+ port: number;
11
+ launcher_pid?: number;
12
+ started_at?: string;
13
+ }
14
+ export interface HubStopProbes {
15
+ platform: NodeJS.Platform;
16
+ socket: Partial<Record<ProbeName, (port: number) => SocketProbeResult | null>>;
17
+ readPidFile: (port: number) => HubPidRecord | null;
18
+ cmdline: (pid: number) => string | null;
19
+ alive: (pid: number) => boolean;
20
+ }
21
+ export type CandidateVerdict = "commhub" | "not-commhub" | "cmdline-unreadable";
22
+ export interface Candidate {
23
+ pid: number;
24
+ source: ProbeName | "pidfile";
25
+ cmdline: string | null;
26
+ verdict: CandidateVerdict;
27
+ }
28
+ export interface HubListenerResolution {
29
+ port: number;
30
+ /** 每条探针的结果,按尝试顺序。 */
31
+ tried: {
32
+ probe: ProbeName | "pidfile";
33
+ outcome: string;
34
+ }[];
35
+ /** 给出端口归属的那条探针;null = 本机没有一条能跑。 */
36
+ authority: ProbeName | null;
37
+ /** 端口被监听但读不到属主 PID 的个数。 */
38
+ unresolved: number;
39
+ /** 核实过是 commhub-server 的 PID —— 只有这些会被停。 */
40
+ hubPids: Candidate[];
41
+ /** 端口上的其他进程 / cmdline 读不到的进程 —— 拒绝动手。 */
42
+ refused: Candidate[];
43
+ }
44
+ export declare function probeOrder(platform: NodeJS.Platform): ProbeName[];
45
+ /** cmdline 是不是 commhub-server。只做核实,不用来挑选进程。 */
46
+ export declare function isCommhubServerCmdline(cmdline: string | null | undefined): boolean;
47
+ /** /proc/net/tcp 或 tcp6 文本 → 在 port 上 LISTEN(st=0A)的 socket inode。 */
48
+ export declare function parseProcNetTcp(text: string, port: number): string[];
49
+ /** `ss -Hltnp 'sport = :PORT'` → pids;有行却没有 users:(…) 的算 unresolved。 */
50
+ export declare function parseSsOutput(text: string, port: number): SocketProbeResult;
51
+ /** Windows `netstat -ano`:`TCP 127.0.0.1:9200 0.0.0.0:0 LISTENING 1234`。 */
52
+ export declare function parseNetstatWindows(text: string, port: number): SocketProbeResult;
53
+ /** macOS `netstat -anv -p tcp`:按表头找 pid 列;本地地址形如 `127.0.0.1.9200` / `*.9200`。 */
54
+ export declare function parseNetstatDarwin(text: string, port: number): SocketProbeResult;
55
+ export declare function resolveHubListener(port: number, probes: HubStopProbes): HubListenerResolution;
56
+ export interface StopHubDeps {
57
+ probes: HubStopProbes;
58
+ kill: (pid: number, signal: "SIGTERM" | "SIGKILL") => void;
59
+ sleep: (ms: number) => Promise<void>;
60
+ /** /health 是否 ok —— 与探针无关的独立判据。 */
61
+ healthy: () => Promise<boolean>;
62
+ log: (line: string) => void;
63
+ error: (line: string) => void;
64
+ graceMs?: number;
65
+ }
66
+ export interface StopHubResult {
67
+ code: 0 | 1;
68
+ killed: number[];
69
+ refused: Candidate[];
70
+ }
71
+ export declare function stopHub(port: number, d: StopHubDeps): Promise<StopHubResult>;
72
+ export declare function procNetListeners(port: number, procRoot?: string): SocketProbeResult | null;
73
+ export declare function defaultHubStopProbes(readPidFile: (port: number) => HubPidRecord | null, platform?: NodeJS.Platform): HubStopProbes;
74
+ export declare function readCmdline(pid: number, platform?: NodeJS.Platform): string | null;