@sleep2agi/agent-network 2.3.0-preview.97 → 2.3.0-preview.99

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.
@@ -1 +1 @@
1
- const a0_0x1d2064=a0_0x1266;(function(_0x180b91,_0x148ca8){const _0x150974=a0_0x1266,_0x233117=_0x180b91();while(!![]){try{const _0x1c70c2=-parseInt(_0x150974(0x183))/0x1*(parseInt(_0x150974(0x154))/0x2)+parseInt(_0x150974(0x10b))/0x3+-parseInt(_0x150974(0x177))/0x4*(-parseInt(_0x150974(0x173))/0x5)+-parseInt(_0x150974(0x180))/0x6+parseInt(_0x150974(0x12c))/0x7*(-parseInt(_0x150974(0x185))/0x8)+parseInt(_0x150974(0x132))/0x9*(parseInt(_0x150974(0x15a))/0xa)+-parseInt(_0x150974(0x144))/0xb;if(_0x1c70c2===_0x148ca8)break;else _0x233117['push'](_0x233117['shift']());}catch(_0x3c2564){_0x233117['push'](_0x233117['shift']());}}}(a0_0x646a,0x52e5a));import{EventEmitter as a0_0xba609b}from'events';import{hostname as a0_0x39f3af}from'os';var K=/(?:atok|ntok|utok|ghp|github_pat)_[A-Za-z0-9_-]+|Bearer\s+\S+/gi,L=(_0x176564,_0x230396)=>(_0x176564??_0x230396)['replace'](/[\r\n\x00-\x1f\x7f]/g,'\x20')[a0_0x1d2064(0x15e)](0x0,0xf0);function N(_0xdcc1a6){const _0x29906a=a0_0x1d2064;return(_0xdcc1a6 instanceof Error?_0xdcc1a6[_0x29906a(0x12f)]:String(_0xdcc1a6??_0x29906a(0x178)))[_0x29906a(0x169)](K,_0x29906a(0x112))[_0x29906a(0x169)](/[\r\n\x00-\x1f\x7f]/g,'\x20')[_0x29906a(0x15e)](0x0,0xf0);}function O(_0x2841e2,_0x19f5a7=process.env.ANET_TASK_TRACE_FORMAT===a0_0x1d2064(0x12e)){const _0x3c368c=a0_0x1d2064;if(_0x19f5a7)return JSON[_0x3c368c(0x12b)](_0x2841e2);let _0xef2512=L(_0x2841e2[_0x3c368c(0x17e)],_0x3c368c(0x12a)),_0x27927d=L(_0x2841e2[_0x3c368c(0x15b)],_0x3c368c(0x17f)),_0x391ba7=_0x2841e2[_0x3c368c(0x125)]?_0x3c368c(0x118)+_0x2841e2[_0x3c368c(0x125)]+':'+(_0x2841e2['error_message']??''):'';return _0x3c368c(0x124)+_0x2841e2['status']+_0x3c368c(0x158)+L(_0x2841e2[_0x3c368c(0x162)],_0x3c368c(0x152))+_0x3c368c(0x14a)+L(_0x2841e2[_0x3c368c(0x13b)],'<unknown>')+_0x3c368c(0x13f)+_0x27927d+_0x3c368c(0x114)+_0xef2512+_0x3c368c(0x145)+L(_0x2841e2[_0x3c368c(0x150)],'<unknown>')+_0x3c368c(0x142)+_0x2841e2[_0x3c368c(0x168)]+_0x3c368c(0x16b)+_0x2841e2[_0x3c368c(0x11a)]+_0x3c368c(0x138)+_0x2841e2[_0x3c368c(0x113)]+_0x391ba7;}function U(_0x43e9dc){const _0x466699=a0_0x1d2064;return{'event':{'sending':'task.send.start','delivered':'task.send.delivered','failed':'task.send.failed','acked':_0x466699(0x136),'started':_0x466699(0x115),'replied':_0x466699(0x13d),'expired':'task.expired'}[_0x43e9dc['status']],..._0x43e9dc};}function a0_0x646a(){const _0x2859e0=['emit','[REDACTED]','lifecycle_tracking','\x20parent_task_id=','task.started','offline','running','\x20error=','send_rejected','duration_ms','send_failed','SSE\x20error:\x20','new_task','tools/call','min','processInbox','application/json','data:\x20','string','[commhub:task]\x20','error_code','s...','url','connectSSE','heartbeatInterval','<missing>','stringify','21ryKVsT','toString','json','message','/mcp','/events/','45RklLOC','send_task','decode','send_reply','task.ack','disconnect','\x20lifecycle=','text/event-stream','missing_task_id','to_alias','call','task.replied','networkId','\x20task_id=','delivered','registered','\x20transport=','sleep','1535644WxYkdZ','\x20network_id=','body','reconnectDelay','get_all_status','not_tracked','\x20to=','cwd','token','error','broadcast','getReader','network_id','connect','<unknown>','sdk','14JEtBep','autoConnect','signal','CommHub\x20response\x20omitted\x20task_id','\x20from=','type','1151180gmTGNX','task_id','SSE\x20connected','agent','slice','split','resumeId','result','from_alias','get_inbox','log','sdk-','failed','now','transport','replace','heartbeatTimer','\x20duration_ms=','parentTaskId','send','new_message','fromAlias','sending','text','POST','557365PTwSXB','content','abort','SSE\x20reconnecting\x20in\x20','4Qpowix','unknown\x20error','report_status','Authorization','status','getAllStatus','application/json,\x20text/event-stream','parent_task_id','<pending>','2686524OyplFV','parse','2.0','2258fDxLGW','sseAbort','697832gYgJUm','ack_inbox','idle','lifecycleTracking','match','read','toAlias','Bearer\x20','messages','completed','1552002NIDIIr','connected','send_message','alias','task','disconnected'];a0_0x646a=function(){return _0x2859e0;};return a0_0x646a();}function j(_0x5c2381){const _0x1f6646=a0_0x1d2064;let _0x4e1dbe=_0x5c2381?.['task_id']||_0x5c2381?.['message_id']||_0x5c2381?.['id'];if(_0x4e1dbe)return String(_0x4e1dbe);let _0x1a6e88=_0x5c2381?.[_0x1f6646(0x174)]?.[0x0]?.['text'];if(typeof _0x1a6e88!==_0x1f6646(0x123))return null;try{let _0x282af6=JSON[_0x1f6646(0x181)](_0x1a6e88);return _0x282af6?.[_0x1f6646(0x15b)]||_0x282af6?.['message_id']||_0x282af6?.['id']||null;}catch{return null;}}function a0_0x1266(_0x39a0c9,_0x5949ba){_0x39a0c9=_0x39a0c9-0x103;const _0x646acf=a0_0x646a();let _0x1266e4=_0x646acf[_0x39a0c9];return _0x1266e4;}async function X(_0x4b2073,_0x436f21){const _0x1dd640=a0_0x1d2064;let _0x32b876=_0x436f21[_0x1dd640(0x167)]??Date[_0x1dd640(0x167)],_0x26d543=_0x32b876(),_0x88c677=(_0x4afcd9,_0x3d7cf7,_0x8f99ac,_0x163e39)=>{const _0xd19f4c=_0x1dd640;_0x436f21['log'](O(U({'from_alias':_0x4b2073[_0xd19f4c(0x16f)],'to_alias':_0x4b2073[_0xd19f4c(0x107)],'task_id':_0x3d7cf7,'parent_task_id':_0x4b2073[_0xd19f4c(0x16c)],'network_id':_0x4b2073['networkId'],'transport':_0x4b2073[_0xd19f4c(0x168)],'status':_0x4afcd9,'duration_ms':_0x32b876()-_0x26d543,'lifecycle_tracking':_0x4b2073[_0xd19f4c(0x104)],..._0x8f99ac!==void 0x0?{'error_code':_0x163e39||'send_failed','error_message':N(_0x8f99ac)}:{}})));};_0x88c677(_0x1dd640(0x170),null);try{let _0x40745f=await _0x436f21[_0x1dd640(0x16d)](),_0x43d890=j(_0x40745f);if(_0x43d890)_0x88c677(_0x1dd640(0x140),_0x43d890);else{if(_0x40745f?.['ok']===!0x1||_0x40745f?.[_0x1dd640(0x14d)])_0x88c677(_0x1dd640(0x166),_0x43d890,_0x40745f?.[_0x1dd640(0x14d)]||'CommHub\x20rejected\x20task',_0x1dd640(0x119));else _0x88c677('failed',null,_0x1dd640(0x157),_0x1dd640(0x13a));}return _0x40745f;}catch(_0x45245a){throw _0x88c677(_0x1dd640(0x166),null,_0x45245a,_0x1dd640(0x11b)),_0x45245a;}}async function Y(_0x87284f,_0x427af5){const _0x345106=a0_0x1d2064;return X({'fromAlias':_0x87284f['fromAlias'],'toAlias':_0x87284f[_0x345106(0x10e)],'parentTaskId':_0x87284f[_0x345106(0x16c)]||null,'networkId':_0x87284f[_0x345106(0x13e)]||null,'transport':'mcp_http','lifecycleTracking':_0x345106(0x149)},_0x427af5);}class $ extends a0_0xba609b{['url'];[a0_0x1d2064(0x10e)];['token'];['agent'];[a0_0x1d2064(0x160)];[a0_0x1d2064(0x129)];[a0_0x1d2064(0x147)];[a0_0x1d2064(0x16a)];[a0_0x1d2064(0x184)];[a0_0x1d2064(0x117)]=!0x1;constructor(_0x3cbf34){const _0x4f27ac=a0_0x1d2064;super();if(this[_0x4f27ac(0x127)]=_0x3cbf34[_0x4f27ac(0x127)][_0x4f27ac(0x169)](/\/$/,''),this[_0x4f27ac(0x10e)]=_0x3cbf34[_0x4f27ac(0x10e)],this[_0x4f27ac(0x14c)]=_0x3cbf34[_0x4f27ac(0x14c)],this[_0x4f27ac(0x15d)]=_0x3cbf34[_0x4f27ac(0x15d)]||_0x4f27ac(0x153),this[_0x4f27ac(0x160)]=_0x4f27ac(0x165)+_0x3cbf34[_0x4f27ac(0x10e)]+'-'+Date[_0x4f27ac(0x167)]()[_0x4f27ac(0x12d)](0x24),this[_0x4f27ac(0x129)]=_0x3cbf34[_0x4f27ac(0x129)]??0x2bf20,this[_0x4f27ac(0x147)]=_0x3cbf34[_0x4f27ac(0x147)]??0xbb8,_0x3cbf34[_0x4f27ac(0x155)]!==!0x1)this[_0x4f27ac(0x151)]();}['log'](_0x4fd95b){const _0x1ccd77=a0_0x1d2064;console['log']('['+new Date()['toTimeString']()[_0x1ccd77(0x15e)](0x0,0x8)+']\x20[commhub:'+this['alias']+']\x20'+_0x4fd95b);}async['call'](_0x31d49a,_0x52b12a){const _0x42945e=a0_0x1d2064;let _0x5af303={'Content-Type':_0x42945e(0x121),'Accept':_0x42945e(0x17d)};if(this[_0x42945e(0x14c)])_0x5af303[_0x42945e(0x17a)]=_0x42945e(0x108)+this[_0x42945e(0x14c)];let _0x4c8213=await(await fetch(this[_0x42945e(0x127)]+_0x42945e(0x130),{'method':_0x42945e(0x172),'headers':_0x5af303,'body':JSON[_0x42945e(0x12b)]({'jsonrpc':_0x42945e(0x182),'id':Date[_0x42945e(0x167)](),'method':_0x42945e(0x11e),'params':{'name':_0x31d49a,'arguments':_0x52b12a}})}))[_0x42945e(0x171)](),_0x4a552d=_0x4c8213[_0x42945e(0x105)](/data: (.+)/),_0x19a50b=_0x4a552d?JSON[_0x42945e(0x181)](_0x4a552d[0x1]):JSON[_0x42945e(0x181)](_0x4c8213),_0xc06a07=_0x19a50b?.[_0x42945e(0x161)]?.[_0x42945e(0x174)]?.[0x0]?.[_0x42945e(0x171)];return _0xc06a07?JSON['parse'](_0xc06a07):_0x19a50b;}async['connect'](){const _0x12c255=a0_0x1d2064;if(this[_0x12c255(0x117)])return;this[_0x12c255(0x117)]=!0x0,await this[_0x12c255(0x17b)]('idle'),this[_0x12c255(0x164)](_0x12c255(0x141)),this[_0x12c255(0x16a)]=setInterval(()=>{const _0xdcd6a0=_0x12c255;this[_0xdcd6a0(0x17b)](_0xdcd6a0(0x103))['catch'](_0x1d1eab=>this['log']('heartbeat\x20failed:\x20'+_0x1d1eab['message']));},this[_0x12c255(0x129)]),this[_0x12c255(0x128)]();}async[a0_0x1d2064(0x137)](){const _0x49efa6=a0_0x1d2064;if(this[_0x49efa6(0x117)]=!0x1,this['sseAbort']?.[_0x49efa6(0x175)](),this[_0x49efa6(0x16a)])clearInterval(this['heartbeatTimer']);await this['status'](_0x49efa6(0x116))['catch'](()=>{}),this[_0x49efa6(0x164)](_0x49efa6(0x110));}async[a0_0x1d2064(0x16d)](_0x1539ac,_0x3f8c99,_0x161c2f='normal'){const _0x29883a=a0_0x1d2064;return Y({'alias':_0x1539ac,'fromAlias':this[_0x29883a(0x10e)]},{'log':_0x21a8e3=>console[_0x29883a(0x164)](_0x21a8e3),'send':()=>this[_0x29883a(0x13c)](_0x29883a(0x133),{'alias':_0x1539ac,'task':_0x3f8c99,'priority':_0x161c2f,'from_session':this['alias']})});}async[a0_0x1d2064(0x12f)](_0x55cf87,_0x51e982){const _0x59f179=a0_0x1d2064;return this[_0x59f179(0x13c)](_0x59f179(0x10d),{'alias':_0x55cf87,'message':_0x51e982,'from_session':this[_0x59f179(0x10e)]});}async['reply'](_0x3ce911,_0x537bf5,_0x2e802f=a0_0x1d2064(0x10a)){const _0x534ab8=a0_0x1d2064;return this[_0x534ab8(0x13c)](_0x534ab8(0x135),{'in_reply_to':_0x3ce911,'text':_0x537bf5,'status':_0x2e802f});}async['status'](_0x1abab2,_0x2ffc54){const _0x46f760=a0_0x1d2064;return this['call'](_0x46f760(0x179),{'resume_id':this['resumeId'],'alias':this[_0x46f760(0x10e)],'status':_0x1abab2,'server':a0_0x39f3af(),'hostname':a0_0x39f3af(),'agent':this['agent'],'project_dir':process[_0x46f760(0x14b)](),..._0x2ffc54});}async[a0_0x1d2064(0x17c)](){const _0x29922f=a0_0x1d2064;return this[_0x29922f(0x13c)](_0x29922f(0x148),{});}async[a0_0x1d2064(0x14e)](_0x2b8f6f,_0x151049){const _0x47f4d0=a0_0x1d2064;return this[_0x47f4d0(0x13c)](_0x47f4d0(0x14e),{'message':_0x2b8f6f,'filter_server':_0x151049?.['server'],'filter_status':_0x151049?.['status']});}async[a0_0x1d2064(0x128)](){const _0x538b00=a0_0x1d2064;let _0x1c2e2e=encodeURIComponent(this['alias']),_0x11dc47=this[_0x538b00(0x127)]+_0x538b00(0x131)+_0x1c2e2e,_0x526054=this['reconnectDelay'];while(this[_0x538b00(0x117)]){try{this['sseAbort']=new AbortController();let _0x2af4d4={'Accept':_0x538b00(0x139)};if(this[_0x538b00(0x14c)])_0x2af4d4[_0x538b00(0x17a)]=_0x538b00(0x108)+this[_0x538b00(0x14c)];let _0x3f987a=await fetch(_0x11dc47,{'headers':_0x2af4d4,'signal':this[_0x538b00(0x184)][_0x538b00(0x156)]});if(!_0x3f987a['ok']||!_0x3f987a['body']){this[_0x538b00(0x164)]('SSE\x20failed:\x20'+_0x3f987a[_0x538b00(0x17b)]),await this[_0x538b00(0x143)](_0x526054),_0x526054=Math[_0x538b00(0x11f)](_0x526054*1.5,0xea60);continue;}_0x526054=this[_0x538b00(0x147)];let _0x241b24=_0x3f987a[_0x538b00(0x146)][_0x538b00(0x14f)](),_0x4f3eff=new TextDecoder(),_0x3cea8e='';while(this['running']){let {done:_0x34fb27,value:_0x7d2147}=await _0x241b24[_0x538b00(0x106)]();if(_0x34fb27)break;_0x3cea8e+=_0x4f3eff[_0x538b00(0x134)](_0x7d2147,{'stream':!0x0});let _0x16ab31=_0x3cea8e[_0x538b00(0x15f)]('\x0a');_0x3cea8e=_0x16ab31['pop']()||'';for(let _0x4d5a85 of _0x16ab31){if(!_0x4d5a85['startsWith'](_0x538b00(0x122)))continue;try{let _0x22cd71=JSON[_0x538b00(0x181)](_0x4d5a85[_0x538b00(0x15e)](0x6));if(_0x22cd71[_0x538b00(0x159)]===_0x538b00(0x10c)){this[_0x538b00(0x164)](_0x538b00(0x15c)),this[_0x538b00(0x111)](_0x538b00(0x10c));continue;}if(_0x22cd71[_0x538b00(0x159)]===_0x538b00(0x11d)||_0x22cd71[_0x538b00(0x159)]===_0x538b00(0x16e)||_0x22cd71[_0x538b00(0x159)]===_0x538b00(0x14e))await this[_0x538b00(0x120)]();}catch{}}}}catch(_0xaab24b){if(_0xaab24b['name']==='AbortError')break;this['emit']('error',_0xaab24b),this[_0x538b00(0x164)](_0x538b00(0x11c)+_0xaab24b['message']);}if(this[_0x538b00(0x117)])this[_0x538b00(0x111)](_0x538b00(0x110)),this[_0x538b00(0x164)](_0x538b00(0x176)+_0x526054/0x3e8+_0x538b00(0x126)),await this[_0x538b00(0x143)](_0x526054),_0x526054=Math[_0x538b00(0x11f)](_0x526054*1.5,0xea60);}}async[a0_0x1d2064(0x120)](){const _0x24b28e=a0_0x1d2064;try{let _0x493349=(await this[_0x24b28e(0x13c)](_0x24b28e(0x163),{'alias':this[_0x24b28e(0x10e)],'limit':0xa}))?.[_0x24b28e(0x109)]||[];for(let _0xce7b95 of _0x493349)await this[_0x24b28e(0x13c)](_0x24b28e(0x186),{'alias':this[_0x24b28e(0x10e)],'message_id':_0xce7b95['id']}),this[_0x24b28e(0x164)]('←\x20'+_0xce7b95['from_session']+':\x20'+_0xce7b95[_0x24b28e(0x174)][_0x24b28e(0x15e)](0x0,0x3c)),this[_0x24b28e(0x111)](_0x24b28e(0x10f),_0xce7b95),this[_0x24b28e(0x111)]('message',_0xce7b95);}catch(_0x57c5aa){this[_0x24b28e(0x164)]('inbox\x20error:\x20'+_0x57c5aa[_0x24b28e(0x12f)]);}}['sleep'](_0xf639b4){return new Promise(_0x2c98a7=>setTimeout(_0x2c98a7,_0xf639b4));}}var F=$;export{F as default,$ as CommHub};
1
+ const a0_0x5854f1=a0_0x1b4b;(function(_0x53c16b,_0x3a5df4){const _0x533106=a0_0x1b4b,_0x345704=_0x53c16b();while(!![]){try{const _0x4b26d3=-parseInt(_0x533106(0x1b5))/0x1*(-parseInt(_0x533106(0x1a4))/0x2)+parseInt(_0x533106(0x14e))/0x3+parseInt(_0x533106(0x198))/0x4+-parseInt(_0x533106(0x18d))/0x5+-parseInt(_0x533106(0x15a))/0x6*(-parseInt(_0x533106(0x171))/0x7)+parseInt(_0x533106(0x14f))/0x8*(parseInt(_0x533106(0x14b))/0x9)+parseInt(_0x533106(0x19a))/0xa*(-parseInt(_0x533106(0x1a3))/0xb);if(_0x4b26d3===_0x3a5df4)break;else _0x345704['push'](_0x345704['shift']());}catch(_0x1876a3){_0x345704['push'](_0x345704['shift']());}}}(a0_0x4618,0xe8e9c));import{EventEmitter as a0_0x468ae6}from'events';import{hostname as a0_0x3b9f9e}from'os';function a0_0x1b4b(_0x55aedb,_0x301d5c){_0x55aedb=_0x55aedb-0x13e;const _0x461872=a0_0x4618();let _0x1b4b0b=_0x461872[_0x55aedb];return _0x1b4b0b;}var K=/(?:atok|ntok|utok|ghp|github_pat)_[A-Za-z0-9_-]+|Bearer\s+\S+/gi,L=(_0x46efde,_0x25faf2)=>(_0x46efde??_0x25faf2)[a0_0x5854f1(0x18a)](/[\r\n\x00-\x1f\x7f]/g,'\x20')['slice'](0x0,0xf0);function N(_0x1f2cee){const _0x3b920e=a0_0x5854f1;return(_0x1f2cee instanceof Error?_0x1f2cee[_0x3b920e(0x185)]:String(_0x1f2cee??_0x3b920e(0x18b)))['replace'](K,_0x3b920e(0x1ab))[_0x3b920e(0x18a)](/[\r\n\x00-\x1f\x7f]/g,'\x20')[_0x3b920e(0x176)](0x0,0xf0);}function O(_0x214625,_0x5c52a5=process.env.ANET_TASK_TRACE_FORMAT===a0_0x5854f1(0x14c)){const _0x59e3c0=a0_0x5854f1;if(_0x5c52a5)return JSON[_0x59e3c0(0x151)](_0x214625);let _0x322e33=L(_0x214625[_0x59e3c0(0x153)],_0x59e3c0(0x182)),_0x282b22=L(_0x214625['task_id'],_0x59e3c0(0x19e)),_0x3834df=_0x214625[_0x59e3c0(0x17d)]?_0x59e3c0(0x187)+_0x214625[_0x59e3c0(0x17d)]+':'+(_0x214625[_0x59e3c0(0x17a)]??''):'';return _0x59e3c0(0x186)+_0x214625[_0x59e3c0(0x1a2)]+_0x59e3c0(0x1ae)+L(_0x214625[_0x59e3c0(0x168)],_0x59e3c0(0x1b2))+'\x20to='+L(_0x214625[_0x59e3c0(0x147)],_0x59e3c0(0x1b2))+_0x59e3c0(0x164)+_0x282b22+_0x59e3c0(0x19b)+_0x322e33+'\x20network_id='+L(_0x214625[_0x59e3c0(0x19f)],_0x59e3c0(0x1b2))+'\x20transport='+_0x214625[_0x59e3c0(0x179)]+_0x59e3c0(0x158)+_0x214625[_0x59e3c0(0x1ad)]+_0x59e3c0(0x18e)+_0x214625[_0x59e3c0(0x155)]+_0x3834df;}function U(_0x50d7c0){const _0x5077bc=a0_0x5854f1;return{'event':{'sending':_0x5077bc(0x167),'delivered':_0x5077bc(0x1a0),'failed':_0x5077bc(0x145),'acked':'task.ack','started':_0x5077bc(0x165),'replied':_0x5077bc(0x189),'expired':_0x5077bc(0x1ba)}[_0x50d7c0[_0x5077bc(0x1a2)]],..._0x50d7c0};}function j(_0x99ff25){const _0x302cd1=a0_0x5854f1;let _0x30ac17=_0x99ff25?.[_0x302cd1(0x159)]||_0x99ff25?.[_0x302cd1(0x15b)]||_0x99ff25?.['id'];if(_0x30ac17)return String(_0x30ac17);let _0x10eb42=_0x99ff25?.[_0x302cd1(0x166)]?.[0x0]?.['text'];if(typeof _0x10eb42!==_0x302cd1(0x1a8))return null;try{let _0x394be3=JSON[_0x302cd1(0x152)](_0x10eb42);return _0x394be3?.['task_id']||_0x394be3?.[_0x302cd1(0x15b)]||_0x394be3?.['id']||null;}catch{return null;}}async function X(_0x4a440a,_0x315d56){const _0x3e8747=a0_0x5854f1;let _0x1ef1fd=_0x315d56[_0x3e8747(0x1bf)]??Date['now'],_0x72bcb8=_0x1ef1fd(),_0x2d2b3c=(_0x2a2f87,_0x1a764f,_0x230c05,_0x4c4f78)=>{const _0x4c83de=_0x3e8747;_0x315d56[_0x4c83de(0x15c)](O(U({'from_alias':_0x4a440a[_0x4c83de(0x15d)],'to_alias':_0x4a440a[_0x4c83de(0x1a1)],'task_id':_0x1a764f,'parent_task_id':_0x4a440a[_0x4c83de(0x146)],'network_id':_0x4a440a[_0x4c83de(0x1a7)],'transport':_0x4a440a['transport'],'status':_0x2a2f87,'duration_ms':_0x1ef1fd()-_0x72bcb8,'lifecycle_tracking':_0x4a440a[_0x4c83de(0x13f)],..._0x230c05!==void 0x0?{'error_code':_0x4c4f78||_0x4c83de(0x142),'error_message':N(_0x230c05)}:{}})));};_0x2d2b3c(_0x3e8747(0x16c),null);try{let _0x30a9df=await _0x315d56['send'](),_0xe7acd8=j(_0x30a9df);if(_0xe7acd8)_0x2d2b3c(_0x3e8747(0x15f),_0xe7acd8);else{if(_0x30a9df?.['ok']===!0x1||_0x30a9df?.[_0x3e8747(0x141)])_0x2d2b3c(_0x3e8747(0x17f),_0xe7acd8,_0x30a9df?.[_0x3e8747(0x141)]||_0x3e8747(0x13e),'send_rejected');else _0x2d2b3c('failed',null,_0x3e8747(0x150),_0x3e8747(0x173));}return _0x30a9df;}catch(_0x4423b9){throw _0x2d2b3c(_0x3e8747(0x17f),null,_0x4423b9,'send_failed'),_0x4423b9;}}async function Y(_0x372538,_0x4d7a6b){const _0x3b3c3a=a0_0x5854f1;return X({'fromAlias':_0x372538[_0x3b3c3a(0x15d)],'toAlias':_0x372538[_0x3b3c3a(0x16e)],'parentTaskId':_0x372538['parentTaskId']||null,'networkId':_0x372538['networkId']||null,'transport':_0x3b3c3a(0x1b4),'lifecycleTracking':'not_tracked'},_0x4d7a6b);}class $ extends a0_0x468ae6{['url'];[a0_0x5854f1(0x16e)];[a0_0x5854f1(0x184)];[a0_0x5854f1(0x149)];[a0_0x5854f1(0x1aa)];['heartbeatInterval'];['reconnectDelay'];['heartbeatTimer'];[a0_0x5854f1(0x18f)];[a0_0x5854f1(0x143)]=!0x1;constructor(_0x5a2987){const _0x44a414=a0_0x5854f1;super();if(this[_0x44a414(0x1bb)]=_0x5a2987[_0x44a414(0x1bb)][_0x44a414(0x18a)](/\/$/,''),this[_0x44a414(0x16e)]=_0x5a2987[_0x44a414(0x16e)],this[_0x44a414(0x184)]=_0x5a2987[_0x44a414(0x184)],this[_0x44a414(0x149)]=_0x5a2987[_0x44a414(0x149)]||_0x44a414(0x19c),this[_0x44a414(0x1aa)]=_0x44a414(0x199)+_0x5a2987[_0x44a414(0x16e)]+'-'+Date[_0x44a414(0x1bf)]()[_0x44a414(0x193)](0x24),this[_0x44a414(0x1bc)]=_0x5a2987[_0x44a414(0x1bc)]??0x2bf20,this[_0x44a414(0x154)]=_0x5a2987[_0x44a414(0x154)]??0xbb8,_0x5a2987[_0x44a414(0x181)]!==!0x1)this['connect']();}[a0_0x5854f1(0x15c)](_0x5ed4c2){const _0x17ecde=a0_0x5854f1;console[_0x17ecde(0x15c)]('['+new Date()[_0x17ecde(0x1ac)]()[_0x17ecde(0x176)](0x0,0x8)+']\x20[commhub:'+this[_0x17ecde(0x16e)]+']\x20'+_0x5ed4c2);}async[a0_0x5854f1(0x1b7)](_0x5eb968,_0x10a88e){const _0x5267cc=a0_0x5854f1;let _0x4b2bce={'Content-Type':_0x5267cc(0x1c1),'Accept':'application/json,\x20text/event-stream'};if(this['token'])_0x4b2bce['Authorization']=_0x5267cc(0x16f)+this[_0x5267cc(0x184)];let _0x27556f=await(await fetch(this[_0x5267cc(0x1bb)]+_0x5267cc(0x195),{'method':_0x5267cc(0x1a9),'headers':_0x4b2bce,'body':JSON['stringify']({'jsonrpc':'2.0','id':Date[_0x5267cc(0x1bf)](),'method':_0x5267cc(0x194),'params':{'name':_0x5eb968,'arguments':_0x10a88e}})}))[_0x5267cc(0x14a)](),_0x4f9627=_0x27556f['match'](/data: (.+)/),_0x55d1fb=_0x4f9627?JSON[_0x5267cc(0x152)](_0x4f9627[0x1]):JSON['parse'](_0x27556f),_0x32963a=_0x55d1fb?.['result']?.['content']?.[0x0]?.[_0x5267cc(0x14a)];return _0x32963a?JSON[_0x5267cc(0x152)](_0x32963a):_0x55d1fb;}async[a0_0x5854f1(0x156)](){const _0x2d74d1=a0_0x5854f1;if(this['running'])return;this['running']=!0x0,await this[_0x2d74d1(0x1a2)](_0x2d74d1(0x1b3)),this[_0x2d74d1(0x15c)]('registered'),this[_0x2d74d1(0x148)]=setInterval(()=>{const _0x500123=_0x2d74d1;this[_0x500123(0x1a2)]('idle')[_0x500123(0x140)](_0x3eece5=>this[_0x500123(0x15c)]('heartbeat\x20failed:\x20'+_0x3eece5['message']));},this[_0x2d74d1(0x1bc)]),this[_0x2d74d1(0x1b1)]();}async['disconnect'](){const _0x3ab2ef=a0_0x5854f1;if(this['running']=!0x1,this[_0x3ab2ef(0x18f)]?.[_0x3ab2ef(0x191)](),this['heartbeatTimer'])clearInterval(this[_0x3ab2ef(0x148)]);await this['status']('offline')[_0x3ab2ef(0x140)](()=>{}),this['log'](_0x3ab2ef(0x1b6));}async[a0_0x5854f1(0x175)](_0x2f8ed1,_0x11a82e,_0x5440d4=a0_0x5854f1(0x19d)){const _0x42ba03=a0_0x5854f1;return Y({'alias':_0x2f8ed1,'fromAlias':this['alias']},{'log':_0x46e857=>console[_0x42ba03(0x15c)](_0x46e857),'send':()=>this['call'](_0x42ba03(0x16d),{'alias':_0x2f8ed1,'task':_0x11a82e,'priority':_0x5440d4,'from_session':this[_0x42ba03(0x16e)]})});}async[a0_0x5854f1(0x185)](_0x20f8c9,_0x1add28){const _0x26e86c=a0_0x5854f1;return this[_0x26e86c(0x1b7)](_0x26e86c(0x14d),{'alias':_0x20f8c9,'message':_0x1add28,'from_session':this[_0x26e86c(0x16e)]});}async[a0_0x5854f1(0x190)](_0x4eda71,_0x20468a,_0xde8a06='completed'){const _0x19e966=a0_0x5854f1;return this[_0x19e966(0x1b7)]('send_reply',{'in_reply_to':_0x4eda71,'text':_0x20468a,'status':_0xde8a06});}async[a0_0x5854f1(0x1a2)](_0x8e74b,_0x5985c0){const _0x1379ac=a0_0x5854f1;return this[_0x1379ac(0x1b7)](_0x1379ac(0x15e),{'resume_id':this[_0x1379ac(0x1aa)],'alias':this['alias'],'status':_0x8e74b,'server':a0_0x3b9f9e(),'hostname':a0_0x3b9f9e(),'agent':this[_0x1379ac(0x149)],'project_dir':process[_0x1379ac(0x174)](),..._0x5985c0});}async['getAllStatus'](){const _0x287c77=a0_0x5854f1;return this[_0x287c77(0x1b7)](_0x287c77(0x1a5),{});}async['broadcast'](_0x2d9cdf,_0x187e5f){const _0x2c1a7f=a0_0x5854f1;return this[_0x2c1a7f(0x1b7)](_0x2c1a7f(0x16a),{'message':_0x2d9cdf,'filter_server':_0x187e5f?.[_0x2c1a7f(0x1c0)],'filter_status':_0x187e5f?.['status']});}async[a0_0x5854f1(0x1b1)](){const _0xd1ab75=a0_0x5854f1;let _0x3d5a15=encodeURIComponent(this[_0xd1ab75(0x16e)]),_0x5f6b5c=this[_0xd1ab75(0x1bb)]+'/events/'+_0x3d5a15,_0x474cb9=this[_0xd1ab75(0x154)];while(this['running']){try{this[_0xd1ab75(0x18f)]=new AbortController();let _0x438690={'Accept':_0xd1ab75(0x1b8)};if(this[_0xd1ab75(0x184)])_0x438690[_0xd1ab75(0x177)]=_0xd1ab75(0x16f)+this[_0xd1ab75(0x184)];let _0x37fa17=await fetch(_0x5f6b5c,{'headers':_0x438690,'signal':this[_0xd1ab75(0x18f)][_0xd1ab75(0x16b)]});if(!_0x37fa17['ok']||!_0x37fa17[_0xd1ab75(0x1be)]){this[_0xd1ab75(0x15c)]('SSE\x20failed:\x20'+_0x37fa17[_0xd1ab75(0x1a2)]),await this[_0xd1ab75(0x197)](_0x474cb9),_0x474cb9=Math[_0xd1ab75(0x180)](_0x474cb9*1.5,0xea60);continue;}_0x474cb9=this[_0xd1ab75(0x154)];let _0x33ecce=_0x37fa17['body'][_0xd1ab75(0x1b0)](),_0x3bd71e=new TextDecoder(),_0x432334='';while(this[_0xd1ab75(0x143)]){let {done:_0x41fcf7,value:_0x31c674}=await _0x33ecce[_0xd1ab75(0x17e)]();if(_0x41fcf7)break;_0x432334+=_0x3bd71e[_0xd1ab75(0x157)](_0x31c674,{'stream':!0x0});let _0x334d3f=_0x432334[_0xd1ab75(0x172)]('\x0a');_0x432334=_0x334d3f['pop']()||'';for(let _0x3b8fff of _0x334d3f){if(!_0x3b8fff[_0xd1ab75(0x162)](_0xd1ab75(0x1af)))continue;try{let _0x4bfade=JSON[_0xd1ab75(0x152)](_0x3b8fff[_0xd1ab75(0x176)](0x6));if(_0x4bfade[_0xd1ab75(0x1bd)]===_0xd1ab75(0x196)){this[_0xd1ab75(0x15c)](_0xd1ab75(0x178)),this[_0xd1ab75(0x192)](_0xd1ab75(0x196));continue;}if(_0x4bfade[_0xd1ab75(0x1bd)]===_0xd1ab75(0x1a6)||_0x4bfade[_0xd1ab75(0x1bd)]===_0xd1ab75(0x163)||_0x4bfade[_0xd1ab75(0x1bd)]==='broadcast')await this[_0xd1ab75(0x17b)]();}catch{}}}}catch(_0x317143){if(_0x317143[_0xd1ab75(0x183)]===_0xd1ab75(0x1b9))break;this[_0xd1ab75(0x192)](_0xd1ab75(0x141),_0x317143),this[_0xd1ab75(0x15c)](_0xd1ab75(0x144)+_0x317143['message']);}if(this[_0xd1ab75(0x143)])this[_0xd1ab75(0x192)](_0xd1ab75(0x1b6)),this['log'](_0xd1ab75(0x161)+_0x474cb9/0x3e8+_0xd1ab75(0x170)),await this[_0xd1ab75(0x197)](_0x474cb9),_0x474cb9=Math[_0xd1ab75(0x180)](_0x474cb9*1.5,0xea60);}}async[a0_0x5854f1(0x17b)](){const _0x1f59ab=a0_0x5854f1;try{let _0x3ba8f4=(await this['call'](_0x1f59ab(0x18c),{'alias':this[_0x1f59ab(0x16e)],'limit':0xa}))?.[_0x1f59ab(0x17c)]||[];for(let _0x194787 of _0x3ba8f4)await this[_0x1f59ab(0x1b7)](_0x1f59ab(0x169),{'alias':this[_0x1f59ab(0x16e)],'message_id':_0x194787['id']}),this[_0x1f59ab(0x15c)]('←\x20'+_0x194787['from_session']+':\x20'+_0x194787[_0x1f59ab(0x166)][_0x1f59ab(0x176)](0x0,0x3c)),this[_0x1f59ab(0x192)](_0x1f59ab(0x160),_0x194787),this[_0x1f59ab(0x192)](_0x1f59ab(0x185),_0x194787);}catch(_0x3cff12){this[_0x1f59ab(0x15c)](_0x1f59ab(0x188)+_0x3cff12[_0x1f59ab(0x185)]);}}[a0_0x5854f1(0x197)](_0x287f8a){return new Promise(_0x84a403=>setTimeout(_0x84a403,_0x287f8a));}}var F=$;function a0_0x4618(){const _0x3cb583=['stringify','parse','parent_task_id','reconnectDelay','lifecycle_tracking','connect','decode','\x20duration_ms=','task_id','12cWffOg','message_id','log','fromAlias','report_status','delivered','task','SSE\x20reconnecting\x20in\x20','startsWith','new_message','\x20task_id=','task.started','content','task.send.start','from_alias','ack_inbox','broadcast','signal','sending','send_task','alias','Bearer\x20','s...','1819202buQwnx','split','missing_task_id','cwd','send','slice','Authorization','SSE\x20connected','transport','error_message','processInbox','messages','error_code','read','failed','min','autoConnect','<missing>','name','token','message','[commhub:task]\x20','\x20error=','inbox\x20error:\x20','task.replied','replace','unknown\x20error','get_inbox','499720jnFyVD','\x20lifecycle=','sseAbort','reply','abort','emit','toString','tools/call','/mcp','connected','sleep','3626784RcQdUm','sdk-','11000szmRhm','\x20parent_task_id=','sdk','normal','<pending>','network_id','task.send.delivered','toAlias','status','32054BKqXCn','4TKTFci','get_all_status','new_task','networkId','string','POST','resumeId','[REDACTED]','toTimeString','duration_ms','\x20from=','data:\x20','getReader','connectSSE','<unknown>','idle','mcp_http','842799cfvlqV','disconnected','call','text/event-stream','AbortError','task.expired','url','heartbeatInterval','type','body','now','server','application/json','CommHub\x20rejected\x20task','lifecycleTracking','catch','error','send_failed','running','SSE\x20error:\x20','task.send.failed','parentTaskId','to_alias','heartbeatTimer','agent','text','9617409pZxWaG','json','send_message','236067OyNHuI','8MeYMvG','CommHub\x20response\x20omitted\x20task_id'];a0_0x4618=function(){return _0x3cb583;};return a0_0x4618();}export{F as default,$ as CommHub};
@@ -1,15 +1,67 @@
1
1
  /** Per-node record, written into the node dir next to the other state files. */
2
2
  export declare const CODEX_AUTH_FINGERPRINT_FILE = ".codex-auth-fingerprint.json";
3
+ /**
4
+ * Host-wide index of the same records — the read side's source of truth.
5
+ *
6
+ * Under `~/.anet/` because that is already this repo's host-scoped state
7
+ * directory (global config lives there) and it does not move with `cwd`, which
8
+ * is the entire point: the nodes that need to see each other are in different
9
+ * workspaces.
10
+ */
11
+ export declare function codexFingerprintIndexDir(home?: string): string;
12
+ /**
13
+ * Index filename for a node.
14
+ *
15
+ * 🔴 Derived from the node's DIRECTORY, never its alias. Aliases are not unique
16
+ * across workspaces — the reference fleet runs `TMA门户鲸2号` beside
17
+ * `TMA门户鲸`, and nothing stops two workspaces from using one name — so an
18
+ * alias-keyed file would let one node silently overwrite another's record,
19
+ * re-creating the very blindness this index fixes. A directory cannot be two
20
+ * nodes.
21
+ *
22
+ * 🔴 And derived from the directory rather than from `node_id`, even though the
23
+ * CLI has one handy: agent-node's `NODE_ID` can be empty (older configs), so
24
+ * a node_id key would need a fallback — and then the same node would write
25
+ * one filename from one launch path and a different one from the other,
26
+ * leaving two records that look like two nodes sharing a credential. One
27
+ * deterministic key from an input both call sites already have is worth more
28
+ * than a prettier name. `node_id` is still recorded, for humans.
29
+ */
30
+ export declare function codexFingerprintIndexFile(nodeDir: string): string;
3
31
  /** Length of the stored fingerprint. Collisions at 8 hex are ~1 in 4 billion;
4
32
  * a false "these two share a login" warning costs a second look, while the
5
33
  * value staying short keeps it obviously non-reversible in logs. */
6
34
  export declare const FINGERPRINT_LENGTH = 8;
35
+ /** Access tokens measured on the reference fleet: `exp - iat` was exactly this,
36
+ * on 29 of 29 samples, with no jitter. Used only to phrase "how long until the
37
+ * shared copy dies" when we have an `exp` but no `iat`. */
38
+ export declare const ACCESS_TOKEN_LIFETIME_SECONDS = 864000;
39
+ /** Past this, a published record's age is shown beside the alias. It does not
40
+ * suppress the warning: a node that has not started in a week still holds the
41
+ * shared credential. See the liveness note on `checkCodexCredentialSharing`. */
42
+ export declare const STALE_RECORD_NOTICE_MS: number;
7
43
  export interface CodexAuthFingerprintRecord {
8
- readonly schema_version: 1;
44
+ readonly schema_version: 1 | 2 | 3;
9
45
  readonly alias: string;
10
46
  /** sha256(refresh_token) truncated — never the token. */
11
47
  readonly fingerprint: string;
12
48
  readonly written_at: string;
49
+ /** v2: when this copy's ACCESS token expires, ISO-8601, or null if unreadable.
50
+ * A timestamp, not a credential. Two nodes holding one copied file share this
51
+ * instant exactly — which is how "they stop together" becomes observable. */
52
+ readonly access_expires_at?: string | null;
53
+ /** v2: the CODEX_HOME this record was read from. Distinguishes "two copies of
54
+ * one credential" from "two nodes pointed at one directory", which need
55
+ * different fixes. */
56
+ readonly codex_home?: string | null;
57
+ /** v3: the node directory this record describes, canonical. Three jobs: it is
58
+ * the identity used to de-duplicate the index against the sibling scan and to
59
+ * exclude self; and it is the liveness test — if this directory is gone, the
60
+ * node is gone and the record must not accuse anyone. */
61
+ readonly node_dir?: string;
62
+ /** v3: recorded for humans reading the index by hand. Never the key: it can be
63
+ * absent, and a key that is sometimes absent produces two records per node. */
64
+ readonly node_id?: string | null;
13
65
  }
14
66
  /**
15
67
  * Hash the refresh token out of an auth.json body.
@@ -22,19 +74,39 @@ export interface CodexAuthFingerprintRecord {
22
74
  * collision".
23
75
  */
24
76
  export declare function fingerprintRefreshToken(authJsonText: string): string | null;
77
+ /**
78
+ * When this copy's access token expires, read out of the JWT's own payload.
79
+ *
80
+ * The signature is NOT verified and nothing here authenticates: we are reading
81
+ * a timestamp the token states about itself, the same way `jwt.io` would. A
82
+ * token that is not a JWT, or carries no numeric `exp`, yields null — unknown
83
+ * stays unknown.
84
+ */
85
+ export declare function accessTokenExpiry(authJsonText: string): Date | null;
25
86
  export interface NodeFingerprint {
26
87
  readonly alias: string;
27
88
  /** null when the node has no auth.json, or one we could not read. */
28
89
  readonly fingerprint: string | null;
29
90
  /** When the record was written; used to say how stale a claim is. */
30
91
  readonly writtenAt?: string | null;
92
+ /** When this copy's access token expires, if we could read it. */
93
+ readonly accessExpiresAt?: Date | null;
94
+ /** The CODEX_HOME this fingerprint came from, if known. */
95
+ readonly codexHome?: string | null;
96
+ /** Canonical node directory — identity for de-duplication and self-exclusion. */
97
+ readonly nodeDir?: string | null;
31
98
  }
32
99
  /**
33
100
  * Other nodes holding the same credential chain as `self`.
34
101
  *
35
102
  * Records with no fingerprint are skipped rather than grouped: "unknown" is
36
- * not a match. Self is excluded by alias, so re-reading one's own record is
37
- * harmless.
103
+ * not a match.
104
+ *
105
+ * 🔴 Self is excluded by node DIRECTORY when both sides carry one, and only
106
+ * falls back to alias for pre-v3 records. Once the read side is host-wide,
107
+ * alias stops being an identity: two workspaces may each hold a node called
108
+ * the same thing, and excluding by name would hide a genuine collision
109
+ * between them — the exact failure this index was added to fix.
38
110
  */
39
111
  export declare function collidingNodes(records: readonly NodeFingerprint[], self: NodeFingerprint): NodeFingerprint[];
40
112
  /**
@@ -45,8 +117,25 @@ export declare function collidingNodes(records: readonly NodeFingerprint[], self
45
117
  * Deliberately a warning and never a refusal: every node on a host shares one
46
118
  * login today, so refusing to start would take the whole box down at once
47
119
  * over a condition that is survivable until the next refresh.
120
+ *
121
+ * 🔴 Two outcomes, and the wrong one is actively misleading. The default text
122
+ * ("whichever node refreshes first keeps working") assumes refresh WORKS.
123
+ * On a host that cannot reach the OAuth token endpoint — egress blocked, or
124
+ * a proxy that allowlists the model API and 403s everything else — nobody
125
+ * refreshes, and the nodes holding one copy do not degrade one at a time:
126
+ * they stop together the moment the shared access token expires. Field case:
127
+ * three nodes whose auth.json files were byte-identical, carrying one access
128
+ * token, all expired at the same instant.
129
+ *
130
+ * We do NOT probe the network to tell these apart — a start path is the wrong
131
+ * place to open a socket, and a probe would answer for this moment rather
132
+ * than for the window that matters. We branch on evidence already in the
133
+ * file: an access token whose `exp` has passed is a copy that demonstrably
134
+ * stopped being refreshed, which is the observable the field case exhibits.
135
+ * When `exp` is still in the future we cannot prove reachability either way,
136
+ * and the default wording is the right one to print.
48
137
  */
49
- export declare function sharedCredentialWarningLines(self: NodeFingerprint, colliding: readonly NodeFingerprint[]): string[];
138
+ export declare function sharedCredentialWarningLines(self: NodeFingerprint, colliding: readonly NodeFingerprint[], now?: Date): string[];
50
139
  /**
51
140
  * Two different things both read as "codex cannot refresh", and they need
52
141
  * opposite remedies. Telling them apart is the whole value of this mapping:
@@ -73,3 +162,50 @@ export interface CodexRefreshFailure {
73
162
  * transport failure means no answer arrived at all.
74
163
  */
75
164
  export declare function describeCodexRefreshFailure(text: string, colliding?: readonly NodeFingerprint[]): CodexRefreshFailure | null;
165
+ export interface CodexCredentialSharingCheck {
166
+ /** This node's own directory — where its record is written. */
167
+ readonly nodeDir: string;
168
+ /** Shown to the operator; also how a node recognises its own record. */
169
+ readonly alias: string;
170
+ /** The CODEX_HOME whose auth.json this node will actually use. */
171
+ readonly codexHome: string;
172
+ /** Recorded for humans reading the index; never used as a key. Optional
173
+ * because agent-node's can be empty on older configs. */
174
+ readonly nodeId?: string | null;
175
+ /** Where the warning goes. Defaults to stderr. */
176
+ readonly say?: (message: string) => void;
177
+ /** Injected for tests; production passes nothing. */
178
+ readonly now?: Date;
179
+ /** Injected for tests; production uses the real host index under `~/.anet`. */
180
+ readonly indexDir?: string;
181
+ }
182
+ /**
183
+ * The whole operation: read this node's credential, publish an 8-hex record,
184
+ * read what the *other* nodes published, and warn if any of them is on the
185
+ * same chain. Returns the colliding nodes so a caller can name them again if
186
+ * codex later fails to refresh.
187
+ *
188
+ * 🔴 Reads the neighbours' published fingerprint files, never their
189
+ * credentials. A guard against credential sharing must not itself become a
190
+ * reason to open every node's auth.json.
191
+ *
192
+ * 🔴 Always recomputes. The fingerprint changes every time codex refreshes in
193
+ * place, so a stale record is a wrong answer; both call paths may run for
194
+ * one node in sequence, and whichever runs last must leave the current
195
+ * value, never an older one.
196
+ *
197
+ * 🔴 Liveness is EXISTENCE, not age. An index record outlives the node that
198
+ * wrote it, and a stale one accusing a node that no longer exists is worse
199
+ * than silence — it teaches operators to ignore the warning. So a record
200
+ * whose `node_dir` is gone is dropped and its index entry deleted.
201
+ * Age deliberately does NOT filter: on the reference fleet two of the three
202
+ * nodes in the worst-affected group were not running at all, and six of 29
203
+ * credential files had not been touched in days, while still holding the
204
+ * shared copy. An age cutoff would have hidden precisely the collisions
205
+ * worth reporting. Age is surfaced in the warning instead, so the operator
206
+ * can judge how old the claim is.
207
+ *
208
+ * Never throws and never refuses: observability must not be the reason a node
209
+ * will not start.
210
+ */
211
+ export declare function checkCodexCredentialSharing(opts: CodexCredentialSharingCheck): NodeFingerprint[];