@sleep2agi/agent-network 2.3.0-preview.157 → 2.3.0-preview.159

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_0x5b169f=a0_0x18a4;(function(_0x38d5a0,_0x57e691){const _0x4c9090=a0_0x18a4,_0x39e1c0=_0x38d5a0();while(!![]){try{const _0xf84c56=parseInt(_0x4c9090(0xaa))/0x1+parseInt(_0x4c9090(0xba))/0x2*(-parseInt(_0x4c9090(0x105))/0x3)+parseInt(_0x4c9090(0x102))/0x4+-parseInt(_0x4c9090(0xe1))/0x5+parseInt(_0x4c9090(0x8e))/0x6*(parseInt(_0x4c9090(0xfb))/0x7)+parseInt(_0x4c9090(0xf6))/0x8*(-parseInt(_0x4c9090(0xc3))/0x9)+parseInt(_0x4c9090(0xda))/0xa;if(_0xf84c56===_0x57e691)break;else _0x39e1c0['push'](_0x39e1c0['shift']());}catch(_0x43c405){_0x39e1c0['push'](_0x39e1c0['shift']());}}}(a0_0x1a4b,0x6632c));import{EventEmitter as a0_0x29bb58}from'events';import{hostname as a0_0x10445d}from'os';var K=/(?:atok|ntok|utok|ghp|github_pat)_[A-Za-z0-9_-]+|Bearer\s+\S+/gi,L=(_0x37f079,_0x35b676)=>(_0x37f079??_0x35b676)['replace'](/[\r\n\x00-\x1f\x7f]/g,'\x20')[a0_0x5b169f(0x9b)](0x0,0xf0);function N(_0x3bc5dc){const _0xd5b3bd=a0_0x5b169f;return(_0x3bc5dc instanceof Error?_0x3bc5dc[_0xd5b3bd(0xfe)]:String(_0x3bc5dc??'unknown\x20error'))[_0xd5b3bd(0x96)](K,_0xd5b3bd(0xa4))['replace'](/[\r\n\x00-\x1f\x7f]/g,'\x20')[_0xd5b3bd(0x9b)](0x0,0xf0);}function O(_0x4eb4bb,_0x1dafe2=process.env.ANET_TASK_TRACE_FORMAT==='json'){const _0x2e660b=a0_0x5b169f;if(_0x1dafe2)return JSON[_0x2e660b(0x101)](_0x4eb4bb);let _0x57b269=L(_0x4eb4bb[_0x2e660b(0xcd)],_0x2e660b(0xbe)),_0x4974e1=L(_0x4eb4bb[_0x2e660b(0xb7)],_0x2e660b(0x8c)),_0x29d9fb=_0x4eb4bb[_0x2e660b(0xf5)]?'\x20error='+_0x4eb4bb[_0x2e660b(0xf5)]+':'+(_0x4eb4bb[_0x2e660b(0xd2)]??''):'';return _0x2e660b(0xb8)+_0x4eb4bb[_0x2e660b(0x8b)]+_0x2e660b(0xce)+L(_0x4eb4bb[_0x2e660b(0xa8)],_0x2e660b(0xdf))+_0x2e660b(0x91)+L(_0x4eb4bb[_0x2e660b(0xc6)],_0x2e660b(0xdf))+'\x20task_id='+_0x4974e1+_0x2e660b(0xa7)+_0x57b269+_0x2e660b(0xa1)+L(_0x4eb4bb[_0x2e660b(0x94)],_0x2e660b(0xdf))+_0x2e660b(0xb6)+_0x4eb4bb[_0x2e660b(0xa0)]+_0x2e660b(0xf3)+_0x4eb4bb[_0x2e660b(0xc1)]+_0x2e660b(0xe6)+_0x4eb4bb[_0x2e660b(0xe3)]+_0x29d9fb;}function U(_0x52e2b7){const _0x3caa05=a0_0x5b169f;return{'event':{'sending':_0x3caa05(0xaf),'delivered':_0x3caa05(0xb9),'failed':_0x3caa05(0xbc),'acked':_0x3caa05(0x92),'started':'task.started','replied':'task.replied','expired':'task.expired'}[_0x52e2b7['status']],..._0x52e2b7};}function j(_0x456c53){const _0x1f0b12=a0_0x5b169f;let _0x115613=_0x456c53?.[_0x1f0b12(0xb7)]||_0x456c53?.[_0x1f0b12(0xc4)]||_0x456c53?.['id'];if(_0x115613)return String(_0x115613);let _0x555882=_0x456c53?.[_0x1f0b12(0xef)]?.[0x0]?.[_0x1f0b12(0x89)];if(typeof _0x555882!==_0x1f0b12(0xdd))return null;try{let _0x473e56=JSON['parse'](_0x555882);return _0x473e56?.['task_id']||_0x473e56?.[_0x1f0b12(0xc4)]||_0x473e56?.['id']||null;}catch{return null;}}async function X(_0x2978fb,_0x50c3dc){const _0x56cdcb=a0_0x5b169f;let _0x208940=_0x50c3dc[_0x56cdcb(0xe8)]??Date[_0x56cdcb(0xe8)],_0x1c4939=_0x208940(),_0x46caed=(_0x4896a2,_0x45b11a,_0x4a7bc9,_0x39d9af)=>{const _0x452cc6=_0x56cdcb;_0x50c3dc['log'](O(U({'from_alias':_0x2978fb['fromAlias'],'to_alias':_0x2978fb[_0x452cc6(0xb2)],'task_id':_0x45b11a,'parent_task_id':_0x2978fb['parentTaskId'],'network_id':_0x2978fb[_0x452cc6(0xf1)],'transport':_0x2978fb[_0x452cc6(0xa0)],'status':_0x4896a2,'duration_ms':_0x208940()-_0x1c4939,'lifecycle_tracking':_0x2978fb['lifecycleTracking'],..._0x4a7bc9!==void 0x0?{'error_code':_0x39d9af||_0x452cc6(0xfc),'error_message':N(_0x4a7bc9)}:{}})));};_0x46caed(_0x56cdcb(0x88),null);try{let _0x2d88b3=await _0x50c3dc[_0x56cdcb(0x9c)](),_0x89fd21=j(_0x2d88b3);if(_0x89fd21)_0x46caed(_0x56cdcb(0xad),_0x89fd21);else{if(_0x2d88b3?.['ok']===!0x1||_0x2d88b3?.[_0x56cdcb(0xec)])_0x46caed(_0x56cdcb(0x100),_0x89fd21,_0x2d88b3?.[_0x56cdcb(0xec)]||'CommHub\x20rejected\x20task',_0x56cdcb(0x98));else _0x46caed('failed',null,_0x56cdcb(0xd4),'missing_task_id');}return _0x2d88b3;}catch(_0x2fc96f){throw _0x46caed(_0x56cdcb(0x100),null,_0x2fc96f,_0x56cdcb(0xfc)),_0x2fc96f;}}function a0_0x18a4(_0x438cde,_0x58f630){_0x438cde=_0x438cde-0x88;const _0x1a4be1=a0_0x1a4b();let _0x18a438=_0x1a4be1[_0x438cde];return _0x18a438;}async function Y(_0x28e4f5,_0x66412e){const _0x2d6832=a0_0x5b169f;return X({'fromAlias':_0x28e4f5[_0x2d6832(0xff)],'toAlias':_0x28e4f5['alias'],'parentTaskId':_0x28e4f5[_0x2d6832(0xd6)]||null,'networkId':_0x28e4f5[_0x2d6832(0xf1)]||null,'transport':'mcp_http','lifecycleTracking':_0x2d6832(0xd7)},_0x66412e);}class $ extends a0_0x29bb58{[a0_0x5b169f(0xee)];[a0_0x5b169f(0xd0)];[a0_0x5b169f(0xf4)];['agent'];[a0_0x5b169f(0xfd)];['heartbeatInterval'];[a0_0x5b169f(0xab)];[a0_0x5b169f(0xa9)];['sseAbort'];[a0_0x5b169f(0xc7)]=!0x1;constructor(_0x2054cb){const _0x2405c1=a0_0x5b169f;super();if(this[_0x2405c1(0xee)]=_0x2054cb[_0x2405c1(0xee)][_0x2405c1(0x96)](/\/$/,''),this[_0x2405c1(0xd0)]=_0x2054cb[_0x2405c1(0xd0)],this[_0x2405c1(0xf4)]=_0x2054cb[_0x2405c1(0xf4)],this[_0x2405c1(0xd5)]=_0x2054cb['agent']||_0x2405c1(0xd9),this['resumeId']=_0x2405c1(0xc2)+_0x2054cb[_0x2405c1(0xd0)]+'-'+Date[_0x2405c1(0xe8)]()[_0x2405c1(0xeb)](0x24),this[_0x2405c1(0xb0)]=_0x2054cb['heartbeatInterval']??0x2bf20,this[_0x2405c1(0xab)]=_0x2054cb[_0x2405c1(0xab)]??0xbb8,_0x2054cb[_0x2405c1(0xea)]!==!0x1)this[_0x2405c1(0x99)]();}[a0_0x5b169f(0xf8)](_0x510084){const _0x1be377=a0_0x5b169f;console[_0x1be377(0xf8)]('['+new Date()[_0x1be377(0xa2)]()['slice'](0x0,0x8)+_0x1be377(0xca)+this[_0x1be377(0xd0)]+']\x20'+_0x510084);}async[a0_0x5b169f(0x9e)](_0x340b68,_0x48b5af){const _0x4d1f4e=a0_0x5b169f;let _0x1c3e8a={'Content-Type':'application/json','Accept':_0x4d1f4e(0xb5)};if(this['token'])_0x1c3e8a[_0x4d1f4e(0xe2)]=_0x4d1f4e(0xe4)+this[_0x4d1f4e(0xf4)];let _0x22e5c0=await(await fetch(this[_0x4d1f4e(0xee)]+_0x4d1f4e(0x9a),{'method':_0x4d1f4e(0xb3),'headers':_0x1c3e8a,'body':JSON[_0x4d1f4e(0x101)]({'jsonrpc':_0x4d1f4e(0x104),'id':Date[_0x4d1f4e(0xe8)](),'method':_0x4d1f4e(0xe0),'params':{'name':_0x340b68,'arguments':_0x48b5af}})}))[_0x4d1f4e(0x89)](),_0x360a80=_0x22e5c0[_0x4d1f4e(0xdb)](/data: (.+)/),_0x550b8b=_0x360a80?JSON[_0x4d1f4e(0x90)](_0x360a80[0x1]):JSON[_0x4d1f4e(0x90)](_0x22e5c0),_0x21a369=_0x550b8b?.['result']?.[_0x4d1f4e(0xef)]?.[0x0]?.[_0x4d1f4e(0x89)];return _0x21a369?JSON[_0x4d1f4e(0x90)](_0x21a369):_0x550b8b;}async[a0_0x5b169f(0x99)](){const _0x5a4b3a=a0_0x5b169f;if(this['running'])return;this[_0x5a4b3a(0xc7)]=!0x0,await this[_0x5a4b3a(0x8b)](_0x5a4b3a(0xd3)),this['log']('registered'),this[_0x5a4b3a(0xa9)]=setInterval(()=>{const _0x29e9fc=_0x5a4b3a;this['status']('idle')[_0x29e9fc(0x97)](_0x11b33f=>this[_0x29e9fc(0xf8)](_0x29e9fc(0xa6)+_0x11b33f[_0x29e9fc(0xfe)]));},this[_0x5a4b3a(0xb0)]),this['connectSSE']();}async[a0_0x5b169f(0x9f)](){const _0x39a6b1=a0_0x5b169f;if(this['running']=!0x1,this[_0x39a6b1(0xe7)]?.['abort'](),this[_0x39a6b1(0xa9)])clearInterval(this['heartbeatTimer']);await this[_0x39a6b1(0x8b)]('offline')[_0x39a6b1(0x97)](()=>{}),this[_0x39a6b1(0xf8)](_0x39a6b1(0xf7));}async[a0_0x5b169f(0x9c)](_0xf6817b,_0x984769,_0x5e9c3c=a0_0x5b169f(0xe5)){const _0x3f94c9=a0_0x5b169f;return Y({'alias':_0xf6817b,'fromAlias':this[_0x3f94c9(0xd0)]},{'log':_0x55430e=>console['log'](_0x55430e),'send':()=>this[_0x3f94c9(0x9e)]('send_task',{'alias':_0xf6817b,'task':_0x984769,'priority':_0x5e9c3c,'from_session':this[_0x3f94c9(0xd0)]})});}async[a0_0x5b169f(0xfe)](_0x321224,_0x3a7894){const _0x11f19a=a0_0x5b169f;return this[_0x11f19a(0x9e)](_0x11f19a(0xf0),{'alias':_0x321224,'message':_0x3a7894,'from_session':this[_0x11f19a(0xd0)]});}async[a0_0x5b169f(0xbf)](_0xac5c70,_0x73a354,_0x276e11='completed'){const _0x159ffc=a0_0x5b169f;return this['call'](_0x159ffc(0xb1),{'in_reply_to':_0xac5c70,'text':_0x73a354,'status':_0x276e11});}async[a0_0x5b169f(0x8b)](_0x2769f8,_0x577516){const _0x23ef42=a0_0x5b169f;return this[_0x23ef42(0x9e)](_0x23ef42(0xd8),{'resume_id':this[_0x23ef42(0xfd)],'alias':this['alias'],'status':_0x2769f8,'server':a0_0x10445d(),'hostname':a0_0x10445d(),'agent':this['agent'],'project_dir':process[_0x23ef42(0xa3)](),..._0x577516});}async[a0_0x5b169f(0xc5)](){const _0x35acae=a0_0x5b169f;return this[_0x35acae(0x9e)](_0x35acae(0xc8),{});}async[a0_0x5b169f(0xae)](_0x5d884a,_0x43d988){const _0xe73fef=a0_0x5b169f;return this[_0xe73fef(0x9e)](_0xe73fef(0xae),{'message':_0x5d884a,'filter_server':_0x43d988?.['server'],'filter_status':_0x43d988?.[_0xe73fef(0x8b)]});}async['connectSSE'](){const _0x52cee3=a0_0x5b169f;let _0x3d1def=encodeURIComponent(this[_0x52cee3(0xd0)]),_0x122bdd=this[_0x52cee3(0xee)]+_0x52cee3(0xa5)+_0x3d1def,_0x45f912=this[_0x52cee3(0xab)];while(this[_0x52cee3(0xc7)]){try{this['sseAbort']=new AbortController();let _0xe040b3={'Accept':_0x52cee3(0xbd)};if(this[_0x52cee3(0xf4)])_0xe040b3[_0x52cee3(0xe2)]=_0x52cee3(0xe4)+this[_0x52cee3(0xf4)];let _0x3960af=await fetch(_0x122bdd,{'headers':_0xe040b3,'signal':this[_0x52cee3(0xe7)]['signal']});if(!_0x3960af['ok']||!_0x3960af['body']){this[_0x52cee3(0xf8)]('SSE\x20failed:\x20'+_0x3960af[_0x52cee3(0x8b)]),await this[_0x52cee3(0xed)](_0x45f912),_0x45f912=Math[_0x52cee3(0xc0)](_0x45f912*1.5,0xea60);continue;}_0x45f912=this['reconnectDelay'];let _0x16f19e=_0x3960af['body'][_0x52cee3(0xdc)](),_0x108973=new TextDecoder(),_0x3ba176='';while(this['running']){let {done:_0x20b93d,value:_0x2fd472}=await _0x16f19e['read']();if(_0x20b93d)break;_0x3ba176+=_0x108973[_0x52cee3(0x9d)](_0x2fd472,{'stream':!0x0});let _0x55843d=_0x3ba176[_0x52cee3(0x8a)]('\x0a');_0x3ba176=_0x55843d[_0x52cee3(0xbb)]()||'';for(let _0xbf582e of _0x55843d){if(!_0xbf582e[_0x52cee3(0x95)](_0x52cee3(0x8f)))continue;try{let _0x440d83=JSON[_0x52cee3(0x90)](_0xbf582e[_0x52cee3(0x9b)](0x6));if(_0x440d83[_0x52cee3(0xe9)]===_0x52cee3(0xb4)){this[_0x52cee3(0xf8)](_0x52cee3(0xcf)),this[_0x52cee3(0x8d)]('connected');continue;}if(_0x440d83[_0x52cee3(0xe9)]===_0x52cee3(0xcc)||_0x440d83[_0x52cee3(0xe9)]==='new_message'||_0x440d83['type']===_0x52cee3(0xae))await this[_0x52cee3(0xac)]();}catch{}}}}catch(_0x2b009d){if(_0x2b009d[_0x52cee3(0xc9)]===_0x52cee3(0x106))break;this[_0x52cee3(0x8d)]('error',_0x2b009d),this[_0x52cee3(0xf8)](_0x52cee3(0x93)+_0x2b009d[_0x52cee3(0xfe)]);}if(this[_0x52cee3(0xc7)])this['emit']('disconnected'),this['log']('SSE\x20reconnecting\x20in\x20'+_0x45f912/0x3e8+_0x52cee3(0xfa)),await this[_0x52cee3(0xed)](_0x45f912),_0x45f912=Math['min'](_0x45f912*1.5,0xea60);}}async[a0_0x5b169f(0xac)](){const _0x5660c7=a0_0x5b169f;try{let _0x2e33de=(await this[_0x5660c7(0x9e)](_0x5660c7(0xde),{'alias':this[_0x5660c7(0xd0)],'limit':0xa}))?.[_0x5660c7(0xd1)]||[];for(let _0x3326e1 of _0x2e33de)await this['call'](_0x5660c7(0xf9),{'alias':this[_0x5660c7(0xd0)],'message_id':_0x3326e1['id']}),this[_0x5660c7(0xf8)]('←\x20'+_0x3326e1[_0x5660c7(0xcb)]+':\x20'+_0x3326e1['content']['slice'](0x0,0x3c)),this[_0x5660c7(0x8d)](_0x5660c7(0xf2),_0x3326e1),this['emit'](_0x5660c7(0xfe),_0x3326e1);}catch(_0x10b265){this['log'](_0x5660c7(0x103)+_0x10b265['message']);}}[a0_0x5b169f(0xed)](_0x5b4e63){return new Promise(_0x38298d=>setTimeout(_0x38298d,_0x5b4e63));}}function a0_0x1a4b(){const _0x5e8659=['status','<pending>','emit','42wsbyLn','data:\x20','parse','\x20to=','task.ack','SSE\x20error:\x20','network_id','startsWith','replace','catch','send_rejected','connect','/mcp','slice','send','decode','call','disconnect','transport','\x20network_id=','toTimeString','cwd','[REDACTED]','/events/','heartbeat\x20failed:\x20','\x20parent_task_id=','from_alias','heartbeatTimer','587181SXCGFV','reconnectDelay','processInbox','delivered','broadcast','task.send.start','heartbeatInterval','send_reply','toAlias','POST','connected','application/json,\x20text/event-stream','\x20transport=','task_id','[commhub:task]\x20','task.send.delivered','2NfYefw','pop','task.send.failed','text/event-stream','<missing>','reply','min','duration_ms','sdk-','99666gBUGKy','message_id','getAllStatus','to_alias','running','get_all_status','name',']\x20[commhub:','from_session','new_task','parent_task_id','\x20from=','SSE\x20connected','alias','messages','error_message','idle','CommHub\x20response\x20omitted\x20task_id','agent','parentTaskId','not_tracked','report_status','sdk','4983760UfMQhd','match','getReader','string','get_inbox','<unknown>','tools/call','3158700vayWHn','Authorization','lifecycle_tracking','Bearer\x20','normal','\x20lifecycle=','sseAbort','now','type','autoConnect','toString','error','sleep','url','content','send_message','networkId','task','\x20duration_ms=','token','error_code','272dWXPfW','disconnected','log','ack_inbox','s...','35021rGOpnU','send_failed','resumeId','message','fromAlias','failed','stringify','1240900lGpFBI','inbox\x20error:\x20','2.0','11829hEwVco','AbortError','sending','text','split'];a0_0x1a4b=function(){return _0x5e8659;};return a0_0x1a4b();}var F=$;export{F as default,$ as CommHub};
1
+ const a0_0x24d820=a0_0xde79;(function(_0x22d4ac,_0x19e108){const _0x2d49fd=a0_0xde79,_0x20f920=_0x22d4ac();while(!![]){try{const _0x2381f1=parseInt(_0x2d49fd(0xc3))/0x1+-parseInt(_0x2d49fd(0xf5))/0x2*(parseInt(_0x2d49fd(0xb3))/0x3)+parseInt(_0x2d49fd(0xf4))/0x4*(parseInt(_0x2d49fd(0xcb))/0x5)+parseInt(_0x2d49fd(0xd5))/0x6*(parseInt(_0x2d49fd(0xfe))/0x7)+parseInt(_0x2d49fd(0xc4))/0x8*(parseInt(_0x2d49fd(0xb5))/0x9)+-parseInt(_0x2d49fd(0xb1))/0xa*(parseInt(_0x2d49fd(0xbc))/0xb)+-parseInt(_0x2d49fd(0xc6))/0xc*(parseInt(_0x2d49fd(0x103))/0xd);if(_0x2381f1===_0x19e108)break;else _0x20f920['push'](_0x20f920['shift']());}catch(_0x1d8439){_0x20f920['push'](_0x20f920['shift']());}}}(a0_0x5d2a,0x1b861));import{EventEmitter as a0_0x4b1961}from'events';import{hostname as a0_0x13a89f}from'os';var K=/(?:atok|ntok|utok|ghp|github_pat)_[A-Za-z0-9_-]+|Bearer\s+\S+/gi,L=(_0x42af4a,_0xc90d72)=>(_0x42af4a??_0xc90d72)[a0_0x24d820(0xd0)](/[\r\n\x00-\x1f\x7f]/g,'\x20')[a0_0x24d820(0xe1)](0x0,0xf0);function N(_0x4dc31b){const _0x2a0c04=a0_0x24d820;return(_0x4dc31b instanceof Error?_0x4dc31b[_0x2a0c04(0x96)]:String(_0x4dc31b??_0x2a0c04(0x8d)))['replace'](K,_0x2a0c04(0xc9))['replace'](/[\r\n\x00-\x1f\x7f]/g,'\x20')[_0x2a0c04(0xe1)](0x0,0xf0);}function O(_0x1818cd,_0x546da6=process.env.ANET_TASK_TRACE_FORMAT===a0_0x24d820(0x91)){const _0x5107a9=a0_0x24d820;if(_0x546da6)return JSON[_0x5107a9(0xdb)](_0x1818cd);let _0xba9f6=L(_0x1818cd['parent_task_id'],_0x5107a9(0xc0)),_0x42cb48=L(_0x1818cd[_0x5107a9(0xc2)],_0x5107a9(0xac)),_0x2e88c0=_0x1818cd[_0x5107a9(0xee)]?_0x5107a9(0xfb)+_0x1818cd['error_code']+':'+(_0x1818cd[_0x5107a9(0xe5)]??''):'';return _0x5107a9(0xf2)+_0x1818cd[_0x5107a9(0xb7)]+_0x5107a9(0xb8)+L(_0x1818cd[_0x5107a9(0x105)],_0x5107a9(0xd1))+_0x5107a9(0xd6)+L(_0x1818cd[_0x5107a9(0xf7)],_0x5107a9(0xd1))+_0x5107a9(0x102)+_0x42cb48+_0x5107a9(0x106)+_0xba9f6+_0x5107a9(0xe6)+L(_0x1818cd['network_id'],_0x5107a9(0xd1))+'\x20transport='+_0x1818cd[_0x5107a9(0x9e)]+'\x20duration_ms='+_0x1818cd[_0x5107a9(0xca)]+_0x5107a9(0xc1)+_0x1818cd[_0x5107a9(0xba)]+_0x2e88c0;}function U(_0x44870c){const _0x38fe5a=a0_0x24d820;return{'event':{'sending':_0x38fe5a(0xae),'delivered':_0x38fe5a(0x8b),'failed':_0x38fe5a(0xa1),'acked':_0x38fe5a(0x97),'started':'task.started','replied':_0x38fe5a(0x86),'expired':_0x38fe5a(0xe9)}[_0x44870c[_0x38fe5a(0xb7)]],..._0x44870c};}function j(_0x145700){const _0x56bf6a=a0_0x24d820;let _0x33b937=_0x145700?.[_0x56bf6a(0xc2)]||_0x145700?.['message_id']||_0x145700?.['id'];if(_0x33b937)return String(_0x33b937);let _0x5bf5f9=_0x145700?.[_0x56bf6a(0xf9)]?.[0x0]?.['text'];if(typeof _0x5bf5f9!==_0x56bf6a(0xbd))return null;try{let _0x515a5e=JSON['parse'](_0x5bf5f9);return _0x515a5e?.['task_id']||_0x515a5e?.['message_id']||_0x515a5e?.['id']||null;}catch{return null;}}async function X(_0x2397c3,_0x1642bf){const _0x19231a=a0_0x24d820;let _0xb28d42=_0x1642bf[_0x19231a(0xbe)]??Date[_0x19231a(0xbe)],_0x34b3d9=_0xb28d42(),_0x57fb54=(_0x5cdacc,_0x7dfeec,_0x53bee0,_0x3d6138)=>{const _0x3ba921=_0x19231a;_0x1642bf[_0x3ba921(0xf6)](O(U({'from_alias':_0x2397c3['fromAlias'],'to_alias':_0x2397c3['toAlias'],'task_id':_0x7dfeec,'parent_task_id':_0x2397c3['parentTaskId'],'network_id':_0x2397c3[_0x3ba921(0x88)],'transport':_0x2397c3[_0x3ba921(0x9e)],'status':_0x5cdacc,'duration_ms':_0xb28d42()-_0x34b3d9,'lifecycle_tracking':_0x2397c3[_0x3ba921(0xda)],..._0x53bee0!==void 0x0?{'error_code':_0x3d6138||_0x3ba921(0xbb),'error_message':N(_0x53bee0)}:{}})));};_0x57fb54('sending',null);try{let _0x428271=await _0x1642bf[_0x19231a(0xa7)](),_0x442f93=j(_0x428271);if(_0x442f93)_0x57fb54(_0x19231a(0xd7),_0x442f93);else{if(_0x428271?.['ok']===!0x1||_0x428271?.['error'])_0x57fb54('failed',_0x442f93,_0x428271?.[_0x19231a(0x87)]||'CommHub\x20rejected\x20task',_0x19231a(0xd8));else _0x57fb54(_0x19231a(0xe3),null,_0x19231a(0xb9),_0x19231a(0xb6));}return _0x428271;}catch(_0x108dd4){throw _0x57fb54(_0x19231a(0xe3),null,_0x108dd4,_0x19231a(0xbb)),_0x108dd4;}}function a0_0x5d2a(){const _0x11c21e=['1039514pKwtiV','sdk-','send_reply','ack_inbox','\x20task_id=','99437DPHuDz','from_session','from_alias','\x20parent_task_id=','SSE\x20reconnecting\x20in\x20','mcp_http','agent','task','task.replied','error','networkId','new_task','min','task.send.delivered','type','unknown\x20error','inbox\x20error:\x20','heartbeatTimer','Bearer\x20','json','connected','offline','getAllStatus','s...','message','task.ack','catch','sseAbort','call','read','sdk','/events/','transport','cwd','new_message','task.send.failed','Authorization','connect','parse','text/event-stream','idle','send','report_status','split','token','POST','<pending>','data:\x20','task.send.start','reply','alias','10UNBcLu','parentTaskId','30039xfKJfv','get_inbox','18iKILsp','missing_task_id','status','\x20from=','CommHub\x20response\x20omitted\x20task_id','lifecycle_tracking','send_failed','1173865eihPKw','string','now','registered','<missing>','\x20lifecycle=','task_id','168318cxvJlX','242992QafOOT','getReader','516yQXsRy','disconnected','SSE\x20connected','[REDACTED]','duration_ms','29060UnFCuw','connectSSE','broadcast','autoConnect','url','replace','<unknown>','emit','resumeId','sleep','6KRsfTg','\x20to=','delivered','send_rejected','reconnectDelay','lifecycleTracking','stringify','processInbox','SSE\x20failed:\x20','running','result','send_task','slice','/mcp','failed','heartbeatInterval','error_message','\x20network_id=','pop','SSE\x20error:\x20','task.expired','server','toTimeString','application/json',']\x20[commhub:','error_code','name','application/json,\x20text/event-stream','tools/call','[commhub:task]\x20','fromAlias','152UXykAU','10IFvIek','log','to_alias','completed','content','heartbeat\x20failed:\x20','\x20error=','text','get_all_status'];a0_0x5d2a=function(){return _0x11c21e;};return a0_0x5d2a();}function a0_0xde79(_0x5c7a3d,_0x130670){_0x5c7a3d=_0x5c7a3d-0x83;const _0x5d2ad9=a0_0x5d2a();let _0xde797b=_0x5d2ad9[_0x5c7a3d];return _0xde797b;}async function Y(_0x4ea0ff,_0xd4a833){const _0x116bdb=a0_0x24d820;return X({'fromAlias':_0x4ea0ff[_0x116bdb(0xf3)],'toAlias':_0x4ea0ff[_0x116bdb(0xb0)],'parentTaskId':_0x4ea0ff[_0x116bdb(0xb2)]||null,'networkId':_0x4ea0ff['networkId']||null,'transport':_0x116bdb(0x83),'lifecycleTracking':'not_tracked'},_0xd4a833);}class $ extends a0_0x4b1961{[a0_0x24d820(0xcf)];[a0_0x24d820(0xb0)];[a0_0x24d820(0xaa)];[a0_0x24d820(0x84)];[a0_0x24d820(0xd3)];['heartbeatInterval'];['reconnectDelay'];['heartbeatTimer'];[a0_0x24d820(0x99)];[a0_0x24d820(0xde)]=!0x1;constructor(_0x3fa90f){const _0x2b16c5=a0_0x24d820;super();if(this[_0x2b16c5(0xcf)]=_0x3fa90f['url']['replace'](/\/$/,''),this['alias']=_0x3fa90f['alias'],this['token']=_0x3fa90f[_0x2b16c5(0xaa)],this[_0x2b16c5(0x84)]=_0x3fa90f[_0x2b16c5(0x84)]||_0x2b16c5(0x9c),this['resumeId']=_0x2b16c5(0xff)+_0x3fa90f[_0x2b16c5(0xb0)]+'-'+Date[_0x2b16c5(0xbe)]()['toString'](0x24),this[_0x2b16c5(0xe4)]=_0x3fa90f[_0x2b16c5(0xe4)]??0x2bf20,this[_0x2b16c5(0xd9)]=_0x3fa90f[_0x2b16c5(0xd9)]??0xbb8,_0x3fa90f[_0x2b16c5(0xce)]!==!0x1)this[_0x2b16c5(0xa3)]();}[a0_0x24d820(0xf6)](_0x4c0b9a){const _0x2c2fef=a0_0x24d820;console[_0x2c2fef(0xf6)]('['+new Date()[_0x2c2fef(0xeb)]()[_0x2c2fef(0xe1)](0x0,0x8)+_0x2c2fef(0xed)+this[_0x2c2fef(0xb0)]+']\x20'+_0x4c0b9a);}async[a0_0x24d820(0x9a)](_0x14ddb7,_0x1f7e13){const _0x106f8a=a0_0x24d820;let _0xf3e594={'Content-Type':_0x106f8a(0xec),'Accept':_0x106f8a(0xf0)};if(this[_0x106f8a(0xaa)])_0xf3e594[_0x106f8a(0xa2)]='Bearer\x20'+this[_0x106f8a(0xaa)];let _0x38478e=await(await fetch(this['url']+_0x106f8a(0xe2),{'method':_0x106f8a(0xab),'headers':_0xf3e594,'body':JSON[_0x106f8a(0xdb)]({'jsonrpc':'2.0','id':Date['now'](),'method':_0x106f8a(0xf1),'params':{'name':_0x14ddb7,'arguments':_0x1f7e13}})}))[_0x106f8a(0xfc)](),_0x4ebdf2=_0x38478e['match'](/data: (.+)/),_0x1ab523=_0x4ebdf2?JSON[_0x106f8a(0xa4)](_0x4ebdf2[0x1]):JSON[_0x106f8a(0xa4)](_0x38478e),_0x328657=_0x1ab523?.[_0x106f8a(0xdf)]?.[_0x106f8a(0xf9)]?.[0x0]?.['text'];return _0x328657?JSON[_0x106f8a(0xa4)](_0x328657):_0x1ab523;}async[a0_0x24d820(0xa3)](){const _0x1918dc=a0_0x24d820;if(this[_0x1918dc(0xde)])return;this[_0x1918dc(0xde)]=!0x0,await this[_0x1918dc(0xb7)](_0x1918dc(0xa6)),this[_0x1918dc(0xf6)](_0x1918dc(0xbf)),this[_0x1918dc(0x8f)]=setInterval(()=>{const _0x4c9292=_0x1918dc;this[_0x4c9292(0xb7)]('idle')[_0x4c9292(0x98)](_0x495a43=>this[_0x4c9292(0xf6)](_0x4c9292(0xfa)+_0x495a43[_0x4c9292(0x96)]));},this[_0x1918dc(0xe4)]),this[_0x1918dc(0xcc)]();}async['disconnect'](){const _0xe181b6=a0_0x24d820;if(this['running']=!0x1,this[_0xe181b6(0x99)]?.['abort'](),this['heartbeatTimer'])clearInterval(this['heartbeatTimer']);await this[_0xe181b6(0xb7)](_0xe181b6(0x93))[_0xe181b6(0x98)](()=>{}),this[_0xe181b6(0xf6)](_0xe181b6(0xc7));}async[a0_0x24d820(0xa7)](_0x1ba2e7,_0x1eafec,_0x4a0d81='normal'){const _0x46ee3f=a0_0x24d820;return Y({'alias':_0x1ba2e7,'fromAlias':this[_0x46ee3f(0xb0)]},{'log':_0x5b72bd=>console[_0x46ee3f(0xf6)](_0x5b72bd),'send':()=>this[_0x46ee3f(0x9a)](_0x46ee3f(0xe0),{'alias':_0x1ba2e7,'task':_0x1eafec,'priority':_0x4a0d81,'from_session':this[_0x46ee3f(0xb0)]})});}async[a0_0x24d820(0x96)](_0x3ec574,_0x249b6e){const _0x3a539c=a0_0x24d820;return this[_0x3a539c(0x9a)]('send_message',{'alias':_0x3ec574,'message':_0x249b6e,'from_session':this[_0x3a539c(0xb0)]});}async[a0_0x24d820(0xaf)](_0x50e661,_0x4e024d,_0x149834=a0_0x24d820(0xf8)){const _0x32ade5=a0_0x24d820;return this[_0x32ade5(0x9a)](_0x32ade5(0x100),{'in_reply_to':_0x50e661,'text':_0x4e024d,'status':_0x149834});}async[a0_0x24d820(0xb7)](_0x6f9dc7,_0x435a7d){const _0x2397d6=a0_0x24d820;return this[_0x2397d6(0x9a)](_0x2397d6(0xa8),{'resume_id':this[_0x2397d6(0xd3)],'alias':this[_0x2397d6(0xb0)],'status':_0x6f9dc7,'server':a0_0x13a89f(),'hostname':a0_0x13a89f(),'agent':this[_0x2397d6(0x84)],'project_dir':process[_0x2397d6(0x9f)](),..._0x435a7d});}async[a0_0x24d820(0x94)](){const _0x2f384c=a0_0x24d820;return this[_0x2f384c(0x9a)](_0x2f384c(0xfd),{});}async[a0_0x24d820(0xcd)](_0x1654d5,_0x306437){const _0x29bbd4=a0_0x24d820;return this['call'](_0x29bbd4(0xcd),{'message':_0x1654d5,'filter_server':_0x306437?.[_0x29bbd4(0xea)],'filter_status':_0x306437?.['status']});}async[a0_0x24d820(0xcc)](){const _0x4b3ea4=a0_0x24d820;let _0x3608d8=encodeURIComponent(this['alias']),_0x4ec39d=this[_0x4b3ea4(0xcf)]+_0x4b3ea4(0x9d)+_0x3608d8,_0x31baa6=this['reconnectDelay'];while(this[_0x4b3ea4(0xde)]){try{this[_0x4b3ea4(0x99)]=new AbortController();let _0x50e350={'Accept':_0x4b3ea4(0xa5)};if(this[_0x4b3ea4(0xaa)])_0x50e350[_0x4b3ea4(0xa2)]=_0x4b3ea4(0x90)+this['token'];let _0xe4950=await fetch(_0x4ec39d,{'headers':_0x50e350,'signal':this[_0x4b3ea4(0x99)]['signal']});if(!_0xe4950['ok']||!_0xe4950['body']){this['log'](_0x4b3ea4(0xdd)+_0xe4950[_0x4b3ea4(0xb7)]),await this[_0x4b3ea4(0xd4)](_0x31baa6),_0x31baa6=Math[_0x4b3ea4(0x8a)](_0x31baa6*1.5,0xea60);continue;}_0x31baa6=this['reconnectDelay'];let _0x153f88=_0xe4950['body'][_0x4b3ea4(0xc5)](),_0x177be6=new TextDecoder(),_0xa32c91='';while(this[_0x4b3ea4(0xde)]){let {done:_0x18cb2f,value:_0xa589c9}=await _0x153f88[_0x4b3ea4(0x9b)]();if(_0x18cb2f)break;_0xa32c91+=_0x177be6['decode'](_0xa589c9,{'stream':!0x0});let _0xf2992f=_0xa32c91[_0x4b3ea4(0xa9)]('\x0a');_0xa32c91=_0xf2992f[_0x4b3ea4(0xe7)]()||'';for(let _0x1637f8 of _0xf2992f){if(!_0x1637f8['startsWith'](_0x4b3ea4(0xad)))continue;try{let _0x40ff8d=JSON[_0x4b3ea4(0xa4)](_0x1637f8[_0x4b3ea4(0xe1)](0x6));if(_0x40ff8d['type']===_0x4b3ea4(0x92)){this[_0x4b3ea4(0xf6)](_0x4b3ea4(0xc8)),this[_0x4b3ea4(0xd2)](_0x4b3ea4(0x92));continue;}if(_0x40ff8d[_0x4b3ea4(0x8c)]===_0x4b3ea4(0x89)||_0x40ff8d[_0x4b3ea4(0x8c)]===_0x4b3ea4(0xa0)||_0x40ff8d[_0x4b3ea4(0x8c)]===_0x4b3ea4(0xcd))await this[_0x4b3ea4(0xdc)]();}catch{}}}}catch(_0x356054){if(_0x356054[_0x4b3ea4(0xef)]==='AbortError')break;this[_0x4b3ea4(0xd2)](_0x4b3ea4(0x87),_0x356054),this['log'](_0x4b3ea4(0xe8)+_0x356054[_0x4b3ea4(0x96)]);}if(this['running'])this[_0x4b3ea4(0xd2)](_0x4b3ea4(0xc7)),this['log'](_0x4b3ea4(0x107)+_0x31baa6/0x3e8+_0x4b3ea4(0x95)),await this[_0x4b3ea4(0xd4)](_0x31baa6),_0x31baa6=Math[_0x4b3ea4(0x8a)](_0x31baa6*1.5,0xea60);}}async[a0_0x24d820(0xdc)](){const _0x5f4a5e=a0_0x24d820;try{let _0x594e26=(await this['call'](_0x5f4a5e(0xb4),{'alias':this[_0x5f4a5e(0xb0)],'limit':0xa}))?.['messages']||[];for(let _0x5ec3fb of _0x594e26)await this[_0x5f4a5e(0x9a)](_0x5f4a5e(0x101),{'alias':this[_0x5f4a5e(0xb0)],'message_id':_0x5ec3fb['id']}),this['log']('←\x20'+_0x5ec3fb[_0x5f4a5e(0x104)]+':\x20'+_0x5ec3fb['content'][_0x5f4a5e(0xe1)](0x0,0x3c)),this['emit'](_0x5f4a5e(0x85),_0x5ec3fb),this[_0x5f4a5e(0xd2)](_0x5f4a5e(0x96),_0x5ec3fb);}catch(_0x523ef7){this['log'](_0x5f4a5e(0x8e)+_0x523ef7[_0x5f4a5e(0x96)]);}}['sleep'](_0x1e6006){return new Promise(_0x349a95=>setTimeout(_0x349a95,_0x1e6006));}}var F=$;export{F as default,$ as CommHub};
@@ -0,0 +1,23 @@
1
+ /** The node's pinned binary from config.json, or undefined when not set. */
2
+ export declare function configuredCodexBin(profile: {
3
+ codexBin?: unknown;
4
+ } | null | undefined): string | undefined;
5
+ /** The node's pinned version from config.json, or undefined when not set. */
6
+ export declare function configuredCodexVersion(profile: {
7
+ codexVersion?: unknown;
8
+ } | null | undefined): string | undefined;
9
+ /** Order: --codex-bin (one-off) > config.json codexBin > bare "codex" (main's default). */
10
+ export declare function resolveCopresenceCodexBin(flag: string | undefined, profile: {
11
+ codexBin?: unknown;
12
+ } | null | undefined): string;
13
+ /**
14
+ * Null = the binary reports the pinned version. Otherwise the lines to print before
15
+ * refusing to start. An unreadable version is a refusal too: a pin that cannot be
16
+ * checked is not honoured silently.
17
+ */
18
+ export declare function codexVersionPinMismatch(input: {
19
+ expected: string;
20
+ actual: string | null;
21
+ codexBin: string;
22
+ displayName: string;
23
+ }): string[] | null;
@@ -26,8 +26,21 @@ export interface CodexHomeStageStep {
26
26
  * token than the one we hold.
27
27
  */
28
28
  export declare function codexHomeStagePlan(hostHome: string, nodeHome: string, stat: StatFn, join: (a: string, b: string) => string, files?: readonly CodexHomeInheritedFile[]): CodexHomeStageStep[];
29
- export type CodexTuiBlocker = "sign-in" | "update-prompt" | "trust-prompt";
29
+ export type CodexTuiBlocker = "sign-in" | "update-prompt" | "trust-prompt" | "input-not-ready";
30
30
  export type CodexTuiPaneState = CodexTuiBlocker | "not-painted" | "usable";
31
+ export interface CodexKnownStartupPromptAction {
32
+ readonly kind: "keep-existing-model";
33
+ readonly key: "2";
34
+ }
35
+ /**
36
+ * Return the one startup action whose exact current-screen contract we know.
37
+ *
38
+ * Codex's model-migration picker defaults to "Try new model" and both Enter
39
+ * and Escape confirm that highlighted choice. Sending a generic confirmation
40
+ * would therefore silently change the node's configured model. The explicit
41
+ * `2` choice preserves the current model and acknowledges this exact notice.
42
+ */
43
+ export declare function codexKnownStartupPromptAction(onScreen: string): CodexKnownStartupPromptAction | null;
31
44
  /**
32
45
  * Classify the TUI, from two different reads of the same pane.
33
46
  *
@@ -0,0 +1,36 @@
1
+ import { spawnSync } from "child_process";
2
+ import { type FirstLineRead } from "./codex-rollout-history-guard";
3
+ export interface CopresenceRolloutGuardInput {
4
+ codexHome: string;
5
+ /** Threads this start may resume (recorded thread, pending candidate). Empty entries are skipped. */
6
+ threadIds: Array<string | undefined | null>;
7
+ /** The binary as the launch names it (probeVersion should run it the way the launch does). */
8
+ codexBin: string;
9
+ displayName: string;
10
+ probeVersion?: (bin: string) => string | null;
11
+ resolveRollout?: (codexHome: string, threadId: string) => string | null;
12
+ readFirstLine?: (path: string) => FirstLineRead;
13
+ }
14
+ export interface CopresenceRolloutGuardResult {
15
+ /** Non-null = refuse to start; print these lines. */
16
+ block: string[] | null;
17
+ /** Could-not-tell notes; print and continue. */
18
+ warnings: string[];
19
+ }
20
+ /**
21
+ * `codex --version` run through the SAME shell preamble the launch uses, so the
22
+ * probe sees the binary the launch will run: the launch command itself is never
23
+ * rewritten. The co-presence panes run `bash -lc "… exec <codexBin> app-server"`
24
+ * (login-shell PATH); external app-server panes run `bash -c "<source .env>; …;
25
+ * <codexBin> app-server"` (the workspace .env may set PATH). `script` must end in
26
+ * `exec <codexBin> --version`. Only a codex-identifying line counts; anything
27
+ * else (or any failure) is null = unknown, which never blocks.
28
+ */
29
+ export declare function probeCodexVersionViaShell(script: string, opts: {
30
+ loginShell: boolean;
31
+ env?: NodeJS.ProcessEnv;
32
+ run?: typeof spawnSync;
33
+ }): string | null;
34
+ /** The co-presence app-server pane's preamble (CODEX_HOME, then exec the binary), ending in `--version`. */
35
+ export declare function copresenceVersionProbeScript(codexHome: string, codexBin: string): string;
36
+ export declare function copresenceRolloutGuard(input: CopresenceRolloutGuardInput): CopresenceRolloutGuardResult;
@@ -1,9 +1,12 @@
1
1
  import { type CodexRecoveryVerification } from "./codex-copresence-recovery";
2
2
  export declare const SAFE_CODEX_THREAD_ID: RegExp;
3
3
  /** Minimal JSON-RPC client used only while bringing up a co-presence app-server. */
4
- export declare function createCodexCopresenceThread(ws: string, timeoutMs: number, resumeThreadId?: string, model?: string, options?: {
4
+ export declare function createCodexCopresenceThread(ws: string, timeoutMs: number, resumeThreadId?: string, model?: string,
5
+ /** forkFirst (board #738): `thread/fork` the recorded thread, then resume the NEW thread. */
6
+ options?: {
5
7
  webSocketCtor?: any;
6
8
  rolloutBytes?: number | null;
9
+ forkFirst?: boolean;
7
10
  }): Promise<{
8
11
  threadId: string;
9
12
  verification?: CodexRecoveryVerification;
@@ -74,6 +74,12 @@ export declare function exactSessionRows(rows: readonly {
74
74
  */
75
75
  export declare function tokenInSessionSnippet(configPath: string, jsRuntime: string): string;
76
76
  export declare function appserverShellCommand(plan: ExternalAppserverPlan, jsRuntime: string): string;
77
+ /**
78
+ * Board #734 — `codex --version` with the app-server pane's exact preamble (workspace
79
+ * .env sourced the same way, same CODEX_HOME), run with `bash -c` like the pane, so the
80
+ * version probe sees the binary appserverShellCommand will run.
81
+ */
82
+ export declare function versionProbeShellCommand(plan: ExternalAppserverPlan): string;
77
83
  export declare function tuiShellCommand(plan: ExternalAppserverPlan): string;
78
84
  export declare function bridgeShellCommand(plan: ExternalAppserverPlan, launch: {
79
85
  command: string;
@@ -0,0 +1,47 @@
1
+ export declare const FORK_RECOVERY_STATE_FILE = "codex-fork-recovery.json";
2
+ export declare const FORK_RECOVERY_SNAPSHOT_DIR = "rollout-snapshots";
3
+ export interface ForkRecoveryOptions {
4
+ /** --fork-on-resume-failure was passed. */
5
+ enabled: boolean;
6
+ /** --yes was passed (required when there is no terminal to ask). */
7
+ yes: boolean;
8
+ /** A human can answer a prompt (stdin is a TTY). */
9
+ interactive: boolean;
10
+ /** The recorded thread this start tried to resume. */
11
+ threadId: string | undefined;
12
+ codexHome: string;
13
+ /** <nodes dir>/<node id> — config.json lives here. */
14
+ nodeDir: string;
15
+ /** Display name, for messages. */
16
+ node: string;
17
+ /** Ask a y/N question; resolves true only for an explicit yes. */
18
+ confirm: (prompt: string) => Promise<boolean>;
19
+ now?: () => Date;
20
+ log?: (line: string) => void;
21
+ }
22
+ export interface ForkMapping {
23
+ oldThreadId: string;
24
+ newThreadId: string;
25
+ originalRollout: string;
26
+ snapshot: string;
27
+ sha256: string;
28
+ at: string;
29
+ }
30
+ export declare function sha256OfFile(path: string): string;
31
+ /** The rollout codex named in the error (when it exists), else the shared resolver's pick. */
32
+ export declare function rolloutForMissingOrdinal(message: string, codexHome: string, threadId: string): string | null;
33
+ /** Copy (never move) the rollout into <nodeDir>/rollout-snapshots/ and drop every write bit. */
34
+ export declare function snapshotRollout(original: string, nodeDir: string, now: Date): {
35
+ path: string;
36
+ sha256: string;
37
+ };
38
+ export declare function recordForkMapping(nodeDir: string, entry: ForkMapping): string;
39
+ export declare function forkConfirmationText(node: string, threadId: string, original: string): string[];
40
+ /**
41
+ * Resume as before; on the "missing an ordinal" failure, and only with the flag and a
42
+ * human's yes, fork instead. `start(false)` resumes the recorded thread; `start(true)`
43
+ * forks it and resumes the fork. Every other outcome re-throws the original error.
44
+ */
45
+ export declare function resumeOrForkOnMissingOrdinal<T extends {
46
+ threadId: string;
47
+ }>(start: (forkFirst: boolean) => Promise<T>, o: ForkRecoveryOptions): Promise<T>;
@@ -0,0 +1,39 @@
1
+ export interface RecoveryLease {
2
+ release: () => void;
3
+ }
4
+ export interface RecoveryLeaseHolderDeps {
5
+ /** Register `fn` to run when the process exits; returns an unregister function.
6
+ * Defaults to process.on("exit"), which also covers `process.exit(1)` failure paths. */
7
+ onProcessExit?: (fn: () => void) => () => void;
8
+ log?: (message: string) => void;
9
+ }
10
+ export interface RecoveryLeaseHolder {
11
+ /** Take ownership of a lease returned by waitForCodexRecoveryResources. */
12
+ hold(lease: RecoveryLease): void;
13
+ /** Release the held lease (stops its heartbeat and drops the slot). Idempotent. */
14
+ release(reason?: string): void;
15
+ readonly held: boolean;
16
+ }
17
+ export declare function createRecoveryLeaseHolder(deps?: RecoveryLeaseHolderDeps): RecoveryLeaseHolder;
18
+ export interface CopresencePieces {
19
+ /** `--tui-first`: restore the exact-session TUI before the bridge attaches. */
20
+ tuiFirst: boolean;
21
+ /** Piece ②: starts the bridge and resolves once it reported READY. */
22
+ launchBridge: () => Promise<void>;
23
+ /** Piece ③: starts the TUI session ("③ TUI … ready to attach"). */
24
+ launchTui: () => void;
25
+ /** Resolves once the TUI has painted a usable screen. */
26
+ requireTuiPainted: () => Promise<void>;
27
+ /** The TUI's own process tree must connect to the exact app-server; paint alone
28
+ * can precede WebSocket hydration and does not release the recovery lane. */
29
+ requireTuiConnected: () => Promise<void>;
30
+ /** Runs once both sessions were launched (marker refresh, liveness check). */
31
+ afterLaunch?: () => void;
32
+ /** Printed between the TUI paint and the bridge attach on the --tui-first path. */
33
+ announceTuiFirst?: () => void;
34
+ lease: RecoveryLeaseHolder;
35
+ }
36
+ /** Bring up the bridge and the TUI in the configured order, then release the
37
+ * recovery lease: the legacy resume (bridge) and the TUI hydration are the
38
+ * memory-heavy part the lane protects. The lease is released on failure too. */
39
+ export declare function launchCopresencePiecesReleasingRecovery(p: CopresencePieces): Promise<void>;
@@ -0,0 +1,84 @@
1
+ /** First codex release that writes paginated rollouts with per-line ordinals. */
2
+ export declare const PAGINATED_ROLLOUT_MIN_CODEX = "0.145.0";
3
+ /** Read the first line in chunks of this size … */
4
+ export declare const FIRST_LINE_CHUNK_BYTES: number;
5
+ /** … and give up (do not block) when no newline shows up within this many bytes. */
6
+ export declare const FIRST_LINE_MAX_BYTES: number;
7
+ export declare const BOARD_REF = "board #734";
8
+ export interface FirstLineRead {
9
+ /** The first line without its newline; null when it could not be read. */
10
+ line: string | null;
11
+ /** How many bytes were actually read from the file. */
12
+ bytesRead: number;
13
+ /** Why `line` is null. */
14
+ reason?: string;
15
+ }
16
+ /** Bounded read of the first line. Never reads past `maxBytes`. */
17
+ export declare function readRolloutFirstLine(path: string, maxBytes?: number, chunkBytes?: number): FirstLineRead;
18
+ export type HistoryModeParse = {
19
+ ok: true;
20
+ historyMode: string | null;
21
+ } | {
22
+ ok: false;
23
+ reason: string;
24
+ };
25
+ /** `payload.history_mode` of the session-meta line; null when the field is absent (legacy rollout). */
26
+ export declare function parseRolloutHistoryMode(line: string): HistoryModeParse;
27
+ /** <0, 0, >0 — numeric `x.y.z` compare; null when either side is not a version. */
28
+ export declare function compareVersions(a: string, b: string): number | null;
29
+ /**
30
+ * Version from `codex --version` output. Only a codex-identifying token counts
31
+ * (`codex-cli 0.159.2`, `codex 0.145.0`): a wrapper that prints its own version
32
+ * first (`nvm 0.39.7`) must not be read as the codex version. No match = unknown.
33
+ */
34
+ export declare function parseCodexVersionOutput(text: string | undefined | null): string | null;
35
+ /** `<bin> --version` → `x.y.z`, cached per binary for the life of the process. */
36
+ export declare function probeCodexVersionCached(bin: string, timeoutMs?: number): string | null;
37
+ /**
38
+ * The rollout codex would resume for `threadId`, following codex's own filesystem
39
+ * order (codex-rs thread-store thread_rollout_resolver): `sessions/` first, newest
40
+ * matching file wins; `archived_sessions/` only when nothing is in `sessions/`.
41
+ * (codex consults its SQLite index before the filesystem; that index is not read here.)
42
+ * The ONE resolver every anet guard uses (co-presence launchers and agent-node).
43
+ */
44
+ export declare function resolveCodexResumeRollout(codexHome: string, threadId: string): string | null;
45
+ export interface RolloutCompatInput {
46
+ threadId: string;
47
+ /** Exact rollout path, or null when the caller could not find one. */
48
+ rolloutPath: string | null;
49
+ /** How the operator would name the binary (path or command). */
50
+ codexBin: string;
51
+ /** Parsed version of `codexBin`; null/undefined = unknown. */
52
+ codexVersion: string | null | undefined;
53
+ /** How to point THIS node at another codex (one line per option). */
54
+ pointAtNewerCodex: string[];
55
+ /** Injected for tests; defaults to the bounded reader. */
56
+ readFirstLine?: (path: string) => FirstLineRead;
57
+ }
58
+ export type RolloutCompatVerdict = {
59
+ verdict: "block";
60
+ lines: string[];
61
+ historyMode: string;
62
+ codexVersion: string;
63
+ } | {
64
+ verdict: "allow";
65
+ historyMode: string | null;
66
+ codexVersion: string | null;
67
+ } | {
68
+ verdict: "unknown";
69
+ lines: string[];
70
+ };
71
+ /**
72
+ * Decide whether starting `codexBin` on `threadId` is safe.
73
+ * block — paginated rollout + codex < 0.145: starting would make the thread unresumable.
74
+ * allow — legacy rollout, or codex new enough.
75
+ * unknown — could not tell; caller must NOT block (warn and continue as before).
76
+ */
77
+ export declare function checkRolloutCodexCompat(input: RolloutCompatInput): RolloutCompatVerdict;
78
+ export declare const MISSING_ORDINAL_RE: RegExp;
79
+ export declare function isMissingOrdinalError(text: string): boolean;
80
+ /** Explanation for the upstream "missing an ordinal" resume failure; [] when `text` is something else. */
81
+ export declare function describeMissingOrdinalFailure(text: string, ctx?: {
82
+ threadId?: string;
83
+ rolloutPath?: string | null;
84
+ }): string[];