shellbell 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,7 +13,7 @@ const fs=BigInt(0),ps=BigInt(1),ms=BigInt(2),hs=BigInt(4),gs=BigInt(8);function
13
13
  const bs=BigInt(0),xs=BigInt(1),Ss=BigInt(2);function Cs(e,t){return e+t-(t>>xs<<xs)}function ws(e){let t=BigInt(6)*e;return(n,r,i)=>{let a=r+i,o=((t+i-r)*n+r)%e;return{x_2:o,x_3:a-o}}}function Ts(e){return po(e,{P:`bigint`,type:`string`,adjustScalarBytes:`function`,powPminus2:`function`},{randomBytes:`function`,scalarMultBase:`function`}),Object.freeze({...e})}function Es(e){let t=Ts(e),{P:n,type:r,adjustScalarBytes:i,powPminus2:a,randomBytes:o}=t,s=t.scalarMultBase,c=r===`x25519`;if(!c&&r!==`x448`)throw Error(`invalid type`);let l=o===void 0?Ja:o,u=c?255:448,d=ws(n),f=c?32:56,p=BigInt(c?9:5),m=BigInt(c?121665:39081),h=c?Ss**BigInt(254):Ss**BigInt(447),g=h+(c?BigInt(8)*(Ss**BigInt(251)-xs):BigInt(4)*(Ss**BigInt(445)-xs))+xs,_=e=>J(e,n),v=y(p);function y(e){return ao(_(e),f)}function b(e){let t=oo(Ba(e,f,`uCoordinate`));return c&&(t[31]&=127),_(ro(t))}function ee(e){return ro(i(oo(Ba(e,f,`scalar`))))}let x=new Set(c?[bs,xs,n-xs,BigInt(`325606250916557431795983626356110631294008115727848805560023387167927233504`),BigInt(`39382357235489614581723060781553021112529911719440698176882885853963445705823`)]:[bs,xs,n-xs]);function te(e,t){let n=b(t);if(x.has(n))throw Error(`invalid private or public key received`);let r=T(n,ee(e));if(r===bs)throw Error(`invalid private or public key received`);return y(r)}function S(e){if(s===void 0)return te(e,v);let t=ee(e);lo(`scalar`,t,h,g);let n=_(s(t));if(n===bs)throw Error(`invalid private or public key received`);return y(n)}let C=S,w=te;function T(e,t){lo(`u`,e,bs,n),lo(`scalar`,t,h,g);let r=t,i=e,o=xs,s=bs,c=e,l=xs,f=r^r>>xs;for(let e=BigInt(u-1);e>=bs;e--){let t=Cs(n,f>>e);({x_2:o,x_3:c}=d(t,o,c)),{x_2:s,x_3:l}=d(t,s,l);let r=o+s,a=_(r*r),u=o-s,p=_(u*u),h=a-p,g=c+l,v=c-l,y=_(v*r),b=_(g*u),ee=y+b,x=y-b;c=_(ee*ee),l=_(i*_(x*x)),o=_(a*p),s=_(h*(a+_(m*h)))}let p=Cs(n,r);({x_2:o,x_3:c}=d(p,o,c)),{x_2:s,x_3:l}=d(p,s,l);let v=a(s);return _(o*v)}let E={secretKey:f,publicKey:f,seed:f},D=e=>(e=e===void 0?l(f):e,Ba(e,E.seed,`seed`),e),O={randomSecretKey:D};return Object.freeze(E),Object.freeze(O),Object.freeze({keygen:ds(D,C),getSharedSecret:w,getPublicKey:C,scalarMult:te,scalarMultBase:S,utils:O,GuBytes:v.slice(),lengths:E})}
14
14
  /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
15
15
  const Ds=BigInt(0),Os=BigInt(1),ks=BigInt(2),As=BigInt(3),js=BigInt(5),Ms=BigInt(8),Ns=BigInt(`0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed`),Ps={p:Ns,n:BigInt(`0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed`),h:Ms,a:BigInt(`0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec`),d:BigInt(`0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3`),Gx:BigInt(`0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a`),Gy:BigInt(`0x6666666666666666666666666666666666666666666666666666666666666658`)};function Fs(e){let t=BigInt(10),n=BigInt(20),r=BigInt(40),i=BigInt(80),a=Ns,o=e*e%a*e%a,s=Eo(Eo(o,ks,a)*o%a,Os,a)*e%a,c=Eo(s,js,a)*s%a,l=Eo(c,t,a)*c%a,u=Eo(l,n,a)*l%a,d=Eo(u,r,a)*u%a;return{pow_p_5_8:Eo(Eo(Eo(Eo(d,i,a)*d%a,i,a)*d%a,t,a)*c%a,ks,a)*e%a,b2:o}}function Is(e){return e[0]&=248,e[31]&=127,e[31]|=64,e}const Ls=BigInt(`19681161376707505956807079304988542015446066515923890162744021073123829784752`);function Rs(e,t){let n=Ns,r=J(t*t*t,n),i=Fs(e*J(r*r*t,n)).pow_p_5_8,a=J(e*r*i,n),o=J(t*a*a,n),s=a,c=J(a*Ls,n),l=o===e,u=o===J(-e,n),d=o===J(-e*Ls,n);return l&&(a=s),(u||d)&&(a=c),Fo(a,n)&&(a=J(-a,n)),{isValid:l||u,value:a}}const zs=vs(Ps,{uvRatio:Rs}),Bs=zs.Fp;function Vs(e){let{y:t}=e;return Bs.toBytes(Bs.div(Os+t,Os-t))}function Hs(e){let t=zs.Fp.BYTES;return na(e,t),Is(Ra(e.subarray(0,t))).subarray(0,t)}function Us(e){return ys(zs,Ra,Object.assign({adjustScalarBytes:Is,toMontgomery:Vs,toMontgomerySecret:Hs,zip215:!0},e))}const Ws=Us({}),Gs=(()=>{let e=Ns,t=t=>{let{pow_p_5_8:n,b2:r}=Fs(t);return J(Eo(n,As,e)*r,e)};return Es({P:e,type:`x25519`,powPminus2:t,adjustScalarBytes:Is,scalarMultBase:n=>{let r=J(n,zs.Fn.ORDER);if(r===Ds)return Ds;let i=zs.BASE.multiply(r);return J((i.Z+i.Y)*t(J(i.Z-i.Y,e)),e)}})})();var Ks=class{oHash;iHash;blockLen;outputLen;canXOF=!1;finished=!1;destroyed=!1;constructor(e,t){if(ra(e),na(t,void 0,`key`),this.iHash=e.create(),typeof this.iHash.update!=`function`)throw Error(`expected Hash instance`);this.blockLen=this.iHash.blockLen,this.outputLen=this.iHash.outputLen;let n=this.blockLen,r=new Uint8Array(n);r.set(t.length>n?e.create().update(t).digest():t);for(let e=0;e<r.length;e++)r[e]^=54;this.iHash.update(r),this.oHash=e.create();for(let e=0;e<r.length;e++)r[e]^=106;this.oHash.update(r),ca(r)}update(e){return oa(this),this.iHash.update(e),this}digestInto(e){oa(this),sa(e,this),this.finished=!0;let t=e.subarray(0,this.outputLen);this.iHash.digestInto(t),this.oHash.update(t),this.oHash.digestInto(t),this.destroy()}digest(){let e=new Uint8Array(this.oHash.outputLen);return this.digestInto(e),e}_cloneInto(e){e||=Object.create(Object.getPrototypeOf(this),{});let{oHash:t,iHash:n,finished:r,destroyed:i,blockLen:a,outputLen:o,canXOF:s}=this;return e=e,e.finished=r,e.destroyed=i,e.blockLen=a,e.outputLen=o,e.canXOF=s,e.oHash=t._cloneInto(e.oHash),e.iHash=n._cloneInto(e.iHash),e}clone(){return this._cloneInto()}destroy(){this.destroyed=!0,this.oHash.destroy(),this.iHash.destroy()}};const qs=(()=>{let e=((e,t,n)=>new Ks(e,t).update(n).digest());return e.create=(e,t)=>new Ks(e,t),e})(),Js=Uint8Array.of(0),Ys=Uint8Array.of();function Xs(e,t,n,r=32,i){ra(e),ta(r,`length`),na(t,void 0,`prk`);let a=e.outputLen;if(t.length<a)throw Error(`"prk" must be at least HashLen octets`);if(r>255*a)throw Error(`Length must be <= 255*HashLen`);let o=Math.ceil(r/a);if(n===void 0?n=Ys:na(n,void 0,`info`),!o)return i&&ca(t),new Uint8Array;let s=i&&o===1?t:new Uint8Array(o*a),{iHash:c,oHash:l}=qs.create(e,t),u=i?t:new Uint8Array(a),d=o>1?i?.iHash||e.create():void 0;for(let e=0;e<o-1;e++){Js[0]=e+1;let t=c._cloneInto(d);e&&t.update(u),t.update(n).update(Js).digestInto(u),l._cloneInto(d).update(u).digestInto(u),s.set(u,a*e)}if(Js[0]=o,o>1&&c.update(u),c.update(n).update(Js).digestInto(u),l.update(u).digestInto(u),s.set(u,a*(o-1)),c.destroy(),l.destroy(),d?.destroy(),u!==s&&ca(u),ca(Js),r===s.length)return s;let f=s.slice(0,r);return ca(s),f}const Zs=(e,t,n,r,i)=>{ra(e),n===void 0&&(n=new Uint8Array(e.outputLen));let a=qs.create(e,n).update(t);return Xs(e,a.digest(),r,i,a)};function Qs(){return $s(ya(32),ya(32),new Date().toISOString())}function $s(e,t,n){let r=Ws.keygen(e),i=Gs.keygen(t);return{ed25519:{pub:r.publicKey,priv:r.secretKey},x25519:{pub:i.publicKey,priv:i.secretKey},createdAt:n}}const ec=F.object({v:F.literal(1),ed25519:F.object({pub:F.string(),priv:F.string()}),x25519:F.object({pub:F.string(),priv:F.string()}),createdAt:F.string()});function tc(e){return{v:1,ed25519:{pub:br(e.ed25519.pub),priv:br(e.ed25519.priv)},x25519:{pub:br(e.x25519.pub),priv:br(e.x25519.priv)},createdAt:e.createdAt}}function nc(e){let t=ec.safeParse(e);if(!t.success)throw new V(`malformed`,`identity: ${F.prettifyError(t.error)}`);let n=t.data,r,i,a,o;try{r=xr(n.ed25519.pub),i=xr(n.ed25519.priv),a=xr(n.x25519.pub),o=xr(n.x25519.priv)}catch{throw new V(`malformed`,`identity: bad base64url`)}if(r.length!==32||i.length!==32||a.length!==32||o.length!==32)throw new V(`malformed`,`identity: key length`);return{ed25519:{pub:r,priv:i},x25519:{pub:a,priv:o},createdAt:n.createdAt}}function rc(e){return Sr(La(e)).slice(0,26)}function ic(e){return typeof e==`string`?yr(e):e}function ac(e,t){return Ws.sign(ic(t),e)}function oc(e,t,n){try{return Ws.verify(n,ic(t),e)}catch{return!1}}function sc(e,t,n,r){return`shellbell-auth-v1|${e}|${t}|${n}|${br(r)}`}function cc(e,t,n,r){return{n:t,c:Mi(e,t,yr(r)).encrypt(n)}}function lc(e,t,n){return cc(e,ya(24),t,n)}function uc(e,t,n){try{return Mi(e,t.n,yr(n)).decrypt(t.c)}catch{throw new V(`crypto`,`aead open failed`)}}function dc(e,t){return Zs(La,e,yr(`shellbell-pairing-v1`),yr(t),32)}function fc(e,t,n,r,i){let a=Gs.getSharedSecret(e,t);if(a.every(e=>e===0))throw new V(`crypto`,`low-order point`);return Zs(La,Tr(a,n),yr(`shellbell-pair-v1`),yr(`${r}|${i}`),32)}function pc(e,t,n,r,i){let a=Tr(t,n);return{kConn:Zs(La,e,a,yr(`shellbell-conn-v1|${r}|${i}`),32),connTag:br(La(a)).slice(0,22)}}function mc(e,t,n){if(e.length!==32||!/^[a-z2-7]{26}$/.test(t)||!/^[a-z2-7]{26}$/.test(n))throw new V(`malformed`,`invalid Noise PSK derivation input`);return Zs(La,e,yr(`shellbell-noise-v2-psk`),yr(`${t}|${n}`),32)}function hc(e,t,n,r){return`1|${e}|${t}|${n}|${r}`}function gc(e,t){return`1|${e}|${t}|hello|0`}function _c(e,t,n){return`pairing-${e}|${t}|${n}`}function vc(e,t,n,r){return`shellbell-pair-bind-v1|${e}|${t}|${n}|${br(r)}`}function yc(e){return e.match(/.{1,4}/g)?.join(` `)??e}const bc=`notify-context-v1`,xc=`shellbell-notification-v1`,Sc={plaintextBytes:1536,ciphertextBytes:1552,providerBytes:3500,freshnessMs:12e4,clockSkewMs:6e4,previousGenerationMs:3e5,sessions:500,encryptions:2**20};function Cc(e,t=e){return F.string().min(Math.ceil(e*4/3)).max(Math.ceil(t*4/3)).refine(n=>{try{let r=xr(n);return r.length>=e&&r.length<=t&&br(r)===n}catch{return!1}},`invalid canonical base64url`)}const wc=Cc(16),Tc=F.array(F.string().min(1).max(32)).max(8),Ec=F.number().int().nonnegative().max(2**53-1),Dc=F.string().regex(/^[1-9][0-9]{0,19}$/).refine(e=>/^[1-9][0-9]{0,19}$/.test(e)&&BigInt(e)<=18446744073709551615n,`sequence overflow`),Oc=/[\p{Cc}\p{Cs}\u061c\u200e\u200f\u2028-\u202e\u2066-\u2069]/u;function kc(e){return F.string().min(1).max(e).refine(t=>t.trim().length>0&&!Oc.test(t)&&yr(t).length<=e,`invalid notification label`)}const Ac=F.strictObject({computerName:kc(128),sessionLabel:kc(128),observedAt:Ec,customName:kc(256).optional(),repository:kc(256).optional(),branch:kc(256).optional(),title:kc(256).optional(),shell:kc(64).optional(),agentName:kc(64).optional()}),jc=F.strictObject({computerFp:U,phoneFp:U,generation:wc,sessionId:F.string().min(1).max(128),eventId:Cc(16)}),Mc=F.enum([`command-finished`,`prompt-returned`,`agent-finished`,`agent-blocked`,`quiet`]),Nc=jc.extend({context:Ac,reason:Mc,exitCode:F.number().int().optional(),durationMs:Ec.optional(),issuedAt:Ec,expiresAt:Ec,sequence:Dc}).refine(e=>e.expiresAt>e.issuedAt&&e.expiresAt-e.issuedAt<=Sc.freshnessMs&&e.context.observedAt<=e.issuedAt,`invalid notification times`).refine(e=>yr(JSON.stringify(e)).length<=Sc.plaintextBytes,`notification plaintext exceeds byte limit`),Pc=jc.extend({nonce:Cc(12),ciphertext:Cc(17,Sc.ciphertextBytes)});function Fc(e){return jc.parse({computerFp:e.computerFp,phoneFp:e.phoneFp,generation:e.generation,sessionId:e.sessionId,eventId:e.eventId})}const Ic=yr(`shellbell-pair-revocation-id-v2\0`),Lc=F.strictObject({v:F.literal(2),computerFp:U,phoneFp:U,pairId:H(32),signature:H(64)});function Rc(e){if(!(e instanceof Uint8Array)||e.length!==32)throw Error(`K_pair must be 32 bytes`);return La(Tr(Ic,e))}function zc(e,t,n){return Gn([`shellbell-pair-revocation-v2`,e,t,n])}function Bc(e,t){if(e.length!==32||t.length!==32)return!1;let n=0;for(let r=0;r<32;r++)n|=(e[r]??0)^(t[r]??0);return n===0}function Vc(e,t){if(!Hc(e,t))return!1;try{return Bc(e.pairId,Rc(t.kPair))}catch{return!1}}function Hc(e,t){let n=Lc.safeParse(e);if(!n.success)return!1;let r=n.data;if(r.computerFp!==t.computerFp||r.phoneFp!==t.phoneFp||t.phoneEd25519Pub.length!==32||rc(t.phoneEd25519Pub)!==t.phoneFp)return!1;try{return oc(t.phoneEd25519Pub,zc(r.computerFp,r.phoneFp,r.pairId),r.signature)}catch{return!1}}const Uc=F.enum([`agent`,`phone`,`pairing`]),Wc=F.enum([`prompt`,`idle`,`exit`,`blocked`]),Gc=F.enum([`bad-sig`,`not-paired`,`fp-mismatch`,`no-agent`,`no-window`,`timeout`]),Kc=F.enum([`bad-code`,`declined`,`window-closed`,`no-agent`,`too-many`]),qc=F.string().min(1).max(64),Jc=F.string().max(256).regex(/^(stun|turns?):[\x21-\x7e]+$/,`ICE server URL must be STUN or TURN`),Yc=F.object({urls:F.array(Jc).min(1).max(8),username:F.string().min(1).max(256).optional(),credential:F.string().min(1).max(256).optional()}).strict(),Xc=F.array(Yc).max(4),Zc=F.number().int().min(0).max(6048e5),Qc=F.string().min(1).max(64),$c=Qn;function el(e){let t=e.environment??void 0;return e.provider===`fcm`?e.platform===`android`&&t===void 0:e.provider===`apns`&&e.platform===`ios`&&(t===`development`||t===`production`)}const tl=F.strictObject({type:F.literal(`push-token`),token:F.string().min(1).max(4096),platform:F.enum([`ios`,`android`]),provider:F.enum([`fcm`,`apns`]).optional(),environment:F.enum([`development`,`production`]).optional(),enabled:F.boolean(),features:Tc.optional()}).superRefine((e,t)=>{if(e.provider===void 0){e.token.length>256&&t.addIssue({code:`custom`,path:[`token`],message:`legacy token exceeds 256 characters`}),e.environment!==void 0&&t.addIssue({code:`custom`,path:[`environment`],message:`environment requires APNs`});return}[...e.token].some(e=>e.charCodeAt(0)>127)&&t.addIssue({code:`custom`,path:[`token`],message:`native token must be ASCII`}),!el(e)&&(e.provider===`fcm`?(e.platform!==`android`&&t.addIssue({code:`custom`,path:[`platform`],message:`FCM requires Android`}),e.environment!==void 0&&t.addIssue({code:`custom`,path:[`environment`],message:`FCM has no environment`})):(e.platform!==`ios`&&t.addIssue({code:`custom`,path:[`platform`],message:`APNs requires iOS`}),e.environment===void 0&&t.addIssue({code:`custom`,path:[`environment`],message:`APNs requires an environment`})))}).refine(e=>e.provider===void 0?e.token.length<=256&&e.environment===void 0:![...e.token].some(e=>e.charCodeAt(0)>127)&&el(e),{message:`invalid push-token provider, platform, environment, or token`}),nl=F.object({phoneFp:U,ed25519Pub:H(32),name:qc,pairId:H(32).optional()}),rl=F.discriminatedUnion(`type`,[F.strictObject({type:F.literal(`notify-context`),sessionId:jc.shape.sessionId,eventId:jc.shape.eventId,kind:F.enum([`prompt`,`idle`,`blocked`]),exitCode:F.number().int().optional(),durationMs:F.number().int().nonnegative().optional(),boxes:F.array(Pc).max(10)}).refine(e=>new Set(e.boxes.map(e=>e.phoneFp)).size===e.boxes.length&&e.boxes.every(t=>t.sessionId===e.sessionId&&t.eventId===e.eventId&&t.computerFp===e.boxes[0]?.computerFp),`inconsistent notification recipients`),F.object({type:F.literal(`challenge`),nonce:H(32),connId:Qc}),F.object({type:F.literal(`auth`),role:Uc,fp:U,ed25519Pub:H(32),sig:H(64),name:qc,appVersion:F.string().max(32),gate:H(16).optional(),turn:F.literal(!1).optional()}),F.object({type:F.literal(`auth-ok`),role:Uc,agentOnline:F.boolean(),computerName:F.string().max(64).nullable(),serverTime:F.number(),minFrameMs:F.number().int().min(50).max(2e3),features:Tc.optional(),iceServers:Xc.optional(),iceExpiresInMs:Zc.optional(),turnOff:F.literal(!0).optional()}),F.object({type:F.literal(`auth-fail`),reason:Gc}),F.object({type:F.literal(`presence`),agentOnline:F.boolean(),computerName:F.string().max(64).nullable()}),F.object({type:F.literal(`unpaired`),phoneFps:F.array(U).max(10),proofs:F.array(Lc).max(10).optional()}),F.object({type:F.literal(`phones`),connected:F.array(F.object({phoneFp:U,connId:Qc,name:qc})).max(10)}),F.object({type:F.literal(`pairings-sync`),phones:F.array(nl).max(10)}),F.object({type:F.literal(`revocation-ack`),phoneFp:U,pairId:H(32)}),F.object({type:F.literal(`pairing-open`),gateHash:H(32),expiresAt:F.number()}),F.object({type:F.literal(`pairing-close`)}),F.object({type:F.literal(`pairing-request`),phoneFp:U,box:$c}),F.object({type:F.literal(`pairing-response`),phoneFp:U,box:$c}),F.object({type:F.literal(`pairing-reject`),phoneFp:U,reason:Kc}),F.object({type:F.literal(`pairing-add`),phoneFp:U,ed25519Pub:H(32),name:qc,pairId:H(32).optional()}),F.object({type:F.literal(`unpair`),phoneFp:U,proof:Lc.optional()}),F.object({type:F.literal(`revocation-submit`),phoneEd25519Pub:H(32),proof:Lc}),F.object({type:F.literal(`revocation-receipt`),phoneFp:U,pairId:H(32),status:F.enum([`stored`,`absent`,`stale`,`unavailable`])}),tl,F.object({type:F.literal(`lease`),ttlMs:F.number().int().min(0).max(12e4)}),F.object({type:F.literal(`ice-refresh`)}),F.object({type:F.literal(`ice-servers`),iceServers:Xc,iceExpiresInMs:Zc}),F.object({type:F.literal(`notify`),sessionId:F.string().min(1).max(128),kind:F.enum([`prompt`,`idle`,`blocked`]),exitCode:F.number().int().optional(),durationMs:F.number().int().nonnegative().optional()}),F.object({type:F.literal(`phone-connected`),phoneFp:U,connId:Qc,name:qc}),F.object({type:F.literal(`phone-disconnected`),phoneFp:U,connId:Qc}),F.object({type:F.literal(`error`),code:F.string().max(64),message:F.string().max(512)})]);function il(e){let t=rl.safeParse(e);if(!t.success)throw new V(`malformed`,`ctrl: ${F.prettifyError(t.error)}`);return t.data}const al={enter:`\r`,tab:` `,"shift-tab":`\x1B[Z`,esc:`\x1B`,backspace:``,delete:`\x1B[3~`,up:`\x1B[A`,down:`\x1B[B`,right:`\x1B[C`,left:`\x1B[D`,home:`\x1B[H`,end:`\x1B[F`,"page-up":`\x1B[5~`,"page-down":`\x1B[6~`,"ctrl-space":`\0`,...Object.fromEntries(`abcdefghijklmnopqrstuvwxyz`.split(``).map((e,t)=>[`ctrl-${e}`,String.fromCharCode(t+1)])),f1:`\x1BOP`,f2:`\x1BOQ`,f3:`\x1BOR`,f4:`\x1BOS`,f5:`\x1B[15~`,f6:`\x1B[17~`,f7:`\x1B[18~`,f8:`\x1B[19~`,f9:`\x1B[20~`,f10:`\x1B[21~`,f11:`\x1B[23~`,f12:`\x1B[24~`},ol=F.enum(Object.keys(al));function sl(e){return al[e]}const cl=new Uint8Array,ll=yr(`Noise_KKpsk2_25519_ChaChaPoly_SHA256`),ul=(1n<<64n)-2n,dl=65535,fl=Symbol(`Noise transport factory`);function pl(){return globalThis.process?.env?.NODE_ENV===`test`}function ml(e){if(e<0n||e>ul)throw Error(`invalid Noise sequence or reserved nonce`)}function hl(e){ml(e);let t=new Uint8Array(8);return new DataView(t.buffer).setBigUint64(0,e,!0),t}function gl(e){if(e.length!==8)throw Error(`invalid Noise sequence length`);let t=new DataView(e.buffer,e.byteOffset,8).getBigUint64(0,!0);return ml(t),t}function _l(e){let t=new Uint8Array(12);return t.set(hl(e),4),t}function vl(e,t,n){let r=qs(La,e,t),i=qs(La,r,Uint8Array.of(1)),a=qs(La,r,Tr(i,Uint8Array.of(2))),o=n===2?[i,a]:[i,a,qs(La,r,Tr(a,Uint8Array.of(3)))];return r.fill(0),o}function yl(e,t){let n=Gs.getSharedSecret(e,t);if(n.every(e=>e===0))throw Error(`invalid Noise public key`);return n}var bl=class{chainingKey=La(ll);hash=this.chainingKey.slice();key=null;nonce=0n;get handshakeHash(){return this.hash.slice()}mixHash(e){this.hash=La(Tr(this.hash,e))}setKey(e){this.key?.fill(0),this.key=e,this.nonce=0n}mixKey(e){let[t,n]=vl(this.chainingKey,e,2);this.chainingKey.fill(0),this.chainingKey=t,this.setKey(n)}mixKeyAndHash(e){let[t,n,r]=vl(this.chainingKey,e,3);this.chainingKey.fill(0),this.chainingKey=t,this.mixHash(n),n.fill(0),this.setKey(r)}encryptAndHash(e){if(!this.key)throw Error(`Noise handshake key missing`);let t=ji(this.key,_l(this.nonce),this.hash).encrypt(e);return this.nonce+=1n,this.mixHash(t),t}decryptAndHash(e){if(!this.key)throw Error(`Noise handshake key missing`);let t=ji(this.key,_l(this.nonce),this.hash).decrypt(e);return this.nonce+=1n,this.mixHash(e),t}split(){let[e,t]=vl(this.chainingKey,cl,2);return this.close(),[e,t]}close(){this.chainingKey.fill(0),this.hash.fill(0),this.key?.fill(0),this.key=null}},xl=class{sendKey;receiveKey;lastSent=-1n;lastReceived=-1n;closed=!1;constructor(e,t,n,r){if(r!==fl)throw Error(`Noise transport factory required`);this.sendKey=new Uint8Array(e===`initiator`?t:n),this.receiveKey=new Uint8Array(e===`initiator`?n:t),t.fill(0),n.fill(0)}seal(e,t,n=cl){if(this.closed)throw Error(`Noise transport closed`);if(t.length>65519)throw Error(`Noise message too large`);if(ml(e),e<=this.lastSent)throw Error(`Noise send sequence reuse`);let r=ji(this.sendKey,_l(e),n).encrypt(t);return this.lastSent=e,r}open(e,t,n=cl){if(this.closed)throw Error(`Noise transport closed`);if(t.length<16||t.length>dl)throw Error(`Noise message length invalid`);if(ml(e),e<=this.lastReceived)throw Error(`Noise receive sequence replay`);let r=ji(this.receiveKey,_l(e),n).decrypt(t);return this.lastReceived=e,r}close(){this.closed||(this.closed=!0,this.sendKey.fill(0),this.receiveKey.fill(0))}},Sl=class{role;staticPrivate;remoteStatic;psk;ephemeralPrivate;remoteEphemeral=null;symmetric=new bl;finalHash=null;phase=`first`;constructor(e){if(e.role!==`initiator`&&e.role!==`responder`)throw Error(`invalid Noise role`);if(e.ephemeralPrivate&&!pl())throw Error(`fixed Noise ephemeral key is test-only`);for(let t of[e.staticPrivate,e.remoteStatic,e.psk])if(t.length!==32)throw Error(`Noise key must be 32 bytes`);if(e.prologue.length>1024)throw Error(`Noise prologue too large`);if(e.ephemeralPrivate&&e.ephemeralPrivate.length!==32)throw Error(`Noise ephemeral key must be 32 bytes`);this.role=e.role,this.staticPrivate=new Uint8Array(e.staticPrivate),this.remoteStatic=new Uint8Array(e.remoteStatic),this.psk=new Uint8Array(e.psk),this.ephemeralPrivate=e.ephemeralPrivate?new Uint8Array(e.ephemeralPrivate):Gs.utils.randomSecretKey(),this.symmetric.mixHash(e.prologue);let t=Gs.getPublicKey(this.staticPrivate);this.symmetric.mixHash(this.role===`initiator`?t:this.remoteStatic),this.symmetric.mixHash(this.role===`responder`?t:this.remoteStatic)}get handshakeHash(){if(this.finalHash)return this.finalHash.slice();if(this.phase!==`complete`)throw Error(`Noise handshake not complete`);return this.symmetric.handshakeHash}write(e=cl){if(e.length>0&&!pl())throw Error(`Noise handshake payloads are test-only`);if(this.role===`initiator`&&this.phase!==`first`||this.role===`responder`&&this.phase!==`second`)throw Error(`Noise handshake message order`);if(e.length>65487)throw Error(`Noise handshake payload too large`);try{let t=Gs.getPublicKey(this.ephemeralPrivate);if(this.symmetric.mixHash(t),this.symmetric.mixKey(t),this.role===`initiator`)this.symmetric.mixKey(yl(this.ephemeralPrivate,this.remoteStatic)),this.symmetric.mixKey(yl(this.staticPrivate,this.remoteStatic));else{if(!this.remoteEphemeral)throw Error(`Noise peer ephemeral key missing`);this.symmetric.mixKey(yl(this.ephemeralPrivate,this.remoteEphemeral)),this.symmetric.mixKey(yl(this.ephemeralPrivate,this.remoteStatic)),this.symmetric.mixKeyAndHash(this.psk)}let n=Tr(t,this.symmetric.encryptAndHash(e));return this.phase=this.role===`initiator`?`second`:`complete`,n}catch(e){throw this.close(),e}}read(e){if(this.role===`responder`&&this.phase!==`first`||this.role===`initiator`&&this.phase!==`second`)throw Error(`Noise handshake message order`);if(e.length<48||e.length>dl)throw this.close(),Error(`Noise handshake message length`);if(e.length!==48&&!pl())throw this.close(),Error(`Noise handshake payloads are test-only`);try{let t=new Uint8Array(e.subarray(0,32));this.remoteEphemeral=t,this.symmetric.mixHash(t),this.symmetric.mixKey(t),this.role===`responder`?(this.symmetric.mixKey(yl(this.staticPrivate,t)),this.symmetric.mixKey(yl(this.staticPrivate,this.remoteStatic))):(this.symmetric.mixKey(yl(this.ephemeralPrivate,t)),this.symmetric.mixKey(yl(this.staticPrivate,t)),this.symmetric.mixKeyAndHash(this.psk));let n=this.symmetric.decryptAndHash(e.subarray(32));return this.phase=this.role===`responder`?`second`:`complete`,n}catch(e){throw this.close(),e}}split(){if(this.phase!==`complete`)throw Error(`Noise handshake not complete`);this.finalHash=this.symmetric.handshakeHash;let[e,t]=this.symmetric.split();return this.close(),new xl(this.role,e,t,fl)}close(){this.phase!==`failed`&&(this.phase=`failed`,this.staticPrivate.fill(0),this.remoteStatic.fill(0),this.psk.fill(0),this.ephemeralPrivate.fill(0),this.remoteEphemeral?.fill(0),this.symmetric.close())}};const Cl=`shellbell-v2-key-confirm`,wl=Symbol(`v2 handshake factory`),Tl=Symbol(`v2 session factory`),El=H(16).refine(e=>e.some(e=>e!==0),{message:`v2 ID must not be zero`}),Dl=H(8).refine(e=>{try{return gl(e)>0n}catch{return!1}},{message:`invalid v2 route generation`}),Ol={computerFp:U,phoneFp:U,sessionId:El,attemptId:El,generation:Dl},kl=F.discriminatedUnion(`route`,[F.object({...Ol,route:F.literal(`relay`)}).strict(),F.object({...Ol,route:F.literal(`direct`),phoneDtls:H(32),computerDtls:H(32)}).strict()]),Al=F.custom(e=>e instanceof Uint8Array&&e.length>=16&&e.length<=60016,{message:`invalid v2 ciphertext length`}),jl=F.object({v:F.literal(2),type:F.enum([`confirm`,`data`]),sessionId:El,generation:Dl,seq:H(8),ciphertext:Al}).strict();function Ml(e){let t=kl.parse(e),n={...t,sessionId:new Uint8Array(t.sessionId),attemptId:new Uint8Array(t.attemptId),generation:new Uint8Array(t.generation),...t.route===`direct`&&{phoneDtls:new Uint8Array(t.phoneDtls),computerDtls:new Uint8Array(t.computerDtls)}};return kl.parse(n)}function Nl(e){let t=kl.parse(e);return Gn([`shellbell-session-v2`,2,`phone`,`computer`,t.computerFp,t.phoneFp,t.sessionId,t.attemptId,t.generation,t.route,t.route===`direct`?t.phoneDtls:null,t.route===`direct`?t.computerDtls:null])}function Pl(e,t,n){return Gn([`shellbell-v2-frame`,e.sessionId,e.attemptId,e.generation,e.route,t,n.type,n.seq])}function Fl(e){return e===`phone`?`computer`:`phone`}function Il(e){let t=Gn(jl.parse(e));if(t.length>61e3)throw new V(`malformed`,`v2 frame too large`);return t}function Ll(e){if(e.length>61e3)throw new V(`malformed`,`v2 frame too large`);return jl.parse(Kn(e))}var Rl=class{context;role;noise;finished=!1;constructor(e,t,n,r){if(this.context=e,this.role=t,this.noise=n,r!==wl)throw Error(`v2 handshake factory required`)}write(){if(this.finished)throw Error(`v2 handshake finished`);return this.noise.write()}read(e){if(this.finished)throw Error(`v2 handshake finished`);if(e.length!==48)throw Error(`v2 empty-payload handshake must be 48 bytes`);if(this.noise.read(e).length!==0)throw Error(`v2 handshake payload forbidden`)}finish(){if(this.finished)throw Error(`v2 handshake already finished`);let e=this.noise.handshakeHash,t=this.noise.split();return this.finished=!0,new Bl(this.context,this.role,t,e,Tl)}close(){this.finished=!0,this.noise.close()}};function zl(e,t,n){if(t!==`phone`&&t!==`computer`)throw Error(`invalid v2 role`);let r=Ml(e),i=mc(n.pairKey,r.computerFp,r.phoneFp);try{return new Rl(r,t,new Sl({role:t===`phone`?`initiator`:`responder`,staticPrivate:n.staticPrivate,remoteStatic:n.remoteStatic,psk:i,prologue:Nl(r)}),wl)}finally{i.fill(0)}}var Bl=class{context;role;transport;handshakeHash;sentConfirmation=!1;receivedConfirmation=!1;dtlsVerified=!1;nextSequence=0n;lastReceived=-1n;closed=!1;constructor(e,t,n,r,i){if(this.context=e,this.role=t,this.transport=n,this.handshakeHash=r,i!==Tl)throw Error(`v2 session factory required`)}get ready(){return!this.closed&&this.sentConfirmation&&this.receivedConfirmation&&(this.context.route===`relay`||this.dtlsVerified)}get description(){return Ml(this.context)}get senderRole(){return this.role}verifyRemoteDtls(e){if(this.closed)throw Error(`v2 session closed`);if(this.context.route!==`direct`)throw Error(`relay route has no DTLS certificate`);let t=this.role===`phone`?this.context.computerDtls:this.context.phoneDtls;if(e.length!==32||!Er(e,t))throw this.close(),Error(`remote DTLS certificate mismatch`);this.dtlsVerified=!0}frame(e,t){if(this.closed)throw Error(`v2 session closed`);if(t.length>6e4)throw Error(`v2 data too large`);let n=hl(this.nextSequence),r={v:2,type:e,sessionId:this.context.sessionId.slice(),generation:this.context.generation.slice(),seq:n,ciphertext:new Uint8Array};return r.ciphertext=this.transport.seal(this.nextSequence,t,Pl(this.context,this.role,r)),this.nextSequence+=1n,r}openFrame(e,t){if(this.closed)throw Error(`v2 session closed`);let n=jl.parse(e);if(n.type!==t)throw Error(`wrong v2 frame type`);if(!Er(n.sessionId,this.context.sessionId)||!Er(n.generation,this.context.generation))throw Error(`wrong v2 session or route generation`);let r=gl(n.seq),i=this.transport.open(r,n.ciphertext,Pl(this.context,Fl(this.role),n));if(r!==this.lastReceived+1n)throw i.fill(0),this.close(),Error(`v2 sequence gap requires resync`);return this.lastReceived=r,i}confirmation(){if(this.sentConfirmation)throw Error(`v2 confirmation already sent`);let e=this.frame(`confirm`,Gn([Cl,this.handshakeHash,this.role]));return this.sentConfirmation=!0,e}acceptConfirmation(e){try{if(this.receivedConfirmation)throw Error(`v2 confirmation already received`);if(gl(e.seq)!==0n)throw Error(`v2 confirmation sequence must be 0`);let t=Kn(this.openFrame(e,`confirm`));if(!Array.isArray(t)||t.length!==3||t[0]!==Cl||!(t[1]instanceof Uint8Array)||!Er(t[1],this.handshakeHash)||t[2]!==Fl(this.role))throw Error(`invalid v2 key confirmation`);this.receivedConfirmation=!0}catch(e){throw this.close(),e}}seal(e){if(this.closed)throw Error(`v2 session closed`);if(!this.ready)throw Error(`v2 key confirmation incomplete`);return this.frame(`data`,e)}open(e){if(this.closed)throw Error(`v2 session closed`);if(!this.ready)throw Error(`v2 key confirmation incomplete`);if(gl(e.seq)<1n)throw Error(`v2 data sequence must be positive`);return this.openFrame(e,`data`)}close(){this.closed||(this.closed=!0,this.transport.close(),this.handshakeHash.fill(0))}};const Vl=`shellbell-v2-route-payload`,Hl=59e3,Ul={terminalBytes:Hl,signalBytes:3e4,controlBytes:512,payloadBytes:6e4,attemptMs:15e3,directAttempts:32,wireSessions:128},Wl={transitionId:El,target:F.object({route:F.enum([`relay`,`direct`]),sessionId:El,attemptId:El,generation:Dl}).strict()},Gl=F.discriminatedUnion(`type`,[F.object({type:F.literal(`route.prepare`),...Wl}).strict(),F.object({type:F.literal(`route.prepared`),...Wl}).strict(),F.object({type:F.literal(`route.commit`),...Wl}).strict(),F.object({type:F.literal(`route.committed`),...Wl}).strict(),F.object({type:F.literal(`route.abort`),...Wl,reason:F.enum([`cancelled`,`timeout`,`not-ready`,`candidate-failed`])}).strict()]);function Kl(e,t){return e instanceof Uint8Array&&e.length>0&&e.length<=t}function ql(e){let t;if(e.kind===`control`){if(t=Gl.parse(e.control),Gn(t).length>Ul.controlBytes)throw new V(`malformed`)}else{if(!Kl(e.bytes,e.kind===`terminal`?Ul.terminalBytes:Ul.signalBytes))throw new V(`malformed`);t=e.bytes}let n=Gn([Vl,e.kind,t]);if(n.length>Ul.payloadBytes)throw new V(`malformed`);return n}function Jl(e){let t=hr(e,Ul.payloadBytes,{allowBytes:!0});if(!Array.isArray(t)||t.length!==3||t[0]!==Vl)throw new V(`malformed`);if(t[1]===`control`){if(Gn(t[2]).length>Ul.controlBytes)throw new V(`malformed`);let e=Gl.parse(t[2]);return{kind:`control`,control:{...e,transitionId:e.transitionId.slice(),target:{route:e.target.route,sessionId:e.target.sessionId.slice(),attemptId:e.target.attemptId.slice(),generation:e.target.generation.slice()}}}}if(t[1]!==`terminal`&&t[1]!==`signal`||!Kl(t[2],t[1]===`terminal`?Ul.terminalBytes:Ul.signalBytes))throw new V(`malformed`);return{kind:t[1],bytes:t[2].slice()}}const Yl=F.enum([`iterm2`,`tmux`,`herdr`]),Xl=F.string().regex(/^[a-z][a-z0-9-]{0,31}$/),Zl={iterm2:`iTerm2`,tmux:`tmux`,herdr:`Herdr`},Ql=F.enum([`darwin`,`linux`,`win32`,`unknown`]),$l=F.number().int().min(0).max(255),eu=F.union([$l,F.tuple([$l,$l,$l])]),tu=F.object({t:F.string().max(4096),fg:eu.optional(),bg:eu.optional(),b:F.boolean().optional(),i:F.boolean().optional(),u:F.boolean().optional(),s:F.boolean().optional(),f:F.boolean().optional(),n:F.number().int().min(0).max(4096).optional()}),nu=F.object({r:F.array(tu).max(2048),w:F.boolean().optional()}),ru=F.object({x:F.number().int(),y:F.number().int()}),iu=F.object({subscribe:F.boolean(),prompts:F.boolean(),createSession:F.boolean(),focus:F.boolean(),history:F.boolean(),absoluteLines:F.boolean(),mouseClick:F.boolean().optional(),terminalInput:F.boolean().optional(),terminalPaste:F.boolean().optional(),vtStream:F.boolean().optional()}),au=F.string().min(1).max(64).refine(e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127)),ou=F.object({name:Xl,label:au,capabilities:iu,connected:F.boolean(),launchable:F.boolean()}),su=F.array(ou).max(32).refine(e=>new Set(e.map(e=>e.name)).size===e.length,`adapter IDs must be unique`),cu=F.object({backend:Xl,host:Xl,label:au}),lu=F.array(cu).max(64).refine(e=>new Set(e.map(e=>`${e.backend}:${e.host}`)).size===e.length,`launch targets must be unique`),uu=F.object({backend:Xl,reason:F.string().min(1).max(240).refine(e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127))}),du=F.array(uu).max(16).refine(e=>new Set(e.map(e=>e.backend)).size===e.length,`one launch issue per backend`),fu=F.enum([`not-installed`,`not-running`,`no-session`,`api-off`,`needs-consent`,`connecting`,`automation-denied`,`iterm2-denied`,`timed-out`,`too-old`,`limited`,`failed`]),pu=F.strictObject({name:Xl,connected:F.boolean(),issue:fu.optional(),detail:uu.shape.reason.optional()}),mu=F.array(pu).max(16).refine(e=>new Set(e.map(e=>e.name)).size===e.length),hu=[`iterm2`,`ghostty`];function gu(e,t){let n=e=>{let t=hu.indexOf(e);return t===-1?hu.length:t};return n(e)-n(t)||e.localeCompare(t)}function _u(e,t=[]){return t.filter(t=>t.backend===e).sort((e,t)=>gu(e.host,t.host))[0]}const vu=F.object({column:F.number().int().min(0).max(W.cols-1),row:F.number().int().min(0).max(W.rows-1),cols:F.number().int().min(1).max(W.cols),rows:F.number().int().min(1).max(W.rows),button:F.enum([`left`,`right`,`middle`]),modifiers:F.number().int().min(0).max(7)}),yu=F.enum([`unknown`,`editing`,`running`,`finished`,`blocked`]),bu=F.string().min(1).max(64),xu=F.object({id:nr,backend:Xl,title:F.string().max(256),cwd:F.string().max(1024).optional(),cols:F.number().int().positive(),rows:F.number().int().positive(),windowId:F.string().max(128),windowNumber:F.number().int(),tabId:F.string().max(128),tabIndex:F.number().int(),paneIndex:F.number().int(),isFocusedOnMac:F.boolean(),state:yu,project:F.string().min(1).max(128).optional(),windowLabel:F.string().min(1).max(128).optional(),agent:F.object({kind:F.string().min(1).max(32),task:F.string().min(1).max(256).optional(),reportsState:F.literal(!0).optional()}).optional(),stateSince:F.number().int().nonnegative().optional(),activeAt:F.number().int().nonnegative().optional(),alternateScreen:F.boolean().optional(),shownIn:F.array(au).min(1).max(4).optional(),instance:F.string().min(1).max(64).optional()}),Su=Object.freeze({minCols:40,maxCols:240,minRows:24,maxRows:100}),Cu=F.object({cols:F.number().int().min(Su.minCols).max(Su.maxCols),rows:F.number().int().min(Su.minRows).max(Su.maxRows)}),wu=F.union([F.object({kind:F.literal(`tab`),backend:Xl,windowId:F.string().max(128).optional(),host:Xl.optional(),initialSize:Cu.optional()}).refine(e=>e.host===void 0||e.windowId===void 0,`host launch requires a new independent session`).refine(e=>e.initialSize===void 0||e.windowId===void 0,`initial size applies only to a new independent window`),F.object({kind:F.literal(`split`),sessionId:nr,direction:F.enum([`vertical`,`horizontal`])})]),Tu={sessionId:nr,cursor:ru,scrollbackTotal:F.number().int().nonnegative(),gen:F.number().int().nonnegative()},Eu=F.object({type:F.literal(`hello`),agentVersion:F.string().max(32),features:Tc.optional(),conversationEnabled:F.boolean().optional(),hostPlatform:Ql.optional(),launchableBackends:F.array(Xl).max(4).optional(),backendCatalog:su.optional(),sessionLaunchTargets:lu.optional(),sessionLaunchIssues:du.optional(),terminalSetup:mu.optional(),backends:F.array(F.object({name:Xl,capabilities:iu})).max(4),computerName:F.string().max(64),accent:F.string().max(32)}),Du=F.object({type:F.literal(`sessions`),list:F.array(xu).max(500),complete:F.boolean().optional()}),Ou=F.object({type:F.literal(`event`),sessionId:nr,kind:Wc,exitCode:F.number().int().optional(),durationMs:F.number().int().nonnegative().optional(),command:F.string().max(512).optional(),at:F.number()}),ku=F.discriminatedUnion(`type`,[F.object({type:F.literal(`notification.enroll`),generation:wc}),F.object({type:F.literal(`notification.enrolled`),generation:wc}),F.object({type:F.literal(`conn.hello`),n:H(16),features:F.array(F.string().min(1).max(32)).max(8).optional()}),F.object({type:F.literal(`session.v2.bootstrap`),bytes:H().refine(e=>e.length>0&&e.length<=1024)}),Eu,Du,F.object({type:F.literal(`screen.snapshot`),...Tu,cols:F.number().int().positive(),rows:F.number().int().positive(),lines:F.array(nu).max(1e3),reset:F.boolean().optional(),degraded:F.boolean().optional()}),F.object({type:F.literal(`screen.diff`),...Tu,scroll:F.number().int().nonnegative().max(1e3),changed:F.array(F.object({i:F.number().int().nonnegative(),line:nu})).max(1e3)}),F.object({type:F.literal(`history`),sessionId:nr,before:F.number().int().nonnegative(),lines:F.array(nu).max(200),oldestAvailable:F.number().int().nonnegative()}),Ou,F.object({type:F.literal(`ack`),reqId:bu,ok:F.boolean(),error:F.string().max(256).optional(),sessionId:nr.optional()}),F.object({type:F.literal(`subscribe`),sessionId:nr.nullable()}),F.object({type:F.literal(`input.line`),reqId:bu,sessionId:nr,text:F.string().max(8192)}),F.object({type:F.literal(`input.text`),reqId:bu,sessionId:nr,text:F.string().max(65536)}),F.object({type:F.literal(`input.key`),reqId:bu,sessionId:nr,key:ol}),F.object({type:F.literal(`input.terminal`),reqId:bu,sessionId:nr,data:F.string().min(1).max(Hl)}),F.object({type:F.literal(`input.paste`),reqId:bu,sessionId:nr,text:F.string().min(1).max(Hl),submit:F.boolean()}),vu.extend({type:F.literal(`input.mouse`),reqId:bu,sessionId:nr}).refine(e=>e.column<e.cols&&e.row<e.rows,`Mouse coordinates must be inside the source grid`),F.object({type:F.literal(`history.get`),reqId:bu,sessionId:nr,before:F.number().int().nonnegative(),count:F.number().int().min(1).max(200)}),F.object({type:F.literal(`session.create`),reqId:bu,in:wu}),F.object({type:F.literal(`session.focus`),reqId:bu,sessionId:nr}),F.object({type:F.literal(`snapshot.get`),reqId:bu,sessionId:nr}),...ur.options,...Lr.options]);function Au(e){let t=ku.safeParse(e);if(!t.success)throw new V(`malformed`,`inner: ${F.prettifyError(t.error)}`);return t.data}const ju=e=>F.union([e,F.string().min(1).max(32)]),Mu=ju(Xl),Nu=ju(yu),Pu=ju(Wc),Fu=xu.extend({backend:Mu,state:Nu});F.discriminatedUnion(`type`,[Eu.extend({launchableBackends:F.array(Mu).max(4).optional(),backends:F.array(F.object({name:Mu,capabilities:iu})).max(4)}),Du.extend({list:F.array(Fu).max(500)}),Ou.extend({kind:Pu})]),F.object({type:F.literal(`notify`),sessionId:nr,kind:Pu,exitCode:F.number().int().optional(),durationMs:F.number().int().nonnegative().optional()});const Iu=/[\x00-\x1f\x7f-\x9f]/;function Lu(e,t){if(!Number.isSafeInteger(e)||e<1||e>W.cols||t.length>2e3)return null;let n=La.create();n.update(yr(`shellbell-native-history-v1\n${e}\n${t.length}\n`));let r=0;for(let e of t){if(typeof e!=`string`||e.length>W.screenBytes||Iu.test(e))return null;let t=yr(`${JSON.stringify(e.replace(/ +$/,``))}\n`);if(r+=t.byteLength,r>W.screenBytes)return null;n.update(t)}return Cr(n.digest())}const Ru=new Uint8Array(16),zu=Jr(Ru),Bu=(e,t,n,r)=>{let i=r&1;return{s3:n<<31|r>>>1,s2:t<<31|n>>>1,s1:e<<31|t>>>1,s0:e>>>1^225<<24&-(i&1)}},Vu=e=>(e>>>0&255)<<24|(e>>>8&255)<<16|(e>>>16&255)<<8|e>>>24&255|0,Hu=e=>e>65536?8:e>1024?4:2;var Uu=class{blockLen=16;outputLen=16;s0=0;s1=0;s2=0;s3=0;finished=!1;destroyed=!1;t;W;windowSize;constructor(e,t){Hr(e,16,`key`),e=di(e);let n=Xr(e),r=n.getUint32(0,!1),i=n.getUint32(4,!1),a=n.getUint32(8,!1),o=n.getUint32(12,!1),s=[];for(let e=0;e<128;e++)s.push({s0:Vu(r),s1:Vu(i),s2:Vu(a),s3:Vu(o)}),{s0:r,s1:i,s2:a,s3:o}=Bu(r,i,a,o);let c=Hu(t||1024);if(![1,2,4,8].includes(c))throw Error(`ghash: invalid window size, expected 2, 4 or 8`);this.W=c;let l=128/c,u=this.windowSize=2**c,d=[];for(let e=0;e<l;e++)for(let t=0;t<u;t++){let n=0,r=0,i=0,a=0;for(let o=0;o<c;o++){if(!(t>>>c-o-1&1))continue;let{s0:l,s1:u,s2:d,s3:f}=s[c*e+o];n^=l,r^=u,i^=d,a^=f}d.push({s0:n,s1:r,s2:i,s3:a})}this.t=d}_updateBlock(e,t,n,r){e^=this.s0,t^=this.s1,n^=this.s2,r^=this.s3;let{W:i,t:a,windowSize:o}=this,s=0,c=0,l=0,u=0,d=(1<<i)-1,f=0;for(let p of[e,t,n,r])for(let e=0;e<4;e++){let t=p>>>8*e&255;for(let e=8/i-1;e>=0;e--){let n=t>>>i*e&d,{s0:r,s1:p,s2:m,s3:h}=a[f*o+n];s^=r,c^=p,l^=m,u^=h,f+=1}}this.s0=s,this.s1=c,this.s2=l,this.s3=u}update(e){Wr(this),Hr(e),e=di(e);let t=Jr(e),n=Math.floor(e.length/16),r=e.length%16;for(let e=0;e<n;e++)this._updateBlock($r(t[e*4+0]),$r(t[e*4+1]),$r(t[e*4+2]),$r(t[e*4+3]));return r&&(Ru.set(e.subarray(n*16)),this._updateBlock($r(zu[0]),$r(zu[1]),$r(zu[2]),$r(zu[3])),Yr(zu)),this}destroy(){this.destroyed=!0;let{t:e}=this;for(let t of e)t.s0=0,t.s1=0,t.s2=0,t.s3=0}digestInto(e){Wr(this),Kr(e,this),this.finished=!0;let{s0:t,s1:n,s2:r,s3:i}=this,a=Jr(e);a[0]=t,a[1]=n,a[2]=r,a[3]=i,Zr||ti(a.subarray(0,4))}digest(){let e=new Uint8Array(16);return this.digestInto(e),this.destroy(),e}};const Wu=oi(16,(e,t)=>new Uu(e,t),e=>[e.length]),Gu=new Uint8Array(16);function Ku(e){if(![16,24,32].includes(e.length))throw Error(`"aes key" expected Uint8Array of length 16/24/32, got length=`+e.length)}function qu(e){return e<<1^283&-(e>>7)}function Ju(e,t){let n=0;for(;t>0;t>>=1)n^=e&-(t&1),e=qu(e);return n}const Yu=(()=>{let e=new Uint8Array(256);for(let t=0,n=1;t<256;t++,n^=qu(n))e[t]=n;let t=new Uint8Array(256);t[0]=99;for(let n=0;n<255;n++){let r=e[255-n];r|=r<<8,t[e[n]]=(r^r>>4^r>>5^r>>6^r>>7^99)&255}return Yr(e),t})(),Xu=e=>e<<24|e>>>8,Zu=e=>e<<8|e>>>24;function Qu(e,t){if(e.length!==256)throw Error(`wrong sbox length`);let n=new Uint32Array(256).map((n,r)=>t(e[r])),r=n.map(Zu),i=r.map(Zu),a=i.map(Zu),o=new Uint32Array(65536),s=new Uint32Array(65536),c=new Uint16Array(65536);for(let t=0;t<256;t++)for(let l=0;l<256;l++){let u=t*256+l;o[u]=n[t]^r[l],s[u]=i[t]^a[l],c[u]=e[t]<<8|e[l]}return{sbox:e,sbox2:c,T0:n,T1:r,T2:i,T3:a,T01:o,T23:s}}const $u=Qu(Yu,e=>Ju(e,3)<<24|e<<16|e<<8|Ju(e,2)),ed=(()=>{let e=new Uint8Array(16);for(let t=0,n=1;t<16;t++,n=qu(n))e[t]=n;return e})();function td(e){Hr(e);let t=e.length;Ku(e);let{sbox2:n}=$u,r=[];(!Zr||!ui(e))&&r.push(e=di(e));let i=ti(Jr(e)),a=i.length,o=e=>rd(n,e,e,e,e),s=new Uint32Array(t+28);s.set(i);for(let e=a;e<s.length;e++){let t=s[e-1];e%a===0?t=o(Xu(t))^ed[e/a-1]:a>6&&e%a===4&&(t=o(t)),s[e]=s[e-a]^t}return Yr(...r),s}function nd(e,t,n,r,i,a){return e[n<<8&65280|r>>>8&255]^t[i>>>8&65280|a>>>24&255]}function rd(e,t,n,r,i){return e[t&255|n&65280]|e[r>>>16&255|i>>>16&65280]<<16}function id(e,t,n,r,i){let{sbox2:a,T01:o,T23:s}=$u,c=0;t^=e[c++],n^=e[c++],r^=e[c++],i^=e[c++];let l=e.length/4-2;for(let a=0;a<l;a++){let a=e[c++]^nd(o,s,t,n,r,i),l=e[c++]^nd(o,s,n,r,i,t),u=e[c++]^nd(o,s,r,i,t,n),d=e[c++]^nd(o,s,i,t,n,r);t=a,n=l,r=u,i=d}return{s0:e[c++]^rd(a,t,n,r,i),s1:e[c++]^rd(a,n,r,i,t),s2:e[c++]^rd(a,r,i,t,n),s3:e[c++]^rd(a,i,t,n,r)}}function ad(e,t,n,r,i){Hr(n,16,`nonce`),Hr(r),i=ci(r.length,i);let a=n,o=Jr(a),s=Xr(a),c=Jr(r),l=Jr(i),u=t?0:12,d=r.length,f=s.getUint32(u,t);for(let n=0;n+4<=c.length;n+=4){let{s0:r,s1:i,s2:a,s3:d}=id(e,$r(o[0]),$r(o[1]),$r(o[2]),$r(o[3]));l[n+0]=c[n+0]^$r(r),l[n+1]=c[n+1]^$r(i),l[n+2]=c[n+2]^$r(a),l[n+3]=c[n+3]^$r(d),f=f+1>>>0,s.setUint32(u,f,t)}let p=16*Math.floor(c.length/4);if(p<d){let{s0:t,s1:n,s2:a,s3:s}=id(e,$r(o[0]),$r(o[1]),$r(o[2]),$r(o[3])),c=new Uint32Array([t,n,a,s]);ti(c);let l=qr(c);for(let e=p,t=0;e<d;e++,t++)i[e]=r[e]^l[t];Yr(c)}return i}function od(e,t,n,r,i){let a=i?i.length:0,o=e.create(n,r.length+a);i&&o.update(i);let s=li(8*r.length,8*a,t);o.update(r),o.update(s);let c=o.digest();return Yr(s),c}const sd=si({blockSize:16,nonceLength:12,tagLength:16,withAAD:!0,varSizeNonce:!0},function(e,t,n){if(t.length<8)throw Error(`aes/gcm: invalid nonce length`);function r(e,t,r){let i=od(Wu,!1,e,r,n);for(let e=0;e<t.length;e++)i[e]^=t[e];return i}function i(){let n=td(e),r=Gu.slice(),i=Gu.slice();if(ad(n,!1,i,i,r),t.length===12)i.set(t);else{let e=Gu.slice();Xr(e).setBigUint64(8,BigInt(t.length*8),!1);let n=Wu.create(r).update(t).update(e);n.digestInto(i),n.destroy()}return{xk:n,authKey:r,counter:i,tagMask:ad(n,!1,i,Gu)}}return{encrypt(e){let{xk:t,authKey:n,counter:a,tagMask:o}=i(),s=new Uint8Array(e.length+16),c=[t,n,a,o];ui(e)||c.push(e=di(e)),ad(t,!1,a,e,s.subarray(0,e.length));let l=r(n,o,s.subarray(0,s.length-16));return c.push(l),s.set(l,e.length),Yr(...c),s},decrypt(e){let{xk:t,authKey:n,counter:a,tagMask:o}=i(),s=[t,n,o,a];ui(e)||s.push(e=di(e));let c=e.subarray(0,-16),l=e.subarray(-16),u=r(n,o,c);if(s.push(u),!ai(u,l))throw Yr(...s),Error(`aes-gcm: invalid tag`);let d=ad(t,!1,a,c);return Yr(...s),d}}});function cd(e){if(!(e instanceof Uint8Array)||e.length!==32)throw new V(`crypto`,`invalid notification key`)}const ld=jc.pick({computerFp:!0,phoneFp:!0,generation:!0});function ud(e,t){cd(e);let n=ld.parse({computerFp:t.computerFp,phoneFp:t.phoneFp,generation:t.generation});return Zs(La,e,yr(xc),yr(JSON.stringify([n.computerFp,n.phoneFp,n.generation])),32)}function dd(e){let t=Fc(e);return yr(JSON.stringify([xc,t.computerFp,t.phoneFp,t.generation,t.sessionId,t.eventId]))}function fd(e,t){try{cd(e);let n=Nc.parse(t),r=Fc(n),i=ya(12),a=yr(JSON.stringify(n));try{let t=sd(e,i,dd(r)).encrypt(a);return{...r,nonce:br(i),ciphertext:br(t)}}finally{a.fill(0)}}catch{throw new V(`crypto`,`notification seal failed`)}}const pd=F.string().regex(/^[A-Za-z0-9_-]{22}$/),md=F.object({v:F.literal(1),r:F.url().max(256),c:U,e:F.string().regex(/^[A-Za-z0-9_-]{43}$/),n:F.string().min(1).max(40),p:pd,g:pd,b:F.literal(1).optional(),x:F.number().int().positive().max(2**32).optional()});function hd(e){return JSON.stringify(e)}function gd(e,t={}){let n;try{n=JSON.parse(e)}catch{throw new V(`malformed`,`qr: not json`)}let r=md.safeParse(n);if(!r.success)throw new V(`malformed`,`qr: ${F.prettifyError(r.error)}`);let i=r.data,a=new URL(i.r);if(a.username||a.password)throw new V(`malformed`,`qr: relay url must not contain credentials`);if(a.protocol!==`wss:`&&!(t.allowInsecure&&a.protocol===`ws:`))throw new V(`malformed`,`qr: relay must be wss://`);if(i.r.endsWith(`/`)||/[?#]/.test(i.r)||a.pathname!==`/`||a.search||a.hash)throw new V(`malformed`,`qr: relay url must be scheme://host[:port] with no path`);if(rc(xr(i.e))!==i.c)throw new V(`malformed`,`qr: fingerprint mismatch`);return i}function _d(e,t){return`${e}/ws/${t}`}function vd(){return{r:[]}}function yd(e){let t=0;for(let n of e)t++;return t}function bd(e){return e===void 0?``:typeof e==`number`?String(e):`${e[0]},${e[1]},${e[2]}`}function xd(e,t){return bd(e.fg)===bd(t.fg)&&bd(e.bg)===bd(t.bg)&&!!e.b==!!t.b&&!!e.i==!!t.i&&!!e.u==!!t.u&&!!e.s==!!t.s&&!!e.f==!!t.f}function Sd(e){return e.n??yd(e.t)}function Cd(e){let t=[];for(let n of e){let e=t[t.length-1];if(e&&xd(e,n)){let t=Sd(e)+Sd(n);e.t+=n.t,t===yd(e.t)?delete e.n:e.n=t}else{let e={...n};e.n!==void 0&&e.n===yd(e.t)&&delete e.n,t.push(e)}}return t}function wd(e){let t=e.slice();for(;t.length>0;){let e=t[t.length-1];if(e.bg!==void 0)break;let n=e.t.replace(/ +$/,``);if(n===``){t.pop();continue}if(n!==e.t){let r=yd(e.t)-yd(n),i=(e.n??yd(e.t))-r,a={...e,t:n};i===yd(n)?delete a.n:a.n=i,t[t.length-1]=a}break}return t}function Td(e){let t={r:[]};for(let n of e.r){let e=Sd(n);if(n.t===``&&e===0)continue;let r=t.r[t.r.length-1];if(r&&r.t.length+n.t.length<=4096&&Sd(r)+e<=4096){let t=Sd(r)+e;r.t+=n.t,t===yd(r.t)?delete r.n:r.n=t}else{let r={t:n.t};e!==yd(n.t)&&(r.n=e),t.r.push(r)}}return e.w!==void 0&&(t.w=e.w),t}function Ed(e){return`${+!!e.b}${+!!e.i}${+!!e.u}${+!!e.s}${+!!e.f}`}function Dd(e){let t=e.r.map(e=>`${e.t}|${bd(e.fg)}|${bd(e.bg)}|${Ed(e)}|${e.n??``}`).join(``);return e.w===!0?`${t}\x00w`:t}const Od={sdpChars:24e3,candidateChars:1024,candidatesPerSide:32,encodedBytes:3e4,bootstrapConfirmBytes:512},kd=Dl.refine(e=>e[0]===1&&e.subarray(1).every(e=>e===0),{message:`initial relay generation must be one`}),Ad=Dl.refine(e=>e[0]!==1||e.subarray(1).some(e=>e!==0),{message:`direct generation must exceed one`}),jd=F.string().min(1).max(Od.sdpChars).regex(/^[\x20-\x7e\r\n]+$/,`SDP must contain printable ASCII and line endings only`),Md=F.string().min(1).max(Od.candidateChars).startsWith(`candidate:`).regex(/^[\x20-\x7e]+$/,`ICE candidate must contain printable ASCII only`),Nd={sessionId:El,offerId:El,generation:Ad};function Pd(e,t){if(/\r(?!\n)/.test(e))return!1;let n=e.split(/\r?\n/).filter(e=>e.length>0);if(n.some(e=>!/^[a-z]=/.test(e)))return!1;let r=n.filter(e=>e.startsWith(`m=`));if(r.length!==1||!/^m=application [0-9]+ (?:UDP|TCP)\/DTLS\/SCTP webrtc-datachannel$/i.test(r[0]??``)||n.some(e=>/^a=(?:candidate|remote-candidates|end-of-candidates)(?::|$)/i.test(e))||!n.some(e=>/^a=ice-ufrag:/i.test(e))||!n.some(e=>/^a=ice-pwd:/i.test(e)))return!1;let i=n.filter(e=>/^a=fingerprint:/i.test(e));if(i.length===0)return!1;for(let e of i){let n=/^a=fingerprint:sha-256 ((?:[0-9a-f]{2}:){31}[0-9a-f]{2})$/i.exec(e);if(!n?.[1]||!Er(wr(n[1].replaceAll(`:`,``)),t))return!1}return!0}const Fd=F.discriminatedUnion(`type`,[F.object({type:F.literal(`session.v2.begin`),sessionId:El,generation:kd}).strict(),F.object({type:F.literal(`session.v2.accept`),sessionId:El,attemptId:El,generation:kd}).strict(),F.object({type:F.literal(`session.v2.noise1`),sessionId:El,attemptId:El,message:H(48)}).strict(),F.object({type:F.literal(`session.v2.noise2`),sessionId:El,attemptId:El,message:H(48)}).strict(),F.object({type:F.literal(`session.v2.confirm`),sessionId:El,attemptId:El,frame:F.custom(e=>e instanceof Uint8Array&&e.length>0&&e.length<=Od.bootstrapConfirmBytes,{message:`invalid v2 confirmation frame length`})}).strict()]);function Id(e,t){return t!==void 0&&El.safeParse(t).success&&Er(e,t)}function Ld(e,t){return!t||e.type!==t.expectedType?!1:e.type===`session.v2.begin`?t.sender===`phone`&&t.sessionId===void 0&&t.attemptId===void 0:Id(e.sessionId,t.sessionId)?e.type===`session.v2.accept`?t.sender===`computer`&&t.attemptId===void 0:Id(e.attemptId,t.attemptId)?e.type===`session.v2.noise1`?t.sender===`phone`:e.type===`session.v2.noise2`?t.sender===`computer`:t.sender===`phone`||t.sender===`computer`:!1:!1}const Rd=1024;function zd(e){let t=Fd.safeParse(e);if(!t.success)throw new V(`malformed`,`invalid v2 bootstrap`);let n=Gn(t.data);if(n.length>Rd)throw new V(`malformed`,`v2 bootstrap too large`);return n}function Bd(e,t){if(e.length>Rd)throw new V(`malformed`,`v2 bootstrap too large`);let n=Fd.safeParse(Kn(e));if(!n.success||!Ld(n.data,t))throw new V(`malformed`,`invalid or stale v2 bootstrap`);return n.data}const Vd=F.discriminatedUnion(`type`,[F.object({type:F.literal(`direct.offer`),...Nd,sdp:jd,phoneDtls:H(32)}).strict(),F.object({type:F.literal(`direct.answer`),...Nd,attemptId:El,sdp:jd,computerDtls:H(32)}).strict(),F.object({type:F.literal(`direct.candidate`),...Nd,index:F.number().int().min(0).max(Od.candidatesPerSide-1),candidate:Md,mid:F.string().min(1).max(64).regex(/^[\x21-\x7e]+$/).nullable(),mlineIndex:F.number().int().min(0).max(0).nullable()}).strict(),F.object({type:F.literal(`direct.end`),...Nd,count:F.number().int().min(0).max(Od.candidatesPerSide)}).strict(),F.object({type:F.literal(`direct.abort`),...Nd,reason:F.enum([`timeout`,`ice-failed`,`dtls-failed`,`resource-limit`,`cancelled`])}).strict()]).superRefine((e,t)=>{e.type===`direct.candidate`&&e.mid===null&&e.mlineIndex===null&&t.addIssue({code:`custom`,message:`candidate needs a media section`}),e.type===`direct.offer`&&!Pd(e.sdp,e.phoneDtls)&&t.addIssue({code:`custom`,message:`invalid data-channel offer SDP`}),e.type===`direct.answer`&&!Pd(e.sdp,e.computerDtls)&&t.addIssue({code:`custom`,message:`invalid data-channel answer SDP`})});function Hd(e,t){if(!t||t.sender!==`phone`&&t.sender!==`computer`||!El.safeParse(t.sessionId).success||!Dl.safeParse(t.committedGeneration).success||!Er(e.sessionId,t.sessionId))return!1;if(e.type===`direct.offer`)return t.sender===`phone`&&t.pending===void 0&&gl(e.generation)>gl(t.committedGeneration);let n=t.pending;return n!==void 0&&El.safeParse(n.offerId).success&&Dl.safeParse(n.generation).success&&gl(n.generation)>gl(t.committedGeneration)&&Er(e.offerId,n.offerId)&&Er(e.generation,n.generation)&&(e.type!==`direct.answer`||t.sender===`computer`)}function Ud(e){let t=Vd.safeParse(e);if(!t.success)throw new V(`malformed`,`invalid direct signal`);let n=Gn(t.data);if(n.length>Od.encodedBytes)throw new V(`malformed`,`direct signal too large`);return n}function Wd(e,t){if(e.length>Od.encodedBytes)throw new V(`malformed`,`direct signal too large`);let n=Vd.safeParse(Kn(e));if(!n.success||!Hd(n.data,t))throw new V(`malformed`,`invalid or stale direct signal`);return n.data}var Gd=class{context;role;actualRemoteCertificate;handshake;session=null;phase;constructor(e,t,n,r){if(this.context=e,this.role=t,this.actualRemoteCertificate=r,e.route!==`direct`)throw Error(`direct context required`);this.handshake=zl(e,t,n),this.phase=t===`phone`?`new`:`noise1`}get ready(){return this.phase===`ready`&&this.session?.ready===!0}begin(){if(this.phase!==`new`||!this.handshake)throw Error(`direct handshake order`);return this.phase=`noise2`,zd({type:`session.v2.noise1`,sessionId:this.context.sessionId,attemptId:this.context.attemptId,message:this.handshake.write()})}receive(e){try{if((this.phase===`noise1`||this.phase===`noise2`)&&this.handshake){let t=this.phase===`noise1`?`session.v2.noise1`:`session.v2.noise2`,n=Bd(e,{sender:this.role===`phone`?`computer`:`phone`,expectedType:t,sessionId:this.context.sessionId,attemptId:this.context.attemptId});if(n.type!==t)throw Error(`direct handshake order`);this.handshake.read(n.message);let r=null;return this.role===`computer`&&(r=zd({type:`session.v2.noise2`,sessionId:this.context.sessionId,attemptId:this.context.attemptId,message:this.handshake.write()})),this.session=this.handshake.finish(),this.handshake=null,this.session.verifyRemoteDtls(this.actualRemoteCertificate),this.phase=`confirm`,r??zd({type:`session.v2.confirm`,sessionId:this.context.sessionId,attemptId:this.context.attemptId,frame:Il(this.session.confirmation())})}if(this.phase!==`confirm`||!this.session)throw Error(`direct handshake order`);let t=Bd(e,{sender:this.role===`phone`?`computer`:`phone`,expectedType:`session.v2.confirm`,sessionId:this.context.sessionId,attemptId:this.context.attemptId});if(t.type!==`session.v2.confirm`)throw Error(`direct confirmation required`);this.session.acceptConfirmation(Ll(t.frame));let n=this.role===`computer`?zd({type:`session.v2.confirm`,sessionId:this.context.sessionId,attemptId:this.context.attemptId,frame:Il(this.session.confirmation())}):null;if(!this.session.ready)throw Error(`direct confirmation incomplete`);return this.phase=`ready`,n}catch(e){throw this.close(),e}}takeReadySession(){if(!this.ready||!this.session)throw Error(`direct handshake incomplete`);let e=this.session;return this.session=null,this.phase=`closed`,e}close(){this.handshake?.close(),this.handshake=null,this.session?.close(),this.session=null,this.phase=`closed`}};function Kd(e,t){return e===`relay`||t===`relay`?`turn`:e===`host`&&t===`host`?`local`:`internet`}const qd=e=>/ typ relay(?: |$)/.test(e.candidate);function Jd(e){let t=/^a=fingerprint:sha-256 ((?:[0-9a-f]{2}:){31}[0-9a-f]{2})\r?$/im.exec(e);if(!t?.[1])throw Error(`missing SHA-256 SDP fingerprint`);return wr(t[1].replaceAll(`:`,``))}function Yd(e){return`${e.split(/\r?\n/).filter(e=>e.length&&!/^a=(?:candidate|remote-candidates|end-of-candidates)(?::|$)/i.test(e)).join(`\r
16
- `)}\r\n`}var Xd=class{options;offerId;generation;attemptId;peer=null;phoneDtls;computerDtls=null;localSdp=null;remoteSdp=!1;opened=!1;verifying=!1;sentDescription=!1;sentCandidates=0;receivedCandidates=0;pendingData=[];pendingLocal=[];pendingRemote=[];handshake=null;secureSession=null;closed=!1;timer;constructor(e){this.options=e,this.offerId=e.offer?.offerId.slice()??ya(16),this.attemptId=e.offer?ya(16):null,this.generation=e.generation.slice(),this.phoneDtls=e.offer?.phoneDtls.slice()??null,this.timer=setTimeout(()=>this.fail(`timeout`),15e3)}get session(){return this.secureSession}get phase(){return this.secureSession?`cutover`:this.handshake?`noise`:this.verifying?`certificate`:this.opened?`open`:this.remoteSdp?`connecting`:this.localSdp?`offer`:`native`}get active(){return!this.closed&&this.options.current()}cancelDeadline(){clearTimeout(this.timer)}close(){this.closed||(this.closed=!0,this.cancelDeadline(),this.pendingData=[],this.pendingLocal=[],this.pendingRemote=[],this.handshake?.close(),this.secureSession?.close(),this.peer?.close())}routeStats(){return this.peer?.routeStats?.()??Promise.resolve(null)}send(e){let t=this.active&&(this.peer?.send(e)??!1);return t&&this.options.sent(e.length),t}fail(e=`closed`){this.active&&this.options.failed(e)}async start(){let e={description:(e,t)=>{this.active&&this.description(e,t)},candidate:(e,t,n)=>{if(this.active)try{this.localCandidate({candidate:e,mid:t,mlineIndex:n})}catch{this.fail(`local-candidate`)}},open:()=>{this.active&&(this.opened=!0,this.openDirect().catch(()=>this.fail(`certificate`)))},message:e=>{this.active&&(this.options.received(e.length),this.directMessage(e))},closed:()=>this.fail(`native-closed`)},t;try{t=await this.options.native(e)}catch{this.fail(`native-create`);return}if(!this.active){t.close();return}this.peer=t;try{if(this.options.offer){if(await t.answer(this.options.offer.sdp),!this.active)return;this.remoteSdp=!0}else await t.offer();if(!this.active)return;await this.flushRemote(),await this.openDirect()}catch{this.fail(`native-description`)}}description(e,t){try{let n=Jd(e);if(this.localSdp=Yd(e),this.options.role===`phone`&&t===`offer`)this.phoneDtls=n;else if(this.options.role===`computer`&&t===`answer`)this.computerDtls=n;else throw Error(`description role mismatch`);let r=this.signalContext(),i=t===`offer`?{type:`direct.offer`,...r,phoneDtls:n,sdp:this.localSdp}:{type:`direct.answer`,...r,attemptId:this.attemptId,computerDtls:n,sdp:this.localSdp};if(!this.options.sendSignal(i))throw Error(`signaling queue refused`);this.sentDescription=!0;for(let e of this.pendingLocal.splice(0))this.localCandidate(e);this.openDirect().catch(()=>this.fail(`certificate`))}catch{this.fail(`local-description`)}}admits(e){return this.sentCandidates+this.pendingLocal.length<(qd(e)?Od.candidatesPerSide:Od.candidatesPerSide-6)}localCandidate(e){if(this.active&&!this.options.committed()&&this.admits(e)){if(!this.sentDescription){this.pendingLocal.push(e);return}this.options.sendSignal({type:`direct.candidate`,...this.signalContext(),index:this.sentCandidates++,...e})||this.fail()}}async signal(e){if(this.active&&this.peer){if(e.type===`direct.answer`){if(this.remoteSdp||(this.computerDtls=e.computerDtls.slice(),this.attemptId=e.attemptId.slice(),await this.peer.acceptAnswer(e.sdp),!this.active))return;this.remoteSdp=!0,await this.flushRemote(),await this.openDirect()}else if(e.type===`direct.candidate`){if(e.index!==this.receivedCandidates++)throw Error(`candidate order`);this.remoteSdp?await this.peer.candidate(e.candidate,e.mid,e.mlineIndex):this.pendingRemote.push(e)}else e.type===`direct.abort`&&this.fail()}}async flushRemote(){if(this.remoteSdp&&this.peer)for(let e of this.pendingRemote.splice(0)){if(!this.active)return;await this.peer.candidate(e.candidate,e.mid,e.mlineIndex)}}signalContext(){return{sessionId:this.options.relay.sessionId,offerId:this.offerId,generation:this.generation}}async openDirect(){if(!this.active||!this.opened||!this.peer||!this.phoneDtls||!this.computerDtls||!this.attemptId||this.verifying||this.handshake||this.secureSession)return;this.verifying=!0;let e=await this.peer.remoteCertificate(this.options.role===`phone`?this.computerDtls:this.phoneDtls);if(this.active){if(this.handshake=new Gd({route:`direct`,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,sessionId:this.options.relay.sessionId,generation:this.generation,attemptId:this.attemptId,phoneDtls:this.phoneDtls,computerDtls:this.computerDtls},this.options.role,this.options.keys,e),this.options.role===`phone`&&!this.send(this.handshake.begin())){this.fail();return}for(let e of this.pendingData.splice(0))this.directMessage(e)}}directMessage(e){if(this.active)try{if(!this.peer||e.length>61e3)throw Error(`direct frame bounds`);if(this.secureSession){this.options.frame(this.secureSession,e);return}if(!this.handshake){if(!this.verifying||this.pendingData.length>=4||e.length>1024)throw Error(`direct handshake missing`);this.pendingData.push(e.slice());return}let t=this.handshake.receive(e);if(t&&!this.send(t))throw Error(`direct queue refused`);this.handshake.ready&&(this.secureSession=this.handshake.takeReadySession(),this.handshake=null,this.options.ready(this.secureSession))}catch{this.fail(`direct-frame`)}}};const Zd=Uint8Array.of(1,0,0,0,0,0,0,0);var Qd=class{options;stage;startedAt=null;sessionId=null;attemptId=null;handshake=null;session=null;timer=null;keys;timeoutMs;constructor(e){if(this.options=e,U.parse(e.computerFp),U.parse(e.phoneFp),e.role!==`phone`&&e.role!==`computer`)throw Error(`invalid v2 role`);if(e.keys.staticPrivate.length!==32||e.keys.remoteStatic.length!==32||e.keys.pairKey.length!==32)throw Error(`invalid v2 pairing keys`);if(this.timeoutMs=e.timeoutMs??15e3,!Number.isSafeInteger(this.timeoutMs)||this.timeoutMs<1||this.timeoutMs>3e4)throw Error(`invalid v2 bootstrap timeout`);this.keys={staticPrivate:e.keys.staticPrivate.slice(),remoteStatic:e.keys.remoteStatic.slice(),pairKey:e.keys.pairKey.slice()},this.stage=e.role===`phone`?`phone:new`:`computer:begin`}get ready(){return this.stage===`ready`&&this.session?.ready===!0}begin(){if(this.stage!==`phone:new`)throw Error(`v2 begin not allowed`);try{return this.startedAt=this.clock(),this.armTimer(),this.sessionId=this.freshId(),this.stage=`phone:accept`,zd({type:`session.v2.begin`,sessionId:this.sessionId,generation:Zd})}catch(e){throw this.close(),e}}receive(e){try{if(this.stage===`closed`||this.stage===`detached`||this.stage===`ready`)throw Error(`v2 bootstrap no longer accepts messages`);switch(this.stage!==`computer:begin`&&this.assertNotExpired(),this.stage){case`computer:begin`:{let t=Bd(e,{sender:`phone`,expectedType:`session.v2.begin`});if(t.type!==`session.v2.begin`)throw Error(`invalid v2 begin`);if(this.startedAt=this.clock(),this.armTimer(),this.sessionId=t.sessionId.slice(),this.attemptId=this.freshId(),Er(this.sessionId,this.attemptId))throw Error(`repeated v2 attempt ID`);return this.handshake=this.newHandshake(),this.stage=`computer:noise1`,zd({type:`session.v2.accept`,sessionId:this.sessionId,attemptId:this.attemptId,generation:Zd})}case`phone:accept`:{let t=Bd(e,{sender:`computer`,expectedType:`session.v2.accept`,sessionId:this.requireSessionId()});if(t.type!==`session.v2.accept`)throw Error(`invalid v2 accept`);if(this.attemptId=t.attemptId.slice(),Er(this.requireSessionId(),this.attemptId))throw Error(`repeated v2 attempt ID`);this.handshake=this.newHandshake();let n=this.handshake.write();return this.stage=`phone:noise2`,zd({type:`session.v2.noise1`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),message:n})}case`computer:noise1`:{let t=Bd(e,{sender:`phone`,expectedType:`session.v2.noise1`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId()});if(t.type!==`session.v2.noise1`||!this.handshake)throw Error(`invalid v2 noise1`);this.handshake.read(t.message);let n=this.handshake.write();return this.session=this.handshake.finish(),this.handshake=null,this.stage=`computer:confirm`,zd({type:`session.v2.noise2`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),message:n})}case`phone:noise2`:{let t=Bd(e,{sender:`computer`,expectedType:`session.v2.noise2`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId()});if(t.type!==`session.v2.noise2`||!this.handshake)throw Error(`invalid v2 noise2`);this.handshake.read(t.message),this.session=this.handshake.finish(),this.handshake=null;let n=Il(this.session.confirmation());return this.stage=`phone:confirm`,zd({type:`session.v2.confirm`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),frame:n})}case`computer:confirm`:{let t=this.decodeConfirmation(e,`phone`);if(!this.session)throw Error(`v2 session missing`);this.session.acceptConfirmation(Ll(t.frame));let n=Il(this.session.confirmation());if(!this.session.ready)throw Error(`v2 computer confirmation incomplete`);return this.markReady(),zd({type:`session.v2.confirm`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),frame:n})}case`phone:confirm`:{let t=this.decodeConfirmation(e,`computer`);if(!this.session)throw Error(`v2 session missing`);if(this.session.acceptConfirmation(Ll(t.frame)),!this.session.ready)throw Error(`v2 phone confirmation incomplete`);return this.markReady(),null}default:throw Error(`invalid v2 bootstrap stage`)}}catch(e){throw this.close(),e}}takeReadySession(){if(!this.ready||!this.session)throw Error(`v2 session not confirmed`);let e=this.session;return this.session=null,this.stage=`detached`,e}close(){this.stage!==`closed`&&(this.stage=`closed`,this.clearTimer(),this.handshake?.close(),this.handshake=null,this.session?.close(),this.session=null,this.keys.staticPrivate.fill(0),this.keys.remoteStatic.fill(0),this.keys.pairKey.fill(0))}decodeConfirmation(e,t){let n=Bd(e,{sender:t,expectedType:`session.v2.confirm`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId()});if(n.type!==`session.v2.confirm`)throw Error(`invalid v2 confirmation`);return n}newHandshake(){let e={route:`relay`,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),generation:Zd};try{return zl(e,this.options.role,this.keys)}finally{this.keys.staticPrivate.fill(0),this.keys.remoteStatic.fill(0),this.keys.pairKey.fill(0)}}freshId(){return El.parse(this.options.newId()).slice()}requireSessionId(){if(!this.sessionId)throw Error(`v2 session ID missing`);return this.sessionId}requireAttemptId(){if(!this.attemptId)throw Error(`v2 attempt ID missing`);return this.attemptId}clock(){let e=this.options.now();if(!Number.isFinite(e)||e<0)throw Error(`invalid v2 clock`);return e}armTimer(){this.clearTimer(),this.timer=setTimeout(()=>this.close(),this.timeoutMs)}clearTimer(){this.timer!==null&&clearTimeout(this.timer),this.timer=null}markReady(){this.stage=`ready`,this.clearTimer()}assertNotExpired(){if(this.startedAt===null)throw Error(`v2 bootstrap not started`);let e=this.clock()-this.startedAt;if(e<0||e>this.timeoutMs)throw Error(`v2 bootstrap expired`)}},$d=class{options;stage;pairKey;bootstrap;timeoutMs;startedAt=null;timer=null;phoneNonce=null;connKey=null;connTag=``;seqIn=0;seqOut=0;constructor(e){if(this.options=e,U.parse(e.computerFp),U.parse(e.phoneFp),e.role!==`phone`&&e.role!==`computer`)throw Error(`invalid v2 role`);if(e.keys.pairKey.length!==32)throw Error(`invalid pair key`);if(this.timeoutMs=e.timeoutMs??15e3,!Number.isSafeInteger(this.timeoutMs)||this.timeoutMs<1)throw Error(`invalid v2 carrier timeout`);this.pairKey=e.keys.pairKey.slice(),this.bootstrap=new Qd(e),this.stage=e.role===`phone`?`phone:new`:`computer:hello`}get ready(){return this.stage===`ready`&&this.bootstrap.ready}get closed(){return this.stage===`closed`}start(){if(this.stage!==`phone:new`)throw Error(`v2 carrier cannot start`);try{return this.startDeadline(),this.phoneNonce=ya(16),this.stage=`phone:hello`,this.hello(this.phoneNonce)}catch(e){throw this.close(),e}}receive(e){if(this.stage===`closed`||this.stage===`ready`||this.stage===`phone:new`)throw Error(`v2 carrier not receiving`);try{this.stage!==`computer:hello`&&this.checkDeadline();let t=this.options.role===`phone`?this.options.computerFp:this.options.phoneFp,n=this.options.role===`phone`?this.options.phoneFp:this.options.computerFp;if(e.v!==1||e.t!==`e2e`||e.from!==t||e.to!==n)throw Error(`v2 carrier peer mismatch`);let r=Qn.parse(e.body);if(r.c.length<16||r.c.length>2048)throw Error(`v2 carrier ciphertext exceeds bound`);if(this.stage===`phone:hello`||this.stage===`computer:hello`){if(e.seq!==0)throw Error(`v2 carrier expected hello`);let i=Au(Kn(uc(this.pairKey,r,gc(t,n))));if(i.type!==`conn.hello`||!i.features?.includes(`session-v2`))throw Error(`v2 carrier requires v2 hello intent`);if(this.stage===`computer:hello`){this.startDeadline(),this.phoneNonce=i.n.slice();let e=ya(16);if(Er(this.phoneNonce,e))throw Error(`reused hello nonce`);return this.deriveConnection(this.phoneNonce,e),this.stage=`bootstrap`,this.hello(e)}if(!this.phoneNonce||Er(this.phoneNonce,i.n))throw Error(`invalid hello nonce`);return this.deriveConnection(this.phoneNonce,i.n),this.stage=`bootstrap`,this.frame(this.bootstrap.begin())}if(!this.connKey||e.seq!==this.seqIn+1)throw Error(`v2 carrier frame sequence mismatch`);let i=Au(Kn(uc(this.connKey,r,hc(t,n,this.connTag,e.seq))));if(i.type!==`session.v2.bootstrap`)throw Error(`v2 carrier rejects legacy terminal message`);this.seqIn=e.seq;let a=this.bootstrap.receive(i.bytes);return this.bootstrap.ready&&(this.stage=`ready`,this.clearDeadline()),a?this.frame(a):null}catch(e){throw this.close(),e}}takeReadySession(){if(!this.ready)throw Error(`v2 carrier not confirmed`);let e=this.bootstrap.takeReadySession();return this.close(),e}close(){this.stage!==`closed`&&(this.stage=`closed`,this.clearDeadline(),this.pairKey.fill(0),this.phoneNonce?.fill(0),this.phoneNonce=null,this.connKey?.fill(0),this.connKey=null,this.connTag=``,this.bootstrap.close())}hello(e){let t=this.options.role===`phone`?this.options.phoneFp:this.options.computerFp,n=this.options.role===`phone`?this.options.computerFp:this.options.phoneFp;return{v:1,t:`e2e`,from:t,to:n,seq:0,body:lc(this.pairKey,Gn({type:`conn.hello`,n:e,features:[`session-v2`]}),gc(t,n))}}frame(e){if(!this.connKey||this.seqOut>=2**53-1)throw Error(`v2 carrier unavailable`);let t=this.options.role===`phone`?this.options.phoneFp:this.options.computerFp,n=this.options.role===`phone`?this.options.computerFp:this.options.phoneFp,r=++this.seqOut;return{v:1,t:`e2e`,from:t,to:n,seq:r,body:lc(this.connKey,Gn({type:`session.v2.bootstrap`,bytes:e}),hc(t,n,this.connTag,r))}}deriveConnection(e,t){let n=pc(this.pairKey,e,t,this.options.computerFp,this.options.phoneFp);this.connKey=n.kConn,this.connTag=n.connTag}startDeadline(){if(this.startedAt=this.options.now(),!Number.isFinite(this.startedAt))throw Error(`invalid v2 carrier clock`);this.timer=setTimeout(()=>this.close(),this.timeoutMs)}checkDeadline(){let e=this.options.now();if(this.startedAt===null||!Number.isFinite(e)||e<this.startedAt||e-this.startedAt>=this.timeoutMs)throw Error(`v2 carrier handshake expired`)}clearDeadline(){this.timer&&clearTimeout(this.timer),this.timer=null}};function ef(e){return{route:e.route,sessionId:e.sessionId.slice(),attemptId:e.attemptId.slice(),generation:e.generation.slice()}}function tf(e,t){return e.route===t.route&&Er(e.sessionId,t.sessionId)&&Er(e.attemptId,t.attemptId)&&Er(e.generation,t.generation)}var nf=class{options;relay=null;active=null;staged=null;transition=null;wireIds=new Set;attemptIds=new Set;transitionIds=new Set;highGeneration=1n;directAttempts=0;lastNow=-1;deadline=null;timer=null;revoked=!1;recovering=!1;snapshot=!1;revision=0;constructor(e){if(this.options=e,U.parse(e.computerFp),U.parse(e.phoneFp),e.role!==`phone`&&e.role!==`computer`)throw Error(`invalid route role`);this.installRelay(e.relay)}get status(){return this.revoked?`closed`:this.recovering?`recovering`:this.transition?`cutover`:this.active?.reference.route??`uncommitted`}get activeRoute(){return this.active?ef(this.active.reference):null}get routeRevision(){return this.revision}get needsSnapshot(){return this.snapshot}get preparationPending(){return this.transition?.phase===`computer:preparing`}get paused(){return this.revoked||this.recovering||this.transition!==null||this.active===null}get directActive(){return this.active?.reference.route===`direct`}snapshotApplied(){this.paused||(this.snapshot=!1)}stageDirect(e){if(this.sweep(),this.revoked||this.recovering||!this.active||!this.relay||this.staged||this.transition)throw Error(`route candidate unavailable`);let t=null;try{if(t=this.validate(e,`direct`),!Er(t.reference.sessionId,this.relay.reference.sessionId))throw Error(`direct wire session mismatch`);let n=gl(t.reference.generation);if(n<=this.highGeneration)throw Error(`direct generation reused`);let r=Cr(t.reference.attemptId);if(this.attemptIds.has(r))throw Error(`direct attempt reused`);if(this.directAttempts>=Ul.directAttempts)throw Error(`direct attempt capacity`);this.highGeneration=n,this.directAttempts+=1,this.attemptIds.add(r),this.staged=t,this.arm()}catch(t){throw e.session!==this.active?.session&&e.session!==this.relay?.session&&e.session.close(),t}}begin(){if(this.sweep(),this.options.role!==`phone`||this.revoked||this.recovering||!this.staged||!this.relay||this.transition)throw Error(`route prepare unavailable`);if(!this.options.prepareReady())return!1;let e=El.parse(this.options.newId()).slice();if(this.transitionIds.has(Cr(e)))throw Error(`route transition reused`);return this.transitionIds.add(Cr(e)),this.transition={id:e,target:this.staged,phase:`phone:prepared`},this.sendControl(`route.prepare`)}approve(){return this.sweep(),!this.preparationPending||!this.transition||!this.options.prepareReady()||!this.transition.target.session.ready?!1:(this.transition.phase=`computer:commit`,this.sendControl(`route.prepared`))}receive(e,t){if(this.sweep(),this.revoked||this.recovering||!this.registered(e))return null;try{let n=e.open(t),r;try{r=Jl(n)}finally{n.fill(0)}if(r.kind===`control`){if(e!==this.relay?.session)throw Error(`route control requires relay session`);return this.control(r.control),null}if(r.kind===`signal`){if(e!==this.relay?.session)throw Error(`direct signaling requires relay session`);return r}return this.paused||e!==this.active?.session||!this.directActive?(r.bytes.fill(0),null):r}catch{return this.routeLost(e),null}}sendTerminal(e){return this.sweep(),this.paused||!this.active||!this.directActive?!1:this.sendPayload(this.active,{kind:`terminal`,bytes:e})}sendSignal(e){return this.sweep(),this.revoked||this.recovering||!this.relay?!1:this.sendPayload(this.relay,{kind:`signal`,bytes:e})}abort(e=`cancelled`){if(!this.staged&&!this.transition)return;if(this.transition?.phase===`phone:committed`||!this.active){this.failAll();return}let t=this.transition;t&&this.relay&&this.sendPayload(this.relay,{kind:`control`,control:{type:`route.abort`,transitionId:t.id,target:ef(t.target.reference),reason:e}}),this.discardCandidate(),t&&(this.snapshot=!0)}relayLost(){this.active?.reference.route===`direct`&&!this.transition&&!this.staged?(this.relay?.session.close(),this.relay=null):this.failAll()}routeLost(e){e===this.active?.session?this.failAll():e===this.relay?.session?this.relayLost():e===this.staged?.session&&this.abort(`candidate-failed`)}recover(e){if(this.revoked)throw e.session.close(),Error(`route owner revoked`);let t=this.validate(e,`relay`);if(this.wireIds.has(Cr(t.reference.sessionId)))throw t.session.close(),Error(`wire session reused`);this.failAll(),this.installRelay(t)}sweep(){if(this.revoked)return;let e=this.clock();this.deadline!==null&&e>=this.deadline&&this.abort(`timeout`)}close(){this.failAll(),this.revoked=!0,this.recovering=!1}validate(e,t){if(!(e.session instanceof Bl)||!e.session.ready||e.session.senderRole!==this.options.role)throw Error(`route session not ready`);let n=e.session.description;if(n.computerFp!==this.options.computerFp||n.phoneFp!==this.options.phoneFp||n.route!==t)throw Error(`route pairing mismatch`);if(t===`relay`&&gl(n.generation)!==1n)throw Error(`relay generation must be one`);return{session:e.session,send:e.send.bind(e),reference:ef(n)}}installRelay(e){let t=this.validate(e,`relay`),n=Cr(t.reference.sessionId);if(this.wireIds.has(n)||this.wireIds.size>=Ul.wireSessions)throw t.session.close(),Error(`wire session reused or capacity reached`);this.wireIds.add(n),this.attemptIds.clear(),this.transitionIds.clear(),this.attemptIds.add(Cr(t.reference.attemptId)),this.highGeneration=1n,this.directAttempts=0,this.relay=t,this.staged=t,this.recovering=!1,this.arm()}control(e){if(e.type===`route.prepare`){if(this.options.role!==`computer`||this.transition||!this.staged||!tf(e.target,this.staged.reference)||this.transitionIds.has(Cr(e.transitionId)))throw Error(`invalid route prepare`);this.transitionIds.add(Cr(e.transitionId)),this.transition={id:e.transitionId.slice(),target:this.staged,phase:`computer:preparing`};return}let t=this.transition;if(!t||!tf(e.target,t.target.reference)||!Er(e.transitionId,t.id))throw Error(`route transition mismatch`);if(e.type===`route.abort`){this.abortWithoutSending();return}if(e.type===`route.prepared`&&t.phase===`phone:prepared`){if(!this.options.prepareReady()||!t.target.session.ready)throw Error(`route prepare gate changed`);t.phase=`phone:committed`,this.sendControl(`route.commit`);return}if(e.type===`route.commit`&&t.phase===`computer:commit`){if(!this.options.prepareReady()||!t.target.session.ready)throw Error(`route commit gate changed`);let e={type:`route.committed`,transitionId:t.id,target:ef(t.target.reference)};this.activate(),(!this.relay||!this.sendPayload(this.relay,{kind:`control`,control:e}))&&this.failAll();return}if(e.type===`route.committed`&&t.phase===`phone:committed`){this.activate();return}throw Error(`route control order mismatch`)}sendControl(e){return!this.relay||!this.transition?!1:this.sendPayload(this.relay,{kind:`control`,control:{type:e,transitionId:this.transition.id,target:ef(this.transition.target.reference)}})}sendPayload(e,t){let n=ql(t);try{if(e.send(e.session.seal(n))===!0)return!0}catch{}finally{n.fill(0)}return t.kind===`control`?this.failAll():this.routeLost(e.session),!1}activate(){if(!this.staged)throw Error(`route target missing`);let e=this.active;this.active=this.staged,this.staged=null,this.transition=null,e&&e!==this.relay&&e!==this.active&&e.session.close(),this.clearTimer(),this.snapshot=!0,this.revision+=1}abortWithoutSending(){if(this.transition?.phase===`phone:committed`||!this.active){this.failAll();return}this.discardCandidate(),this.snapshot=!0}discardCandidate(){this.staged&&this.staged!==this.active&&this.staged!==this.relay&&this.staged.session.close(),this.staged=null,this.transition=null,this.clearTimer()}failAll(){for(let e of new Set([this.active,this.staged,this.relay]))e?.session.close();this.active=null,this.staged=null,this.relay=null,this.transition=null,this.clearTimer(),this.recovering=!0,this.snapshot=!0,this.revision+=1}registered(e){return e===this.relay?.session||e===this.active?.session||e===this.staged?.session}clock(){let e=this.options.now();if(!Number.isFinite(e)||e<0||e<this.lastNow)throw this.failAll(),Error(`invalid route clock`);return this.lastNow=e,e}arm(){this.clearTimer(),this.deadline=this.clock()+Ul.attemptMs,this.timer=setTimeout(()=>this.abort(`timeout`),Ul.attemptMs)}clearTimer(){this.timer&&clearTimeout(this.timer),this.timer=null,this.deadline=null}};function rf(e,t,n,r){if(e.seq!==0||e.from!==r||e.to!==n)return!1;try{let i=Au(Kn(uc(t,Qn.parse(e.body),gc(r,n))));return i.type===`conn.hello`&&i.features?.includes(`session-v2`)===!0}catch{return!1}}var af=class{options;carrier=null;owner=null;relaySession=null;direct=null;directStartedAt=null;directSetupMs=null;generation=1n;lastFailure=null;retryAt=null;retryFailures=0;nativeAttempts=0;retriesExhausted=!1;traffic={relaySent:0,relayReceived:0,directSent:0,directReceived:0};bootstrapRevision=0;reportedRevision=-1;reportedRoute=null;reportedState=``;recoveryNotified=!1;closed=!1;incoming=Promise.resolve();queued=0;clock;interval;constructor(e){this.options=e,this.clock=e.now??(()=>performance.now()),this.interval=setInterval(()=>this.poll(),100)}get activeRoute(){return this.owner?.activeRoute?.route??null}get ready(){return this.activeRoute!==null&&this.owner?.paused===!1}get routeRevision(){return this.owner?.routeRevision??0}get diagnostics(){let e=this.direct,t=this.activeRoute===`direct`?`direct`:e?.phase??`none`;return{route:this.activeRoute,ready:this.ready,phase:t,lastFailure:this.lastFailure,directSetupMs:this.directSetupMs,...this.traffic}}routeStats(){return this.activeRoute!==`direct`||!this.direct?Promise.resolve(null):this.direct.routeStats().catch(()=>null)}get state(){let{route:e,ready:t,phase:n,lastFailure:r}=this.diagnostics;return{route:e,ready:t,phase:n,lastFailure:r,retryPending:this.retryAt!==null}}sendRelay(e){let t=this.options.sendRelay(e);return t&&e.v===2&&(this.traffic.relaySent+=e.body.length),t}begin(){this.closed||this.options.role!==`phone`||(this.carrier?.close(),this.carrier=this.newCarrier(),this.bootstrapRevision+=1,this.sendRelay(this.carrier.start())||this.bootstrapFailed())}receiveRelay(e){if(this.closed)return Promise.resolve();if(++this.queued>32)return--this.queued,this.bootstrapFailed(),Promise.resolve();let t=this.incoming.then(()=>this.relay(e));return this.incoming=t.catch(()=>this.bootstrapFailed()).finally(()=>{--this.queued}),this.incoming}sendTerminal(e){return this.owner?.sendTerminal(e)??!1}relayLost(){this.owner?.relayLost(),this.carrier?.close(),this.carrier=null,this.changed()}close(){this.closed||(this.closed=!0,clearInterval(this.interval),this.carrier?.close(),this.carrier=null,this.owner?.close(),this.owner=null,this.closeDirect())}interruptDirect(){this.directFailed(`interrupted`)}newCarrier(){return new $d({role:this.options.role,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,keys:this.options.keys,now:this.clock,newId:()=>ya(16)})}async relay(e){if(this.closed||e.from!==(this.options.role===`phone`?this.options.computerFp:this.options.phoneFp)||e.to!==(this.options.role===`phone`?this.options.phoneFp:this.options.computerFp))return;if(e.v===2){if(this.traffic.relayReceived+=e.body.length,!this.owner||!this.relaySession)return;let t=this.owner.receive(this.relaySession,Ll(e.body));if(t?.kind===`terminal`)this.options.terminal(t.bytes,e.body.length);else if(t?.kind===`signal`){let e=this.direct;try{await this.signal(t.bytes)}catch{this.direct===e&&!e?.session?.ready&&this.directFailed(`remote-signal`,e??void 0)}}this.poll();return}if(e.t!==`e2e`)return;if(this.options.role===`computer`&&e.seq===0){if(!rf(e,this.options.keys.pairKey,this.options.computerFp,this.options.phoneFp))return;this.carrier?.close(),this.carrier=this.newCarrier(),this.bootstrapRevision+=1}let t=this.carrier;if(!t)return;let n=this.bootstrapRevision,r=t.receive(e);if(r&&!this.sendRelay(r))throw Error(`bootstrap queue refused`);if(!t.ready)return;let i=t.takeReadySession();this.carrier=null;try{await this.options.commitFloor()}catch(e){throw i.close(),e}if(this.closed||n!==this.bootstrapRevision){i.close();return}this.closeDirect(),this.relaySession=i,this.generation=1n,this.nativeAttempts=0,this.retriesExhausted=!1,this.retryAt=null;let a={session:i,send:e=>this.sendRelay({v:2,t:`e2e`,from:this.options.role===`phone`?this.options.phoneFp:this.options.computerFp,to:this.options.role===`phone`?this.options.computerFp:this.options.phoneFp,body:Il(e)})};this.owner?this.owner.recover(a):this.owner=new nf({role:this.options.role,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,relay:a,now:this.clock,newId:()=>ya(16),prepareReady:this.options.prepareReady}),this.options.role===`phone`&&this.owner.begin(),this.recoveryNotified=!1,this.poll()}poll(){if(this.closed||(this.carrier?.closed&&this.bootstrapFailed(),!this.owner))return;try{this.owner.sweep(),this.owner.preparationPending&&this.owner.approve(),this.options.role===`phone`&&(this.owner.status===`uncommitted`||this.owner.status===`relay`&&this.direct?.session&&this.direct.session.ready)&&this.owner.begin(),this.changed(),this.retryDirect(),this.owner.status===`recovering`&&!this.carrier&&!this.recoveryNotified&&(this.recoveryNotified=!0,this.closeDirect(),this.options.failure(`recovery`))}catch{this.options.failure(`recovery`)}let e=this.state,t=JSON.stringify(e);t!==this.reportedState&&(this.reportedState=t,this.options.stateChanged?.(e))}changed(){let e=this.activeRoute,t=this.routeRevision;(this.reportedRevision!==t||this.reportedRoute!==e)&&(this.reportedRevision=t,this.reportedRoute=e,this.options.routeChanged(e,t),e===`direct`&&this.direct&&(this.directStartedAt!==null&&(this.directSetupMs=Math.round(this.clock()-this.directStartedAt)),this.directStartedAt=null,this.direct.cancelDeadline(),this.retryFailures=0,this.retryAt=null,this.lastFailure=null))}retryDirect(){if(this.options.role===`phone`&&this.options.allowDirect&&this.options.native&&!this.retriesExhausted&&!this.direct&&!this.carrier&&this.ready&&this.activeRoute===`relay`&&this.options.prepareReady()&&!(this.retryAt!==null&&this.clock()<this.retryAt)){if(this.nativeAttempts>=Ul.directAttempts){this.retriesExhausted=!0,this.bootstrapFailed();return}this.nativeAttempts+=1,this.retryAt=null,this.startDirect()}}bootstrapFailed(){this.carrier?.close(),this.carrier=null,this.options.failure(`bootstrap`)}async startDirect(e){if(this.closed||this.direct||!this.ready||!this.relaySession||!this.options.native)return;this.generation=e?new DataView(e.generation.buffer,e.generation.byteOffset,8).getBigUint64(0,!0):this.generation+1n;let t=new Xd({role:this.options.role,keys:this.options.keys,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,relay:this.relaySession.description,generation:e?.generation??hl(this.generation),offer:e,native:this.options.native,current:()=>!this.closed&&this.direct===t,committed:()=>this.activeRoute===`direct`,sendSignal:e=>this.sendSignal(e),sent:e=>{this.traffic.directSent+=e},received:e=>{this.traffic.directReceived+=e},ready:e=>{this.owner?.stageDirect({session:e,send:e=>t.send(Il(e))}),this.options.role===`phone`&&this.owner?.begin()},frame:(e,t)=>{let n=this.owner?.receive(e,Ll(t));n?.kind===`terminal`&&this.options.terminal(n.bytes,t.length),this.poll()},failed:e=>this.directFailed(e,t)});this.direct=t,this.directStartedAt=this.clock(),await t.start()}async signal(e){if(!this.relaySession||!this.owner)return;let t=this.direct;if(this.activeRoute===`direct`&&t?.session?.ready)return;let n=Wd(e,{sender:this.options.role===`phone`?`computer`:`phone`,sessionId:this.relaySession.description.sessionId,committedGeneration:this.relaySession.description.generation,...t&&{pending:{offerId:t.offerId,generation:t.generation}}});if(n.type===`direct.offer`){if(!this.options.native||this.options.role!==`computer`)return;await this.startDirect(n);return}await t?.signal(n)}sendSignal(e){return this.owner?.sendSignal(Ud(e))??!1}directFailed(e=`closed`,t){if(t&&this.direct!==t)return;let n=this.direct;if(!n)return;let r=this.diagnostics.phase,i=Math.min(6e4,5e3*2**this.retryFailures);if(this.retryFailures=Math.min(this.retryFailures+1,4),this.retryAt=this.clock()+Math.min(6e4,i*(.8+.4*ya(1)[0]/255)),this.lastFailure=e,!n.session?.ready)try{this.sendSignal({type:`direct.abort`,...n.signalContext(),reason:e===`timeout`?`timeout`:e===`certificate`?`dtls-failed`:`ice-failed`})}catch{}let a=n?.session;a&&this.owner?.routeLost(a),this.closeDirect(),this.options.failure(`direct`,{code:e,phase:r}),this.poll()}closeDirect(){let e=this.direct;this.direct=null,e&&e.close()}};function of(e,t){return rr.every(n=>e?.includes(n)&&t.includes(n))?[...rr,...e?.includes(`native-history-v1`)&&t.includes(`native-history-v1`)?[ir]:[]]:[]}function sf(e){if(e.length>4096)return!1;for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n>=55296&&n<=56319){let n=e.charCodeAt(++t);if(!(n>=56320&&n<=57343))return!1}else if(n>=56320&&n<=57343)return!1}return!0}const cf=tu.extend({t:tu.shape.t.refine(sf)}).strict(),lf=nu.extend({r:F.array(cf)}).strict(),uf=lf.extend({r:F.array(cf).max(2048)}),df=F.number().int().min(0).max(2**53-1),ff={kind:F.literal(`history`),generation:df,requestId:G,before:df},pf=F.custom(e=>Array.isArray(e)&&e.length>0&&e.length<=W.historyLines),mf=F.strictObject({...ff,status:F.literal(`page`),from:df,to:df,oldestAvailable:df,lines:pf});function hf(e){return e.to===e.before&&e.lines.length<=2**53-1-e.from&&e.from+e.lines.length===e.to&&e.oldestAvailable<=e.from}const gf=mf.refine(hf),_f=mf.extend({nextBefore:df}).refine(e=>hf(e)&&e.nextBefore===e.from),vf=F.strictObject({...ff,status:F.literal(`boundary`),reason:F.enum([`end`,`truncated`]),oldestAvailable:df}).refine(e=>e.reason===`end`?e.before===e.oldestAvailable:e.before<e.oldestAvailable),yf=F.discriminatedUnion(`status`,[gf,vf]),bf=F.discriminatedUnion(`status`,[_f,vf]),xf=F.strictObject({r:F.unknown(),w:F.boolean().optional()}),Sf={ok:!1,code:`invalid-transfer`},Cf={ok:!1,code:`history-line-too-large`};function wf(e){let t=xf.safeParse(e);if(!t.success||!Array.isArray(t.data.r))return Sf;if(t.data.r.length>2048)return Cf;let n={r:[],...t.data.w===void 0?{}:{w:t.data.w}},r=0,i=0;for(let e of t.data.r){let t=cf.safeParse(e);if(!t.success)return Sf;if(r+=t.data.n??yd(t.data.t),r>W.historyCells||(i+=Gn(t.data).length,i>W.historyBytes))return Cf;n.r.push(t.data)}let a=Gn(n).length;return a>W.historyBytes?Cf:{ok:!0,line:n,bytes:a}}F.unknown().transform((e,t)=>{let n=()=>(t.addIssue({code:`custom`,message:`invalid history record`}),F.NEVER);try{let t=bf.safeParse(e);if(!t.success)return n();let r;if(t.data.status===`boundary`)r=t.data;else{let e=[],i=0;for(let r of t.data.lines){let t=wf(r);if(!t.ok||(i+=t.bytes,i>W.historyBytes))return n();e.push(t.line)}r={...t.data,lines:e}}return Gn(r).length>W.historyBytes?n():r}catch{return n()}});function Tf(e){try{let t=yf.safeParse(e);if(!t.success)return Sf;if(t.data.status===`boundary`){let e=t.data;return{ok:!0,record:e,bytes:Gn(e)}}let n=t.data,r=[],i=0,a;for(let e=n.lines.length-1;e>=0;e--){let t=wf(n.lines[e]);if(!t.ok){if(t.code===`invalid-transfer`)return Sf;break}if(i+=t.bytes,i>W.historyBytes)break;r.unshift(t.line);let o=n.from+e,s={...n,from:o,nextBefore:o,lines:r.slice()},c=Gn(s);c.length<=W.historyBytes&&(a={ok:!0,record:s,bytes:c})}return a??{...Cf,before:n.before}}catch{return Sf}}const Ef=F.number().int().min(0).max(2**53-1),Df=Ef.min(1),Of=ru.extend({x:Ef,y:F.number().int().min(-1).max(2**53-1)}).strict(),kf=F.strictObject({cols:Df,rows:Df,cursor:Of,lines:F.array(lf),scrollbackTotal:Ef,gen:Ef,reset:F.boolean().optional(),degraded:F.boolean().optional()});function Af(e){return e.lines.length===e.rows&&e.cursor.x<=e.cols&&e.cursor.y<e.rows&&jf(e.lines,e.cols)}function jf(e,t){return e.every(e=>{let n=0;for(let r of e.r)if(n+=r.n??yd(r.t),n>t)return!1;return!0})}function Mf(e){let t=0,n=0;for(let r of e){t+=r.r.length;for(let e of r.r)n+=yd(e.t)}return{runs:t,points:n}}function Nf(e){let{runs:t,points:n}=Mf(e);return t<=W.runs&&n<=W.codePoints}const Pf=kf.extend({kind:F.literal(`snapshot`),cols:Df.max(W.cols),rows:Df.max(W.rows),lines:F.array(uf).max(W.rows)}).refine(e=>Af(e)&&Nf(e.lines)),Ff=F.strictObject({scroll:Ef.max(W.rows),changed:F.array(F.strictObject({i:Ef.max(W.rows-1),line:uf})).max(W.rows),cursor:Of.extend({x:Ef.max(W.cols),y:Of.shape.y.max(W.rows-1)}),scrollbackTotal:Ef,gen:Df}),If=Ff.extend({kind:F.literal(`diff`)}).refine(e=>{let t=new Set(e.changed.map(e=>e.i)),n=e.changed.map(e=>e.line);return t.size===e.changed.length&&jf(n,W.cols)&&Nf(n)}),Lf=F.discriminatedUnion(`kind`,[Pf,If]);function Rf(e){let t=Lf.safeParse(e);if(!t.success)throw new V(`malformed`);let n;try{n=Gn(t.data)}catch{throw new V(`malformed`)}if(n.length>W.screenBytes)throw new V(`malformed`);return{record:t.data,bytes:n}}function zf(e){let{kind:t,...n}=e;return n}function Bf(e){let t=kf.safeParse(e);if(!t.success||!Af(t.data))return{ok:!1,code:`invalid-transfer`};let n=t.data;if(n.cols>W.cols||n.rows>W.rows||Mf(n.lines).points>W.codePoints)return{ok:!1,code:`screen-too-large`};for(let e=0;e<2;e++){let t=e===0?n:{...n,lines:n.lines.map(Td),degraded:!0};try{let{record:e,bytes:n}=Rf({kind:`snapshot`,...t});if(e.kind===`snapshot`)return{ok:!0,snapshot:zf(e),bytes:n}}catch{}}return{ok:!1,code:`screen-too-large`}}function Vf(e){let t=Ff.safeParse(e);if(!t.success)throw new V(`malformed`);return Rf({kind:`diff`,...t.data}).bytes}var Hf=class{options;lanes=[null,null];outstanding=[];state=`open`;nextLane=0;lastSequence=0;acknowledgedThrough=0;constructor(e){if(!lr.shape.subscriptionId.safeParse(e.subscriptionId).success||!lr.shape.sessionId.safeParse(e.sessionId).success)throw Error(`Invalid stream sender identity`);this.options={...e}}canOffer(e){return this.tick()===`open`&&this.lanes[+(e===`history`)]===null}offer(e,t){if(this.tick()!==`open`)return{accepted:!1,reason:`closed`};let n=cr.safeParse(e);if(!n.success||!(t instanceof Uint8Array)||t.length===0)throw Error(`Invalid stream transfer`);let r=+(n.data.kind===`history`),i=r===1?W.historyBytes:W.screenBytes;if(t.length>i)return{accepted:!1,reason:`too-large`};if(this.lanes[r])return{accepted:!1,reason:`busy`};let a;try{a=this.options.newTransferId()}catch(e){throw this.cancel(),e}if(!lr.shape.transferId.safeParse(a).success)throw Error(`Invalid stream transfer identity`);return this.state===`open`?(this.lanes[r]={id:a,meta:n.data,bytes:new Uint8Array(t),count:Math.ceil(t.length/W.chunkBytes),nextIndex:0,acknowledged:0,startedAt:null,progressAt:null},{accepted:!0,transferId:a}):{accepted:!1,reason:`closed`}}pump(){if(this.tick()!==`open`)return 0;let e=0;for(;e<W.unacked&&this.inFlight<W.unacked&&this.tick()===`open`;){let t=this.nextLane,n=this.lanes[t];if((!n||n.nextIndex===n.count)&&(t=1-t,n=this.lanes[t]),!n||n.nextIndex===n.count)break;if(this.lastSequence===2**53-1){this.cancel();break}let r=this.lastSequence+1,i=n.nextIndex,a={type:`stream.chunk`,subscriptionId:this.options.subscriptionId,sessionId:this.options.sessionId,transferId:n.id,sequence:r,index:i,count:n.count,totalBytes:n.bytes.length,data:n.bytes.slice(i*W.chunkBytes,(i+1)*W.chunkBytes),meta:{...n.meta}},o;try{o=this.options.send(a)}catch(e){throw this.cancel(),e}if(o&&e++,this.state!==`open`||!o)break;this.lastSequence=r,n.nextIndex++,n.startedAt===null&&(n.startedAt=this.options.now(),n.progressAt=n.startedAt),this.outstanding.push({sequence:r,transfer:n}),this.nextLane=1-t}return e}acknowledge(e,t){if(e!==this.options.subscriptionId||this.tick()!==`open`)return`ignored`;if(!Number.isSafeInteger(t)||t<1||t>this.lastSequence)return`invalid`;if(t<=this.acknowledgedThrough)return`duplicate`;let n=this.options.now();for(let e of this.outstanding){if(e.sequence>t)break;e.transfer.acknowledged++,e.transfer.progressAt=n,e.transfer.acknowledged===e.transfer.count&&(this.lanes[+(e.transfer.meta.kind===`history`)]=null)}return this.outstanding=this.outstanding.filter(e=>e.sequence>t),this.acknowledgedThrough=t,`advanced`}tick(){let e=this.nextDeadline();return e!==null&&this.options.now()>=e&&this.stop(`stalled`),this.state}nextDeadline(){let e=1/0;for(let t of this.lanes)t&&t.startedAt!==null&&t.progressAt!==null&&(e=Math.min(e,t.startedAt+W.totalMs,t.progressAt+W.progressMs));return Number.isFinite(e)?e:null}cancel(){this.stop(`closed`)}stop(e){this.state=e,this.lanes[0]=null,this.lanes[1]=null,this.outstanding=[]}get inFlight(){return this.outstanding.length}get retainedBytes(){return(this.lanes[0]?.bytes.length??0)+(this.lanes[1]?.bytes.length??0)}},Uf=`0.12.0`;const Wf=/^owner-([1-9][0-9]*)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;function Gf(e){if(!/^[1-9][0-9]*$/.test(e))return null;let t=Number(e);return Number.isInteger(t)&&t<=2147483647?t:null}function Kf(e){try{return process.kill(e,0),!0}catch(e){let t=e.code;if(t===`ESRCH`)return!1;if(t===`EPERM`)return!0;throw e}}function qf(e,n){try{t.unlinkSync(N(e,n))}catch(e){if(e.code!==`ENOENT`)throw e}try{t.rmdirSync(e)}catch(e){if(![`ENOENT`,`ENOTEMPTY`,`EEXIST`].includes(e.code??``))throw e}}function Jf(e){let n=`${A(e)}.lock-candidate-`;for(let r of t.readdirSync(j(e))){if(!r.startsWith(n))continue;let i=`owner-${r.slice(n.length)}`,a=Wf.exec(i),o=a&&Gf(a[1]);if(!o)continue;let s=N(j(e),r);try{if(Kf(o)||!t.lstatSync(s).isDirectory())continue;let e=t.readdirSync(s);e.length===0?t.rmdirSync(s):e.length===1&&e[0]===i&&t.lstatSync(N(s,i)).isFile()&&qf(s,i)}catch{}}}function Yf(e){let n=`${e}.lock`,r=`${process.pid}-${ce()}`,i=`${e}.lock-candidate-${r}`,a=`owner-${r}`;t.mkdirSync(i,{mode:448});let o=!1;try{t.writeFileSync(N(i,a),``,{mode:384,flag:`wx`});for(let r=0;r<3;r++){try{t.renameSync(i,n),o=!0;try{Jf(e)}catch{}return()=>qf(n,a)}catch(e){if(![`EEXIST`,`ENOTEMPTY`].includes(e.code??``))throw e}try{if(!t.lstatSync(n).isDirectory())throw Error(`Invalid control guard ${n}; inspect it before retrying`);let e=t.readdirSync(n);if(e.length===0)continue;let r=e[0],i=Wf.exec(r),a=i&&Gf(i[1]);if(e.length!==1||!a||!t.lstatSync(N(n,r)).isFile())throw Error(`Invalid control guard ${n}; inspect its owner marker before retrying`);if(Kf(a))throw Error(`Control endpoint busy (guard owner pid ${a})`);qf(n,r)}catch(e){if(e.code!==`ENOENT`)throw e}}throw Error(`Control endpoint busy; could not acquire ${n} after three attempts`)}finally{o||qf(i,a)}}var Y=class extends Error{kind;constructor(e){super(`shellbell: ${e} Linux host state; inspect ownership, permissions and host initialization`),this.kind=e}};function X(e){try{return p(e)}catch(e){if(e.code===`ENOENT`)return;throw new Y(`unsafe`)}}function Xf(e,t){return e.dev===t.dev&&e.ino===t.ino}function Z(e,t){let n=X(e);if(!n)throw new Y(`missing`);if(!n.isDirectory()||n.isSymbolicLink()||n.uid!==t||(n.mode&4095)!=448)throw new Y(`unsafe`);return n}function Zf(e){let t=P(e),n=X(t);if(n){if(n.isSymbolicLink()||!n.isDirectory())throw new Y(`unsafe`);return y(t)}return N(Qf(j(t)),A(t))}function Qf(e){if(X(e))try{return y(e)}catch{throw new Y(`unsafe`)}return N(Qf(j(e)),A(e))}function $f(e,t,n,r=!0){let i;try{let a=X(e);if(!a)throw new Y(`missing`);let s=e=>{if(!e.isFile()||e.isSymbolicLink()||n!==void 0&&(e.uid!==n||(e.mode&4095)!=384))throw new Y(`unsafe`);if(e.size>t)throw new Y(`invalid`)};s(a),i=h(e,o.O_RDONLY|o.O_NOFOLLOW|o.O_NONBLOCK);let c=l(i);if(s(c),!Xf(a,c))throw new Y(`unsafe`);let u=Buffer.alloc(t+ +!!r),d=0;for(;d<u.length;){let e=_(i,u,d,u.length-d,null);if(e===0)break;d+=e}let f=l(i),p=X(e);if(s(f),!p||!Xf(c,p)||!Xf(c,f)||c.size!==f.size||c.mtimeMs!==f.mtimeMs||c.ctimeMs!==f.ctimeMs)throw new Y(`unsafe`);if(s(p),d>t||d!==f.size)throw new Y(`invalid`);return u.subarray(0,d)}catch(e){throw e instanceof Y?e:new Y(`unsafe`)}finally{i!==void 0&&a(i)}}function ep(e={}){let t=e.uid??process.getuid?.(),n=e.euid??process.geteuid?.();if(!Number.isInteger(t)||t===void 0||t<=0||t!==n)throw Error(`shellbell: Linux hosting requires matching non-root real and effective users`);let r;try{let t=$f(e.machineIdPath??`/etc/machine-id`,256,void 0,!1).toString(`utf8`);if(!/^[0-9a-fA-F]{32}\n?$/.test(t)||/^0{32}\n?$/.test(t))throw Error();r=Buffer.from(t.trim().toLowerCase(),`hex`)}catch{throw Error(`shellbell: Linux machine identity is unavailable or invalid; provision /etc/machine-id before host initialization`)}let i=oe(`sha256`,`shellbell.local-host-scope.v1`).update(r).digest(`hex`),a=i.slice(0,32);return{uid:t,machineId:r.toString(`hex`),hostDigest:i,hostScope:a}}const tp=new WeakMap,np=new Set([16914836,61267,1481003842,2435016766]);function rp(e,t){let n=tp.get(e),r=n?.root??j(j(e.runtimeDir)),i=n?.fsType??(e=>S(e).type);try{if(Z(r,e.linuxHost.uid),!np.has(Number(i(r))))throw new Y(`unsafe`);for(let n of[N(r,`shellbell`),e.runtimeDir]){if(!X(n)){if(!t)continue;try{m(n,{mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}}if(Z(n,e.linuxHost.uid),!np.has(Number(i(n))))throw new Y(`unsafe`)}X(e.runtimeDir)&&ip(e.runtimeDir,e.linuxHost.uid,0,i)}catch{throw Error(`shellbell: unsafe or unavailable Linux runtime; provide a private 0700 local XDG_RUNTIME_DIR`)}}function ip(e,t,n,r){if(n>2)throw new Y(`unsafe`);let i=v(e);if(i.length>256)throw new Y(`unsafe`);for(let a of i){let i=N(e,a),o=X(i);if(!o||o.uid!==t||o.isSymbolicLink())throw new Y(`unsafe`);if(o.isDirectory()){if(Z(i,t),!np.has(Number(r(i))))throw new Y(`unsafe`);ip(i,t,n+1,r)}else if(!o.isFile()&&!o.isSocket()||(o.mode&4095)!=384)throw new Y(`unsafe`)}}function ap(e,t){if(j(t)!==j(e.runtimeDir))throw new Y(`unsafe`);Z(t,e.linuxHost.uid);let n=tp.get(e)?.fsType??(e=>S(e).type);if(!np.has(Number(n(t))))throw new Y(`unsafe`);ip(t,e.linuxHost.uid,0,n)}function op(e={}){let{uid:t,hostDigest:n,hostScope:r}=ep(e),i=e.env??process.env,a=e.home??E(),o=i.SHELLBELL_DIR;if(o!==void 0&&!M(o))throw Error(`shellbell: SHELLBELL_DIR must be absolute`);let s=i.XDG_STATE_HOME&&M(i.XDG_STATE_HOME)?i.XDG_STATE_HOME:N(a,`.local`,`state`),c=Zf(o??N(s,`shellbell`,`hosts`,r));X(c)&&Z(c,t);let l=i.XDG_RUNTIME_DIR??`/run/user/${t}`;if(!M(l))throw Error(`shellbell: XDG_RUNTIME_DIR must be absolute`);let u=N(P(l),`shellbell`,ae(`sha256`).update(c).digest(`hex`).slice(0,32)),d={dir:c,serviceOwner:N(c,`service-owner.json`),identity:N(c,`identity.json`),config:N(c,`config.json`),pairings:N(c,`pairings.json`),log:N(c,`agent.log`),runtimeDir:u,sock:N(u,`agent.sock`),pid:N(u,`agent.pid`),linuxHost:{uid:t,hostDigest:n,hostScope:r}};if(Buffer.byteLength(d.sock)>107)throw Error(`shellbell: Linux socket path exceeds 107 bytes; choose a shorter XDG_RUNTIME_DIR`);return tp.set(d,{root:P(l),fsType:e.runtimeFsType??(e=>S(e).type)}),rp(d,!1),d}function sp(e){rp(e,!0)}const cp=F.object({v:F.literal(1),relayUrl:F.string().url(),computerName:F.string().min(1).max(64),accent:F.string().min(1).max(32),notifyMinCommandMs:F.number().int().nonnegative().default(1e4),idleQuietMs:F.number().int().positive().default(4e3),idleMinActiveMs:F.number().int().nonnegative().default(1500),turn:F.boolean().optional(),showAgentConversations:F.boolean().optional(),terminalPlugins:F.array(F.string().min(1).max(4096).refine(e=>e.startsWith(`/`)&&e.endsWith(`.mjs`)&&[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127))).max(29).optional()}),lp=F.object({phoneFp:F.string().regex(/^[a-z2-7]{26}$/),name:F.string().min(1).max(64),platform:F.enum([`ios`,`android`]),ed25519Pub:F.string(),x25519Pub:F.string(),kPair:F.string(),minProtocolVersion:F.literal(2).optional(),pairedAt:F.string(),lastSeenAt:F.string().nullable()}),up=F.object({v:F.literal(1),phones:F.array(lp)});function dp(e,t){if(!e||e.phoneFp!==t.phoneFp||e.kPair!==t.kPair)return t;if(e.ed25519Pub!==t.ed25519Pub||e.x25519Pub!==t.x25519Pub)throw Error(`shellbell: pairing identity changed without a new pairing key`);return e.minProtocolVersion===2?{...t,minProtocolVersion:2}:t}const fp=F.object({v:F.literal(1),hostDigest:F.string().regex(/^[0-9a-f]{64}$/),installationId:F.string().uuid()}).strict();function pp(e){try{let t=nc(JSON.parse(e.toString(`utf8`))),n=$s(t.ed25519.priv,t.x25519.priv,t.createdAt);if(!Buffer.from(n.ed25519.pub).equals(Buffer.from(t.ed25519.pub))||!Buffer.from(n.x25519.pub).equals(Buffer.from(t.x25519.pub)))throw Error();return{identity:t,fp:rc(t.ed25519.pub)}}catch{throw new Y(`invalid`)}}function mp(e){try{return cp.parse(JSON.parse(e.toString(`utf8`)))}catch{throw new Y(`invalid`)}}function hp(e){try{let{phones:t}=up.parse(JSON.parse(e.toString(`utf8`)));for(let e of t){let t=xr(e.ed25519Pub);if(t.length!==32||xr(e.x25519Pub).length!==32||xr(e.kPair).length!==32||rc(t)!==e.phoneFp)throw Error()}return t}catch{throw new Y(`invalid`)}}function gp(e,t){let n=Z(e,t),r=$f(N(e,`identity.json`),65536,t),i=$f(N(e,`config.json`),65536,t),a=$f(N(e,`pairings.json`),1048576,t);if(pp(r),mp(i),hp(a),!Xf(n,Z(e,t)))throw new Y(`unsafe`);return{identity:r,config:i,pairings:a}}function _p(e){try{if(!X(e.dir))return{status:`absent`};let t=Z(e.dir,e.linuxHost.uid);for(let t of v(e.dir)){let n=/^owner-[1-9][0-9]*-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,r=`owner-${t.slice(34)}`,i=t.startsWith(`service-owner.json.lock-candidate-`)&&n.test(r);if(t===`service-owner.json.lock`||i){let a=N(e.dir,t),o;try{o=Z(a,e.linuxHost.uid);let t=v(a),s=t[0];if(!(i&&t.length===0)){if(t.length!==1||!s||!n.test(s)||i&&s!==r)throw new Y(`unsafe`);$f(N(a,s),0,e.linuxHost.uid)}if(!Xf(o,Z(a,e.linuxHost.uid)))throw new Y(`unsafe`)}catch(t){let n=X(a);if(!n)continue;try{if(i&&o&&Xf(o,n)&&v(a).length===0&&Xf(n,Z(a,e.linuxHost.uid)))continue}catch(e){if(e instanceof Y&&e.kind===`missing`||e.code===`ENOENT`)continue;throw e}throw t}continue}let a=X(N(e.dir,t));if(a&&(!a.isFile()||a.isSymbolicLink()||a.uid!==e.linuxHost.uid||(a.mode&4095)!=384))throw new Y(`unsafe`)}let n=N(e.dir,`host.json`);if(!X(n))return{status:`unmarked`,reason:`Host marker missing; explicit host initialization or recovery required`};let r,i=$f(n,4096,e.linuxHost.uid);try{r=fp.parse(JSON.parse(i.toString(`utf8`)))}catch{throw new Y(`invalid`)}if(r.hostDigest!==e.linuxHost.hostDigest)return{status:`wrong-host`,reason:`State belongs to a different host; choose this host's state directory`};let a=gp(e.dir,e.linuxHost.uid);if(!i.equals($f(n,4096,e.linuxHost.uid))||!Xf(t,Z(e.dir,e.linuxHost.uid)))throw new Y(`unsafe`);return{status:`ready`,bytes:a}}catch(e){return{status:e instanceof Y&&e.kind===`unsafe`?`unsafe`:`invalid`,reason:`Host state failed validation; inspect files and recover explicitly`}}}function vp(e){let t=_p(e);return t.status===`ready`?{status:`ready`}:t}function yp(){return Error(`shellbell: Linux host state is not ready; use shellbell host init --new or host init --adopt <absolute-source> --confirm-source-inactive for absent state; inspect existing state before recovery`)}function bp(e){let t=_p(e);if(!(`bytes`in t))throw yp();return t.bytes}function xp(e){if(vp(e).status!==`ready`)throw yp()}function Sp(e){return pp(bp(e).identity)}function Cp(e){return mp(bp(e).config)}function wp(e){return hp(bp(e).pairings)}const Tp=[`emerald`,`blue`,`amber`,`violet`,`rose`,`cyan`,`lime`,`orange`];function Ep(e=process.env.SHELLBELL_DIR??N(E(),`.shellbell`)){return{dir:e,serviceOwner:N(e,`service-owner.json`),identity:N(e,`identity.json`),pairings:N(e,`pairings.json`),config:N(e,`config.json`),log:N(e,`agent.log`),sock:N(e,`agent.sock`),pid:N(e,`agent.pid`)}}function Dp(e){if(e.linuxHost){xp(e);return}m(e.dir,{recursive:!0,mode:448}),i(e.dir,448)}function Op(e,t,n){Mp(e,t,t=>{n?.(),b(t,e)})}const kp=new Set([`EPERM`,`ENOTSUP`,`EOPNOTSUPP`,`EXDEV`]);function Ap(e,t){try{return Mp(e,t,n=>{try{f(n,e)}catch(n){if(!kp.has(n.code??``))throw n;jp(e,t)}ee(n)}),!0}catch(e){if(e.code===`EEXIST`)return!1;throw e}}function jp(e,t){let n=h(e,`wx`,384),r=l(n),i=!1;try{c(n,384);let e=typeof t==`string`?Buffer.from(t):t,r=0;for(;r<e.byteLength;){let t=T(n,e,r,e.byteLength-r);if(t<=0)throw Error(`secret file write made no progress`);r+=t}u(n),i=!0}finally{if(a(n),!i)try{let t=p(e);t.dev===r.dev&&t.ino===r.ino&&ee(e)}catch{}}}function Mp(e,t,n){let r=`${e}.tmp-${process.pid}`,o=null;try{let e=h(r,`wx`,384),s=l(e);o={dev:s.dev,ino:s.ino};try{let n=typeof t==`string`?Buffer.from(t):t,r=0;for(;r<n.byteLength;){let t=T(e,n,r,n.byteLength-r);if(t<=0)throw Error(`atomic file write made no progress`);r+=t}u(e)}finally{a(e)}i(r,384),n(r)}catch(e){try{if(o){let e=p(r);e.dev===o.dev&&e.ino===o.ino&&ee(r)}}catch{}throw e}}function Np(e){let t;try{t=g(e,`utf8`)}catch(t){throw Error(`shellbell: cannot read ${e}: ${t.message}`)}try{return JSON.parse(t)}catch{throw Error(`shellbell: ${e} is not valid JSON`)}}function Pp(){return{v:1,relayUrl:`wss://relay.shellbell.dev`,computerName:D().replace(/\.local$/,``)||`Mac`,accent:Tp[0],notifyMinCommandMs:1e4,idleQuietMs:3e4,idleMinActiveMs:1500}}function Fp(e){return Bp(e,()=>{if(Up(e),e.linuxHost)return Cp(e);if(!X(e.dir))return Pp();let t=Z(e.dir,process.getuid());if(!X(e.config))return Pp();let n=$f(e.config,Rp,process.getuid());if(!Xf(t,Z(e.dir,process.getuid())))throw new Y(`unsafe`);let r;try{r=JSON.parse(n.toString(`utf8`))}catch{throw new zp(`invalid`,e.config,`not valid JSON`)}return Vp(e,r)})}function Ip(e){return e.linuxHost?Fp(e):Gp(e,()=>{let t=Fp(e);return X(e.config)||Kp(e,t),t})}function Lp(e,t){return Gp(e,()=>t(Fp(e)))}const Rp=65536;var zp=class extends Error{code;constructor(e,t,n=e){super(`shellbell: config ${n} at ${t}`),this.code=e,this.name=`ConfigEditError`}};function Bp(e,t){try{return t()}catch(t){throw t instanceof zp?t:new zp(t instanceof Y?t.kind===`invalid`?`invalid`:`unsafe`:`io`,e.config)}}function Vp(e,t){let n=cp.safeParse(t);if(!n.success)throw new zp(`invalid`,e.config);return n.data}function Hp(e){if(e.linuxHost){xp(e);return}Z(e.dir,process.getuid())}function Up(e){if([e.dir,e.config].some(e=>Buffer.byteLength(e)>4096||e.includes(`\0`))||j(P(e.config))!==P(e.dir))throw new zp(`unsafe`,e.config)}function Wp(e,t){let n=`${A(e)}.lock`;for(let r of v(j(e))){if(r!==n&&!r.startsWith(`${n}-candidate-`))continue;let i=N(j(e),r);if(X(i)){Z(i,t);for(let e of v(i)){let n=X(N(i,e));if(n&&(!n.isFile()||n.isSymbolicLink()||n.uid!==t||(n.mode&4095)!=384))throw new Y(`unsafe`)}}}}function Gp(e,t){let n=Bp(e,()=>{if(Up(e),!e.linuxHost&&!X(e.dir))try{m(e.dir,{recursive:!0,mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}Hp(e);let t=e.config;e.linuxHost&&(sp(e),t=N(e.runtimeDir,`config-${ae(`sha256`).update(e.config).digest(`hex`)}`)),Wp(t,e.linuxHost?.uid??process.getuid());try{return Yf(t)}catch(t){throw t instanceof Error&&t.message.startsWith(`Control endpoint busy`)?new zp(`busy`,e.config):t instanceof Error&&t.message.startsWith(`Invalid control guard`)?new zp(`unsafe`,e.config):t}}),r;try{r=t()}catch(e){try{n()}catch{}throw e}return Bp(e,n),r}function Kp(e,t){Bp(e,()=>{let n=`${JSON.stringify(Vp(e,t),null,2)}\n`;if(Buffer.byteLength(n)>Rp)throw new zp(`invalid`,e.config);Op(e.config,n,()=>{Hp(e),Fp(e)})})}function qp(e,t){return Gp(e,()=>{let n=Vp(e,t(Fp(e)));return Kp(e,n),n})}function Jp(e){if(e.linuxHost)return wp(e);if(Dp(e),!s(e.pairings))return[];let t=up.safeParse(Np(e.pairings));if(!t.success)throw Error(`shellbell: invalid pairings at ${e.pairings}: ${F.prettifyError(t.error)}`);return t.data.phones}function Yp(e,t){Dp(e);let n=new Map(Jp(e).map(e=>[e.phoneFp,e])),r=t.map(e=>dp(n.get(e.phoneFp),e)),i=up.parse({v:1,phones:r}),a=`${JSON.stringify(i,null,2)}\n`;if(e.linuxHost){if(Buffer.byteLength(a)>1048576)throw Error(`shellbell: Linux pairings exceed their state size limit`);hp(Buffer.from(a))}return Op(e.pairings,a,e.linuxHost?()=>xp(e):void 0),i.phones}const Xp=new Set([`Error`,`TypeError`,`RangeError`,`ReferenceError`,`SyntaxError`,`URIError`,`EvalError`,`AggregateError`,`AbortError`,`TimeoutError`,`ProtocolError`,`BackendUnavailable`,`SessionGone`,`Unsupported`,`BadWindow`,`HerdrError`,`ITerm2AuthError`,`ConfigEditError`,`NativeControllerError`,`ControlV2ClientError`]);function Zp(e){try{if(!(e instanceof Error))return`unknown`;let t=e.name;return typeof t==`string`&&Xp.has(t)?t:`Error`}catch{return`unknown`}}const Qp=1048576;function $p(e){return e.isFile()&&e.uid===process.getuid?.()&&e.nlink===1}function em(e,t){return e.dev===t.dev&&e.ino===t.ino}function tm(e,t){let n;try{let i;try{i=p(e)}catch(e){if(e.code!==`ENOENT`)return}if(i&&!$p(i))return;n=h(e,o.O_WRONLY|o.O_APPEND|o.O_NOFOLLOW|o.O_NONBLOCK|(i?0:o.O_CREAT|o.O_EXCL),384);let a=l(n),s=p(e);if(!$p(a)||!$p(s)||!em(a,s)||i&&!em(i,a))return;c(n,384),r(n,t)}catch{}finally{if(n!==void 0)try{a(n)}catch{}}}function nm(e){let t;try{let n=p(e);if(!$p(n)||n.size<Qp)return;t=h(e,o.O_RDWR|o.O_NOFOLLOW|o.O_NONBLOCK);let r=l(t);if(!$p(r)||!em(n,r)||r.size<Qp)return;c(t,384);let i=Math.max(0,r.size-Qp),a=Buffer.alloc(r.size-i);for(let e=0;e<a.length;){let n=_(t,a,e,a.length-e,i+e);if(n===0)return;e+=n}for(let t=4;t>=1;t--)s(`${e}.${t}`)&&b(`${e}.${t}`,`${e}.${t+1}`);Op(`${e}.1`,a);let u=p(e);$p(u)&&em(u,r)&&$p(l(t))&&d(t,0)}catch{}finally{if(t!==void 0)try{a(t)}catch{}}}function rm(e,t={}){let n=e.stdout??process.stdout.isTTY===!0,r=(r,i,a)=>{if(r===`debug`&&!e.verbose)return;let o={t:new Date().toISOString(),level:r,msg:i,...t,...a};if(e.file){nm(e.file);try{tm(e.file,`${JSON.stringify(o)}\n`)}catch{}}if(n){let e=Object.keys({...t,...a}).length?` ${JSON.stringify({...t,...a})}`:``,n=`${o.t.slice(11,19)} ${r.padEnd(5)} ${i}${e}`;(r===`error`||r===`warn`?process.stderr:process.stdout).write(`${n}\n`)}};return{debug:(e,t)=>r(`debug`,e,t),info:(e,t)=>r(`info`,e,t),warn:(e,t)=>r(`warn`,e,t),error:(e,t)=>r(`error`,e,t),child:n=>rm(e,{...t,...n})}}function im(e){if(!am(e.reported)||!am(e.before)||e.before>e.reported||!Number.isSafeInteger(e.count)||e.count<1||e.count>W.historyLines||e.capture===null||typeof e.capture!=`object`)throw RangeError(`invalid history read request`)}function am(e){return Number.isSafeInteger(e)&&e>=0}var om=class extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name=`BackendUnavailable`}},sm=class extends Error{constructor(e){super(`session gone: ${e}`),this.name=`SessionGone`}},cm=class extends Error{code;constructor(e){super(`Terminal input ${e}`),this.code=e,this.name=`TerminalInputError`}},lm=class extends Error{constructor(e){super(`unsupported: ${e}`),this.name=`Unsupported`}},um=class extends Error{constructor(e=`No terminal app on this computer can show a new session.`){super(e),this.name=`NotShownOnComputer`}},dm=class extends Error{constructor(e){super(`bad-window: ${e}`),this.name=`BadWindow`}};async function fm(e,t){let n;try{return await Promise.race([Promise.resolve().then(e),new Promise((e,r)=>{n=setTimeout(()=>r(Error(`Terminal adapter deadline exceeded`)),t),n.unref()})])}finally{n&&clearTimeout(n)}}function pm(e,t){return`${e}:${t}`}const mm=Yl.options,hm=new Set([`iterm2`]);function gm(e){let t=e.indexOf(`:`);if(t<=0)return null;let n=Xl.safeParse(e.slice(0,t));return n.success?{name:n.data,native:e.slice(t+1)}:null}var _m=class{log;listTimeoutMs;conversationPermits=new Map;async conversationReference(e,t){let n=gm(e);if(!n||t.aborted)return null;let r=this.members.get(n.name);if(!r||r.isConnected===!1||!r.conversationReference||this.conversationPermits.has(e)||this.conversationPermits.size>=10)return null;let i={};this.conversationPermits.set(e,i);let a=this.historyMembership.get(n.name),o=!0,s=this.on(t=>{(r.isConnected===!1||(t.type===`session-removed`||t.type===`conversation-changed`)&&t.sessionId===e)&&(o=!1)});try{let e=await r.conversationReference?.(n.native,t);return e&&o&&!t.aborted&&this.historyMembership.get(n.name)===a&&this.members.get(n.name)===r&&this.members.get(n.name)?.isConnected!==!1?e:null}catch{return null}finally{s(),this.conversationPermits.get(e)===i&&this.conversationPermits.delete(e)}}notificationRevision=0;async notificationFacts(e){let t=gm(e);if(!t)return;let n=this.members.get(t.name);if(!n||n.isConnected===!1)return;let r=this.notificationRevision,i=await n.notificationFacts?.(t.native);if(i&&i.sessionId===t.native&&this.members.get(t.name)===n&&r===this.notificationRevision&&this.connected().some(e=>e.name===t.name))return{...i,sessionId:e,revision:JSON.stringify([r,i.revision])}}members=new Map;labels=new Map;hostCommands=new Map;hostedLaunchers=new Map;hostedPending=0;sessionLaunchers=new Map;setupReporters=new Map;setupListeners=new Set;sessionStartups=new Map;startupWaiters=new Map;unsubs=new Map;historyMembership=new Map;historyPermits=new Map;inputCount=0;inputBytes=0;inputQueues=new Map;handlers=new Set;constructor(e,t=8e3){this.log=e,this.listTimeoutMs=t}orderedNames(){let e=new Set([...this.members.keys(),...this.sessionLaunchers.keys()]);for(let t of mm)e.delete(t);return[...mm,...[...e].sort()]}defaultLabel(e){let t=Yl.safeParse(e);return t.success?Zl[t.data]:e}catalog(){return this.orderedNames().map(e=>{let t=this.memberConnected(e);return{name:e,label:this.labels.get(e)??this.defaultLabel(e),capabilities:this.members.get(e)?.capabilities??{subscribe:!1,prompts:!1,createSession:!1,focus:!1,history:!1,absoluteLines:!1},connected:t,launchable:!t&&(this.sessionLaunchers.get(e)?.available()??!1)}})}registerHostedLauncher(e,t){let n=cu.parse(e),r=`${n.backend}:${n.host}`;if(!this.hostedLaunchers.has(r)&&this.hostedLaunchers.size>=64)throw new om(`Too many terminal launch targets`,`Disable a launch target first.`);let i={target:n,launcher:t};return this.hostedLaunchers.set(r,i),this.emit({type:`layout-changed`}),()=>{this.hostedLaunchers.get(r)===i&&(this.hostedLaunchers.delete(r),this.emit({type:`layout-changed`}))}}launchTargets(){return[...this.hostedLaunchers.values()].filter(({target:e,launcher:t})=>t.available()&&(this.memberConnected(e.backend)||this.sessionLaunchers.get(e.backend)?.available())).map(({target:e})=>({...e})).sort((e,t)=>`${e.backend}:${e.host}`.localeCompare(`${t.backend}:${t.host}`))}launchIssues(){let e=new Set(this.launchTargets().map(e=>e.backend)),t=new Map;for(let{target:n,launcher:r}of this.hostedLaunchers.values()){if(e.has(n.backend)||t.has(n.backend))continue;let i=r.unavailableReason?.();i&&t.set(n.backend,i)}return du.parse([...t].map(([e,t])=>({backend:e,reason:t})))}preferredHost(e){return _u(e,this.launchTargets())?.host}async requireShownOnComputer(e,t){if(!hm.has(e.name)&&!(e.shownOnComputer&&await fm(()=>e.shownOnComputer(t),5e3)))throw new um(`This session is not open in a terminal window on your computer, so it cannot be split or extended from the phone.`)}async createHostedSession(e){let t=`${e.backend}:${e.host}`,n=this.hostedLaunchers.get(t);if(e.windowId!==void 0||!n?.launcher.available())throw new om(`Terminal launch target is unavailable`,`Check the selected terminal app on your computer.`);if(this.hostedPending>=8)throw new om(`Terminal startup is busy`,`Wait for the current startup to finish.`);this.hostedPending++;let r=(async()=>{if(this.hostedLaunchers.get(t)!==n)throw new sm(t);let r=this.members.get(e.backend),i;if(!r||r.isConnected===!1){let t=await this.startSession(e.backend,e.initialSize);r=t.backend,i=t.sessionId}if(this.hostedLaunchers.get(t)!==n||this.members.get(e.backend)!==r)throw new sm(t);let a=e.initialSize?await n.launcher.create(r,i,e.initialSize):await n.launcher.create(r,i);if(this.hostedLaunchers.get(t)!==n||this.members.get(e.backend)!==r||r.isConnected===!1)throw new sm(t);return pm(e.backend,a)})().finally(()=>{this.hostedPending--});return fm(()=>r,3e4)}get capabilities(){let e=[...this.members.values()].filter(e=>e.isConnected!==!1).map(e=>e.capabilities),t=t=>e.some(e=>e[t]);return{subscribe:t(`subscribe`),prompts:t(`prompts`),createSession:t(`createSession`)||[...this.sessionLaunchers.values()].some(e=>e.available()),focus:t(`focus`),history:t(`history`),absoluteLines:e.length>0&&e.every(e=>e.absoluteLines)}}add(e,t,n){let r=ou.parse({name:e.name,label:t??this.defaultLabel(e.name),capabilities:e.capabilities,connected:!1,launchable:!1});if(!this.orderedNames().includes(e.name)&&this.orderedNames().length>=32)throw new om(`Too many terminal adapters`,`Disable an adapter before adding another.`);let i={},a=e.on(t=>{this.members.get(e.name)===e&&this.historyMembership.get(e.name)===i&&this.emit(ym(e.name,t))});if(typeof a!=`function`)throw Error(`Terminal adapter subscription is invalid`);let o=this.unsubs.get(e.name);this.labels.set(e.name,r.label),this.hostCommands.set(e.name,n??(e.name===`tmux`||e.name===`herdr`?[e.name]:[])),this.members.set(e.name,e),this.historyMembership.set(e.name,i),this.unsubs.set(e.name,a);try{o?.()}catch(t){this.log.warn(`backend subscription cleanup failed`,{backend:e.name,err:Zp(t)})}this.emit({type:`layout-changed`})}remove(e){let t=this.unsubs.get(e);this.unsubs.delete(e),this.members.delete(e),this.labels.delete(e),this.hostCommands.delete(e),this.historyMembership.delete(e);try{t?.()}catch(t){this.log.warn(`backend subscription cleanup failed`,{backend:e,err:Zp(t)})}this.emit({type:`layout-changed`})}connected(){let e=[];for(let t of this.orderedNames()){let n=this.members.get(t);n&&n.isConnected!==!1&&e.push({name:n.name,capabilities:n.capabilities})}return e}registerSessionLauncher(e,t){if(Xl.parse(e),!this.orderedNames().includes(e)&&this.orderedNames().length>=32)throw new om(`Too many terminal adapters`,`Disable an adapter before adding another.`);return this.sessionLaunchers.set(e,t),this.sessionStartups.delete(e),this.emit({type:`layout-changed`}),()=>{this.sessionLaunchers.get(e)===t&&(this.sessionLaunchers.delete(e),this.sessionStartups.delete(e),this.emit({type:`layout-changed`}))}}launchable(){return this.orderedNames().filter(e=>!this.memberConnected(e)&&this.sessionLaunchers.get(e)?.available())}async startSession(e,t){let n=this.sessionLaunchers.get(e);if(!n?.available())throw new sm(`backend ${e}`);let r=this.startupWaiters.get(e)??0;if(r>=8)throw new om(`Terminal startup is busy`,`Try again after the current startup finishes.`);this.startupWaiters.set(e,r+1);try{let r=this.sessionStartups.get(e);if(!r){let i=Promise.resolve().then(()=>{if(this.sessionLaunchers.get(e)!==n)throw new sm(`backend ${e}`);return t?n.start(t):n.start()}).then(e=>({...e})).finally(()=>{this.sessionStartups.get(e)===i&&this.sessionStartups.delete(e)});r=i,this.sessionStartups.set(e,i)}let i=await r;if(this.sessionLaunchers.get(e)!==n||this.members.get(e)!==i.backend||i.backend.isConnected===!1)throw new sm(`backend ${e}`);let a=i.sessionId;return i.sessionId=void 0,{backend:i.backend,sessionId:a}}finally{let t=(this.startupWaiters.get(e)??1)-1;t===0?this.startupWaiters.delete(e):this.startupWaiters.set(e,t)}}member(e){return this.members.get(e)}registerSetupReporter(e,t){return this.setupReporters.set(e,t),()=>{this.setupReporters.get(e)===t&&this.setupReporters.delete(e)}}onSetupChanged(e){return this.setupListeners.add(e),()=>this.setupListeners.delete(e)}notifySetupChanged(){for(let e of this.setupListeners)try{e()}catch{}}terminalSetup(){return this.orderedNames().flatMap(e=>{let t=this.setupReporters.get(e),n=this.memberConnected(e);if(!t&&!this.members.has(e))return[];let r={};try{r=t?.(n)??{}}catch{r=n?{}:{issue:`failed`}}return[{name:e,connected:n,...r.issue?{issue:r.issue}:{},...r.issue&&r.detail?{detail:r.detail}:{}}]}).slice(0,16)}connectTerminal(e){let t=this.setupReporters.get(e)?.connect;if(!t)return!1;try{t().catch(e=>this.log.debug(`terminal connect failed`,{error:Zp(e)}))}catch(e){this.log.debug(`terminal connect failed`,{error:Zp(e)})}return!0}status(){return this.orderedNames().map(e=>({name:e,connected:this.memberConnected(e)}))}nameOf(e){return gm(e)?.name??null}capabilitiesOf(e){let t=this.nameOf(e);return t?this.members.get(t)?.capabilities??null:null}async connect(){}async close(){let e=[...this.members.values()],t=[...this.unsubs.values()];this.sessionLaunchers.clear(),this.hostedLaunchers.clear(),this.sessionStartups.clear(),this.historyMembership.clear(),this.unsubs.clear(),this.members.clear(),this.labels.clear(),this.hostCommands.clear();for(let e of t)try{e()}catch(e){this.log.warn(`backend subscription cleanup failed`,{err:Zp(e)})}await Promise.all(e.map(async e=>{try{await fm(()=>e.close(),this.listTimeoutMs)}catch(t){this.log.warn(`backend close failed`,{backend:e.name,err:Zp(t)})}}))}async listSessions(){let e=this.orderedNames().map(e=>({name:e,backend:this.members.get(e),membership:this.historyMembership.get(e)})),t=(await Promise.all(e.map(async e=>({...e,sessions:await this.safeListSessions(e.backend,e.name)})))).filter(({name:e,backend:t,membership:n})=>t&&this.members.get(e)===t&&this.historyMembership.get(e)===n),n=new Set;for(let{name:e,backend:r}of t)try{for(let e of r?.representedWindows?.()??[])n.add(JSON.stringify([e.backend,e.windowId]))}catch(t){this.log.warn(`terminal window relationships unavailable`,{backend:e,err:Zp(t)})}let r=[];for(let{name:e,backend:i,sessions:a}of t)for(let o of a){try{let r=i?.nativeWindowIdOf?.(o.id);if(r&&n.has(JSON.stringify([e,r])))continue;let a=i?.hostedProcess?.(o.id);if(a&&t.some(t=>t.name!==e&&this.memberConnected(t.name)&&this.hostCommands.get(t.name)?.includes(a)))continue}catch(t){this.log.warn(`terminal host relationship unavailable`,{backend:e,err:Zp(t)})}r.push(vm(e,o))}return r}projectFolder(e){let t=gm(e),n=t?this.members.get(t.name):void 0;if(t&&n?.projectFolder)try{return n.projectFolder(t.native)}catch(e){this.log.warn(`session project folder unavailable`,{backend:t.name,err:Zp(e)});return}}memberConnected(e){let t=this.members.get(e);return!!t&&t.isConnected!==!1}async safeListSessions(e,t){if(!e)return[];let n=this.historyMembership.get(t);try{let r=await fm(()=>e.listSessions(),this.listTimeoutMs);return this.members.get(t)!==e||this.historyMembership.get(t)!==n?[]:r}catch(e){return this.log.warn(`listSessions failed for backend; returning the other backends' sessions`,{backend:t,err:Zp(e)}),[]}}target(e){let t=gm(e),n=t?this.members.get(t.name):void 0;if(!t||!n)throw new sm(e);return{backend:n,native:t.native}}async getScreen(e,t){let{backend:n,native:r}=this.target(e);return t===void 0?n.getScreen(r):n.getScreen(r,t)}async getHistory(e,t,n){let{backend:r,native:i}=this.target(e);return r.getHistory(i,t,n)}async getHistoryPage(e,t){let{backend:n,native:r}=this.target(e);if(im(t),t.signal.aborted)return{status:`cancelled`};let i=n.getHistoryPage;if(!i)return{status:`unavailable`,reason:`unsupported`};if(this.historyPermits.has(e)||this.historyPermits.size>=10)return{status:`unavailable`,reason:`busy`};let a={};this.historyPermits.set(e,a);let o=this.historyMembership.get(n.name);try{let e=await i.call(n,r,t);return t.signal.aborted?{status:`cancelled`}:this.historyMembership.get(n.name)===o?e:{status:`reset`}}catch(e){if(t.signal.aborted)return{status:`cancelled`};if(this.historyMembership.get(n.name)!==o)return{status:`reset`};throw e}finally{this.historyPermits.get(e)===a&&this.historyPermits.delete(e)}}async sendText(e,t,n){let{backend:r,native:i}=this.target(e);return this.enqueueInput(e,r,t,()=>r.sendText(i,t),n)}async clickMouse(e,t,n){let{backend:r,native:i}=this.target(e);if(!r.capabilities.mouseClick||!r.clickMouse)throw new lm(`mouse input`);return this.enqueueInput(e,r,``,()=>r.clickMouse(i,t),n)}async sendInput(e,t,n){let{backend:r,native:i}=this.target(e);if(!r.capabilities.terminalInput||!r.sendInput)throw new lm(`terminal input`);return this.enqueueInput(e,r,t,()=>r.sendInput(i,t),n)}openVtStream(e){let{backend:t,native:n}=this.target(e);if(!t.capabilities.vtStream||!t.openVtStream)throw new lm(`vt stream`);return t.openVtStream(n)}async paste(e,t,n,r){let{backend:i,native:a}=this.target(e);if(!i.capabilities.terminalPaste||!i.paste)throw new lm(`terminal paste`);return this.enqueueInput(e,i,t,()=>i.paste(a,t,n),r)}enqueueInput(e,t,n,r,i){let a=Buffer.byteLength(n);if(this.inputCount>=256||this.inputBytes+a>1048576)return Promise.reject(new cm(`busy`));let o=this.inputQueues.get(e);if(o||(o={backend:t,membership:this.historyMembership.get(t.name),tail:Promise.resolve(),pending:0,valid:!0},this.inputQueues.set(e,o)),!o.valid||o.backend!==t)return Promise.reject(new cm(`cancelled`));let s=o;s.pending++,this.inputCount++,this.inputBytes+=a;let c=()=>this.members.get(t.name)===t&&t.isConnected!==!1&&this.historyMembership.get(t.name)===s.membership,l=s.tail.then(async()=>{if(!s.valid||i?.()===!1)throw new cm(`cancelled`);if(!c())throw new sm(e);await r(),s.valid&&c()&&this.emit({type:`input-accepted`,sessionId:e})});return s.tail=l.catch(()=>{s.valid=!1}),l.finally(()=>{this.inputCount--,this.inputBytes-=a,--s.pending===0&&this.inputQueues.get(e)===s&&this.inputQueues.delete(e)})}async createSession(e){if(e.kind===`tab`&&e.host!==void 0)return this.createHostedSession(e);if(e.kind===`split`){let{backend:t,native:n}=this.target(e.sessionId),r={kind:`split`,sessionId:n,direction:e.direction};return await this.requireShownOnComputer(t,r),pm(t.name,await t.createSession(r))}let t;if(e.windowId){let n=gm(e.windowId);if(!n||n.name!==e.backend)throw new dm(e.windowId);t=n.native}if(!hm.has(e.backend)){if(t===void 0){let t=this.preferredHost(e.backend);if(t===void 0)throw new um;return this.createHostedSession({kind:`tab`,backend:e.backend,host:t,...e.initialSize?{initialSize:e.initialSize}:{}})}let n=this.members.get(e.backend);if(!n||n.isConnected===!1)throw new sm(`${e.windowId}`);let r={kind:`tab`,backend:e.backend,windowId:t};return await this.requireShownOnComputer(n,r),pm(n.name,await n.createSession(r))}let n=this.members.get(e.backend);if(!n||n.isConnected===!1){if(e.windowId)throw new sm(e.windowId);let t=await this.startSession(e.backend,e.initialSize);if(t.sessionId)return pm(e.backend,t.sessionId);n=t.backend}return pm(n.name,await n.createSession({kind:`tab`,backend:e.backend,windowId:t,...e.initialSize?{initialSize:e.initialSize}:{}}))}async focus(e){let{backend:t,native:n}=this.target(e);return t.focus(n)}setWatched(e){let t=new Map;for(let e of this.members.keys())t.set(e,[]);for(let n of e){let e=gm(n);e&&t.get(e.name)?.push(e.native)}for(let[e,n]of t)try{this.members.get(e)?.setWatched?.(n)}catch(t){this.log.warn(`setWatched failed for backend`,{backend:e,err:Zp(t)})}}setReported(e,t){let n=gm(e);if(n)try{this.members.get(n.name)?.setReported?.(n.native,t)}catch(e){this.log.warn(`setReported failed for backend`,{backend:n.name,err:Zp(e)})}}on(e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(e){if(e.type===`session-removed`){let t=this.inputQueues.get(e.sessionId);t&&(t.valid=!1)}for(let e of this.inputQueues.values())(e.backend.isConnected===!1||this.members.get(e.backend.name)!==e.backend)&&(e.valid=!1);[`layout-changed`,`session-added`,`session-removed`,`title-changed`].includes(e.type)&&this.notificationRevision++;for(let t of[...this.handlers])if(this.handlers.has(t))try{t(e)}catch(e){this.log.error(`backend event handler threw`,{err:Zp(e)})}}};function vm(e,t){return{...t,id:pm(e,t.id),windowId:pm(e,t.windowId),tabId:pm(e,t.tabId),backend:e}}function ym(e,t){return`sessionId`in t?{...t,sessionId:pm(e,t.sessionId)}:t}function bm(e,t){let n;try{n=new URL(e)}catch{return`must be a valid URL, e.g. wss://relay.example.com`}return e.endsWith(`/`)||/[?#]/.test(e)||n.pathname!==`/`||n.username||n.password?`relay url must be scheme://host[:port] with no path, query or credentials`:e.length>256?`relay url is too long for a pairing code (at most 256 characters)`:n.protocol===`wss:`?null:n.protocol===`ws:`?t?null:`ws:// is insecure; pass --insecure or set SHELLBELL_ALLOW_INSECURE_RELAY=1 for LAN dev`:`relay url must use wss:// (ws:// only with --insecure, for LAN dev)`}function xm(e,t,n,r){let i;if(t===`relay`){let t=bm(n,r);if(t)return{error:t};i={...e,relayUrl:n}}else if(t===`name`)i={...e,computerName:n};else if(t===`accent`){if(!Tp.includes(n))return{error:`unknown accent ${n} (must be one of ${Tp.join(`, `)})`};i={...e,accent:n}}else if(t===`turn`){if(n!==`on`&&n!==`off`)return{error:`turn must be on or off`};let{turn:t,...r}=e;i=n===`off`?{...r,turn:!1}:r}else if(t===`conversations`){if(n!==`on`&&n!==`off`)return{error:`conversations must be on or off`};let{showAgentConversations:t,...r}=e;i=n===`on`?{...r,showAgentConversations:!0}:r}else if(wm(t)){if(!/^\d+$/.test(n))return{error:`${t} must be a complete decimal integer`};let r=Number(n);if(!Number.isSafeInteger(r))return{error:`${t} must be a safe decimal integer`};i={...e,[t]:r}}else return{error:`unknown key ${t} (expected ${Tm()})`};let a=cp.safeParse(i);return a.success?{next:a.data}:{error:a.error.issues.map(e=>e.message).join(`; `)}}const Sm=[`notifyMinCommandMs`,`idleQuietMs`,`idleMinActiveMs`],Cm=[`relay`,`name`,`accent`,...Sm,`turn`,`conversations`];function wm(e){return Sm.includes(e)}function Tm(){return`${Cm.slice(0,-1).join(`, `)}, or ${Cm.at(-1)}`}function Em(e,t){switch(t){case`relay`:return e.relayUrl;case`name`:return e.computerName;case`accent`:return e.accent;case`turn`:return e.turn===!1?`off`:`on`;case`conversations`:return e.showAgentConversations===!0?`on`:`off`;default:return String(e[t])}}function Dm(e){let t=cp.parse(e);return ae(`sha256`).update(JSON.stringify({v:t.v,relayUrl:t.relayUrl,computerName:t.computerName,accent:t.accent,notifyMinCommandMs:t.notifyMinCommandMs,idleQuietMs:t.idleQuietMs,idleMinActiveMs:t.idleMinActiveMs,...t.terminalPlugins?.length?{terminalPlugins:t.terminalPlugins}:{},...t.turn===!1?{turn:!1}:{},...t.showAgentConversations===!0?{showAgentConversations:!0}:{}})).digest(`hex`)}const Om=F.object({name:Xl,connected:F.boolean()}),km=F.array(Om).max(32),Am=F.object({pid:F.number().int().positive().max(2**53-1),agentVersion:F.string().min(1),computerFp:U,stateDir:F.string().min(1).refine(M,`state directory must be absolute`),serviceInstance:F.uuid().nullable()}),jm={controlVersion:F.literal(1),process:Am,backends:km,terminalReady:F.boolean()};function Mm(e,t){(e.backends.length<mm.length||mm.some((t,n)=>e.backends[n]?.name!==t)||new Set(e.backends.map(e=>e.name)).size!==e.backends.length||e.backends.slice(mm.length).some((e,t,n)=>t>0&&e.name<n[t-1].name))&&t.addIssue({code:`custom`,path:[`backends`],message:`backend status must contain each known backend in protocol order`}),e.terminalReady!==e.backends.some(e=>e.connected)&&t.addIssue({code:`custom`,path:[`terminalReady`],message:`terminal readiness must match backend connectivity`})}const Nm=F.string().min(1).max(64),Pm=F.object({route:F.enum([`relay`,`direct`]).nullable(),ready:F.boolean(),phase:F.string().max(32),lastFailure:F.string().max(32).nullable(),relaySent:F.number().int().nonnegative(),relayReceived:F.number().int().nonnegative(),directSent:F.number().int().nonnegative(),directReceived:F.number().int().nonnegative()}),Fm=F.object({...jm,relayOnline:F.boolean(),sessions:F.number().int().nonnegative().max(2**53-1),phones:F.array(F.object({phoneFp:U,name:Nm,lastSeenAt:F.string().nullable()})).max(10),connected:F.array(F.object({phoneFp:U,name:Nm,viewed:F.string().nullable(),transport:Pm.optional()})).max(10)}).superRefine(Mm);function Im(e,t=process.env){if(!e)return null;let n=t.SHELLBELL_SERVICE_INSTANCE;if(n===void 0)return null;if(!F.uuid().safeParse(n).success)throw Error(`SHELLBELL_SERVICE_INSTANCE must be a valid UUID`);return n}function Lm(e){try{return t.lstatSync(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}function Rm(e,t){return e?.dev===t.dev&&e.ino===t.ino}function zm(e){let t=process.platform===`darwin`?103:process.platform===`linux`?107:null;if(t===null)throw Error(`Unsupported control socket platform: ${process.platform}`);if(Buffer.byteLength(e)>t)throw Error(`Control socket path is too long (maximum ${t} bytes): ${e}`)}async function Bm(e){return new Promise((t,n)=>{let r=le(e),i=setTimeout(()=>a(Error(`Control socket probe timed out: ${e}`)),1e3),a=(e,a=!1)=>{clearTimeout(i),r.destroy(),e?n(e):t(a)};r.once(`connect`,()=>a(void 0,!0)),r.once(`error`,e=>{e.code===`ENOENT`||e.code===`ECONNREFUSED`?a():a(e)})})}var Vm=class{sockPath;onConnection;log;pidPath;admit;server;clients=new Set;ownedSocket;ownedPid;lifecycle=Promise.resolve();constructor(e,t,n,r,i){this.sockPath=e,this.onConnection=t,this.log=n,this.pidPath=r,this.admit=i}serialize(e){let t=this.lifecycle.then(e);return this.lifecycle=t.catch(()=>{}),t}start(){return this.serialize(async()=>{if(this.server)return;if(this.ownedSocket||this.ownedPid)throw Error(`Control endpoint cleanup pending; stop it before restarting`);zm(this.sockPath),zm(N(j(this.sockPath),`.s12345678`));let e=Yf(this.sockPath);try{this.admit?.(),this.checkPid();let e=Lm(this.sockPath);if(e){if(!e.isSocket())throw Error(`Control socket path is not a socket: ${this.sockPath}`);if(await Bm(this.sockPath))throw Error(`Control endpoint already running: ${this.sockPath}`);if(!Rm(Lm(this.sockPath),e))throw Error(`Control socket changed during startup; retry`);t.unlinkSync(this.sockPath);for(let n of t.readdirSync(j(this.sockPath))){if(!/^\.s[A-Za-z0-9_-]{8}$/.test(n))continue;let r=N(j(this.sockPath),n);Rm(Lm(r),e)&&t.unlinkSync(r)}}let n=await this.bind();t.chmodSync(n,384);let r=t.lstatSync(n);if(t.linkSync(n,this.sockPath),this.ownedSocket=r,this.pidPath){this.checkPid();let e=String(process.pid);Op(this.pidPath,e),this.ownedPid={identity:t.lstatSync(this.pidPath),contents:e}}this.admit?.()}catch(e){try{this.removeOwned()}finally{await this.closeListener()}throw e}finally{e()}})}checkPid(){if(!this.pidPath)return;let e=Lm(this.pidPath);if(!e)return;if(!e.isFile())throw Error(`PID path must be a regular file: ${this.pidPath}`);let n=Gf(t.readFileSync(this.pidPath,`utf8`).trim());if(n===null)throw Error(`Invalid PID file; inspect ${this.pidPath} before retrying`);if(Kf(n))throw Error(`shellbell is already running (pid ${n})`)}async bind(){for(let e=0;e<8;e++){let e=N(j(this.sockPath),`.s${se(6).toString(`base64url`)}`),t=ue(e=>{this.clients.add(e),e.once(`close`,()=>this.clients.delete(e)),e.on(`error`,()=>{}),this.onConnection(e)});this.server=t;try{return await new Promise((n,r)=>{t.once(`error`,r);let i=process.umask(127);try{t.listen(e,()=>{t.removeListener(`error`,r),n()})}finally{process.umask(i)}}),e}catch(e){if(await this.closeListener(),e.code!==`EADDRINUSE`)throw e}}throw Error(`Control endpoint private socket names are in use after eight attempts`)}removeOwned(){if(this.ownedSocket&&=(Rm(Lm(this.sockPath),this.ownedSocket)&&t.unlinkSync(this.sockPath),void 0),this.pidPath&&this.ownedPid){let e=Lm(this.pidPath);e?.isFile()&&Rm(e,this.ownedPid.identity)&&t.readFileSync(this.pidPath,`utf8`)===this.ownedPid.contents&&t.unlinkSync(this.pidPath),this.ownedPid=void 0}}async closeListener(){for(let e of this.clients)e.destroy();this.clients.clear();let e=this.server;this.server=void 0,e&&await new Promise((t,n)=>e.close(e=>{e&&e.code!==`ERR_SERVER_NOT_RUNNING`?n(e):t()}))}stop(){return this.serialize(async()=>{let e;try{(this.ownedSocket||this.ownedPid)&&(e=Yf(this.sockPath),this.removeOwned())}catch(e){throw this.log.warn(`Control endpoint cleanup failed; shared paths retained for retry`,{error:Zp(e)}),e}finally{try{await this.closeListener()}finally{e?.()}}})}};const Hm={lineBytes:65536,queuedBytes:262144,connections:16,initialRequestMs:5e3,requestMs:5e3,challengeMs:6e4};function Um(e){let t;try{t=JSON.stringify(e)}catch{return null}if(t===void 0)return null;let n=new TextEncoder().encode(`${t}\n`);return n.byteLength-1<=Hm.lineBytes?n:null}function Wm(e,t){let n=e.writableLength;if(e.destroyed||!Number.isFinite(n)||n<0||n+t.byteLength>Hm.queuedBytes)return e.destroy(),!1;try{return e.write(t),!0}catch{return e.destroy(),!1}}var Gm=class{onLine;onError;maxBytes;chunks=[];bytes=0;terminal=!1;constructor(e){this.onLine=e.onLine,this.onError=e.onError;let t=e.maxBytes??Hm.lineBytes;this.maxBytes=Number.isFinite(t)?Math.max(0,Math.min(t,Hm.lineBytes)):Hm.lineBytes}push(e){if(this.terminal||e.byteLength===0)return;let t=0;for(;t<e.byteLength&&!this.terminal;){let n=e.indexOf(10,t),r=n===-1?e.byteLength:n,i=r-t;if(this.bytes+i>this.maxBytes){this.fail(`line-too-large`);return}if(i>0&&(this.chunks.push(Uint8Array.from(e.subarray(t,r))),this.bytes+=i),n===-1)return;let a=this.decodeLine();if(a===null)return;this.reset(),this.onLine(a),t=n+1}}finish(){this.terminal||(this.bytes>0?this.fail(`incomplete-line`):(this.terminal=!0,this.reset()))}decodeLine(){let e=new Uint8Array(this.bytes),t=0;for(let n of this.chunks)e.set(n,t),t+=n.byteLength;try{return new TextDecoder(`utf-8`,{fatal:!0,ignoreBOM:!0}).decode(e)}catch{return this.fail(`invalid-utf8`),null}}fail(e){this.terminal||(this.terminal=!0,this.reset(),this.onError(e))}reset(){this.chunks=[],this.bytes=0}};const Km=F.number().int().positive().max(2**53-1),qm=F.string().regex(/^[A-Za-z0-9_-]{22}$/),Jm=F.string().min(1).max(64),Ym=F.object({pid:Km,agentVersion:F.string().min(1),computerFp:U,stateDir:F.string().min(1).refine(M,`state directory must be absolute`),serviceInstance:F.uuid().nullable()}).strict(),Xm=F.object({name:Xl,connected:F.boolean()}).strict(),Zm=F.object({phoneFp:U,name:Jm,lastSeenAt:F.string().nullable()}).strict(),Qm=F.object({phoneFp:U,name:Jm,viewed:F.string().nullable(),transport:Pm.strict().optional()}).strict(),$m=F.object({controlVersion:F.literal(1),process:Ym,backends:F.array(Xm),terminalReady:F.boolean(),relayOnline:F.boolean(),sessions:F.number().int().nonnegative().max(2**53-1),phones:F.array(Zm).max(10),connected:F.array(Qm).max(10)}).strict().superRefine((e,t)=>{Fm.safeParse(e).success||t.addIssue({code:`custom`,message:`status must satisfy LocalStatus semantics`})}),eh=F.object({}).strict(),th=F.object({version:F.literal(2),runtime:Ym,capabilities:F.tuple([F.literal(`status`),F.literal(`devices`),F.literal(`pairing`),F.literal(`revoke`)])}).strict(),nh=F.array(Zm).max(10),rh=F.object({removed:F.boolean()}).strict(),ih=F.object({flowId:qm,qrText:F.string().min(1).refine(e=>new TextEncoder().encode(e).byteLength<=Hm.lineBytes),expiresAt:Km}).strict(),ah={hello:th,status:$m,"status.config":F.object({revision:F.string().regex(/^[0-9a-f]{64}$/)}).strict(),"settings.conversations.apply":F.object({revision:F.string().regex(/^[0-9a-f]{64}$/)}).strict(),devices:nh,"devices.revoke":rh,"pairing.open":ih,"pairing.close":eh,"pairing.confirm":eh,terminals:F.object({terminals:mu}).strict(),"terminals.connect":F.object({started:F.boolean(),terminals:mu}).strict()},oh={v:F.literal(2),id:Km},sh={...oh,expect:Ym},ch=F.discriminatedUnion(`cmd`,[F.object({...sh,cmd:F.literal(`settings.conversations.apply`),args:F.object({revision:F.string().regex(/^[0-9a-f]{64}$/)}).strict()}).strict(),F.object({...oh,cmd:F.literal(`hello`)}).strict(),F.object({...oh,cmd:F.literal(`status`)}).strict(),F.object({...oh,cmd:F.literal(`status.config`)}).strict(),F.object({...oh,cmd:F.literal(`devices`)}).strict(),F.object({...oh,cmd:F.literal(`terminals`)}).strict(),F.object({...sh,cmd:F.literal(`terminals.connect`),args:F.object({name:Xl}).strict()}).strict(),F.object({...sh,cmd:F.literal(`devices.revoke`),args:F.object({phoneFp:U}).strict()}).strict(),F.object({...sh,cmd:F.literal(`pairing.open`)}).strict(),F.object({...sh,cmd:F.literal(`pairing.close`),args:F.object({flowId:qm}).strict()}).strict(),F.object({...sh,cmd:F.literal(`pairing.confirm`),args:F.object({flowId:qm,challengeId:qm,phoneFp:U,accept:F.boolean()}).strict()}).strict()]),lh=F.enum([`bad-request`,`unsupported-version`,`handshake-required`,`runtime-mismatch`,`configuration-mismatch`,`pairing-busy`,`stale-flow`,`stale-challenge`,`response-too-large`,`operation-failed`]),uh=F.object({v:F.literal(2),id:Km,ok:F.literal(!0),data:F.unknown()}).strict().refine(e=>Object.hasOwn(e,`data`)),dh=F.object({v:F.literal(2),id:Km,ok:F.literal(!1),error:F.object({code:lh}).strict()}).strict(),fh=F.union([uh,dh]),ph=F.object({v:F.literal(2),event:F.literal(`pairing.request`),flowId:qm,challengeId:qm,phoneFp:U,name:Jm}).strict(),mh=F.object({v:F.literal(2),event:F.literal(`pairing.closed`),flowId:qm}).strict(),hh=F.discriminatedUnion(`event`,[ph,mh]),gh=[`status`,`devices`,`pairing`,`revoke`];function _h(e,t){return e.pid===t.pid&&e.agentVersion===t.agentVersion&&e.computerFp===t.computerFp&&e.stateDir===t.stateDir&&e.serviceInstance===t.serviceInstance}function vh(e){if(!e||typeof e!=`object`)return;let t=e.id;return typeof t==`number`&&Number.isSafeInteger(t)&&t>0?t:void 0}var yh=class{agent;log;peers=new Set;owner;stopped=!1;newId;constructor(e,t,n){this.agent=e,this.log=t,this.newId=n?.newId??(()=>se(16).toString(`base64url`))}get hasPairOwner(){return this.owner!==void 0}accept(e){let t=new bh(this,e,this.agent);return this.stopped?t.close():this.peers.add(t),t}confirm(e,t){let n=this.owner;if(!n||n.resolve||this.stopped)return Promise.resolve(!1);let r=this.newId();return new Promise(i=>{if(this.owner!==n)return i(!1);n.resolve=i,n.challengeId=r,n.phoneFp=e,n.name=t,n.opening||this.emitRequest(n,t)})}activate(e,t){let n=this.owner;n&&n.peer===e&&n.flowId===t&&(n.opening=!1,n.resolve&&n.phoneFp&&n.challengeId&&this.emitRequest(n,n.name??``))}emitRequest(e,t){if(!e.resolve||!e.challengeId||!e.phoneFp)return;let n=e.resolve,r=Math.max(0,(e.expiresAt??Date.now())-Date.now());e.timer=setTimeout(()=>{this.owner===e&&e.resolve===n&&(e.resolve=void 0,e.challengeId=void 0,e.phoneFp=void 0,n(!1))},Math.min(Hm.challengeMs,r)),e.timer.unref(),e.peer.event({v:2,event:`pairing.request`,flowId:e.flowId,challengeId:e.challengeId,phoneFp:e.phoneFp,name:t})||this.clearOwner(e,!1,!0)}notifyClosed(){let e=this.owner;e&&(this.clearOwner(e,!1,!1),e.peer.event({v:2,event:`pairing.closed`,flowId:e.flowId}))}stop(){this.stopped=!0;let e=this.owner;e&&this.clearOwner(e,!0,!1);for(let e of this.peers)e.close();this.peers.clear()}removed(e){this.peers.delete(e);let t=this.owner;t?.peer===e&&this.clearOwner(t,!0,!1)}open(e){if(this.owner||this.agent.pairingOpen)return`pairing-busy`;try{let t=this.newId(),n={peer:e,flowId:t,opening:!0};this.owner=n;let r=this.agent.openPairing();return this.owner!==n||!this.agent.pairingOpen?(this.clearOwner(n,!0,!1),`operation-failed`):(n.expiresAt=r.expiresAt,{flowId:t,...r})}catch{let t=this.owner;return t?.peer===e&&this.clearOwner(t,!0,!1),`operation-failed`}}close(e,t){let n=this.owner;if(!n||n.peer!==e||n.flowId!==t)return`stale-flow`;this.clearOwner(n,!0,!1)}answer(e,t){let n=this.owner;if(!n||n.peer!==e||n.flowId!==t.args.flowId)return`stale-flow`;if(n.expiresAt===void 0||Date.now()>=n.expiresAt)return this.clearOwner(n,!0,!0),`stale-flow`;if(!n.resolve||n.challengeId!==t.args.challengeId||n.phoneFp!==t.args.phoneFp)return`stale-challenge`;let r=n.resolve;n.timer&&clearTimeout(n.timer),n.timer=void 0,n.resolve=void 0,n.challengeId=void 0,n.phoneFp=void 0,n.name=void 0,r(t.args.accept)}clearOwner(e,t,n){if(this.owner!==e)return;this.owner=void 0;let r=e.resolve;if(e.timer&&clearTimeout(e.timer),e.timer=void 0,e.resolve=void 0,e.challengeId=void 0,e.phoneFp=void 0,e.name=void 0,r?.(!1),t)try{this.agent.closePairing()}catch{this.log.warn(`native pairing close failed`)}n&&e.peer.event({v:2,event:`pairing.closed`,flowId:e.flowId})}},bh=class{hub;socket;agent;helloRuntime;lastId=0;closed=!1;constructor(e,t,n){this.hub=e,this.socket=t,this.agent=n}get handshaken(){return this.helloRuntime!==void 0}close(){this.closed||(this.closed=!0,this.hub.removed(this),this.socket.destroy())}handle(e){if(this.closed||this.socket.destroyed)return;let t=vh(e);if(this.handshaken&&t!==void 0){if(t<=this.lastId){this.close();return}this.lastId=t}if(e&&typeof e==`object`&&e.v!==2){t!==void 0&&this.failure(t,`unsupported-version`),this.close();return}let n=ch.safeParse(e);if(!n.success){t===void 0?this.close():this.failure(t,`bad-request`);return}let r=n.data;if(!this.handshaken){if(r.id!==1||r.cmd!==`hello`){this.close();return}this.lastId=1,this.helloRuntime={...this.runtime()},this.success(r,{version:2,runtime:this.helloRuntime,capabilities:gh});return}if(r.cmd===`hello`){this.close();return}let i=this.helloRuntime,a=this.runtime();if(`expect`in r&&(!i||!_h(r.expect,i)||!_h(r.expect,a))){this.failure(r.id,`runtime-mismatch`);return}switch(r.cmd){case`status`:this.success(r,this.status());return;case`status.config`:this.success(r,{revision:this.agent.configurationRevision});return;case`settings.conversations.apply`:try{let e=this.agent.applyConversationSetting(r.args.revision);e===null?this.failure(r.id,`configuration-mismatch`):this.success(r,{revision:e})}catch{this.failure(r.id,`operation-failed`)}return;case`devices`:this.success(r,this.devices());return;case`devices.revoke`:try{this.success(r,{removed:this.agent.unpairExact(r.args.phoneFp)})}catch{this.failure(r.id,`operation-failed`)}return;case`terminals`:this.success(r,{terminals:this.agent.terminalSetup()});return;case`terminals.connect`:{let e=this.agent.connectTerminal(r.args.name);this.success(r,{started:e,terminals:this.agent.terminalSetup()});return}case`pairing.open`:{let e=this.hub.open(this);typeof e==`string`?this.failure(r.id,e):this.success(r,e)?this.hub.activate(this,e.flowId):this.hub.close(this,e.flowId);return}case`pairing.close`:{let e=this.hub.close(this,r.args.flowId);e?this.failure(r.id,e):this.success(r,{})&&this.event({v:2,event:`pairing.closed`,flowId:r.args.flowId});return}case`pairing.confirm`:{let e=this.hub.answer(this,r);e?this.failure(r.id,e):this.success(r,{});return}}}event(e){return hh.safeParse(e).success?this.write(e):!1}runtime(){return this.agent.localStatus.process}status(){let e=this.agent;return{...e.localStatus,relayOnline:e.relayOnline,sessions:e.sessionList.length,phones:this.devices(),connected:e.connectedPhones}}devices(){return this.agent.pairingList.map(e=>({phoneFp:e.phoneFp,name:e.name,lastSeenAt:e.lastSeenAt}))}success(e,t){if(!ah[e.cmd].safeParse(t).success)return this.failure(e.id,`operation-failed`),!1;let n={v:2,id:e.id,ok:!0,data:t};if(!fh.safeParse(n).success)return this.failure(e.id,`operation-failed`),!1;let r=Um(n);return r?this.writeFrame(r):(this.failure(e.id,`response-too-large`),!1)}failure(e,t){let n={v:2,id:e,ok:!1,error:{code:t}};return fh.safeParse(n).success?this.write(n):!1}write(e){let t=Um(e);return t?this.writeFrame(t):!1}writeFrame(e){return Wm(this.socket,e)?!0:(this.close(),!1)}};const xh={unavailable:`Local control unavailable`,"upgrade-required":`Local control upgrade required`,"protocol-error":`Local control protocol error`,timeout:`Local control timed out`,"delivery-unknown":`Local control mutation outcome unknown`,busy:`Local control request already pending`,closed:`Local control closed`,"server-error":`Local control server rejected request`},Sh=new Set([`hello`,`status`,`status.config`,`devices`,`terminals`]);var Q=class extends Error{code;serverCode;constructor(e,t){super(xh[e]),this.code=e,this.serverCode=t,this.name=`ControlV2ClientError`}};function Ch(e,t={}){return new Promise((n,r)=>{let i;try{i=(t.connector??le)(e)}catch{r(new Q(`unavailable`));return}let a=!1,o=!1,s=!1,c=0,l,u,d,f=setTimeout(()=>p(new Q(`timeout`)),Hm.requestMs);function p(e){if(a)return;a=!0,clearTimeout(f);let n=l;l=void 0,d=void 0,n&&(clearTimeout(n.timer),n.reject(n.mutation&&n.attempted?new Q(`delivery-unknown`):e)),o||r(e),i.destroy(),t.onDisconnect?.(e)}function m(e,t){if(a)return Promise.reject(new Q(`closed`));if(l)return Promise.reject(new Q(`busy`));if(c===2**53-1)return p(new Q(`protocol-error`)),Promise.reject(new Q(`protocol-error`));let n=!Sh.has(e),r=ch.safeParse({v:2,id:c+1,cmd:e,...n?{expect:u}:{},...t===void 0?{}:{args:t}});if(!r.success)return Promise.reject(new Q(`protocol-error`));let o=Um(r.data);if(o===null)return Promise.reject(new Q(`protocol-error`));let s=i.writableLength;return i.destroyed||!Number.isFinite(s)||s<0||s+o.byteLength>Hm.queuedBytes?(p(new Q(`unavailable`)),Promise.reject(new Q(`unavailable`))):(c++,new Promise((t,r)=>{let a={id:c,command:e,mutation:n,attempted:!1,resolve:e=>t(e),reject:r,timer:setTimeout(()=>p(new Q(`timeout`)),Hm.requestMs)};l=a,a.attempted=!0,Wm(i,o)||p(new Q(`unavailable`))}))}let h=new Gm({onError:()=>p(new Q(`protocol-error`)),onLine:e=>{if(a)return;let n;try{n=JSON.parse(e)}catch{p(new Q(`protocol-error`));return}if(typeof n==`object`&&n&&`event`in n){let e=hh.safeParse(n);if(!e.success){p(new Q(`protocol-error`));return}let r=e.data;if(r.event===`pairing.closed`&&r.flowId!==d)return;if(r.flowId!==d){p(new Q(`protocol-error`));return}r.event===`pairing.closed`?(d=void 0,t.onPairingClosed?.(r)):t.onPairingRequest?.(r);return}let r=l;if(r?.command===`hello`&&typeof n==`object`&&n&&!(`v`in n)&&`ok`in n&&typeof n.ok==`boolean`){p(new Q(`upgrade-required`));return}let i=fh.safeParse(n);if(!i.success||!r||i.data.id!==r.id){p(new Q(`protocol-error`));return}if(!i.data.ok){clearTimeout(r.timer),l=void 0;let e=new Q(`server-error`,i.data.error.code);r.reject(e),r.command===`hello`&&p(e);return}let o=ah[r.command].safeParse(i.data.data);if(!o.success){p(new Q(`protocol-error`));return}r.command===`pairing.open`&&(d=o.data.flowId),clearTimeout(r.timer),l=void 0,r.resolve(o.data)}});i.on(`data`,e=>h.push(e)),i.on(`error`,()=>p(new Q(`unavailable`)));let g=()=>{h.finish(),p(new Q(`unavailable`))};i.once(`end`,g),i.once(`close`,g);let _=()=>{a||s||(s=!0,clearTimeout(f),m(`hello`).then(e=>{a||(u={...e.runtime},o=!0,n({runtime:{...e.runtime},status:()=>m(`status`),applyConversationSetting:async e=>{try{return(await m(`settings.conversations.apply`,{revision:e})).revision}catch(e){if(e instanceof Q&&e.code===`server-error`&&e.serverCode===`bad-request`)return null;throw e}},configurationRevision:async()=>{try{return(await m(`status.config`)).revision}catch(e){if(e instanceof Q&&e.code===`server-error`&&e.serverCode===`bad-request`)return null;throw e}},devices:()=>m(`devices`),terminals:async()=>{try{return(await m(`terminals`)).terminals}catch(e){if(wh(e))return null;throw e}},connectTerminal:async e=>{try{return await m(`terminals.connect`,{name:e})}catch(e){if(wh(e))return null;throw e}},revoke:e=>m(`devices.revoke`,{phoneFp:e}),openPairing:()=>m(`pairing.open`),closePairing:async e=>{await m(`pairing.close`,{flowId:e})},confirm:async(e,t,n,r)=>{await m(`pairing.confirm`,{flowId:e,challengeId:t,phoneFp:n,accept:r})},close:()=>p(new Q(`closed`))}))},e=>p(e)))};i.once(`connect`,_),i.connecting||_()})}function wh(e){return e instanceof Q&&e.code===`server-error`&&e.serverCode===`bad-request`}var Th=class{agent;log;admission;pairingMode;endpoint;pending=new Map;pairClients=new Set;controlSockets=new Set;v2;pairingConfirm=(e,t)=>new Promise(n=>{if(this.pending.has(e)){this.log.warn(`pairing confirm requested twice for the same phone; declining the newer one`,{phone:e.slice(0,8)}),n(!1);return}let r=setTimeout(()=>{this.pending.delete(e),n(!1)},6e4);this.pending.set(e,t=>{clearTimeout(r),this.pending.delete(e),n(t)});for(let n of this.pairClients)this.writeLegacy(n,{event:`request`,phoneFp:e,name:t})||this.pairClients.delete(n)});constructor(e,t,n,r,i,a,o=`terminal`){this.agent=t,this.log=n,this.admission=a,this.pairingMode=o,this.endpoint=new Vm(e,e=>this.handle(e),n,r,i),this.v2=new yh(t,n)}get hasPairClients(){return this.pairClients.size>0}get hasNativePairOwner(){return this.v2.hasPairOwner}nativePairingConfirm=(e,t)=>this.v2.confirm(e,t);notifyClosed(e=`closed`){for(let e of this.pending.values())e(!1);this.pending.clear();for(let t of this.pairClients)this.writeLegacy(t,{event:`closed`,reason:e})||this.pairClients.delete(t);this.pairClients.clear(),this.v2.notifyClosed()}async start(){this.admission?await this.admission(()=>this.endpoint.start()):await this.endpoint.start()}async stop(){for(let e of this.pending.values())e(!1);for(let e of this.controlSockets)e.destroy();this.controlSockets.clear();for(let e of this.pairClients)e.destroy();this.pairClients.clear(),this.v2.stop(),await this.endpoint.stop()}handle(e){if(this.controlSockets.size>=Hm.connections){e.destroy();return}this.controlSockets.add(e);let t=!0,n,r,i=setTimeout(()=>e.destroy(),Hm.initialRequestMs),a=new Gm({onLine:a=>{if(e.destroyed)return;let o;try{o=JSON.parse(a)}catch{if(n===`v2`){e.destroy();return}this.writeLegacy(e,{ok:!1,error:`bad json`});return}if(n===`v2`){r?.handle(o),t&&r?.handshaken&&(t=!1,clearTimeout(i));return}if(n===void 0&&o&&typeof o==`object`&&Object.hasOwn(o,`v`)){n=`v2`,r=this.v2.accept(e),r.handle(o),r.handshaken&&(t=!1,clearTimeout(i));return}if(n===`legacy`&&o&&typeof o==`object`&&Object.hasOwn(o,`v`)){e.destroy();return}n=`legacy`;let s=o;if(!s||typeof s!=`object`||typeof s.cmd!=`string`){this.writeLegacy(e,{ok:!1,error:`bad request`});return}t&&(t=!1,clearTimeout(i));try{let t=this.dispatch(s,e);this.writeLegacy(e,{ok:!0,data:t})}catch(t){this.writeLegacy(e,{ok:!1,error:t.message})}},onError:()=>e.destroy()});e.on(`data`,e=>a.push(new Uint8Array(e))),e.once(`end`,()=>a.finish()),e.once(`close`,()=>{clearTimeout(i),this.controlSockets.delete(e),this.pairClients.delete(e),r?.close()}),e.on(`error`,()=>this.log.debug(`control socket error`))}writeLegacy(e,t){let n=Um(t);if(n&&Wm(e,n))return!0;let r=Um({ok:!1,error:`response too large`});return r!==null&&Wm(e,r)}dispatch(e,t){let n=this.agent;if(this.pairingMode===`native`&&[`pair-open`,`pair-close`,`confirm`].includes(e.cmd))throw Error(`pairing is managed by the Shellbell app`);if(this.v2.hasPairOwner&&[`pair-open`,`pair-close`,`confirm`].includes(e.cmd))throw Error(`native pairing active`);switch(e.cmd){case`status`:return{...n.localStatus,relayOnline:n.relayOnline,sessions:n.sessionList.length,phones:n.pairingList.map(e=>({phoneFp:e.phoneFp,name:e.name,lastSeenAt:e.lastSeenAt})),connected:n.connectedPhones};case`devices`:return n.pairingList.map(e=>({phoneFp:e.phoneFp,name:e.name,lastSeenAt:e.lastSeenAt}));case`unpair`:return{removed:n.unpair(String(e.args?.target??``))};case`pair-open`:{let e=n.openPairing();return this.pairClients.add(t),e}case`pair-close`:return n.closePairing(),{};case`confirm`:{let t=String(e.args?.phoneFp??``),n=this.pending.get(t);if(!n)throw Error(`no pending request`);return n(!!e.args?.accept),{}}default:throw Error(`unknown command: ${e.cmd}`)}}};function Eh(e,t,n,r){return new Promise((i,a)=>{let o=Um({cmd:t,args:n});if(!o){a(Error(`control socket request too large`));return}let s=!1,c=le(e),l=r?.timeoutMs??5e3,u=e=>{s||(s=!0,clearTimeout(d),c.destroy(),e())},d=setTimeout(()=>u(()=>a(Error(`control socket timed out`))),l),f=new Gm({maxBytes:r?.maxResponseBytes,onError:e=>u(()=>a(Error(e===`line-too-large`?`control socket response too large`:`control socket sent a malformed response`))),onLine:e=>{f.finish(),u(()=>{let t;try{if(t=JSON.parse(e),typeof t!=`object`||!t||typeof t.ok!=`boolean`)throw Error()}catch{a(Error(`control socket sent a malformed response`));return}t.ok?i(t.data):a(Error(t.error??`control error`))})}});c.on(`error`,e=>u(()=>a(e))),c.once(`connect`,()=>{Wm(c,o)||u(()=>a(Error(`control socket write failed`)))}),c.once(`close`,()=>u(()=>a(Error(`control socket closed without a response`)))),c.once(`end`,()=>u(()=>a(Error(`control socket closed without a response`)))),c.on(`data`,e=>{s||f.push(new Uint8Array(e))}),c.once(`end`,()=>f.finish())})}function Dh(e,t){let n=le(e),r=!1,i,a=()=>{r||(r=!0,i?.finish(),n.end())};n.on(`error`,t.onError);let o=Um({cmd:`pair-open`});return n.once(`connect`,()=>{(o===null||!Wm(n,o))&&t.onError(Error(`control socket write failed`))}),i=new Gm({onError:()=>{n.destroy(),t.onError(Error(`control socket sent a malformed message`))},onLine:e=>{if(r)return;let i;try{i=JSON.parse(e)}catch{t.onError(Error(`control socket sent a malformed message`));return}i.event===`request`&&i.phoneFp?t.onRequest(i.phoneFp,i.name??``).then(e=>{if(r)return;let t=Um({cmd:`confirm`,args:{phoneFp:i.phoneFp,accept:e}});if(t===null||!Wm(n,t))throw Error(`control socket write failed`)}).catch(e=>t.onError(e)):i.event===`closed`?t.onClose(i.reason===`replaced`?`replaced`:`closed`):i.ok&&i.data?.qrText?t.onOpen(i.data.qrText,i.data.expiresAt):i.ok===!1&&t.onError(Error(i.error??`control error`))}}),n.on(`data`,e=>i.push(new Uint8Array(e))),n.once(`end`,()=>{r=!0,i?.finish()}),n.once(`close`,()=>{r=!0,i?.finish()}),{close:a}}function Oh(e){if(e.linuxHost)return Sp(e);let t;try{t=g(e.identity,`utf8`)}catch(t){if(t.code===`ENOENT`)return null;throw Error(`shellbell: cannot read identity at ${e.identity}`)}try{let e=nc(JSON.parse(t));return{identity:e,fp:rc(e.ed25519.pub)}}catch{throw Error(`shellbell: invalid identity at ${e.identity}`)}}function kh(e){if(e.linuxHost)return Sp(e);Dp(e);let t;return s(e.identity)?t=Ah(e):(t=Qs(),Ap(e.identity,`${JSON.stringify(tc(t),null,2)}\n`)||(t=Ah(e))),{identity:t,fp:rc(t.ed25519.pub)}}function Ah(e){try{return nc(Np(e.identity))}catch(t){throw Error(`shellbell: invalid identity at ${e.identity}: ${t.message}`)}}const jh=[`dev.bilalahmad.shellbell`,`dev.bilalahmad.shellbell.host.agent`,`dev.bilalahmad.shellbell.host.manual`];async function Mh(e,t,n){if(!Number.isSafeInteger(t)||t<0)throw Error(`Invalid service UID`);let r=()=>Error(`Legacy Shellbell installation requires migration before starting the new service; preserve identity and remove old registrations explicitly.`);if(n)for(let e of jh){try{p(N(n,`Library`,`LaunchAgents`,`${e}.plist`))}catch(e){if(e.code===`ENOENT`)continue;throw e}throw r()}for(let n of[...jh.map(e=>`gui/${t}/${e}`),`system/dev.bilalahmad.shellbell.power`]){let t=await e(`/bin/launchctl`,[`print`,n],{timeoutMs:5e3,maxOutputBytes:65536,captureOutput:!1});if(t.exitCode===0)throw r();if(t.exitCode!==113)throw Error(`Could not verify legacy Shellbell registration absence`)}}const Nh=(t,n,r)=>new Promise((i,a)=>{let o=e(t,n,{shell:!1,stdio:[`pipe`,`pipe`,`pipe`]}),s=0,c=0,l=[],u=!1,d=e=>{u||(u=!0,clearTimeout(f),o.kill(),a(e))},f=setTimeout(()=>d(Error(`${t} timed out`)),r.timeoutMs);o.stdout.on(`data`,e=>{if(s+=e.length,s>r.maxOutputBytes)return d(Error(`${t} output limit exceeded`));r.captureOutput&&l.push(e)}),o.stderr.on(`data`,e=>{c+=e.length,c>r.maxOutputBytes&&d(Error(`${t} output limit exceeded`))}),o.on(`error`,d),o.on(`close`,(e,n)=>{if(!u){if(u=!0,clearTimeout(f),n||e===null)return a(Error(`${t} terminated by signal`));i({exitCode:e,stdout:r.captureOutput?Buffer.concat(l):Buffer.alloc(0)})}}),o.stdin.on(`error`,d),o.stdin.end(r.input)}),Ph=[`/opt/homebrew/bin`,`/usr/local/bin`,`/usr/bin`,`/bin`],Fh=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function Ih(e){for(let t of e){let e=t.codePointAt(0);if(!(e===9||e===10||e===13||e>=32&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111))throw Error(`invalid XML character in service definition`)}}function Lh(e,t){if(!e||!M(e))throw Error(`${t} must be an absolute path`);return Ih(e),e}function Rh(e){if(Lh(e.stateDir,`stateDir`),Lh(e.nodePath,`nodePath`),!Fh.test(e.serviceInstance))throw Error(`serviceInstance must be a UUID`);let t=[j(e.nodePath),...e.env.PATH?.split(`:`)??[],...Ph].filter(e=>e.length>0&&M(e)),n={SHELLBELL_DIR:e.stateDir,SHELLBELL_SERVICE_INSTANCE:e.serviceInstance,PATH:[...new Set(t)].join(`:`)};for(let t of[`HERDR_SOCKET_PATH`,`XDG_CONFIG_HOME`]){let r=e.env[t];r&&(n[t]=Lh(r,t))}for(let e of Object.values(n))Ih(e);return n}const zh=`sh.bilal.shellbell`;N(E(),`Library`,`LaunchAgents`,`${zh}.plist`);const Bh=1048576,Vh=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Hh=new Set([`SHELLBELL_DIR`,`SHELLBELL_SERVICE_INSTANCE`,`PATH`,`HERDR_SOCKET_PATH`,`XDG_CONFIG_HOME`]),Uh=new Set([`Label`,`ProgramArguments`,`EnvironmentVariables`,`RunAtLoad`,`KeepAlive`,`StandardOutPath`,`StandardErrorPath`]);function Wh(e){return Ih(e),e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&apos;`)}function Gh(e){let t=Wh,n=e.environment??{PATH:`/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin`},r=Object.entries(n).map(([e,n])=>`<key>${t(e)}</key><string>${t(n)}</string>`).join(``);return`<?xml version="1.0" encoding="UTF-8"?>
16
+ `)}\r\n`}var Xd=class{options;offerId;generation;attemptId;peer=null;phoneDtls;computerDtls=null;localSdp=null;remoteSdp=!1;opened=!1;verifying=!1;sentDescription=!1;sentCandidates=0;receivedCandidates=0;pendingData=[];pendingLocal=[];pendingRemote=[];handshake=null;secureSession=null;closed=!1;timer;constructor(e){this.options=e,this.offerId=e.offer?.offerId.slice()??ya(16),this.attemptId=e.offer?ya(16):null,this.generation=e.generation.slice(),this.phoneDtls=e.offer?.phoneDtls.slice()??null,this.timer=setTimeout(()=>this.fail(`timeout`),15e3)}get session(){return this.secureSession}get phase(){return this.secureSession?`cutover`:this.handshake?`noise`:this.verifying?`certificate`:this.opened?`open`:this.remoteSdp?`connecting`:this.localSdp?`offer`:`native`}get active(){return!this.closed&&this.options.current()}cancelDeadline(){clearTimeout(this.timer)}close(){this.closed||(this.closed=!0,this.cancelDeadline(),this.pendingData=[],this.pendingLocal=[],this.pendingRemote=[],this.handshake?.close(),this.secureSession?.close(),this.peer?.close())}routeStats(){return this.peer?.routeStats?.()??Promise.resolve(null)}send(e){let t=this.active&&(this.peer?.send(e)??!1);return t&&this.options.sent(e.length),t}fail(e=`closed`){this.active&&this.options.failed(e)}async start(){let e={description:(e,t)=>{this.active&&this.description(e,t)},candidate:(e,t,n)=>{if(this.active)try{this.localCandidate({candidate:e,mid:t,mlineIndex:n})}catch{this.fail(`local-candidate`)}},open:()=>{this.active&&(this.opened=!0,this.openDirect().catch(()=>this.fail(`certificate`)))},message:e=>{this.active&&(this.options.received(e.length),this.directMessage(e))},closed:()=>this.fail(`native-closed`)},t;try{t=await this.options.native(e)}catch{this.fail(`native-create`);return}if(!this.active){t.close();return}this.peer=t;try{if(this.options.offer){if(await t.answer(this.options.offer.sdp),!this.active)return;this.remoteSdp=!0}else await t.offer();if(!this.active)return;await this.flushRemote(),await this.openDirect()}catch{this.fail(`native-description`)}}description(e,t){try{let n=Jd(e);if(this.localSdp=Yd(e),this.options.role===`phone`&&t===`offer`)this.phoneDtls=n;else if(this.options.role===`computer`&&t===`answer`)this.computerDtls=n;else throw Error(`description role mismatch`);let r=this.signalContext(),i=t===`offer`?{type:`direct.offer`,...r,phoneDtls:n,sdp:this.localSdp}:{type:`direct.answer`,...r,attemptId:this.attemptId,computerDtls:n,sdp:this.localSdp};if(!this.options.sendSignal(i))throw Error(`signaling queue refused`);this.sentDescription=!0;for(let e of this.pendingLocal.splice(0))this.localCandidate(e);this.openDirect().catch(()=>this.fail(`certificate`))}catch{this.fail(`local-description`)}}admits(e){return this.sentCandidates+this.pendingLocal.length<(qd(e)?Od.candidatesPerSide:Od.candidatesPerSide-6)}localCandidate(e){if(this.active&&!this.options.committed()&&this.admits(e)){if(!this.sentDescription){this.pendingLocal.push(e);return}this.options.sendSignal({type:`direct.candidate`,...this.signalContext(),index:this.sentCandidates++,...e})||this.fail()}}async signal(e){if(this.active&&this.peer){if(e.type===`direct.answer`){if(this.remoteSdp||(this.computerDtls=e.computerDtls.slice(),this.attemptId=e.attemptId.slice(),await this.peer.acceptAnswer(e.sdp),!this.active))return;this.remoteSdp=!0,await this.flushRemote(),await this.openDirect()}else if(e.type===`direct.candidate`){if(e.index!==this.receivedCandidates++)throw Error(`candidate order`);this.remoteSdp?await this.peer.candidate(e.candidate,e.mid,e.mlineIndex):this.pendingRemote.push(e)}else e.type===`direct.abort`&&this.fail()}}async flushRemote(){if(this.remoteSdp&&this.peer)for(let e of this.pendingRemote.splice(0)){if(!this.active)return;await this.peer.candidate(e.candidate,e.mid,e.mlineIndex)}}signalContext(){return{sessionId:this.options.relay.sessionId,offerId:this.offerId,generation:this.generation}}async openDirect(){if(!this.active||!this.opened||!this.peer||!this.phoneDtls||!this.computerDtls||!this.attemptId||this.verifying||this.handshake||this.secureSession)return;this.verifying=!0;let e=await this.peer.remoteCertificate(this.options.role===`phone`?this.computerDtls:this.phoneDtls);if(this.active){if(this.handshake=new Gd({route:`direct`,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,sessionId:this.options.relay.sessionId,generation:this.generation,attemptId:this.attemptId,phoneDtls:this.phoneDtls,computerDtls:this.computerDtls},this.options.role,this.options.keys,e),this.options.role===`phone`&&!this.send(this.handshake.begin())){this.fail();return}for(let e of this.pendingData.splice(0))this.directMessage(e)}}directMessage(e){if(this.active)try{if(!this.peer||e.length>61e3)throw Error(`direct frame bounds`);if(this.secureSession){this.options.frame(this.secureSession,e);return}if(!this.handshake){if(!this.verifying||this.pendingData.length>=4||e.length>1024)throw Error(`direct handshake missing`);this.pendingData.push(e.slice());return}let t=this.handshake.receive(e);if(t&&!this.send(t))throw Error(`direct queue refused`);this.handshake.ready&&(this.secureSession=this.handshake.takeReadySession(),this.handshake=null,this.options.ready(this.secureSession))}catch{this.fail(`direct-frame`)}}};const Zd=Uint8Array.of(1,0,0,0,0,0,0,0);var Qd=class{options;stage;startedAt=null;sessionId=null;attemptId=null;handshake=null;session=null;timer=null;keys;timeoutMs;constructor(e){if(this.options=e,U.parse(e.computerFp),U.parse(e.phoneFp),e.role!==`phone`&&e.role!==`computer`)throw Error(`invalid v2 role`);if(e.keys.staticPrivate.length!==32||e.keys.remoteStatic.length!==32||e.keys.pairKey.length!==32)throw Error(`invalid v2 pairing keys`);if(this.timeoutMs=e.timeoutMs??15e3,!Number.isSafeInteger(this.timeoutMs)||this.timeoutMs<1||this.timeoutMs>3e4)throw Error(`invalid v2 bootstrap timeout`);this.keys={staticPrivate:e.keys.staticPrivate.slice(),remoteStatic:e.keys.remoteStatic.slice(),pairKey:e.keys.pairKey.slice()},this.stage=e.role===`phone`?`phone:new`:`computer:begin`}get ready(){return this.stage===`ready`&&this.session?.ready===!0}begin(){if(this.stage!==`phone:new`)throw Error(`v2 begin not allowed`);try{return this.startedAt=this.clock(),this.armTimer(),this.sessionId=this.freshId(),this.stage=`phone:accept`,zd({type:`session.v2.begin`,sessionId:this.sessionId,generation:Zd})}catch(e){throw this.close(),e}}receive(e){try{if(this.stage===`closed`||this.stage===`detached`||this.stage===`ready`)throw Error(`v2 bootstrap no longer accepts messages`);switch(this.stage!==`computer:begin`&&this.assertNotExpired(),this.stage){case`computer:begin`:{let t=Bd(e,{sender:`phone`,expectedType:`session.v2.begin`});if(t.type!==`session.v2.begin`)throw Error(`invalid v2 begin`);if(this.startedAt=this.clock(),this.armTimer(),this.sessionId=t.sessionId.slice(),this.attemptId=this.freshId(),Er(this.sessionId,this.attemptId))throw Error(`repeated v2 attempt ID`);return this.handshake=this.newHandshake(),this.stage=`computer:noise1`,zd({type:`session.v2.accept`,sessionId:this.sessionId,attemptId:this.attemptId,generation:Zd})}case`phone:accept`:{let t=Bd(e,{sender:`computer`,expectedType:`session.v2.accept`,sessionId:this.requireSessionId()});if(t.type!==`session.v2.accept`)throw Error(`invalid v2 accept`);if(this.attemptId=t.attemptId.slice(),Er(this.requireSessionId(),this.attemptId))throw Error(`repeated v2 attempt ID`);this.handshake=this.newHandshake();let n=this.handshake.write();return this.stage=`phone:noise2`,zd({type:`session.v2.noise1`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),message:n})}case`computer:noise1`:{let t=Bd(e,{sender:`phone`,expectedType:`session.v2.noise1`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId()});if(t.type!==`session.v2.noise1`||!this.handshake)throw Error(`invalid v2 noise1`);this.handshake.read(t.message);let n=this.handshake.write();return this.session=this.handshake.finish(),this.handshake=null,this.stage=`computer:confirm`,zd({type:`session.v2.noise2`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),message:n})}case`phone:noise2`:{let t=Bd(e,{sender:`computer`,expectedType:`session.v2.noise2`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId()});if(t.type!==`session.v2.noise2`||!this.handshake)throw Error(`invalid v2 noise2`);this.handshake.read(t.message),this.session=this.handshake.finish(),this.handshake=null;let n=Il(this.session.confirmation());return this.stage=`phone:confirm`,zd({type:`session.v2.confirm`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),frame:n})}case`computer:confirm`:{let t=this.decodeConfirmation(e,`phone`);if(!this.session)throw Error(`v2 session missing`);this.session.acceptConfirmation(Ll(t.frame));let n=Il(this.session.confirmation());if(!this.session.ready)throw Error(`v2 computer confirmation incomplete`);return this.markReady(),zd({type:`session.v2.confirm`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),frame:n})}case`phone:confirm`:{let t=this.decodeConfirmation(e,`computer`);if(!this.session)throw Error(`v2 session missing`);if(this.session.acceptConfirmation(Ll(t.frame)),!this.session.ready)throw Error(`v2 phone confirmation incomplete`);return this.markReady(),null}default:throw Error(`invalid v2 bootstrap stage`)}}catch(e){throw this.close(),e}}takeReadySession(){if(!this.ready||!this.session)throw Error(`v2 session not confirmed`);let e=this.session;return this.session=null,this.stage=`detached`,e}close(){this.stage!==`closed`&&(this.stage=`closed`,this.clearTimer(),this.handshake?.close(),this.handshake=null,this.session?.close(),this.session=null,this.keys.staticPrivate.fill(0),this.keys.remoteStatic.fill(0),this.keys.pairKey.fill(0))}decodeConfirmation(e,t){let n=Bd(e,{sender:t,expectedType:`session.v2.confirm`,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId()});if(n.type!==`session.v2.confirm`)throw Error(`invalid v2 confirmation`);return n}newHandshake(){let e={route:`relay`,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,sessionId:this.requireSessionId(),attemptId:this.requireAttemptId(),generation:Zd};try{return zl(e,this.options.role,this.keys)}finally{this.keys.staticPrivate.fill(0),this.keys.remoteStatic.fill(0),this.keys.pairKey.fill(0)}}freshId(){return El.parse(this.options.newId()).slice()}requireSessionId(){if(!this.sessionId)throw Error(`v2 session ID missing`);return this.sessionId}requireAttemptId(){if(!this.attemptId)throw Error(`v2 attempt ID missing`);return this.attemptId}clock(){let e=this.options.now();if(!Number.isFinite(e)||e<0)throw Error(`invalid v2 clock`);return e}armTimer(){this.clearTimer(),this.timer=setTimeout(()=>this.close(),this.timeoutMs)}clearTimer(){this.timer!==null&&clearTimeout(this.timer),this.timer=null}markReady(){this.stage=`ready`,this.clearTimer()}assertNotExpired(){if(this.startedAt===null)throw Error(`v2 bootstrap not started`);let e=this.clock()-this.startedAt;if(e<0||e>this.timeoutMs)throw Error(`v2 bootstrap expired`)}},$d=class{options;stage;pairKey;bootstrap;timeoutMs;startedAt=null;timer=null;phoneNonce=null;connKey=null;connTag=``;seqIn=0;seqOut=0;constructor(e){if(this.options=e,U.parse(e.computerFp),U.parse(e.phoneFp),e.role!==`phone`&&e.role!==`computer`)throw Error(`invalid v2 role`);if(e.keys.pairKey.length!==32)throw Error(`invalid pair key`);if(this.timeoutMs=e.timeoutMs??15e3,!Number.isSafeInteger(this.timeoutMs)||this.timeoutMs<1)throw Error(`invalid v2 carrier timeout`);this.pairKey=e.keys.pairKey.slice(),this.bootstrap=new Qd(e),this.stage=e.role===`phone`?`phone:new`:`computer:hello`}get ready(){return this.stage===`ready`&&this.bootstrap.ready}get closed(){return this.stage===`closed`}start(){if(this.stage!==`phone:new`)throw Error(`v2 carrier cannot start`);try{return this.startDeadline(),this.phoneNonce=ya(16),this.stage=`phone:hello`,this.hello(this.phoneNonce)}catch(e){throw this.close(),e}}receive(e){if(this.stage===`closed`||this.stage===`ready`||this.stage===`phone:new`)throw Error(`v2 carrier not receiving`);try{this.stage!==`computer:hello`&&this.checkDeadline();let t=this.options.role===`phone`?this.options.computerFp:this.options.phoneFp,n=this.options.role===`phone`?this.options.phoneFp:this.options.computerFp;if(e.v!==1||e.t!==`e2e`||e.from!==t||e.to!==n)throw Error(`v2 carrier peer mismatch`);let r=Qn.parse(e.body);if(r.c.length<16||r.c.length>2048)throw Error(`v2 carrier ciphertext exceeds bound`);if(this.stage===`phone:hello`||this.stage===`computer:hello`){if(e.seq!==0)throw Error(`v2 carrier expected hello`);let i=Au(Kn(uc(this.pairKey,r,gc(t,n))));if(i.type!==`conn.hello`||!i.features?.includes(`session-v2`))throw Error(`v2 carrier requires v2 hello intent`);if(this.stage===`computer:hello`){this.startDeadline(),this.phoneNonce=i.n.slice();let e=ya(16);if(Er(this.phoneNonce,e))throw Error(`reused hello nonce`);return this.deriveConnection(this.phoneNonce,e),this.stage=`bootstrap`,this.hello(e)}if(!this.phoneNonce||Er(this.phoneNonce,i.n))throw Error(`invalid hello nonce`);return this.deriveConnection(this.phoneNonce,i.n),this.stage=`bootstrap`,this.frame(this.bootstrap.begin())}if(!this.connKey||e.seq!==this.seqIn+1)throw Error(`v2 carrier frame sequence mismatch`);let i=Au(Kn(uc(this.connKey,r,hc(t,n,this.connTag,e.seq))));if(i.type!==`session.v2.bootstrap`)throw Error(`v2 carrier rejects legacy terminal message`);this.seqIn=e.seq;let a=this.bootstrap.receive(i.bytes);return this.bootstrap.ready&&(this.stage=`ready`,this.clearDeadline()),a?this.frame(a):null}catch(e){throw this.close(),e}}takeReadySession(){if(!this.ready)throw Error(`v2 carrier not confirmed`);let e=this.bootstrap.takeReadySession();return this.close(),e}close(){this.stage!==`closed`&&(this.stage=`closed`,this.clearDeadline(),this.pairKey.fill(0),this.phoneNonce?.fill(0),this.phoneNonce=null,this.connKey?.fill(0),this.connKey=null,this.connTag=``,this.bootstrap.close())}hello(e){let t=this.options.role===`phone`?this.options.phoneFp:this.options.computerFp,n=this.options.role===`phone`?this.options.computerFp:this.options.phoneFp;return{v:1,t:`e2e`,from:t,to:n,seq:0,body:lc(this.pairKey,Gn({type:`conn.hello`,n:e,features:[`session-v2`]}),gc(t,n))}}frame(e){if(!this.connKey||this.seqOut>=2**53-1)throw Error(`v2 carrier unavailable`);let t=this.options.role===`phone`?this.options.phoneFp:this.options.computerFp,n=this.options.role===`phone`?this.options.computerFp:this.options.phoneFp,r=++this.seqOut;return{v:1,t:`e2e`,from:t,to:n,seq:r,body:lc(this.connKey,Gn({type:`session.v2.bootstrap`,bytes:e}),hc(t,n,this.connTag,r))}}deriveConnection(e,t){let n=pc(this.pairKey,e,t,this.options.computerFp,this.options.phoneFp);this.connKey=n.kConn,this.connTag=n.connTag}startDeadline(){if(this.startedAt=this.options.now(),!Number.isFinite(this.startedAt))throw Error(`invalid v2 carrier clock`);this.timer=setTimeout(()=>this.close(),this.timeoutMs)}checkDeadline(){let e=this.options.now();if(this.startedAt===null||!Number.isFinite(e)||e<this.startedAt||e-this.startedAt>=this.timeoutMs)throw Error(`v2 carrier handshake expired`)}clearDeadline(){this.timer&&clearTimeout(this.timer),this.timer=null}};function ef(e){return{route:e.route,sessionId:e.sessionId.slice(),attemptId:e.attemptId.slice(),generation:e.generation.slice()}}function tf(e,t){return e.route===t.route&&Er(e.sessionId,t.sessionId)&&Er(e.attemptId,t.attemptId)&&Er(e.generation,t.generation)}var nf=class{options;relay=null;active=null;staged=null;transition=null;wireIds=new Set;attemptIds=new Set;transitionIds=new Set;highGeneration=1n;directAttempts=0;lastNow=-1;deadline=null;timer=null;revoked=!1;recovering=!1;snapshot=!1;revision=0;constructor(e){if(this.options=e,U.parse(e.computerFp),U.parse(e.phoneFp),e.role!==`phone`&&e.role!==`computer`)throw Error(`invalid route role`);this.installRelay(e.relay)}get status(){return this.revoked?`closed`:this.recovering?`recovering`:this.transition?`cutover`:this.active?.reference.route??`uncommitted`}get activeRoute(){return this.active?ef(this.active.reference):null}get routeRevision(){return this.revision}get needsSnapshot(){return this.snapshot}get preparationPending(){return this.transition?.phase===`computer:preparing`}get paused(){return this.revoked||this.recovering||this.transition!==null||this.active===null}get directActive(){return this.active?.reference.route===`direct`}snapshotApplied(){this.paused||(this.snapshot=!1)}stageDirect(e){if(this.sweep(),this.revoked||this.recovering||!this.active||!this.relay||this.staged||this.transition)throw Error(`route candidate unavailable`);let t=null;try{if(t=this.validate(e,`direct`),!Er(t.reference.sessionId,this.relay.reference.sessionId))throw Error(`direct wire session mismatch`);let n=gl(t.reference.generation);if(n<=this.highGeneration)throw Error(`direct generation reused`);let r=Cr(t.reference.attemptId);if(this.attemptIds.has(r))throw Error(`direct attempt reused`);if(this.directAttempts>=Ul.directAttempts)throw Error(`direct attempt capacity`);this.highGeneration=n,this.directAttempts+=1,this.attemptIds.add(r),this.staged=t,this.arm()}catch(t){throw e.session!==this.active?.session&&e.session!==this.relay?.session&&e.session.close(),t}}begin(){if(this.sweep(),this.options.role!==`phone`||this.revoked||this.recovering||!this.staged||!this.relay||this.transition)throw Error(`route prepare unavailable`);if(!this.options.prepareReady())return!1;let e=El.parse(this.options.newId()).slice();if(this.transitionIds.has(Cr(e)))throw Error(`route transition reused`);return this.transitionIds.add(Cr(e)),this.transition={id:e,target:this.staged,phase:`phone:prepared`},this.sendControl(`route.prepare`)}approve(){return this.sweep(),!this.preparationPending||!this.transition||!this.options.prepareReady()||!this.transition.target.session.ready?!1:(this.transition.phase=`computer:commit`,this.sendControl(`route.prepared`))}receive(e,t){if(this.sweep(),this.revoked||this.recovering||!this.registered(e))return null;try{let n=e.open(t),r;try{r=Jl(n)}finally{n.fill(0)}if(r.kind===`control`){if(e!==this.relay?.session)throw Error(`route control requires relay session`);return this.control(r.control),null}if(r.kind===`signal`){if(e!==this.relay?.session)throw Error(`direct signaling requires relay session`);return r}return this.paused||e!==this.active?.session||!this.directActive?(r.bytes.fill(0),null):r}catch{return this.routeLost(e),null}}sendTerminal(e){return this.sweep(),this.paused||!this.active||!this.directActive?!1:this.sendPayload(this.active,{kind:`terminal`,bytes:e})}sendSignal(e){return this.sweep(),this.revoked||this.recovering||!this.relay?!1:this.sendPayload(this.relay,{kind:`signal`,bytes:e})}abort(e=`cancelled`){if(!this.staged&&!this.transition)return;if(this.transition?.phase===`phone:committed`||!this.active){this.failAll();return}let t=this.transition;t&&this.relay&&this.sendPayload(this.relay,{kind:`control`,control:{type:`route.abort`,transitionId:t.id,target:ef(t.target.reference),reason:e}}),this.discardCandidate(),t&&(this.snapshot=!0)}relayLost(){this.active?.reference.route===`direct`&&!this.transition&&!this.staged?(this.relay?.session.close(),this.relay=null):this.failAll()}routeLost(e){e===this.active?.session?this.failAll():e===this.relay?.session?this.relayLost():e===this.staged?.session&&this.abort(`candidate-failed`)}recover(e){if(this.revoked)throw e.session.close(),Error(`route owner revoked`);let t=this.validate(e,`relay`);if(this.wireIds.has(Cr(t.reference.sessionId)))throw t.session.close(),Error(`wire session reused`);this.failAll(),this.installRelay(t)}sweep(){if(this.revoked)return;let e=this.clock();this.deadline!==null&&e>=this.deadline&&this.abort(`timeout`)}close(){this.failAll(),this.revoked=!0,this.recovering=!1}validate(e,t){if(!(e.session instanceof Bl)||!e.session.ready||e.session.senderRole!==this.options.role)throw Error(`route session not ready`);let n=e.session.description;if(n.computerFp!==this.options.computerFp||n.phoneFp!==this.options.phoneFp||n.route!==t)throw Error(`route pairing mismatch`);if(t===`relay`&&gl(n.generation)!==1n)throw Error(`relay generation must be one`);return{session:e.session,send:e.send.bind(e),reference:ef(n)}}installRelay(e){let t=this.validate(e,`relay`),n=Cr(t.reference.sessionId);if(this.wireIds.has(n)||this.wireIds.size>=Ul.wireSessions)throw t.session.close(),Error(`wire session reused or capacity reached`);this.wireIds.add(n),this.attemptIds.clear(),this.transitionIds.clear(),this.attemptIds.add(Cr(t.reference.attemptId)),this.highGeneration=1n,this.directAttempts=0,this.relay=t,this.staged=t,this.recovering=!1,this.arm()}control(e){if(e.type===`route.prepare`){if(this.options.role!==`computer`||this.transition||!this.staged||!tf(e.target,this.staged.reference)||this.transitionIds.has(Cr(e.transitionId)))throw Error(`invalid route prepare`);this.transitionIds.add(Cr(e.transitionId)),this.transition={id:e.transitionId.slice(),target:this.staged,phase:`computer:preparing`};return}let t=this.transition;if(!t||!tf(e.target,t.target.reference)||!Er(e.transitionId,t.id))throw Error(`route transition mismatch`);if(e.type===`route.abort`){this.abortWithoutSending();return}if(e.type===`route.prepared`&&t.phase===`phone:prepared`){if(!this.options.prepareReady()||!t.target.session.ready)throw Error(`route prepare gate changed`);t.phase=`phone:committed`,this.sendControl(`route.commit`);return}if(e.type===`route.commit`&&t.phase===`computer:commit`){if(!this.options.prepareReady()||!t.target.session.ready)throw Error(`route commit gate changed`);let e={type:`route.committed`,transitionId:t.id,target:ef(t.target.reference)};this.activate(),(!this.relay||!this.sendPayload(this.relay,{kind:`control`,control:e}))&&this.failAll();return}if(e.type===`route.committed`&&t.phase===`phone:committed`){this.activate();return}throw Error(`route control order mismatch`)}sendControl(e){return!this.relay||!this.transition?!1:this.sendPayload(this.relay,{kind:`control`,control:{type:e,transitionId:this.transition.id,target:ef(this.transition.target.reference)}})}sendPayload(e,t){let n=ql(t);try{if(e.send(e.session.seal(n))===!0)return!0}catch{}finally{n.fill(0)}return t.kind===`control`?this.failAll():this.routeLost(e.session),!1}activate(){if(!this.staged)throw Error(`route target missing`);let e=this.active;this.active=this.staged,this.staged=null,this.transition=null,e&&e!==this.relay&&e!==this.active&&e.session.close(),this.clearTimer(),this.snapshot=!0,this.revision+=1}abortWithoutSending(){if(this.transition?.phase===`phone:committed`||!this.active){this.failAll();return}this.discardCandidate(),this.snapshot=!0}discardCandidate(){this.staged&&this.staged!==this.active&&this.staged!==this.relay&&this.staged.session.close(),this.staged=null,this.transition=null,this.clearTimer()}failAll(){for(let e of new Set([this.active,this.staged,this.relay]))e?.session.close();this.active=null,this.staged=null,this.relay=null,this.transition=null,this.clearTimer(),this.recovering=!0,this.snapshot=!0,this.revision+=1}registered(e){return e===this.relay?.session||e===this.active?.session||e===this.staged?.session}clock(){let e=this.options.now();if(!Number.isFinite(e)||e<0||e<this.lastNow)throw this.failAll(),Error(`invalid route clock`);return this.lastNow=e,e}arm(){this.clearTimer(),this.deadline=this.clock()+Ul.attemptMs,this.timer=setTimeout(()=>this.abort(`timeout`),Ul.attemptMs)}clearTimer(){this.timer&&clearTimeout(this.timer),this.timer=null,this.deadline=null}};function rf(e,t,n,r){if(e.seq!==0||e.from!==r||e.to!==n)return!1;try{let i=Au(Kn(uc(t,Qn.parse(e.body),gc(r,n))));return i.type===`conn.hello`&&i.features?.includes(`session-v2`)===!0}catch{return!1}}var af=class{options;carrier=null;owner=null;relaySession=null;direct=null;directStartedAt=null;directSetupMs=null;generation=1n;lastFailure=null;retryAt=null;retryFailures=0;nativeAttempts=0;retriesExhausted=!1;traffic={relaySent:0,relayReceived:0,directSent:0,directReceived:0};bootstrapRevision=0;reportedRevision=-1;reportedRoute=null;reportedState=``;recoveryNotified=!1;closed=!1;incoming=Promise.resolve();queued=0;clock;interval;constructor(e){this.options=e,this.clock=e.now??(()=>performance.now()),this.interval=setInterval(()=>this.poll(),100)}get activeRoute(){return this.owner?.activeRoute?.route??null}get ready(){return this.activeRoute!==null&&this.owner?.paused===!1}get routeRevision(){return this.owner?.routeRevision??0}get diagnostics(){let e=this.direct,t=this.activeRoute===`direct`?`direct`:e?.phase??`none`;return{route:this.activeRoute,ready:this.ready,phase:t,lastFailure:this.lastFailure,directSetupMs:this.directSetupMs,...this.traffic}}routeStats(){return this.activeRoute!==`direct`||!this.direct?Promise.resolve(null):this.direct.routeStats().catch(()=>null)}get state(){let{route:e,ready:t,phase:n,lastFailure:r}=this.diagnostics;return{route:e,ready:t,phase:n,lastFailure:r,retryPending:this.retryAt!==null}}sendRelay(e){let t=this.options.sendRelay(e);return t&&e.v===2&&(this.traffic.relaySent+=e.body.length),t}begin(){this.closed||this.options.role!==`phone`||(this.carrier?.close(),this.carrier=this.newCarrier(),this.bootstrapRevision+=1,this.sendRelay(this.carrier.start())||this.bootstrapFailed())}receiveRelay(e){if(this.closed)return Promise.resolve();if(++this.queued>32)return--this.queued,this.bootstrapFailed(),Promise.resolve();let t=this.incoming.then(()=>this.relay(e));return this.incoming=t.catch(()=>this.bootstrapFailed()).finally(()=>{--this.queued}),this.incoming}sendTerminal(e){return this.owner?.sendTerminal(e)??!1}relayLost(){this.owner?.relayLost(),this.carrier?.close(),this.carrier=null,this.changed()}close(){this.closed||(this.closed=!0,clearInterval(this.interval),this.carrier?.close(),this.carrier=null,this.owner?.close(),this.owner=null,this.closeDirect())}interruptDirect(){this.directFailed(`interrupted`)}newCarrier(){return new $d({role:this.options.role,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,keys:this.options.keys,now:this.clock,newId:()=>ya(16)})}async relay(e){if(this.closed||e.from!==(this.options.role===`phone`?this.options.computerFp:this.options.phoneFp)||e.to!==(this.options.role===`phone`?this.options.phoneFp:this.options.computerFp))return;if(e.v===2){if(this.traffic.relayReceived+=e.body.length,!this.owner||!this.relaySession)return;let t=this.owner.receive(this.relaySession,Ll(e.body));if(t?.kind===`terminal`)this.options.terminal(t.bytes,e.body.length);else if(t?.kind===`signal`){let e=this.direct;try{await this.signal(t.bytes)}catch{this.direct===e&&!e?.session?.ready&&this.directFailed(`remote-signal`,e??void 0)}}this.poll();return}if(e.t!==`e2e`)return;if(this.options.role===`computer`&&e.seq===0){if(!rf(e,this.options.keys.pairKey,this.options.computerFp,this.options.phoneFp))return;this.carrier?.close(),this.carrier=this.newCarrier(),this.bootstrapRevision+=1}let t=this.carrier;if(!t)return;let n=this.bootstrapRevision,r=t.receive(e);if(r&&!this.sendRelay(r))throw Error(`bootstrap queue refused`);if(!t.ready)return;let i=t.takeReadySession();this.carrier=null;try{await this.options.commitFloor()}catch(e){throw i.close(),e}if(this.closed||n!==this.bootstrapRevision){i.close();return}this.closeDirect(),this.relaySession=i,this.generation=1n,this.nativeAttempts=0,this.retriesExhausted=!1,this.retryAt=null;let a={session:i,send:e=>this.sendRelay({v:2,t:`e2e`,from:this.options.role===`phone`?this.options.phoneFp:this.options.computerFp,to:this.options.role===`phone`?this.options.computerFp:this.options.phoneFp,body:Il(e)})};this.owner?this.owner.recover(a):this.owner=new nf({role:this.options.role,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,relay:a,now:this.clock,newId:()=>ya(16),prepareReady:this.options.prepareReady}),this.options.role===`phone`&&this.owner.begin(),this.recoveryNotified=!1,this.poll()}poll(){if(this.closed||(this.carrier?.closed&&this.bootstrapFailed(),!this.owner))return;try{this.owner.sweep(),this.owner.preparationPending&&this.owner.approve(),this.options.role===`phone`&&(this.owner.status===`uncommitted`||this.owner.status===`relay`&&this.direct?.session&&this.direct.session.ready)&&this.owner.begin(),this.changed(),this.retryDirect(),this.owner.status===`recovering`&&!this.carrier&&!this.recoveryNotified&&(this.recoveryNotified=!0,this.closeDirect(),this.options.failure(`recovery`))}catch{this.options.failure(`recovery`)}let e=this.state,t=JSON.stringify(e);t!==this.reportedState&&(this.reportedState=t,this.options.stateChanged?.(e))}changed(){let e=this.activeRoute,t=this.routeRevision;(this.reportedRevision!==t||this.reportedRoute!==e)&&(this.reportedRevision=t,this.reportedRoute=e,this.options.routeChanged(e,t),e===`direct`&&this.direct&&(this.directStartedAt!==null&&(this.directSetupMs=Math.round(this.clock()-this.directStartedAt)),this.directStartedAt=null,this.direct.cancelDeadline(),this.retryFailures=0,this.retryAt=null,this.lastFailure=null))}retryDirect(){if(this.options.role===`phone`&&this.options.allowDirect&&this.options.native&&!this.retriesExhausted&&!this.direct&&!this.carrier&&this.ready&&this.activeRoute===`relay`&&this.options.prepareReady()&&!(this.retryAt!==null&&this.clock()<this.retryAt)){if(this.nativeAttempts>=Ul.directAttempts){this.retriesExhausted=!0,this.bootstrapFailed();return}this.nativeAttempts+=1,this.retryAt=null,this.startDirect()}}bootstrapFailed(){this.carrier?.close(),this.carrier=null,this.options.failure(`bootstrap`)}async startDirect(e){if(this.closed||this.direct||!this.ready||!this.relaySession||!this.options.native)return;this.generation=e?new DataView(e.generation.buffer,e.generation.byteOffset,8).getBigUint64(0,!0):this.generation+1n;let t=new Xd({role:this.options.role,keys:this.options.keys,computerFp:this.options.computerFp,phoneFp:this.options.phoneFp,relay:this.relaySession.description,generation:e?.generation??hl(this.generation),offer:e,native:this.options.native,current:()=>!this.closed&&this.direct===t,committed:()=>this.activeRoute===`direct`,sendSignal:e=>this.sendSignal(e),sent:e=>{this.traffic.directSent+=e},received:e=>{this.traffic.directReceived+=e},ready:e=>{this.owner?.stageDirect({session:e,send:e=>t.send(Il(e))}),this.options.role===`phone`&&this.owner?.begin()},frame:(e,t)=>{let n=this.owner?.receive(e,Ll(t));n?.kind===`terminal`&&this.options.terminal(n.bytes,t.length),this.poll()},failed:e=>this.directFailed(e,t)});this.direct=t,this.directStartedAt=this.clock(),await t.start()}async signal(e){if(!this.relaySession||!this.owner)return;let t=this.direct;if(this.activeRoute===`direct`&&t?.session?.ready)return;let n=Wd(e,{sender:this.options.role===`phone`?`computer`:`phone`,sessionId:this.relaySession.description.sessionId,committedGeneration:this.relaySession.description.generation,...t&&{pending:{offerId:t.offerId,generation:t.generation}}});if(n.type===`direct.offer`){if(!this.options.native||this.options.role!==`computer`)return;await this.startDirect(n);return}await t?.signal(n)}sendSignal(e){return this.owner?.sendSignal(Ud(e))??!1}directFailed(e=`closed`,t){if(t&&this.direct!==t)return;let n=this.direct;if(!n)return;let r=this.diagnostics.phase,i=Math.min(6e4,5e3*2**this.retryFailures);if(this.retryFailures=Math.min(this.retryFailures+1,4),this.retryAt=this.clock()+Math.min(6e4,i*(.8+.4*ya(1)[0]/255)),this.lastFailure=e,!n.session?.ready)try{this.sendSignal({type:`direct.abort`,...n.signalContext(),reason:e===`timeout`?`timeout`:e===`certificate`?`dtls-failed`:`ice-failed`})}catch{}let a=n?.session;a&&this.owner?.routeLost(a),this.closeDirect(),this.options.failure(`direct`,{code:e,phase:r}),this.poll()}closeDirect(){let e=this.direct;this.direct=null,e&&e.close()}};function of(e,t){return rr.every(n=>e?.includes(n)&&t.includes(n))?[...rr,...e?.includes(`native-history-v1`)&&t.includes(`native-history-v1`)?[ir]:[]]:[]}function sf(e){if(e.length>4096)return!1;for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n>=55296&&n<=56319){let n=e.charCodeAt(++t);if(!(n>=56320&&n<=57343))return!1}else if(n>=56320&&n<=57343)return!1}return!0}const cf=tu.extend({t:tu.shape.t.refine(sf)}).strict(),lf=nu.extend({r:F.array(cf)}).strict(),uf=lf.extend({r:F.array(cf).max(2048)}),df=F.number().int().min(0).max(2**53-1),ff={kind:F.literal(`history`),generation:df,requestId:G,before:df},pf=F.custom(e=>Array.isArray(e)&&e.length>0&&e.length<=W.historyLines),mf=F.strictObject({...ff,status:F.literal(`page`),from:df,to:df,oldestAvailable:df,lines:pf});function hf(e){return e.to===e.before&&e.lines.length<=2**53-1-e.from&&e.from+e.lines.length===e.to&&e.oldestAvailable<=e.from}const gf=mf.refine(hf),_f=mf.extend({nextBefore:df}).refine(e=>hf(e)&&e.nextBefore===e.from),vf=F.strictObject({...ff,status:F.literal(`boundary`),reason:F.enum([`end`,`truncated`]),oldestAvailable:df}).refine(e=>e.reason===`end`?e.before===e.oldestAvailable:e.before<e.oldestAvailable),yf=F.discriminatedUnion(`status`,[gf,vf]),bf=F.discriminatedUnion(`status`,[_f,vf]),xf=F.strictObject({r:F.unknown(),w:F.boolean().optional()}),Sf={ok:!1,code:`invalid-transfer`},Cf={ok:!1,code:`history-line-too-large`};function wf(e){let t=xf.safeParse(e);if(!t.success||!Array.isArray(t.data.r))return Sf;if(t.data.r.length>2048)return Cf;let n={r:[],...t.data.w===void 0?{}:{w:t.data.w}},r=0,i=0;for(let e of t.data.r){let t=cf.safeParse(e);if(!t.success)return Sf;if(r+=t.data.n??yd(t.data.t),r>W.historyCells||(i+=Gn(t.data).length,i>W.historyBytes))return Cf;n.r.push(t.data)}let a=Gn(n).length;return a>W.historyBytes?Cf:{ok:!0,line:n,bytes:a}}F.unknown().transform((e,t)=>{let n=()=>(t.addIssue({code:`custom`,message:`invalid history record`}),F.NEVER);try{let t=bf.safeParse(e);if(!t.success)return n();let r;if(t.data.status===`boundary`)r=t.data;else{let e=[],i=0;for(let r of t.data.lines){let t=wf(r);if(!t.ok||(i+=t.bytes,i>W.historyBytes))return n();e.push(t.line)}r={...t.data,lines:e}}return Gn(r).length>W.historyBytes?n():r}catch{return n()}});function Tf(e){try{let t=yf.safeParse(e);if(!t.success)return Sf;if(t.data.status===`boundary`){let e=t.data;return{ok:!0,record:e,bytes:Gn(e)}}let n=t.data,r=[],i=0,a;for(let e=n.lines.length-1;e>=0;e--){let t=wf(n.lines[e]);if(!t.ok){if(t.code===`invalid-transfer`)return Sf;break}if(i+=t.bytes,i>W.historyBytes)break;r.unshift(t.line);let o=n.from+e,s={...n,from:o,nextBefore:o,lines:r.slice()},c=Gn(s);c.length<=W.historyBytes&&(a={ok:!0,record:s,bytes:c})}return a??{...Cf,before:n.before}}catch{return Sf}}const Ef=F.number().int().min(0).max(2**53-1),Df=Ef.min(1),Of=ru.extend({x:Ef,y:F.number().int().min(-1).max(2**53-1)}).strict(),kf=F.strictObject({cols:Df,rows:Df,cursor:Of,lines:F.array(lf),scrollbackTotal:Ef,gen:Ef,reset:F.boolean().optional(),degraded:F.boolean().optional()});function Af(e){return e.lines.length===e.rows&&e.cursor.x<=e.cols&&e.cursor.y<e.rows&&jf(e.lines,e.cols)}function jf(e,t){return e.every(e=>{let n=0;for(let r of e.r)if(n+=r.n??yd(r.t),n>t)return!1;return!0})}function Mf(e){let t=0,n=0;for(let r of e){t+=r.r.length;for(let e of r.r)n+=yd(e.t)}return{runs:t,points:n}}function Nf(e){let{runs:t,points:n}=Mf(e);return t<=W.runs&&n<=W.codePoints}const Pf=kf.extend({kind:F.literal(`snapshot`),cols:Df.max(W.cols),rows:Df.max(W.rows),lines:F.array(uf).max(W.rows)}).refine(e=>Af(e)&&Nf(e.lines)),Ff=F.strictObject({scroll:Ef.max(W.rows),changed:F.array(F.strictObject({i:Ef.max(W.rows-1),line:uf})).max(W.rows),cursor:Of.extend({x:Ef.max(W.cols),y:Of.shape.y.max(W.rows-1)}),scrollbackTotal:Ef,gen:Df}),If=Ff.extend({kind:F.literal(`diff`)}).refine(e=>{let t=new Set(e.changed.map(e=>e.i)),n=e.changed.map(e=>e.line);return t.size===e.changed.length&&jf(n,W.cols)&&Nf(n)}),Lf=F.discriminatedUnion(`kind`,[Pf,If]);function Rf(e){let t=Lf.safeParse(e);if(!t.success)throw new V(`malformed`);let n;try{n=Gn(t.data)}catch{throw new V(`malformed`)}if(n.length>W.screenBytes)throw new V(`malformed`);return{record:t.data,bytes:n}}function zf(e){let{kind:t,...n}=e;return n}function Bf(e){let t=kf.safeParse(e);if(!t.success||!Af(t.data))return{ok:!1,code:`invalid-transfer`};let n=t.data;if(n.cols>W.cols||n.rows>W.rows||Mf(n.lines).points>W.codePoints)return{ok:!1,code:`screen-too-large`};for(let e=0;e<2;e++){let t=e===0?n:{...n,lines:n.lines.map(Td),degraded:!0};try{let{record:e,bytes:n}=Rf({kind:`snapshot`,...t});if(e.kind===`snapshot`)return{ok:!0,snapshot:zf(e),bytes:n}}catch{}}return{ok:!1,code:`screen-too-large`}}function Vf(e){let t=Ff.safeParse(e);if(!t.success)throw new V(`malformed`);return Rf({kind:`diff`,...t.data}).bytes}var Hf=class{options;lanes=[null,null];outstanding=[];state=`open`;nextLane=0;lastSequence=0;acknowledgedThrough=0;constructor(e){if(!lr.shape.subscriptionId.safeParse(e.subscriptionId).success||!lr.shape.sessionId.safeParse(e.sessionId).success)throw Error(`Invalid stream sender identity`);this.options={...e}}canOffer(e){return this.tick()===`open`&&this.lanes[+(e===`history`)]===null}offer(e,t){if(this.tick()!==`open`)return{accepted:!1,reason:`closed`};let n=cr.safeParse(e);if(!n.success||!(t instanceof Uint8Array)||t.length===0)throw Error(`Invalid stream transfer`);let r=+(n.data.kind===`history`),i=r===1?W.historyBytes:W.screenBytes;if(t.length>i)return{accepted:!1,reason:`too-large`};if(this.lanes[r])return{accepted:!1,reason:`busy`};let a;try{a=this.options.newTransferId()}catch(e){throw this.cancel(),e}if(!lr.shape.transferId.safeParse(a).success)throw Error(`Invalid stream transfer identity`);return this.state===`open`?(this.lanes[r]={id:a,meta:n.data,bytes:new Uint8Array(t),count:Math.ceil(t.length/W.chunkBytes),nextIndex:0,acknowledged:0,startedAt:null,progressAt:null},{accepted:!0,transferId:a}):{accepted:!1,reason:`closed`}}pump(){if(this.tick()!==`open`)return 0;let e=0;for(;e<W.unacked&&this.inFlight<W.unacked&&this.tick()===`open`;){let t=this.nextLane,n=this.lanes[t];if((!n||n.nextIndex===n.count)&&(t=1-t,n=this.lanes[t]),!n||n.nextIndex===n.count)break;if(this.lastSequence===2**53-1){this.cancel();break}let r=this.lastSequence+1,i=n.nextIndex,a={type:`stream.chunk`,subscriptionId:this.options.subscriptionId,sessionId:this.options.sessionId,transferId:n.id,sequence:r,index:i,count:n.count,totalBytes:n.bytes.length,data:n.bytes.slice(i*W.chunkBytes,(i+1)*W.chunkBytes),meta:{...n.meta}},o;try{o=this.options.send(a)}catch(e){throw this.cancel(),e}if(o&&e++,this.state!==`open`||!o)break;this.lastSequence=r,n.nextIndex++,n.startedAt===null&&(n.startedAt=this.options.now(),n.progressAt=n.startedAt),this.outstanding.push({sequence:r,transfer:n}),this.nextLane=1-t}return e}acknowledge(e,t){if(e!==this.options.subscriptionId||this.tick()!==`open`)return`ignored`;if(!Number.isSafeInteger(t)||t<1||t>this.lastSequence)return`invalid`;if(t<=this.acknowledgedThrough)return`duplicate`;let n=this.options.now();for(let e of this.outstanding){if(e.sequence>t)break;e.transfer.acknowledged++,e.transfer.progressAt=n,e.transfer.acknowledged===e.transfer.count&&(this.lanes[+(e.transfer.meta.kind===`history`)]=null)}return this.outstanding=this.outstanding.filter(e=>e.sequence>t),this.acknowledgedThrough=t,`advanced`}tick(){let e=this.nextDeadline();return e!==null&&this.options.now()>=e&&this.stop(`stalled`),this.state}nextDeadline(){let e=1/0;for(let t of this.lanes)t&&t.startedAt!==null&&t.progressAt!==null&&(e=Math.min(e,t.startedAt+W.totalMs,t.progressAt+W.progressMs));return Number.isFinite(e)?e:null}cancel(){this.stop(`closed`)}stop(e){this.state=e,this.lanes[0]=null,this.lanes[1]=null,this.outstanding=[]}get inFlight(){return this.outstanding.length}get retainedBytes(){return(this.lanes[0]?.bytes.length??0)+(this.lanes[1]?.bytes.length??0)}},Uf=`0.13.0`;const Wf=/^owner-([1-9][0-9]*)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/;function Gf(e){if(!/^[1-9][0-9]*$/.test(e))return null;let t=Number(e);return Number.isInteger(t)&&t<=2147483647?t:null}function Kf(e){try{return process.kill(e,0),!0}catch(e){let t=e.code;if(t===`ESRCH`)return!1;if(t===`EPERM`)return!0;throw e}}function qf(e,n){try{t.unlinkSync(N(e,n))}catch(e){if(e.code!==`ENOENT`)throw e}try{t.rmdirSync(e)}catch(e){if(![`ENOENT`,`ENOTEMPTY`,`EEXIST`].includes(e.code??``))throw e}}function Jf(e){let n=`${A(e)}.lock-candidate-`;for(let r of t.readdirSync(j(e))){if(!r.startsWith(n))continue;let i=`owner-${r.slice(n.length)}`,a=Wf.exec(i),o=a&&Gf(a[1]);if(!o)continue;let s=N(j(e),r);try{if(Kf(o)||!t.lstatSync(s).isDirectory())continue;let e=t.readdirSync(s);e.length===0?t.rmdirSync(s):e.length===1&&e[0]===i&&t.lstatSync(N(s,i)).isFile()&&qf(s,i)}catch{}}}function Yf(e){let n=`${e}.lock`,r=`${process.pid}-${ce()}`,i=`${e}.lock-candidate-${r}`,a=`owner-${r}`;t.mkdirSync(i,{mode:448});let o=!1;try{t.writeFileSync(N(i,a),``,{mode:384,flag:`wx`});for(let r=0;r<3;r++){try{t.renameSync(i,n),o=!0;try{Jf(e)}catch{}return()=>qf(n,a)}catch(e){if(![`EEXIST`,`ENOTEMPTY`].includes(e.code??``))throw e}try{if(!t.lstatSync(n).isDirectory())throw Error(`Invalid control guard ${n}; inspect it before retrying`);let e=t.readdirSync(n);if(e.length===0)continue;let r=e[0],i=Wf.exec(r),a=i&&Gf(i[1]);if(e.length!==1||!a||!t.lstatSync(N(n,r)).isFile())throw Error(`Invalid control guard ${n}; inspect its owner marker before retrying`);if(Kf(a))throw Error(`Control endpoint busy (guard owner pid ${a})`);qf(n,r)}catch(e){if(e.code!==`ENOENT`)throw e}}throw Error(`Control endpoint busy; could not acquire ${n} after three attempts`)}finally{o||qf(i,a)}}var Y=class extends Error{kind;constructor(e){super(`shellbell: ${e} Linux host state; inspect ownership, permissions and host initialization`),this.kind=e}};function X(e){try{return p(e)}catch(e){if(e.code===`ENOENT`)return;throw new Y(`unsafe`)}}function Xf(e,t){return e.dev===t.dev&&e.ino===t.ino}function Z(e,t){let n=X(e);if(!n)throw new Y(`missing`);if(!n.isDirectory()||n.isSymbolicLink()||n.uid!==t||(n.mode&4095)!=448)throw new Y(`unsafe`);return n}function Zf(e){let t=P(e),n=X(t);if(n){if(n.isSymbolicLink()||!n.isDirectory())throw new Y(`unsafe`);return y(t)}return N(Qf(j(t)),A(t))}function Qf(e){if(X(e))try{return y(e)}catch{throw new Y(`unsafe`)}return N(Qf(j(e)),A(e))}function $f(e,t,n,r=!0){let i;try{let a=X(e);if(!a)throw new Y(`missing`);let s=e=>{if(!e.isFile()||e.isSymbolicLink()||n!==void 0&&(e.uid!==n||(e.mode&4095)!=384))throw new Y(`unsafe`);if(e.size>t)throw new Y(`invalid`)};s(a),i=h(e,o.O_RDONLY|o.O_NOFOLLOW|o.O_NONBLOCK);let c=l(i);if(s(c),!Xf(a,c))throw new Y(`unsafe`);let u=Buffer.alloc(t+ +!!r),d=0;for(;d<u.length;){let e=_(i,u,d,u.length-d,null);if(e===0)break;d+=e}let f=l(i),p=X(e);if(s(f),!p||!Xf(c,p)||!Xf(c,f)||c.size!==f.size||c.mtimeMs!==f.mtimeMs||c.ctimeMs!==f.ctimeMs)throw new Y(`unsafe`);if(s(p),d>t||d!==f.size)throw new Y(`invalid`);return u.subarray(0,d)}catch(e){throw e instanceof Y?e:new Y(`unsafe`)}finally{i!==void 0&&a(i)}}function ep(e={}){let t=e.uid??process.getuid?.(),n=e.euid??process.geteuid?.();if(!Number.isInteger(t)||t===void 0||t<=0||t!==n)throw Error(`shellbell: Linux hosting requires matching non-root real and effective users`);let r;try{let t=$f(e.machineIdPath??`/etc/machine-id`,256,void 0,!1).toString(`utf8`);if(!/^[0-9a-fA-F]{32}\n?$/.test(t)||/^0{32}\n?$/.test(t))throw Error();r=Buffer.from(t.trim().toLowerCase(),`hex`)}catch{throw Error(`shellbell: Linux machine identity is unavailable or invalid; provision /etc/machine-id before host initialization`)}let i=oe(`sha256`,`shellbell.local-host-scope.v1`).update(r).digest(`hex`),a=i.slice(0,32);return{uid:t,machineId:r.toString(`hex`),hostDigest:i,hostScope:a}}const tp=new WeakMap,np=new Set([16914836,61267,1481003842,2435016766]);function rp(e,t){let n=tp.get(e),r=n?.root??j(j(e.runtimeDir)),i=n?.fsType??(e=>S(e).type);try{if(Z(r,e.linuxHost.uid),!np.has(Number(i(r))))throw new Y(`unsafe`);for(let n of[N(r,`shellbell`),e.runtimeDir]){if(!X(n)){if(!t)continue;try{m(n,{mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}}if(Z(n,e.linuxHost.uid),!np.has(Number(i(n))))throw new Y(`unsafe`)}X(e.runtimeDir)&&ip(e.runtimeDir,e.linuxHost.uid,0,i)}catch{throw Error(`shellbell: unsafe or unavailable Linux runtime; provide a private 0700 local XDG_RUNTIME_DIR`)}}function ip(e,t,n,r){if(n>2)throw new Y(`unsafe`);let i=v(e);if(i.length>256)throw new Y(`unsafe`);for(let a of i){let i=N(e,a),o=X(i);if(!o||o.uid!==t||o.isSymbolicLink())throw new Y(`unsafe`);if(o.isDirectory()){if(Z(i,t),!np.has(Number(r(i))))throw new Y(`unsafe`);ip(i,t,n+1,r)}else if(!o.isFile()&&!o.isSocket()||(o.mode&4095)!=384)throw new Y(`unsafe`)}}function ap(e,t){if(j(t)!==j(e.runtimeDir))throw new Y(`unsafe`);Z(t,e.linuxHost.uid);let n=tp.get(e)?.fsType??(e=>S(e).type);if(!np.has(Number(n(t))))throw new Y(`unsafe`);ip(t,e.linuxHost.uid,0,n)}function op(e={}){let{uid:t,hostDigest:n,hostScope:r}=ep(e),i=e.env??process.env,a=e.home??E(),o=i.SHELLBELL_DIR;if(o!==void 0&&!M(o))throw Error(`shellbell: SHELLBELL_DIR must be absolute`);let s=i.XDG_STATE_HOME&&M(i.XDG_STATE_HOME)?i.XDG_STATE_HOME:N(a,`.local`,`state`),c=Zf(o??N(s,`shellbell`,`hosts`,r));X(c)&&Z(c,t);let l=i.XDG_RUNTIME_DIR??`/run/user/${t}`;if(!M(l))throw Error(`shellbell: XDG_RUNTIME_DIR must be absolute`);let u=N(P(l),`shellbell`,ae(`sha256`).update(c).digest(`hex`).slice(0,32)),d={dir:c,serviceOwner:N(c,`service-owner.json`),identity:N(c,`identity.json`),config:N(c,`config.json`),pairings:N(c,`pairings.json`),log:N(c,`agent.log`),runtimeDir:u,sock:N(u,`agent.sock`),pid:N(u,`agent.pid`),linuxHost:{uid:t,hostDigest:n,hostScope:r}};if(Buffer.byteLength(d.sock)>107)throw Error(`shellbell: Linux socket path exceeds 107 bytes; choose a shorter XDG_RUNTIME_DIR`);return tp.set(d,{root:P(l),fsType:e.runtimeFsType??(e=>S(e).type)}),rp(d,!1),d}function sp(e){rp(e,!0)}const cp=F.object({v:F.literal(1),relayUrl:F.string().url(),computerName:F.string().min(1).max(64),accent:F.string().min(1).max(32),notifyMinCommandMs:F.number().int().nonnegative().default(1e4),idleQuietMs:F.number().int().positive().default(4e3),idleMinActiveMs:F.number().int().nonnegative().default(1500),turn:F.boolean().optional(),showAgentConversations:F.boolean().optional(),terminalPlugins:F.array(F.string().min(1).max(4096).refine(e=>e.startsWith(`/`)&&e.endsWith(`.mjs`)&&[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127))).max(29).optional()}),lp=F.object({phoneFp:F.string().regex(/^[a-z2-7]{26}$/),name:F.string().min(1).max(64),platform:F.enum([`ios`,`android`]),ed25519Pub:F.string(),x25519Pub:F.string(),kPair:F.string(),minProtocolVersion:F.literal(2).optional(),pairedAt:F.string(),lastSeenAt:F.string().nullable()}),up=F.object({v:F.literal(1),phones:F.array(lp)});function dp(e,t){if(!e||e.phoneFp!==t.phoneFp||e.kPair!==t.kPair)return t;if(e.ed25519Pub!==t.ed25519Pub||e.x25519Pub!==t.x25519Pub)throw Error(`shellbell: pairing identity changed without a new pairing key`);return e.minProtocolVersion===2?{...t,minProtocolVersion:2}:t}const fp=F.object({v:F.literal(1),hostDigest:F.string().regex(/^[0-9a-f]{64}$/),installationId:F.string().uuid()}).strict();function pp(e){try{let t=nc(JSON.parse(e.toString(`utf8`))),n=$s(t.ed25519.priv,t.x25519.priv,t.createdAt);if(!Buffer.from(n.ed25519.pub).equals(Buffer.from(t.ed25519.pub))||!Buffer.from(n.x25519.pub).equals(Buffer.from(t.x25519.pub)))throw Error();return{identity:t,fp:rc(t.ed25519.pub)}}catch{throw new Y(`invalid`)}}function mp(e){try{return cp.parse(JSON.parse(e.toString(`utf8`)))}catch{throw new Y(`invalid`)}}function hp(e){try{let{phones:t}=up.parse(JSON.parse(e.toString(`utf8`)));for(let e of t){let t=xr(e.ed25519Pub);if(t.length!==32||xr(e.x25519Pub).length!==32||xr(e.kPair).length!==32||rc(t)!==e.phoneFp)throw Error()}return t}catch{throw new Y(`invalid`)}}function gp(e,t){let n=Z(e,t),r=$f(N(e,`identity.json`),65536,t),i=$f(N(e,`config.json`),65536,t),a=$f(N(e,`pairings.json`),1048576,t);if(pp(r),mp(i),hp(a),!Xf(n,Z(e,t)))throw new Y(`unsafe`);return{identity:r,config:i,pairings:a}}function _p(e){try{if(!X(e.dir))return{status:`absent`};let t=Z(e.dir,e.linuxHost.uid);for(let t of v(e.dir)){let n=/^owner-[1-9][0-9]*-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,r=`owner-${t.slice(34)}`,i=t.startsWith(`service-owner.json.lock-candidate-`)&&n.test(r);if(t===`service-owner.json.lock`||i){let a=N(e.dir,t),o;try{o=Z(a,e.linuxHost.uid);let t=v(a),s=t[0];if(!(i&&t.length===0)){if(t.length!==1||!s||!n.test(s)||i&&s!==r)throw new Y(`unsafe`);$f(N(a,s),0,e.linuxHost.uid)}if(!Xf(o,Z(a,e.linuxHost.uid)))throw new Y(`unsafe`)}catch(t){let n=X(a);if(!n)continue;try{if(i&&o&&Xf(o,n)&&v(a).length===0&&Xf(n,Z(a,e.linuxHost.uid)))continue}catch(e){if(e instanceof Y&&e.kind===`missing`||e.code===`ENOENT`)continue;throw e}throw t}continue}let a=X(N(e.dir,t));if(a&&(!a.isFile()||a.isSymbolicLink()||a.uid!==e.linuxHost.uid||(a.mode&4095)!=384))throw new Y(`unsafe`)}let n=N(e.dir,`host.json`);if(!X(n))return{status:`unmarked`,reason:`Host marker missing; explicit host initialization or recovery required`};let r,i=$f(n,4096,e.linuxHost.uid);try{r=fp.parse(JSON.parse(i.toString(`utf8`)))}catch{throw new Y(`invalid`)}if(r.hostDigest!==e.linuxHost.hostDigest)return{status:`wrong-host`,reason:`State belongs to a different host; choose this host's state directory`};let a=gp(e.dir,e.linuxHost.uid);if(!i.equals($f(n,4096,e.linuxHost.uid))||!Xf(t,Z(e.dir,e.linuxHost.uid)))throw new Y(`unsafe`);return{status:`ready`,bytes:a}}catch(e){return{status:e instanceof Y&&e.kind===`unsafe`?`unsafe`:`invalid`,reason:`Host state failed validation; inspect files and recover explicitly`}}}function vp(e){let t=_p(e);return t.status===`ready`?{status:`ready`}:t}function yp(){return Error(`shellbell: Linux host state is not ready; use shellbell host init --new or host init --adopt <absolute-source> --confirm-source-inactive for absent state; inspect existing state before recovery`)}function bp(e){let t=_p(e);if(!(`bytes`in t))throw yp();return t.bytes}function xp(e){if(vp(e).status!==`ready`)throw yp()}function Sp(e){return pp(bp(e).identity)}function Cp(e){return mp(bp(e).config)}function wp(e){return hp(bp(e).pairings)}const Tp=[`emerald`,`blue`,`amber`,`violet`,`rose`,`cyan`,`lime`,`orange`];function Ep(e=process.env.SHELLBELL_DIR??N(E(),`.shellbell`)){return{dir:e,serviceOwner:N(e,`service-owner.json`),identity:N(e,`identity.json`),pairings:N(e,`pairings.json`),config:N(e,`config.json`),log:N(e,`agent.log`),sock:N(e,`agent.sock`),pid:N(e,`agent.pid`)}}function Dp(e){if(e.linuxHost){xp(e);return}m(e.dir,{recursive:!0,mode:448}),i(e.dir,448)}function Op(e,t,n){Mp(e,t,t=>{n?.(),b(t,e)})}const kp=new Set([`EPERM`,`ENOTSUP`,`EOPNOTSUPP`,`EXDEV`]);function Ap(e,t){try{return Mp(e,t,n=>{try{f(n,e)}catch(n){if(!kp.has(n.code??``))throw n;jp(e,t)}ee(n)}),!0}catch(e){if(e.code===`EEXIST`)return!1;throw e}}function jp(e,t){let n=h(e,`wx`,384),r=l(n),i=!1;try{c(n,384);let e=typeof t==`string`?Buffer.from(t):t,r=0;for(;r<e.byteLength;){let t=T(n,e,r,e.byteLength-r);if(t<=0)throw Error(`secret file write made no progress`);r+=t}u(n),i=!0}finally{if(a(n),!i)try{let t=p(e);t.dev===r.dev&&t.ino===r.ino&&ee(e)}catch{}}}function Mp(e,t,n){let r=`${e}.tmp-${process.pid}`,o=null;try{let e=h(r,`wx`,384),s=l(e);o={dev:s.dev,ino:s.ino};try{let n=typeof t==`string`?Buffer.from(t):t,r=0;for(;r<n.byteLength;){let t=T(e,n,r,n.byteLength-r);if(t<=0)throw Error(`atomic file write made no progress`);r+=t}u(e)}finally{a(e)}i(r,384),n(r)}catch(e){try{if(o){let e=p(r);e.dev===o.dev&&e.ino===o.ino&&ee(r)}}catch{}throw e}}function Np(e){let t;try{t=g(e,`utf8`)}catch(t){throw Error(`shellbell: cannot read ${e}: ${t.message}`)}try{return JSON.parse(t)}catch{throw Error(`shellbell: ${e} is not valid JSON`)}}function Pp(){return{v:1,relayUrl:`wss://relay.shellbell.dev`,computerName:D().replace(/\.local$/,``)||`Mac`,accent:Tp[0],notifyMinCommandMs:1e4,idleQuietMs:3e4,idleMinActiveMs:1500}}function Fp(e){return Bp(e,()=>{if(Up(e),e.linuxHost)return Cp(e);if(!X(e.dir))return Pp();let t=Z(e.dir,process.getuid());if(!X(e.config))return Pp();let n=$f(e.config,Rp,process.getuid());if(!Xf(t,Z(e.dir,process.getuid())))throw new Y(`unsafe`);let r;try{r=JSON.parse(n.toString(`utf8`))}catch{throw new zp(`invalid`,e.config,`not valid JSON`)}return Vp(e,r)})}function Ip(e){return e.linuxHost?Fp(e):Gp(e,()=>{let t=Fp(e);return X(e.config)||Kp(e,t),t})}function Lp(e,t){return Gp(e,()=>t(Fp(e)))}const Rp=65536;var zp=class extends Error{code;constructor(e,t,n=e){super(`shellbell: config ${n} at ${t}`),this.code=e,this.name=`ConfigEditError`}};function Bp(e,t){try{return t()}catch(t){throw t instanceof zp?t:new zp(t instanceof Y?t.kind===`invalid`?`invalid`:`unsafe`:`io`,e.config)}}function Vp(e,t){let n=cp.safeParse(t);if(!n.success)throw new zp(`invalid`,e.config);return n.data}function Hp(e){if(e.linuxHost){xp(e);return}Z(e.dir,process.getuid())}function Up(e){if([e.dir,e.config].some(e=>Buffer.byteLength(e)>4096||e.includes(`\0`))||j(P(e.config))!==P(e.dir))throw new zp(`unsafe`,e.config)}function Wp(e,t){let n=`${A(e)}.lock`;for(let r of v(j(e))){if(r!==n&&!r.startsWith(`${n}-candidate-`))continue;let i=N(j(e),r);if(X(i)){Z(i,t);for(let e of v(i)){let n=X(N(i,e));if(n&&(!n.isFile()||n.isSymbolicLink()||n.uid!==t||(n.mode&4095)!=384))throw new Y(`unsafe`)}}}}function Gp(e,t){let n=Bp(e,()=>{if(Up(e),!e.linuxHost&&!X(e.dir))try{m(e.dir,{recursive:!0,mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}Hp(e);let t=e.config;e.linuxHost&&(sp(e),t=N(e.runtimeDir,`config-${ae(`sha256`).update(e.config).digest(`hex`)}`)),Wp(t,e.linuxHost?.uid??process.getuid());try{return Yf(t)}catch(t){throw t instanceof Error&&t.message.startsWith(`Control endpoint busy`)?new zp(`busy`,e.config):t instanceof Error&&t.message.startsWith(`Invalid control guard`)?new zp(`unsafe`,e.config):t}}),r;try{r=t()}catch(e){try{n()}catch{}throw e}return Bp(e,n),r}function Kp(e,t){Bp(e,()=>{let n=`${JSON.stringify(Vp(e,t),null,2)}\n`;if(Buffer.byteLength(n)>Rp)throw new zp(`invalid`,e.config);Op(e.config,n,()=>{Hp(e),Fp(e)})})}function qp(e,t){return Gp(e,()=>{let n=Vp(e,t(Fp(e)));return Kp(e,n),n})}function Jp(e){if(e.linuxHost)return wp(e);if(Dp(e),!s(e.pairings))return[];let t=up.safeParse(Np(e.pairings));if(!t.success)throw Error(`shellbell: invalid pairings at ${e.pairings}: ${F.prettifyError(t.error)}`);return t.data.phones}function Yp(e,t){Dp(e);let n=new Map(Jp(e).map(e=>[e.phoneFp,e])),r=t.map(e=>dp(n.get(e.phoneFp),e)),i=up.parse({v:1,phones:r}),a=`${JSON.stringify(i,null,2)}\n`;if(e.linuxHost){if(Buffer.byteLength(a)>1048576)throw Error(`shellbell: Linux pairings exceed their state size limit`);hp(Buffer.from(a))}return Op(e.pairings,a,e.linuxHost?()=>xp(e):void 0),i.phones}const Xp=new Set([`Error`,`TypeError`,`RangeError`,`ReferenceError`,`SyntaxError`,`URIError`,`EvalError`,`AggregateError`,`AbortError`,`TimeoutError`,`ProtocolError`,`BackendUnavailable`,`SessionGone`,`Unsupported`,`BadWindow`,`HerdrError`,`ITerm2AuthError`,`ConfigEditError`,`NativeControllerError`,`ControlV2ClientError`]);function Zp(e){try{if(!(e instanceof Error))return`unknown`;let t=e.name;return typeof t==`string`&&Xp.has(t)?t:`Error`}catch{return`unknown`}}const Qp=1048576;function $p(e){return e.isFile()&&e.uid===process.getuid?.()&&e.nlink===1}function em(e,t){return e.dev===t.dev&&e.ino===t.ino}function tm(e,t){let n;try{let i;try{i=p(e)}catch(e){if(e.code!==`ENOENT`)return}if(i&&!$p(i))return;n=h(e,o.O_WRONLY|o.O_APPEND|o.O_NOFOLLOW|o.O_NONBLOCK|(i?0:o.O_CREAT|o.O_EXCL),384);let a=l(n),s=p(e);if(!$p(a)||!$p(s)||!em(a,s)||i&&!em(i,a))return;c(n,384),r(n,t)}catch{}finally{if(n!==void 0)try{a(n)}catch{}}}function nm(e){let t;try{let n=p(e);if(!$p(n)||n.size<Qp)return;t=h(e,o.O_RDWR|o.O_NOFOLLOW|o.O_NONBLOCK);let r=l(t);if(!$p(r)||!em(n,r)||r.size<Qp)return;c(t,384);let i=Math.max(0,r.size-Qp),a=Buffer.alloc(r.size-i);for(let e=0;e<a.length;){let n=_(t,a,e,a.length-e,i+e);if(n===0)return;e+=n}for(let t=4;t>=1;t--)s(`${e}.${t}`)&&b(`${e}.${t}`,`${e}.${t+1}`);Op(`${e}.1`,a);let u=p(e);$p(u)&&em(u,r)&&$p(l(t))&&d(t,0)}catch{}finally{if(t!==void 0)try{a(t)}catch{}}}function rm(e,t={}){let n=e.stdout??process.stdout.isTTY===!0,r=(r,i,a)=>{if(r===`debug`&&!e.verbose)return;let o={t:new Date().toISOString(),level:r,msg:i,...t,...a};if(e.file){nm(e.file);try{tm(e.file,`${JSON.stringify(o)}\n`)}catch{}}if(n){let e=Object.keys({...t,...a}).length?` ${JSON.stringify({...t,...a})}`:``,n=`${o.t.slice(11,19)} ${r.padEnd(5)} ${i}${e}`;(r===`error`||r===`warn`?process.stderr:process.stdout).write(`${n}\n`)}};return{debug:(e,t)=>r(`debug`,e,t),info:(e,t)=>r(`info`,e,t),warn:(e,t)=>r(`warn`,e,t),error:(e,t)=>r(`error`,e,t),child:n=>rm(e,{...t,...n})}}function im(e){if(!am(e.reported)||!am(e.before)||e.before>e.reported||!Number.isSafeInteger(e.count)||e.count<1||e.count>W.historyLines||e.capture===null||typeof e.capture!=`object`)throw RangeError(`invalid history read request`)}function am(e){return Number.isSafeInteger(e)&&e>=0}var om=class extends Error{hint;constructor(e,t){super(e),this.hint=t,this.name=`BackendUnavailable`}},sm=class extends Error{constructor(e){super(`session gone: ${e}`),this.name=`SessionGone`}},cm=class extends Error{code;constructor(e){super(`Terminal input ${e}`),this.code=e,this.name=`TerminalInputError`}},lm=class extends Error{constructor(e){super(`unsupported: ${e}`),this.name=`Unsupported`}},um=class extends Error{constructor(e=`No terminal app on this computer can show a new session.`){super(e),this.name=`NotShownOnComputer`}},dm=class extends Error{constructor(e){super(`bad-window: ${e}`),this.name=`BadWindow`}};async function fm(e,t){let n;try{return await Promise.race([Promise.resolve().then(e),new Promise((e,r)=>{n=setTimeout(()=>r(Error(`Terminal adapter deadline exceeded`)),t),n.unref()})])}finally{n&&clearTimeout(n)}}function pm(e,t){return`${e}:${t}`}const mm=Yl.options,hm=new Set([`iterm2`]);function gm(e){let t=e.indexOf(`:`);if(t<=0)return null;let n=Xl.safeParse(e.slice(0,t));return n.success?{name:n.data,native:e.slice(t+1)}:null}var _m=class{log;listTimeoutMs;conversationPermits=new Map;async conversationReference(e,t){let n=gm(e);if(!n||t.aborted)return null;let r=this.members.get(n.name);if(!r||r.isConnected===!1||!r.conversationReference||this.conversationPermits.has(e)||this.conversationPermits.size>=10)return null;let i={};this.conversationPermits.set(e,i);let a=this.historyMembership.get(n.name),o=!0,s=this.on(t=>{(r.isConnected===!1||(t.type===`session-removed`||t.type===`conversation-changed`)&&t.sessionId===e)&&(o=!1)});try{let e=await r.conversationReference?.(n.native,t);return e&&o&&!t.aborted&&this.historyMembership.get(n.name)===a&&this.members.get(n.name)===r&&this.members.get(n.name)?.isConnected!==!1?e:null}catch{return null}finally{s(),this.conversationPermits.get(e)===i&&this.conversationPermits.delete(e)}}notificationRevision=0;async notificationFacts(e){let t=gm(e);if(!t)return;let n=this.members.get(t.name);if(!n||n.isConnected===!1)return;let r=this.notificationRevision,i=await n.notificationFacts?.(t.native);if(i&&i.sessionId===t.native&&this.members.get(t.name)===n&&r===this.notificationRevision&&this.connected().some(e=>e.name===t.name))return{...i,sessionId:e,revision:JSON.stringify([r,i.revision])}}members=new Map;labels=new Map;hostCommands=new Map;hostedLaunchers=new Map;hostedPending=0;sessionLaunchers=new Map;setupReporters=new Map;setupListeners=new Set;sessionStartups=new Map;startupWaiters=new Map;unsubs=new Map;historyMembership=new Map;historyPermits=new Map;inputCount=0;inputBytes=0;inputQueues=new Map;handlers=new Set;constructor(e,t=8e3){this.log=e,this.listTimeoutMs=t}orderedNames(){let e=new Set([...this.members.keys(),...this.sessionLaunchers.keys()]);for(let t of mm)e.delete(t);return[...mm,...[...e].sort()]}defaultLabel(e){let t=Yl.safeParse(e);return t.success?Zl[t.data]:e}catalog(){return this.orderedNames().map(e=>{let t=this.memberConnected(e);return{name:e,label:this.labels.get(e)??this.defaultLabel(e),capabilities:this.members.get(e)?.capabilities??{subscribe:!1,prompts:!1,createSession:!1,focus:!1,history:!1,absoluteLines:!1},connected:t,launchable:!t&&(this.sessionLaunchers.get(e)?.available()??!1)}})}registerHostedLauncher(e,t){let n=cu.parse(e),r=`${n.backend}:${n.host}`;if(!this.hostedLaunchers.has(r)&&this.hostedLaunchers.size>=64)throw new om(`Too many terminal launch targets`,`Disable a launch target first.`);let i={target:n,launcher:t};return this.hostedLaunchers.set(r,i),this.emit({type:`layout-changed`}),()=>{this.hostedLaunchers.get(r)===i&&(this.hostedLaunchers.delete(r),this.emit({type:`layout-changed`}))}}launchTargets(){return[...this.hostedLaunchers.values()].filter(({target:e,launcher:t})=>t.available()&&(this.memberConnected(e.backend)||this.sessionLaunchers.get(e.backend)?.available())).map(({target:e})=>({...e})).sort((e,t)=>`${e.backend}:${e.host}`.localeCompare(`${t.backend}:${t.host}`))}launchIssues(){let e=new Set(this.launchTargets().map(e=>e.backend)),t=new Map;for(let{target:n,launcher:r}of this.hostedLaunchers.values()){if(e.has(n.backend)||t.has(n.backend))continue;let i=r.unavailableReason?.();i&&t.set(n.backend,i)}return du.parse([...t].map(([e,t])=>({backend:e,reason:t})))}preferredHost(e){return _u(e,this.launchTargets())?.host}async requireShownOnComputer(e,t){if(!hm.has(e.name)&&!(e.shownOnComputer&&await fm(()=>e.shownOnComputer(t),5e3)))throw new um(`This session is not open in a terminal window on your computer, so it cannot be split or extended from the phone.`)}async createHostedSession(e){let t=`${e.backend}:${e.host}`,n=this.hostedLaunchers.get(t);if(e.windowId!==void 0||!n?.launcher.available())throw new om(`Terminal launch target is unavailable`,`Check the selected terminal app on your computer.`);if(this.hostedPending>=8)throw new om(`Terminal startup is busy`,`Wait for the current startup to finish.`);this.hostedPending++;let r=(async()=>{if(this.hostedLaunchers.get(t)!==n)throw new sm(t);let r=this.members.get(e.backend),i;if(!r||r.isConnected===!1){let t=await this.startSession(e.backend,e.initialSize);r=t.backend,i=t.sessionId}if(this.hostedLaunchers.get(t)!==n||this.members.get(e.backend)!==r)throw new sm(t);let a=e.initialSize?await n.launcher.create(r,i,e.initialSize):await n.launcher.create(r,i);if(this.hostedLaunchers.get(t)!==n||this.members.get(e.backend)!==r||r.isConnected===!1)throw new sm(t);return pm(e.backend,a)})().finally(()=>{this.hostedPending--});return fm(()=>r,3e4)}get capabilities(){let e=[...this.members.values()].filter(e=>e.isConnected!==!1).map(e=>e.capabilities),t=t=>e.some(e=>e[t]);return{subscribe:t(`subscribe`),prompts:t(`prompts`),createSession:t(`createSession`)||[...this.sessionLaunchers.values()].some(e=>e.available()),focus:t(`focus`),history:t(`history`),absoluteLines:e.length>0&&e.every(e=>e.absoluteLines)}}add(e,t,n){let r=ou.parse({name:e.name,label:t??this.defaultLabel(e.name),capabilities:e.capabilities,connected:!1,launchable:!1});if(!this.orderedNames().includes(e.name)&&this.orderedNames().length>=32)throw new om(`Too many terminal adapters`,`Disable an adapter before adding another.`);let i={},a=e.on(t=>{this.members.get(e.name)===e&&this.historyMembership.get(e.name)===i&&this.emit(ym(e.name,t))});if(typeof a!=`function`)throw Error(`Terminal adapter subscription is invalid`);let o=this.unsubs.get(e.name);this.labels.set(e.name,r.label),this.hostCommands.set(e.name,n??(e.name===`tmux`||e.name===`herdr`?[e.name]:[])),this.members.set(e.name,e),this.historyMembership.set(e.name,i),this.unsubs.set(e.name,a);try{o?.()}catch(t){this.log.warn(`backend subscription cleanup failed`,{backend:e.name,err:Zp(t)})}this.emit({type:`layout-changed`})}remove(e){let t=this.unsubs.get(e);this.unsubs.delete(e),this.members.delete(e),this.labels.delete(e),this.hostCommands.delete(e),this.historyMembership.delete(e);try{t?.()}catch(t){this.log.warn(`backend subscription cleanup failed`,{backend:e,err:Zp(t)})}this.emit({type:`layout-changed`})}connected(){let e=[];for(let t of this.orderedNames()){let n=this.members.get(t);n&&n.isConnected!==!1&&e.push({name:n.name,capabilities:n.capabilities})}return e}registerSessionLauncher(e,t){if(Xl.parse(e),!this.orderedNames().includes(e)&&this.orderedNames().length>=32)throw new om(`Too many terminal adapters`,`Disable an adapter before adding another.`);return this.sessionLaunchers.set(e,t),this.sessionStartups.delete(e),this.emit({type:`layout-changed`}),()=>{this.sessionLaunchers.get(e)===t&&(this.sessionLaunchers.delete(e),this.sessionStartups.delete(e),this.emit({type:`layout-changed`}))}}launchable(){return this.orderedNames().filter(e=>!this.memberConnected(e)&&this.sessionLaunchers.get(e)?.available())}async startSession(e,t){let n=this.sessionLaunchers.get(e);if(!n?.available())throw new sm(`backend ${e}`);let r=this.startupWaiters.get(e)??0;if(r>=8)throw new om(`Terminal startup is busy`,`Try again after the current startup finishes.`);this.startupWaiters.set(e,r+1);try{let r=this.sessionStartups.get(e);if(!r){let i=Promise.resolve().then(()=>{if(this.sessionLaunchers.get(e)!==n)throw new sm(`backend ${e}`);return t?n.start(t):n.start()}).then(e=>({...e})).finally(()=>{this.sessionStartups.get(e)===i&&this.sessionStartups.delete(e)});r=i,this.sessionStartups.set(e,i)}let i=await r;if(this.sessionLaunchers.get(e)!==n||this.members.get(e)!==i.backend||i.backend.isConnected===!1)throw new sm(`backend ${e}`);let a=i.sessionId;return i.sessionId=void 0,{backend:i.backend,sessionId:a}}finally{let t=(this.startupWaiters.get(e)??1)-1;t===0?this.startupWaiters.delete(e):this.startupWaiters.set(e,t)}}member(e){return this.members.get(e)}registerSetupReporter(e,t){return this.setupReporters.set(e,t),()=>{this.setupReporters.get(e)===t&&this.setupReporters.delete(e)}}onSetupChanged(e){return this.setupListeners.add(e),()=>this.setupListeners.delete(e)}notifySetupChanged(){for(let e of this.setupListeners)try{e()}catch{}}terminalSetup(){return this.orderedNames().flatMap(e=>{let t=this.setupReporters.get(e),n=this.memberConnected(e);if(!t&&!this.members.has(e))return[];let r={};try{r=t?.(n)??{}}catch{r=n?{}:{issue:`failed`}}return[{name:e,connected:n,...r.issue?{issue:r.issue}:{},...r.issue&&r.detail?{detail:r.detail}:{}}]}).slice(0,16)}connectTerminal(e){let t=this.setupReporters.get(e)?.connect;if(!t)return!1;try{t().catch(e=>this.log.debug(`terminal connect failed`,{error:Zp(e)}))}catch(e){this.log.debug(`terminal connect failed`,{error:Zp(e)})}return!0}status(){return this.orderedNames().map(e=>({name:e,connected:this.memberConnected(e)}))}nameOf(e){return gm(e)?.name??null}capabilitiesOf(e){let t=this.nameOf(e);return t?this.members.get(t)?.capabilities??null:null}async connect(){}async close(){let e=[...this.members.values()],t=[...this.unsubs.values()];this.sessionLaunchers.clear(),this.hostedLaunchers.clear(),this.sessionStartups.clear(),this.historyMembership.clear(),this.unsubs.clear(),this.members.clear(),this.labels.clear(),this.hostCommands.clear();for(let e of t)try{e()}catch(e){this.log.warn(`backend subscription cleanup failed`,{err:Zp(e)})}await Promise.all(e.map(async e=>{try{await fm(()=>e.close(),this.listTimeoutMs)}catch(t){this.log.warn(`backend close failed`,{backend:e.name,err:Zp(t)})}}))}async listSessions(){let e=this.orderedNames().map(e=>({name:e,backend:this.members.get(e),membership:this.historyMembership.get(e)})),t=(await Promise.all(e.map(async e=>({...e,sessions:await this.safeListSessions(e.backend,e.name)})))).filter(({name:e,backend:t,membership:n})=>t&&this.members.get(e)===t&&this.historyMembership.get(e)===n),n=new Set;for(let{name:e,backend:r}of t)try{for(let e of r?.representedWindows?.()??[])n.add(JSON.stringify([e.backend,e.windowId]))}catch(t){this.log.warn(`terminal window relationships unavailable`,{backend:e,err:Zp(t)})}let r=[];for(let{name:e,backend:i,sessions:a}of t)for(let o of a){try{let r=i?.nativeWindowIdOf?.(o.id);if(r&&n.has(JSON.stringify([e,r])))continue;let a=i?.hostedProcess?.(o.id);if(a&&t.some(t=>t.name!==e&&this.memberConnected(t.name)&&this.hostCommands.get(t.name)?.includes(a)))continue}catch(t){this.log.warn(`terminal host relationship unavailable`,{backend:e,err:Zp(t)})}r.push(vm(e,o))}return r}projectFolder(e){let t=gm(e),n=t?this.members.get(t.name):void 0;if(t&&n?.projectFolder)try{return n.projectFolder(t.native)}catch(e){this.log.warn(`session project folder unavailable`,{backend:t.name,err:Zp(e)});return}}memberConnected(e){let t=this.members.get(e);return!!t&&t.isConnected!==!1}async safeListSessions(e,t){if(!e)return[];let n=this.historyMembership.get(t);try{let r=await fm(()=>e.listSessions(),this.listTimeoutMs);return this.members.get(t)!==e||this.historyMembership.get(t)!==n?[]:r}catch(e){return this.log.warn(`listSessions failed for backend; returning the other backends' sessions`,{backend:t,err:Zp(e)}),[]}}target(e){let t=gm(e),n=t?this.members.get(t.name):void 0;if(!t||!n)throw new sm(e);return{backend:n,native:t.native}}async getScreen(e,t){let{backend:n,native:r}=this.target(e);return t===void 0?n.getScreen(r):n.getScreen(r,t)}async getHistory(e,t,n){let{backend:r,native:i}=this.target(e);return r.getHistory(i,t,n)}async getHistoryPage(e,t){let{backend:n,native:r}=this.target(e);if(im(t),t.signal.aborted)return{status:`cancelled`};let i=n.getHistoryPage;if(!i)return{status:`unavailable`,reason:`unsupported`};if(this.historyPermits.has(e)||this.historyPermits.size>=10)return{status:`unavailable`,reason:`busy`};let a={};this.historyPermits.set(e,a);let o=this.historyMembership.get(n.name);try{let e=await i.call(n,r,t);return t.signal.aborted?{status:`cancelled`}:this.historyMembership.get(n.name)===o?e:{status:`reset`}}catch(e){if(t.signal.aborted)return{status:`cancelled`};if(this.historyMembership.get(n.name)!==o)return{status:`reset`};throw e}finally{this.historyPermits.get(e)===a&&this.historyPermits.delete(e)}}async sendText(e,t,n){let{backend:r,native:i}=this.target(e);return this.enqueueInput(e,r,t,()=>r.sendText(i,t),n)}async clickMouse(e,t,n){let{backend:r,native:i}=this.target(e);if(!r.capabilities.mouseClick||!r.clickMouse)throw new lm(`mouse input`);return this.enqueueInput(e,r,``,()=>r.clickMouse(i,t),n)}async sendInput(e,t,n){let{backend:r,native:i}=this.target(e);if(!r.capabilities.terminalInput||!r.sendInput)throw new lm(`terminal input`);return this.enqueueInput(e,r,t,()=>r.sendInput(i,t),n)}openVtStream(e){let{backend:t,native:n}=this.target(e);if(!t.capabilities.vtStream||!t.openVtStream)throw new lm(`vt stream`);return t.openVtStream(n)}async paste(e,t,n,r){let{backend:i,native:a}=this.target(e);if(!i.capabilities.terminalPaste||!i.paste)throw new lm(`terminal paste`);return this.enqueueInput(e,i,t,()=>i.paste(a,t,n),r)}enqueueInput(e,t,n,r,i){let a=Buffer.byteLength(n);if(this.inputCount>=256||this.inputBytes+a>1048576)return Promise.reject(new cm(`busy`));let o=this.inputQueues.get(e);if(o||(o={backend:t,membership:this.historyMembership.get(t.name),tail:Promise.resolve(),pending:0,valid:!0},this.inputQueues.set(e,o)),!o.valid||o.backend!==t)return Promise.reject(new cm(`cancelled`));let s=o;s.pending++,this.inputCount++,this.inputBytes+=a;let c=()=>this.members.get(t.name)===t&&t.isConnected!==!1&&this.historyMembership.get(t.name)===s.membership,l=s.tail.then(async()=>{if(!s.valid||i?.()===!1)throw new cm(`cancelled`);if(!c())throw new sm(e);await r(),s.valid&&c()&&this.emit({type:`input-accepted`,sessionId:e})});return s.tail=l.catch(()=>{s.valid=!1}),l.finally(()=>{this.inputCount--,this.inputBytes-=a,--s.pending===0&&this.inputQueues.get(e)===s&&this.inputQueues.delete(e)})}async createSession(e){if(e.kind===`tab`&&e.host!==void 0)return this.createHostedSession(e);if(e.kind===`split`){let{backend:t,native:n}=this.target(e.sessionId),r={kind:`split`,sessionId:n,direction:e.direction};return await this.requireShownOnComputer(t,r),pm(t.name,await t.createSession(r))}let t;if(e.windowId){let n=gm(e.windowId);if(!n||n.name!==e.backend)throw new dm(e.windowId);t=n.native}if(!hm.has(e.backend)){if(t===void 0){let t=this.preferredHost(e.backend);if(t===void 0)throw new um;return this.createHostedSession({kind:`tab`,backend:e.backend,host:t,...e.initialSize?{initialSize:e.initialSize}:{}})}let n=this.members.get(e.backend);if(!n||n.isConnected===!1)throw new sm(`${e.windowId}`);let r={kind:`tab`,backend:e.backend,windowId:t};return await this.requireShownOnComputer(n,r),pm(n.name,await n.createSession(r))}let n=this.members.get(e.backend);if(!n||n.isConnected===!1){if(e.windowId)throw new sm(e.windowId);let t=await this.startSession(e.backend,e.initialSize);if(t.sessionId)return pm(e.backend,t.sessionId);n=t.backend}return pm(n.name,await n.createSession({kind:`tab`,backend:e.backend,windowId:t,...e.initialSize?{initialSize:e.initialSize}:{}}))}async focus(e){let{backend:t,native:n}=this.target(e);return t.focus(n)}setWatched(e){let t=new Map;for(let e of this.members.keys())t.set(e,[]);for(let n of e){let e=gm(n);e&&t.get(e.name)?.push(e.native)}for(let[e,n]of t)try{this.members.get(e)?.setWatched?.(n)}catch(t){this.log.warn(`setWatched failed for backend`,{backend:e,err:Zp(t)})}}setReported(e,t){let n=gm(e);if(n)try{this.members.get(n.name)?.setReported?.(n.native,t)}catch(e){this.log.warn(`setReported failed for backend`,{backend:n.name,err:Zp(e)})}}on(e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(e){if(e.type===`session-removed`){let t=this.inputQueues.get(e.sessionId);t&&(t.valid=!1)}for(let e of this.inputQueues.values())(e.backend.isConnected===!1||this.members.get(e.backend.name)!==e.backend)&&(e.valid=!1);[`layout-changed`,`session-added`,`session-removed`,`title-changed`].includes(e.type)&&this.notificationRevision++;for(let t of[...this.handlers])if(this.handlers.has(t))try{t(e)}catch(e){this.log.error(`backend event handler threw`,{err:Zp(e)})}}};function vm(e,t){return{...t,id:pm(e,t.id),windowId:pm(e,t.windowId),tabId:pm(e,t.tabId),backend:e}}function ym(e,t){return`sessionId`in t?{...t,sessionId:pm(e,t.sessionId)}:t}function bm(e,t){let n;try{n=new URL(e)}catch{return`must be a valid URL, e.g. wss://relay.example.com`}return e.endsWith(`/`)||/[?#]/.test(e)||n.pathname!==`/`||n.username||n.password?`relay url must be scheme://host[:port] with no path, query or credentials`:e.length>256?`relay url is too long for a pairing code (at most 256 characters)`:n.protocol===`wss:`?null:n.protocol===`ws:`?t?null:`ws:// is insecure; pass --insecure or set SHELLBELL_ALLOW_INSECURE_RELAY=1 for LAN dev`:`relay url must use wss:// (ws:// only with --insecure, for LAN dev)`}function xm(e,t,n,r){let i;if(t===`relay`){let t=bm(n,r);if(t)return{error:t};i={...e,relayUrl:n}}else if(t===`name`)i={...e,computerName:n};else if(t===`accent`){if(!Tp.includes(n))return{error:`unknown accent ${n} (must be one of ${Tp.join(`, `)})`};i={...e,accent:n}}else if(t===`turn`){if(n!==`on`&&n!==`off`)return{error:`turn must be on or off`};let{turn:t,...r}=e;i=n===`off`?{...r,turn:!1}:r}else if(t===`conversations`){if(n!==`on`&&n!==`off`)return{error:`conversations must be on or off`};let{showAgentConversations:t,...r}=e;i=n===`off`?{...r,showAgentConversations:!1}:r}else if(wm(t)){if(!/^\d+$/.test(n))return{error:`${t} must be a complete decimal integer`};let r=Number(n);if(!Number.isSafeInteger(r))return{error:`${t} must be a safe decimal integer`};i={...e,[t]:r}}else return{error:`unknown key ${t} (expected ${Tm()})`};let a=cp.safeParse(i);return a.success?{next:a.data}:{error:a.error.issues.map(e=>e.message).join(`; `)}}const Sm=[`notifyMinCommandMs`,`idleQuietMs`,`idleMinActiveMs`],Cm=[`relay`,`name`,`accent`,...Sm,`turn`,`conversations`];function wm(e){return Sm.includes(e)}function Tm(){return`${Cm.slice(0,-1).join(`, `)}, or ${Cm.at(-1)}`}function Em(e,t){switch(t){case`relay`:return e.relayUrl;case`name`:return e.computerName;case`accent`:return e.accent;case`turn`:return e.turn===!1?`off`:`on`;case`conversations`:return e.showAgentConversations===!1?`off`:`on`;default:return String(e[t])}}function Dm(e){let t=cp.parse(e);return ae(`sha256`).update(JSON.stringify({v:t.v,relayUrl:t.relayUrl,computerName:t.computerName,accent:t.accent,notifyMinCommandMs:t.notifyMinCommandMs,idleQuietMs:t.idleQuietMs,idleMinActiveMs:t.idleMinActiveMs,...t.terminalPlugins?.length?{terminalPlugins:t.terminalPlugins}:{},...t.turn===!1?{turn:!1}:{},...t.showAgentConversations===!1?{showAgentConversations:!1}:{}})).digest(`hex`)}const Om=F.object({name:Xl,connected:F.boolean()}),km=F.array(Om).max(32),Am=F.object({pid:F.number().int().positive().max(2**53-1),agentVersion:F.string().min(1),computerFp:U,stateDir:F.string().min(1).refine(M,`state directory must be absolute`),serviceInstance:F.uuid().nullable()}),jm={controlVersion:F.literal(1),process:Am,backends:km,terminalReady:F.boolean()};function Mm(e,t){(e.backends.length<mm.length||mm.some((t,n)=>e.backends[n]?.name!==t)||new Set(e.backends.map(e=>e.name)).size!==e.backends.length||e.backends.slice(mm.length).some((e,t,n)=>t>0&&e.name<n[t-1].name))&&t.addIssue({code:`custom`,path:[`backends`],message:`backend status must contain each known backend in protocol order`}),e.terminalReady!==e.backends.some(e=>e.connected)&&t.addIssue({code:`custom`,path:[`terminalReady`],message:`terminal readiness must match backend connectivity`})}const Nm=F.string().min(1).max(64),Pm=F.object({route:F.enum([`relay`,`direct`]).nullable(),ready:F.boolean(),phase:F.string().max(32),lastFailure:F.string().max(32).nullable(),relaySent:F.number().int().nonnegative(),relayReceived:F.number().int().nonnegative(),directSent:F.number().int().nonnegative(),directReceived:F.number().int().nonnegative()}),Fm=F.object({...jm,relayOnline:F.boolean(),sessions:F.number().int().nonnegative().max(2**53-1),phones:F.array(F.object({phoneFp:U,name:Nm,lastSeenAt:F.string().nullable()})).max(10),connected:F.array(F.object({phoneFp:U,name:Nm,viewed:F.string().nullable(),transport:Pm.optional()})).max(10)}).superRefine(Mm);function Im(e,t=process.env){if(!e)return null;let n=t.SHELLBELL_SERVICE_INSTANCE;if(n===void 0)return null;if(!F.uuid().safeParse(n).success)throw Error(`SHELLBELL_SERVICE_INSTANCE must be a valid UUID`);return n}function Lm(e){try{return t.lstatSync(e)}catch(e){if(e.code===`ENOENT`)return;throw e}}function Rm(e,t){return e?.dev===t.dev&&e.ino===t.ino}function zm(e){let t=process.platform===`darwin`?103:process.platform===`linux`?107:null;if(t===null)throw Error(`Unsupported control socket platform: ${process.platform}`);if(Buffer.byteLength(e)>t)throw Error(`Control socket path is too long (maximum ${t} bytes): ${e}`)}async function Bm(e){return new Promise((t,n)=>{let r=le(e),i=setTimeout(()=>a(Error(`Control socket probe timed out: ${e}`)),1e3),a=(e,a=!1)=>{clearTimeout(i),r.destroy(),e?n(e):t(a)};r.once(`connect`,()=>a(void 0,!0)),r.once(`error`,e=>{e.code===`ENOENT`||e.code===`ECONNREFUSED`?a():a(e)})})}var Vm=class{sockPath;onConnection;log;pidPath;admit;server;clients=new Set;ownedSocket;ownedPid;lifecycle=Promise.resolve();constructor(e,t,n,r,i){this.sockPath=e,this.onConnection=t,this.log=n,this.pidPath=r,this.admit=i}serialize(e){let t=this.lifecycle.then(e);return this.lifecycle=t.catch(()=>{}),t}start(){return this.serialize(async()=>{if(this.server)return;if(this.ownedSocket||this.ownedPid)throw Error(`Control endpoint cleanup pending; stop it before restarting`);zm(this.sockPath),zm(N(j(this.sockPath),`.s12345678`));let e=Yf(this.sockPath);try{this.admit?.(),this.checkPid();let e=Lm(this.sockPath);if(e){if(!e.isSocket())throw Error(`Control socket path is not a socket: ${this.sockPath}`);if(await Bm(this.sockPath))throw Error(`Control endpoint already running: ${this.sockPath}`);if(!Rm(Lm(this.sockPath),e))throw Error(`Control socket changed during startup; retry`);t.unlinkSync(this.sockPath);for(let n of t.readdirSync(j(this.sockPath))){if(!/^\.s[A-Za-z0-9_-]{8}$/.test(n))continue;let r=N(j(this.sockPath),n);Rm(Lm(r),e)&&t.unlinkSync(r)}}let n=await this.bind();t.chmodSync(n,384);let r=t.lstatSync(n);if(t.linkSync(n,this.sockPath),this.ownedSocket=r,this.pidPath){this.checkPid();let e=String(process.pid);Op(this.pidPath,e),this.ownedPid={identity:t.lstatSync(this.pidPath),contents:e}}this.admit?.()}catch(e){try{this.removeOwned()}finally{await this.closeListener()}throw e}finally{e()}})}checkPid(){if(!this.pidPath)return;let e=Lm(this.pidPath);if(!e)return;if(!e.isFile())throw Error(`PID path must be a regular file: ${this.pidPath}`);let n=Gf(t.readFileSync(this.pidPath,`utf8`).trim());if(n===null)throw Error(`Invalid PID file; inspect ${this.pidPath} before retrying`);if(Kf(n))throw Error(`shellbell is already running (pid ${n})`)}async bind(){for(let e=0;e<8;e++){let e=N(j(this.sockPath),`.s${se(6).toString(`base64url`)}`),t=ue(e=>{this.clients.add(e),e.once(`close`,()=>this.clients.delete(e)),e.on(`error`,()=>{}),this.onConnection(e)});this.server=t;try{return await new Promise((n,r)=>{t.once(`error`,r);let i=process.umask(127);try{t.listen(e,()=>{t.removeListener(`error`,r),n()})}finally{process.umask(i)}}),e}catch(e){if(await this.closeListener(),e.code!==`EADDRINUSE`)throw e}}throw Error(`Control endpoint private socket names are in use after eight attempts`)}removeOwned(){if(this.ownedSocket&&=(Rm(Lm(this.sockPath),this.ownedSocket)&&t.unlinkSync(this.sockPath),void 0),this.pidPath&&this.ownedPid){let e=Lm(this.pidPath);e?.isFile()&&Rm(e,this.ownedPid.identity)&&t.readFileSync(this.pidPath,`utf8`)===this.ownedPid.contents&&t.unlinkSync(this.pidPath),this.ownedPid=void 0}}async closeListener(){for(let e of this.clients)e.destroy();this.clients.clear();let e=this.server;this.server=void 0,e&&await new Promise((t,n)=>e.close(e=>{e&&e.code!==`ERR_SERVER_NOT_RUNNING`?n(e):t()}))}stop(){return this.serialize(async()=>{let e;try{(this.ownedSocket||this.ownedPid)&&(e=Yf(this.sockPath),this.removeOwned())}catch(e){throw this.log.warn(`Control endpoint cleanup failed; shared paths retained for retry`,{error:Zp(e)}),e}finally{try{await this.closeListener()}finally{e?.()}}})}};const Hm={lineBytes:65536,queuedBytes:262144,connections:16,initialRequestMs:5e3,requestMs:5e3,challengeMs:6e4};function Um(e){let t;try{t=JSON.stringify(e)}catch{return null}if(t===void 0)return null;let n=new TextEncoder().encode(`${t}\n`);return n.byteLength-1<=Hm.lineBytes?n:null}function Wm(e,t){let n=e.writableLength;if(e.destroyed||!Number.isFinite(n)||n<0||n+t.byteLength>Hm.queuedBytes)return e.destroy(),!1;try{return e.write(t),!0}catch{return e.destroy(),!1}}var Gm=class{onLine;onError;maxBytes;chunks=[];bytes=0;terminal=!1;constructor(e){this.onLine=e.onLine,this.onError=e.onError;let t=e.maxBytes??Hm.lineBytes;this.maxBytes=Number.isFinite(t)?Math.max(0,Math.min(t,Hm.lineBytes)):Hm.lineBytes}push(e){if(this.terminal||e.byteLength===0)return;let t=0;for(;t<e.byteLength&&!this.terminal;){let n=e.indexOf(10,t),r=n===-1?e.byteLength:n,i=r-t;if(this.bytes+i>this.maxBytes){this.fail(`line-too-large`);return}if(i>0&&(this.chunks.push(Uint8Array.from(e.subarray(t,r))),this.bytes+=i),n===-1)return;let a=this.decodeLine();if(a===null)return;this.reset(),this.onLine(a),t=n+1}}finish(){this.terminal||(this.bytes>0?this.fail(`incomplete-line`):(this.terminal=!0,this.reset()))}decodeLine(){let e=new Uint8Array(this.bytes),t=0;for(let n of this.chunks)e.set(n,t),t+=n.byteLength;try{return new TextDecoder(`utf-8`,{fatal:!0,ignoreBOM:!0}).decode(e)}catch{return this.fail(`invalid-utf8`),null}}fail(e){this.terminal||(this.terminal=!0,this.reset(),this.onError(e))}reset(){this.chunks=[],this.bytes=0}};const Km=F.number().int().positive().max(2**53-1),qm=F.string().regex(/^[A-Za-z0-9_-]{22}$/),Jm=F.string().min(1).max(64),Ym=F.object({pid:Km,agentVersion:F.string().min(1),computerFp:U,stateDir:F.string().min(1).refine(M,`state directory must be absolute`),serviceInstance:F.uuid().nullable()}).strict(),Xm=F.object({name:Xl,connected:F.boolean()}).strict(),Zm=F.object({phoneFp:U,name:Jm,lastSeenAt:F.string().nullable()}).strict(),Qm=F.object({phoneFp:U,name:Jm,viewed:F.string().nullable(),transport:Pm.strict().optional()}).strict(),$m=F.object({controlVersion:F.literal(1),process:Ym,backends:F.array(Xm),terminalReady:F.boolean(),relayOnline:F.boolean(),sessions:F.number().int().nonnegative().max(2**53-1),phones:F.array(Zm).max(10),connected:F.array(Qm).max(10)}).strict().superRefine((e,t)=>{Fm.safeParse(e).success||t.addIssue({code:`custom`,message:`status must satisfy LocalStatus semantics`})}),eh=F.object({}).strict(),th=F.object({version:F.literal(2),runtime:Ym,capabilities:F.tuple([F.literal(`status`),F.literal(`devices`),F.literal(`pairing`),F.literal(`revoke`)])}).strict(),nh=F.array(Zm).max(10),rh=F.object({removed:F.boolean()}).strict(),ih=F.object({flowId:qm,qrText:F.string().min(1).refine(e=>new TextEncoder().encode(e).byteLength<=Hm.lineBytes),expiresAt:Km}).strict(),ah={hello:th,status:$m,"status.config":F.object({revision:F.string().regex(/^[0-9a-f]{64}$/)}).strict(),"settings.conversations.apply":F.object({revision:F.string().regex(/^[0-9a-f]{64}$/)}).strict(),devices:nh,"devices.revoke":rh,"pairing.open":ih,"pairing.close":eh,"pairing.confirm":eh,terminals:F.object({terminals:mu}).strict(),"terminals.connect":F.object({started:F.boolean(),terminals:mu}).strict()},oh={v:F.literal(2),id:Km},sh={...oh,expect:Ym},ch=F.discriminatedUnion(`cmd`,[F.object({...sh,cmd:F.literal(`settings.conversations.apply`),args:F.object({revision:F.string().regex(/^[0-9a-f]{64}$/)}).strict()}).strict(),F.object({...oh,cmd:F.literal(`hello`)}).strict(),F.object({...oh,cmd:F.literal(`status`)}).strict(),F.object({...oh,cmd:F.literal(`status.config`)}).strict(),F.object({...oh,cmd:F.literal(`devices`)}).strict(),F.object({...oh,cmd:F.literal(`terminals`)}).strict(),F.object({...sh,cmd:F.literal(`terminals.connect`),args:F.object({name:Xl}).strict()}).strict(),F.object({...sh,cmd:F.literal(`devices.revoke`),args:F.object({phoneFp:U}).strict()}).strict(),F.object({...sh,cmd:F.literal(`pairing.open`)}).strict(),F.object({...sh,cmd:F.literal(`pairing.close`),args:F.object({flowId:qm}).strict()}).strict(),F.object({...sh,cmd:F.literal(`pairing.confirm`),args:F.object({flowId:qm,challengeId:qm,phoneFp:U,accept:F.boolean()}).strict()}).strict()]),lh=F.enum([`bad-request`,`unsupported-version`,`handshake-required`,`runtime-mismatch`,`configuration-mismatch`,`pairing-busy`,`stale-flow`,`stale-challenge`,`response-too-large`,`operation-failed`]),uh=F.object({v:F.literal(2),id:Km,ok:F.literal(!0),data:F.unknown()}).strict().refine(e=>Object.hasOwn(e,`data`)),dh=F.object({v:F.literal(2),id:Km,ok:F.literal(!1),error:F.object({code:lh}).strict()}).strict(),fh=F.union([uh,dh]),ph=F.object({v:F.literal(2),event:F.literal(`pairing.request`),flowId:qm,challengeId:qm,phoneFp:U,name:Jm}).strict(),mh=F.object({v:F.literal(2),event:F.literal(`pairing.closed`),flowId:qm}).strict(),hh=F.discriminatedUnion(`event`,[ph,mh]),gh=[`status`,`devices`,`pairing`,`revoke`];function _h(e,t){return e.pid===t.pid&&e.agentVersion===t.agentVersion&&e.computerFp===t.computerFp&&e.stateDir===t.stateDir&&e.serviceInstance===t.serviceInstance}function vh(e){if(!e||typeof e!=`object`)return;let t=e.id;return typeof t==`number`&&Number.isSafeInteger(t)&&t>0?t:void 0}var yh=class{agent;log;peers=new Set;owner;stopped=!1;newId;constructor(e,t,n){this.agent=e,this.log=t,this.newId=n?.newId??(()=>se(16).toString(`base64url`))}get hasPairOwner(){return this.owner!==void 0}accept(e){let t=new bh(this,e,this.agent);return this.stopped?t.close():this.peers.add(t),t}confirm(e,t){let n=this.owner;if(!n||n.resolve||this.stopped)return Promise.resolve(!1);let r=this.newId();return new Promise(i=>{if(this.owner!==n)return i(!1);n.resolve=i,n.challengeId=r,n.phoneFp=e,n.name=t,n.opening||this.emitRequest(n,t)})}activate(e,t){let n=this.owner;n&&n.peer===e&&n.flowId===t&&(n.opening=!1,n.resolve&&n.phoneFp&&n.challengeId&&this.emitRequest(n,n.name??``))}emitRequest(e,t){if(!e.resolve||!e.challengeId||!e.phoneFp)return;let n=e.resolve,r=Math.max(0,(e.expiresAt??Date.now())-Date.now());e.timer=setTimeout(()=>{this.owner===e&&e.resolve===n&&(e.resolve=void 0,e.challengeId=void 0,e.phoneFp=void 0,n(!1))},Math.min(Hm.challengeMs,r)),e.timer.unref(),e.peer.event({v:2,event:`pairing.request`,flowId:e.flowId,challengeId:e.challengeId,phoneFp:e.phoneFp,name:t})||this.clearOwner(e,!1,!0)}notifyClosed(){let e=this.owner;e&&(this.clearOwner(e,!1,!1),e.peer.event({v:2,event:`pairing.closed`,flowId:e.flowId}))}stop(){this.stopped=!0;let e=this.owner;e&&this.clearOwner(e,!0,!1);for(let e of this.peers)e.close();this.peers.clear()}removed(e){this.peers.delete(e);let t=this.owner;t?.peer===e&&this.clearOwner(t,!0,!1)}open(e){if(this.owner||this.agent.pairingOpen)return`pairing-busy`;try{let t=this.newId(),n={peer:e,flowId:t,opening:!0};this.owner=n;let r=this.agent.openPairing();return this.owner!==n||!this.agent.pairingOpen?(this.clearOwner(n,!0,!1),`operation-failed`):(n.expiresAt=r.expiresAt,{flowId:t,...r})}catch{let t=this.owner;return t?.peer===e&&this.clearOwner(t,!0,!1),`operation-failed`}}close(e,t){let n=this.owner;if(!n||n.peer!==e||n.flowId!==t)return`stale-flow`;this.clearOwner(n,!0,!1)}answer(e,t){let n=this.owner;if(!n||n.peer!==e||n.flowId!==t.args.flowId)return`stale-flow`;if(n.expiresAt===void 0||Date.now()>=n.expiresAt)return this.clearOwner(n,!0,!0),`stale-flow`;if(!n.resolve||n.challengeId!==t.args.challengeId||n.phoneFp!==t.args.phoneFp)return`stale-challenge`;let r=n.resolve;n.timer&&clearTimeout(n.timer),n.timer=void 0,n.resolve=void 0,n.challengeId=void 0,n.phoneFp=void 0,n.name=void 0,r(t.args.accept)}clearOwner(e,t,n){if(this.owner!==e)return;this.owner=void 0;let r=e.resolve;if(e.timer&&clearTimeout(e.timer),e.timer=void 0,e.resolve=void 0,e.challengeId=void 0,e.phoneFp=void 0,e.name=void 0,r?.(!1),t)try{this.agent.closePairing()}catch{this.log.warn(`native pairing close failed`)}n&&e.peer.event({v:2,event:`pairing.closed`,flowId:e.flowId})}},bh=class{hub;socket;agent;helloRuntime;lastId=0;closed=!1;constructor(e,t,n){this.hub=e,this.socket=t,this.agent=n}get handshaken(){return this.helloRuntime!==void 0}close(){this.closed||(this.closed=!0,this.hub.removed(this),this.socket.destroy())}handle(e){if(this.closed||this.socket.destroyed)return;let t=vh(e);if(this.handshaken&&t!==void 0){if(t<=this.lastId){this.close();return}this.lastId=t}if(e&&typeof e==`object`&&e.v!==2){t!==void 0&&this.failure(t,`unsupported-version`),this.close();return}let n=ch.safeParse(e);if(!n.success){t===void 0?this.close():this.failure(t,`bad-request`);return}let r=n.data;if(!this.handshaken){if(r.id!==1||r.cmd!==`hello`){this.close();return}this.lastId=1,this.helloRuntime={...this.runtime()},this.success(r,{version:2,runtime:this.helloRuntime,capabilities:gh});return}if(r.cmd===`hello`){this.close();return}let i=this.helloRuntime,a=this.runtime();if(`expect`in r&&(!i||!_h(r.expect,i)||!_h(r.expect,a))){this.failure(r.id,`runtime-mismatch`);return}switch(r.cmd){case`status`:this.success(r,this.status());return;case`status.config`:this.success(r,{revision:this.agent.configurationRevision});return;case`settings.conversations.apply`:try{let e=this.agent.applyConversationSetting(r.args.revision);e===null?this.failure(r.id,`configuration-mismatch`):this.success(r,{revision:e})}catch{this.failure(r.id,`operation-failed`)}return;case`devices`:this.success(r,this.devices());return;case`devices.revoke`:try{this.success(r,{removed:this.agent.unpairExact(r.args.phoneFp)})}catch{this.failure(r.id,`operation-failed`)}return;case`terminals`:this.success(r,{terminals:this.agent.terminalSetup()});return;case`terminals.connect`:{let e=this.agent.connectTerminal(r.args.name);this.success(r,{started:e,terminals:this.agent.terminalSetup()});return}case`pairing.open`:{let e=this.hub.open(this);typeof e==`string`?this.failure(r.id,e):this.success(r,e)?this.hub.activate(this,e.flowId):this.hub.close(this,e.flowId);return}case`pairing.close`:{let e=this.hub.close(this,r.args.flowId);e?this.failure(r.id,e):this.success(r,{})&&this.event({v:2,event:`pairing.closed`,flowId:r.args.flowId});return}case`pairing.confirm`:{let e=this.hub.answer(this,r);e?this.failure(r.id,e):this.success(r,{});return}}}event(e){return hh.safeParse(e).success?this.write(e):!1}runtime(){return this.agent.localStatus.process}status(){let e=this.agent;return{...e.localStatus,relayOnline:e.relayOnline,sessions:e.sessionList.length,phones:this.devices(),connected:e.connectedPhones}}devices(){return this.agent.pairingList.map(e=>({phoneFp:e.phoneFp,name:e.name,lastSeenAt:e.lastSeenAt}))}success(e,t){if(!ah[e.cmd].safeParse(t).success)return this.failure(e.id,`operation-failed`),!1;let n={v:2,id:e.id,ok:!0,data:t};if(!fh.safeParse(n).success)return this.failure(e.id,`operation-failed`),!1;let r=Um(n);return r?this.writeFrame(r):(this.failure(e.id,`response-too-large`),!1)}failure(e,t){let n={v:2,id:e,ok:!1,error:{code:t}};return fh.safeParse(n).success?this.write(n):!1}write(e){let t=Um(e);return t?this.writeFrame(t):!1}writeFrame(e){return Wm(this.socket,e)?!0:(this.close(),!1)}};const xh={unavailable:`Local control unavailable`,"upgrade-required":`Local control upgrade required`,"protocol-error":`Local control protocol error`,timeout:`Local control timed out`,"delivery-unknown":`Local control mutation outcome unknown`,busy:`Local control request already pending`,closed:`Local control closed`,"server-error":`Local control server rejected request`},Sh=new Set([`hello`,`status`,`status.config`,`devices`,`terminals`]);var Q=class extends Error{code;serverCode;constructor(e,t){super(xh[e]),this.code=e,this.serverCode=t,this.name=`ControlV2ClientError`}};function Ch(e,t={}){return new Promise((n,r)=>{let i;try{i=(t.connector??le)(e)}catch{r(new Q(`unavailable`));return}let a=!1,o=!1,s=!1,c=0,l,u,d,f=setTimeout(()=>p(new Q(`timeout`)),Hm.requestMs);function p(e){if(a)return;a=!0,clearTimeout(f);let n=l;l=void 0,d=void 0,n&&(clearTimeout(n.timer),n.reject(n.mutation&&n.attempted?new Q(`delivery-unknown`):e)),o||r(e),i.destroy(),t.onDisconnect?.(e)}function m(e,t){if(a)return Promise.reject(new Q(`closed`));if(l)return Promise.reject(new Q(`busy`));if(c===2**53-1)return p(new Q(`protocol-error`)),Promise.reject(new Q(`protocol-error`));let n=!Sh.has(e),r=ch.safeParse({v:2,id:c+1,cmd:e,...n?{expect:u}:{},...t===void 0?{}:{args:t}});if(!r.success)return Promise.reject(new Q(`protocol-error`));let o=Um(r.data);if(o===null)return Promise.reject(new Q(`protocol-error`));let s=i.writableLength;return i.destroyed||!Number.isFinite(s)||s<0||s+o.byteLength>Hm.queuedBytes?(p(new Q(`unavailable`)),Promise.reject(new Q(`unavailable`))):(c++,new Promise((t,r)=>{let a={id:c,command:e,mutation:n,attempted:!1,resolve:e=>t(e),reject:r,timer:setTimeout(()=>p(new Q(`timeout`)),Hm.requestMs)};l=a,a.attempted=!0,Wm(i,o)||p(new Q(`unavailable`))}))}let h=new Gm({onError:()=>p(new Q(`protocol-error`)),onLine:e=>{if(a)return;let n;try{n=JSON.parse(e)}catch{p(new Q(`protocol-error`));return}if(typeof n==`object`&&n&&`event`in n){let e=hh.safeParse(n);if(!e.success){p(new Q(`protocol-error`));return}let r=e.data;if(r.event===`pairing.closed`&&r.flowId!==d)return;if(r.flowId!==d){p(new Q(`protocol-error`));return}r.event===`pairing.closed`?(d=void 0,t.onPairingClosed?.(r)):t.onPairingRequest?.(r);return}let r=l;if(r?.command===`hello`&&typeof n==`object`&&n&&!(`v`in n)&&`ok`in n&&typeof n.ok==`boolean`){p(new Q(`upgrade-required`));return}let i=fh.safeParse(n);if(!i.success||!r||i.data.id!==r.id){p(new Q(`protocol-error`));return}if(!i.data.ok){clearTimeout(r.timer),l=void 0;let e=new Q(`server-error`,i.data.error.code);r.reject(e),r.command===`hello`&&p(e);return}let o=ah[r.command].safeParse(i.data.data);if(!o.success){p(new Q(`protocol-error`));return}r.command===`pairing.open`&&(d=o.data.flowId),clearTimeout(r.timer),l=void 0,r.resolve(o.data)}});i.on(`data`,e=>h.push(e)),i.on(`error`,()=>p(new Q(`unavailable`)));let g=()=>{h.finish(),p(new Q(`unavailable`))};i.once(`end`,g),i.once(`close`,g);let _=()=>{a||s||(s=!0,clearTimeout(f),m(`hello`).then(e=>{a||(u={...e.runtime},o=!0,n({runtime:{...e.runtime},status:()=>m(`status`),applyConversationSetting:async e=>{try{return(await m(`settings.conversations.apply`,{revision:e})).revision}catch(e){if(e instanceof Q&&e.code===`server-error`&&e.serverCode===`bad-request`)return null;throw e}},configurationRevision:async()=>{try{return(await m(`status.config`)).revision}catch(e){if(e instanceof Q&&e.code===`server-error`&&e.serverCode===`bad-request`)return null;throw e}},devices:()=>m(`devices`),terminals:async()=>{try{return(await m(`terminals`)).terminals}catch(e){if(wh(e))return null;throw e}},connectTerminal:async e=>{try{return await m(`terminals.connect`,{name:e})}catch(e){if(wh(e))return null;throw e}},revoke:e=>m(`devices.revoke`,{phoneFp:e}),openPairing:()=>m(`pairing.open`),closePairing:async e=>{await m(`pairing.close`,{flowId:e})},confirm:async(e,t,n,r)=>{await m(`pairing.confirm`,{flowId:e,challengeId:t,phoneFp:n,accept:r})},close:()=>p(new Q(`closed`))}))},e=>p(e)))};i.once(`connect`,_),i.connecting||_()})}function wh(e){return e instanceof Q&&e.code===`server-error`&&e.serverCode===`bad-request`}var Th=class{agent;log;admission;pairingMode;endpoint;pending=new Map;pairClients=new Set;controlSockets=new Set;v2;pairingConfirm=(e,t)=>new Promise(n=>{if(this.pending.has(e)){this.log.warn(`pairing confirm requested twice for the same phone; declining the newer one`,{phone:e.slice(0,8)}),n(!1);return}let r=setTimeout(()=>{this.pending.delete(e),n(!1)},6e4);this.pending.set(e,t=>{clearTimeout(r),this.pending.delete(e),n(t)});for(let n of this.pairClients)this.writeLegacy(n,{event:`request`,phoneFp:e,name:t})||this.pairClients.delete(n)});constructor(e,t,n,r,i,a,o=`terminal`){this.agent=t,this.log=n,this.admission=a,this.pairingMode=o,this.endpoint=new Vm(e,e=>this.handle(e),n,r,i),this.v2=new yh(t,n)}get hasPairClients(){return this.pairClients.size>0}get hasNativePairOwner(){return this.v2.hasPairOwner}nativePairingConfirm=(e,t)=>this.v2.confirm(e,t);notifyClosed(e=`closed`){for(let e of this.pending.values())e(!1);this.pending.clear();for(let t of this.pairClients)this.writeLegacy(t,{event:`closed`,reason:e})||this.pairClients.delete(t);this.pairClients.clear(),this.v2.notifyClosed()}async start(){this.admission?await this.admission(()=>this.endpoint.start()):await this.endpoint.start()}async stop(){for(let e of this.pending.values())e(!1);for(let e of this.controlSockets)e.destroy();this.controlSockets.clear();for(let e of this.pairClients)e.destroy();this.pairClients.clear(),this.v2.stop(),await this.endpoint.stop()}handle(e){if(this.controlSockets.size>=Hm.connections){e.destroy();return}this.controlSockets.add(e);let t=!0,n,r,i=setTimeout(()=>e.destroy(),Hm.initialRequestMs),a=new Gm({onLine:a=>{if(e.destroyed)return;let o;try{o=JSON.parse(a)}catch{if(n===`v2`){e.destroy();return}this.writeLegacy(e,{ok:!1,error:`bad json`});return}if(n===`v2`){r?.handle(o),t&&r?.handshaken&&(t=!1,clearTimeout(i));return}if(n===void 0&&o&&typeof o==`object`&&Object.hasOwn(o,`v`)){n=`v2`,r=this.v2.accept(e),r.handle(o),r.handshaken&&(t=!1,clearTimeout(i));return}if(n===`legacy`&&o&&typeof o==`object`&&Object.hasOwn(o,`v`)){e.destroy();return}n=`legacy`;let s=o;if(!s||typeof s!=`object`||typeof s.cmd!=`string`){this.writeLegacy(e,{ok:!1,error:`bad request`});return}t&&(t=!1,clearTimeout(i));try{let t=this.dispatch(s,e);this.writeLegacy(e,{ok:!0,data:t})}catch(t){this.writeLegacy(e,{ok:!1,error:t.message})}},onError:()=>e.destroy()});e.on(`data`,e=>a.push(new Uint8Array(e))),e.once(`end`,()=>a.finish()),e.once(`close`,()=>{clearTimeout(i),this.controlSockets.delete(e),this.pairClients.delete(e),r?.close()}),e.on(`error`,()=>this.log.debug(`control socket error`))}writeLegacy(e,t){let n=Um(t);if(n&&Wm(e,n))return!0;let r=Um({ok:!1,error:`response too large`});return r!==null&&Wm(e,r)}dispatch(e,t){let n=this.agent;if(this.pairingMode===`native`&&[`pair-open`,`pair-close`,`confirm`].includes(e.cmd))throw Error(`pairing is managed by the Shellbell app`);if(this.v2.hasPairOwner&&[`pair-open`,`pair-close`,`confirm`].includes(e.cmd))throw Error(`native pairing active`);switch(e.cmd){case`status`:return{...n.localStatus,relayOnline:n.relayOnline,sessions:n.sessionList.length,phones:n.pairingList.map(e=>({phoneFp:e.phoneFp,name:e.name,lastSeenAt:e.lastSeenAt})),connected:n.connectedPhones};case`devices`:return n.pairingList.map(e=>({phoneFp:e.phoneFp,name:e.name,lastSeenAt:e.lastSeenAt}));case`unpair`:return{removed:n.unpair(String(e.args?.target??``))};case`pair-open`:{let e=n.openPairing();return this.pairClients.add(t),e}case`pair-close`:return n.closePairing(),{};case`confirm`:{let t=String(e.args?.phoneFp??``),n=this.pending.get(t);if(!n)throw Error(`no pending request`);return n(!!e.args?.accept),{}}default:throw Error(`unknown command: ${e.cmd}`)}}};function Eh(e,t,n,r){return new Promise((i,a)=>{let o=Um({cmd:t,args:n});if(!o){a(Error(`control socket request too large`));return}let s=!1,c=le(e),l=r?.timeoutMs??5e3,u=e=>{s||(s=!0,clearTimeout(d),c.destroy(),e())},d=setTimeout(()=>u(()=>a(Error(`control socket timed out`))),l),f=new Gm({maxBytes:r?.maxResponseBytes,onError:e=>u(()=>a(Error(e===`line-too-large`?`control socket response too large`:`control socket sent a malformed response`))),onLine:e=>{f.finish(),u(()=>{let t;try{if(t=JSON.parse(e),typeof t!=`object`||!t||typeof t.ok!=`boolean`)throw Error()}catch{a(Error(`control socket sent a malformed response`));return}t.ok?i(t.data):a(Error(t.error??`control error`))})}});c.on(`error`,e=>u(()=>a(e))),c.once(`connect`,()=>{Wm(c,o)||u(()=>a(Error(`control socket write failed`)))}),c.once(`close`,()=>u(()=>a(Error(`control socket closed without a response`)))),c.once(`end`,()=>u(()=>a(Error(`control socket closed without a response`)))),c.on(`data`,e=>{s||f.push(new Uint8Array(e))}),c.once(`end`,()=>f.finish())})}function Dh(e,t){let n=le(e),r=!1,i,a=()=>{r||(r=!0,i?.finish(),n.end())};n.on(`error`,t.onError);let o=Um({cmd:`pair-open`});return n.once(`connect`,()=>{(o===null||!Wm(n,o))&&t.onError(Error(`control socket write failed`))}),i=new Gm({onError:()=>{n.destroy(),t.onError(Error(`control socket sent a malformed message`))},onLine:e=>{if(r)return;let i;try{i=JSON.parse(e)}catch{t.onError(Error(`control socket sent a malformed message`));return}i.event===`request`&&i.phoneFp?t.onRequest(i.phoneFp,i.name??``).then(e=>{if(r)return;let t=Um({cmd:`confirm`,args:{phoneFp:i.phoneFp,accept:e}});if(t===null||!Wm(n,t))throw Error(`control socket write failed`)}).catch(e=>t.onError(e)):i.event===`closed`?t.onClose(i.reason===`replaced`?`replaced`:`closed`):i.ok&&i.data?.qrText?t.onOpen(i.data.qrText,i.data.expiresAt):i.ok===!1&&t.onError(Error(i.error??`control error`))}}),n.on(`data`,e=>i.push(new Uint8Array(e))),n.once(`end`,()=>{r=!0,i?.finish()}),n.once(`close`,()=>{r=!0,i?.finish()}),{close:a}}function Oh(e){if(e.linuxHost)return Sp(e);let t;try{t=g(e.identity,`utf8`)}catch(t){if(t.code===`ENOENT`)return null;throw Error(`shellbell: cannot read identity at ${e.identity}`)}try{let e=nc(JSON.parse(t));return{identity:e,fp:rc(e.ed25519.pub)}}catch{throw Error(`shellbell: invalid identity at ${e.identity}`)}}function kh(e){if(e.linuxHost)return Sp(e);Dp(e);let t;return s(e.identity)?t=Ah(e):(t=Qs(),Ap(e.identity,`${JSON.stringify(tc(t),null,2)}\n`)||(t=Ah(e))),{identity:t,fp:rc(t.ed25519.pub)}}function Ah(e){try{return nc(Np(e.identity))}catch(t){throw Error(`shellbell: invalid identity at ${e.identity}: ${t.message}`)}}const jh=[`dev.bilalahmad.shellbell`,`dev.bilalahmad.shellbell.host.agent`,`dev.bilalahmad.shellbell.host.manual`];async function Mh(e,t,n){if(!Number.isSafeInteger(t)||t<0)throw Error(`Invalid service UID`);let r=()=>Error(`Legacy Shellbell installation requires migration before starting the new service; preserve identity and remove old registrations explicitly.`);if(n)for(let e of jh){try{p(N(n,`Library`,`LaunchAgents`,`${e}.plist`))}catch(e){if(e.code===`ENOENT`)continue;throw e}throw r()}for(let n of[...jh.map(e=>`gui/${t}/${e}`),`system/dev.bilalahmad.shellbell.power`]){let t=await e(`/bin/launchctl`,[`print`,n],{timeoutMs:5e3,maxOutputBytes:65536,captureOutput:!1});if(t.exitCode===0)throw r();if(t.exitCode!==113)throw Error(`Could not verify legacy Shellbell registration absence`)}}const Nh=(t,n,r)=>new Promise((i,a)=>{let o=e(t,n,{shell:!1,stdio:[`pipe`,`pipe`,`pipe`]}),s=0,c=0,l=[],u=!1,d=e=>{u||(u=!0,clearTimeout(f),o.kill(),a(e))},f=setTimeout(()=>d(Error(`${t} timed out`)),r.timeoutMs);o.stdout.on(`data`,e=>{if(s+=e.length,s>r.maxOutputBytes)return d(Error(`${t} output limit exceeded`));r.captureOutput&&l.push(e)}),o.stderr.on(`data`,e=>{c+=e.length,c>r.maxOutputBytes&&d(Error(`${t} output limit exceeded`))}),o.on(`error`,d),o.on(`close`,(e,n)=>{if(!u){if(u=!0,clearTimeout(f),n||e===null)return a(Error(`${t} terminated by signal`));i({exitCode:e,stdout:r.captureOutput?Buffer.concat(l):Buffer.alloc(0)})}}),o.stdin.on(`error`,d),o.stdin.end(r.input)}),Ph=[`/opt/homebrew/bin`,`/usr/local/bin`,`/usr/bin`,`/bin`],Fh=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function Ih(e){for(let t of e){let e=t.codePointAt(0);if(!(e===9||e===10||e===13||e>=32&&e<=55295||e>=57344&&e<=65533||e>=65536&&e<=1114111))throw Error(`invalid XML character in service definition`)}}function Lh(e,t){if(!e||!M(e))throw Error(`${t} must be an absolute path`);return Ih(e),e}function Rh(e){if(Lh(e.stateDir,`stateDir`),Lh(e.nodePath,`nodePath`),!Fh.test(e.serviceInstance))throw Error(`serviceInstance must be a UUID`);let t=[j(e.nodePath),...e.env.PATH?.split(`:`)??[],...Ph].filter(e=>e.length>0&&M(e)),n={SHELLBELL_DIR:e.stateDir,SHELLBELL_SERVICE_INSTANCE:e.serviceInstance,PATH:[...new Set(t)].join(`:`)};for(let t of[`HERDR_SOCKET_PATH`,`XDG_CONFIG_HOME`]){let r=e.env[t];r&&(n[t]=Lh(r,t))}for(let e of Object.values(n))Ih(e);return n}const zh=`sh.bilal.shellbell`;N(E(),`Library`,`LaunchAgents`,`${zh}.plist`);const Bh=1048576,Vh=/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,Hh=new Set([`SHELLBELL_DIR`,`SHELLBELL_SERVICE_INSTANCE`,`PATH`,`HERDR_SOCKET_PATH`,`XDG_CONFIG_HOME`]),Uh=new Set([`Label`,`ProgramArguments`,`EnvironmentVariables`,`RunAtLoad`,`KeepAlive`,`StandardOutPath`,`StandardErrorPath`]);function Wh(e){return Ih(e),e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`).replace(/'/g,`&apos;`)}function Gh(e){let t=Wh,n=e.environment??{PATH:`/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin`},r=Object.entries(n).map(([e,n])=>`<key>${t(e)}</key><string>${t(n)}</string>`).join(``);return`<?xml version="1.0" encoding="UTF-8"?>
17
17
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
18
18
  <plist version="1.0"><dict>
19
19
  <key>Label</key><string>${zh}</string>
@@ -26,4 +26,4 @@ const Ds=BigInt(0),Os=BigInt(1),ks=BigInt(2),As=BigInt(3),js=BigInt(5),Ms=BigInt
26
26
  <key>StandardOutPath</key><string>${t(e.logPath)}</string>
27
27
  <key>StandardErrorPath</key><string>${t(e.logPath)}</string>
28
28
  </dict></plist>
29
- `}function Kh(e,t){if(typeof e!=`string`||!e||!M(e))throw Error(`invalid service definition: ${t} must be an absolute path`);return Wh(e),e}function qh(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`invalid service definition`);let n=e;for(let e of Object.keys(n))if(!Uh.has(e))throw Error(`unrecognized service definition key: ${e}`);if(n.Label!==`sh.bilal.shellbell`||!Array.isArray(n.ProgramArguments)||n.ProgramArguments.length!==4||n.ProgramArguments[2]!==`start`||n.ProgramArguments[3]!==`--service`||n.RunAtLoad!==!0||n.KeepAlive!==!0||n.StandardOutPath!==n.StandardErrorPath)throw Error(`unrecognized Shellbell service definition`);let r=n.EnvironmentVariables;if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`invalid service environment`);let i=r;for(let[e,t]of Object.entries(i)){if(!Hh.has(e))throw Error(`unrecognized service environment: ${e}`);if(typeof t!=`string`)throw Error(`invalid service environment: ${e}`);Wh(e),Wh(t),(e===`HERDR_SOCKET_PATH`||e===`XDG_CONFIG_HOME`)&&Kh(t,e)}if(typeof i.PATH!=`string`||!i.PATH||i.PATH.split(`:`).some(e=>!e||!M(e)))throw Error(`invalid service PATH`);let a=i.SHELLBELL_DIR===void 0?N(t,`.shellbell`):Kh(i.SHELLBELL_DIR,`SHELLBELL_DIR`),o=i.SHELLBELL_SERVICE_INSTANCE;if(o!==void 0&&(typeof o!=`string`||!Vh.test(o)))throw Error(`invalid service instance`);return{nodePath:Kh(n.ProgramArguments[0],`nodePath`),cliPath:Kh(n.ProgramArguments[1],`cliPath`),stateDir:a,serviceInstance:o??null,environment:i,logPath:Kh(n.StandardOutPath,`logPath`)}}function Jh(e){if(Kh(e.nodePath,`nodePath`),Kh(e.cliPath,`cliPath`),Kh(e.stateDir,`stateDir`),Kh(e.logPath,`logPath`),!e.serviceInstance||!Vh.test(e.serviceInstance))throw Error(`serviceInstance must be a UUID`);let t=e.environment;if(t.SHELLBELL_DIR!==e.stateDir||t.SHELLBELL_SERVICE_INSTANCE!==e.serviceInstance)throw Error(`service definition and environment disagree`);if(!t.PATH||t.PATH.split(`:`).some(e=>!e||!M(e)))throw Error(`invalid service PATH`);for(let[e,n]of Object.entries(t)){if(!Hh.has(e))throw Error(`unsupported service environment: ${e}`);if(typeof n!=`string`)throw Error(`invalid service environment: ${e}`);Wh(e),Wh(n),(e===`HERDR_SOCKET_PATH`||e===`XDG_CONFIG_HOME`)&&Kh(n,e)}}function Yh(e={}){let t=e.run??Nh,n=e.uid??k().uid;if(!Number.isSafeInteger(n)||n<0)throw Error(`invalid service UID`);let r=e.homeDir??E(),i=e.definitionPath??N(r,`Library`,`LaunchAgents`,`sh.bilal.shellbell.plist`),a=`gui/${n}`,o=`${a}/${zh}`,s;function c(e,t){return e===null||t===null?e===t:e.stat.dev===t.stat.dev&&e.stat.ino===t.stat.ino&&e.stat.uid===t.stat.uid&&e.stat.mode===t.stat.mode&&e.stat.size===t.stat.size&&e.stat.mtimeMs===t.stat.mtimeMs&&e.stat.ctimeMs===t.stat.ctimeMs&&e.raw.equals(t.raw)}function l(){let e;try{e=p(i)}catch(e){if(e.code===`ENOENT`)return null;throw e}return!e.isFile()||e.isSymbolicLink()||e.uid!==n||e.mode&18||e.size>Bh?{stat:e,raw:Buffer.alloc(0)}:{stat:e,raw:g(i)}}function u(e){if(!c(e,l()))throw Error(`service definition changed or was replaced during operation`)}function d(e){let t=l();if(!t?.raw.equals(e))throw Error(`service definition changed after publication`);s=t}async function f(e,n,r=!1,i){let a=await t(e,n,{input:i,timeoutMs:5e3,maxOutputBytes:e===`/usr/bin/plutil`?Bh:65536,captureOutput:r});if(!Number.isInteger(a.exitCode))throw Error(`${e} returned invalid exit status`);return a}async function h(e){let t=await f(`/usr/bin/plutil`,[`-convert`,`json`,`-o`,`-`,`-`],!0,e);if(t.exitCode!==0)throw Error(`plutil could not parse service definition`);let n;try{n=JSON.parse(t.stdout.toString(`utf8`))}catch{throw Error(`plutil returned invalid service definition JSON`)}return qh(n,r)}async function _(){let e;try{e=p(i)}catch(e){if(e.code===`ENOENT`)return null;throw e}if(!e.isFile()||e.isSymbolicLink()||e.uid!==n||e.mode&18||e.size>Bh)throw Error(`unsafe service definition metadata`);let t=g(i);if(t.length>Bh)throw Error(`service definition too large`);let r=await h(t),a={stat:e,raw:t};return u(a),{...a,definition:r}}async function v(){let e=await f(`/bin/launchctl`,[`print`,o]);if(e.exitCode===0)return!0;if(e.exitCode===113)return!1;throw Error(`launchctl print failed (${e.exitCode})`)}async function y(){try{let e=await f(`/bin/launchctl`,[`print-disabled`,a],!0),t=new TextDecoder(`utf-8`,{fatal:!0}).decode(e.stdout).trim().split(/\r?\n/).map(e=>e.trim());if(e.exitCode!==0||t.shift()!==`disabled services = {`||t.pop()!==`}`)return null;let n=t.filter(e=>e.includes(`"${zh}"`));return n.length===0?!0:n.length===1?n[0]===`"sh.bilal.shellbell" => disabled`||n[0]===`"sh.bilal.shellbell" => true`?!1:n[0]===`"sh.bilal.shellbell" => enabled`||n[0]===`"sh.bilal.shellbell" => false`||null:null}catch{return null}}let b={kind:`launchd`,definitionPath:i,async inspect(){let e=await _(),t=await v();if(u(e),!e&&t)throw Error(`loaded Shellbell job has no valid installed definition`);if(s!==void 0&&!c(s,e))throw Error(`service definition changed or was replaced after inspection`);return s===void 0&&(s=e),{installed:!!e,startupEnabled:e?await y():!1,loaded:t,raw:e?.raw??null,definition:e?.definition??null}},async setStartupEnabled(e){let t=await b.inspect();if(!t.installed)throw Error(`service is not installed`);if(t.startupEnabled!==e){if((await f(`/bin/launchctl`,[e?`enable`:`disable`,o])).exitCode!==0)throw Error(`launchctl startup preference change failed`);if((await b.inspect()).startupEnabled!==e)throw Error(`launchctl startup preference could not be verified`)}},async write(e){await Mh(t,n,r),Jh(e);let a=await _();if(s!==void 0&&!c(s,a))throw Error(`service definition changed or was replaced after inspection`);if(!a&&await v())throw Error(`loaded Shellbell job has no installed definition`);let o=Gh({...e});m(j(i),{recursive:!0,mode:448}),Op(i,o,()=>u(a)),d(Buffer.from(o))},async restore(e){if(e!==null&&e.length>Bh)throw Error(`service definition too large`);let a=await _();if(s!==void 0&&!c(s,a))throw Error(`service definition changed or was replaced after inspection`);if(e===null){if(!a)return;if(s===void 0)throw Error(`refusing to remove unexpected service definition replacement`);u(a),C(i),s=null;return}if(s===void 0)throw Error(`service definition changed unexpectedly`);if(await h(e),a)Op(i,e,()=>u(a));else if(await Mh(t,n,r),m(j(i),{recursive:!0,mode:448}),!Ap(i,e))throw Error(`service definition changed or was replaced after inspection`);d(e)},async load(){await Mh(t,n,r);let e=await b.inspect();if(!e.installed)throw Error(`service definition is not installed`);if(e.startupEnabled===null)throw Error(`service startup preference is unresolved`);let s=e.startupEnabled===!1;try{if(s&&await b.setStartupEnabled(!0),!e.loaded){let e=await f(`/bin/launchctl`,[`bootstrap`,a,i]);if(e.exitCode!==0)throw Error(`launchctl bootstrap failed (${e.exitCode})`)}let t=await f(`/bin/launchctl`,[`kickstart`,`-p`,o],!0);if(t.exitCode!==0)throw Error(`launchctl kickstart failed (${t.exitCode})`);let n=t.stdout.toString(`utf8`).trim();if(!/^[1-9][0-9]*$/.test(n))throw Error(`invalid launchctl PID output`);let r=Number(n);if(!Number.isSafeInteger(r)||r>2147483647)throw Error(`invalid launchctl PID output`);return r}finally{s&&await b.setStartupEnabled(!1)}},async unload(){if(!(await b.inspect()).loaded)return;let e=await f(`/bin/launchctl`,[`bootout`,o]);if(e.exitCode!==0)throw Error(`launchctl bootout failed (${e.exitCode})`);if(await v())throw Error(`launchctl bootout did not unload service`)}};return b}function Xh(e){s(e)?i(e,384):w(e,``,{mode:384})}const Zh=F.string().refine(e=>Buffer.byteLength(e,`utf8`)<=4096&&M(e)&&![...e].some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)),Qh=F.enum([`desktop`,`headless`]),$h=F.enum([`prepared`,`source-stopped`,`destination-started`,`recovery-required`]),eg=F.enum([`manual`,`persistent`,`desktop`]),tg=F.strictObject({id:F.uuid(),source:F.enum([`desktop`,`headless`,`legacy-native`]).nullable(),target:Qh,sourceManager:F.enum([`desktop-child`,`native-manual`,`native-persistent`,`launchd`,`systemd`]).nullable(),sourceInstance:F.uuid().nullable(),stateDir:Zh,computerFp:U,targetBundlePath:Zh.nullable(),targetVersion:F.string().min(1).max(256),phase:$h}),ng=F.strictObject({v:F.literal(1),revision:F.uuid(),mode:Qh,consented:F.boolean(),startupEnabled:F.boolean(),transition:tg.nullable()}),rg=2097152,ig=F.number().int().positive().max(2**53-1),ag=F.uuid(),og=F.string().regex(/^[0-9a-f]{64}$/),sg=F.string().refine(e=>Buffer.byteLength(e,`utf8`)<=4096),cg=F.enum([`manual`,`persistent`]);function lg(e){if(e===`desktop`)throw new Ag(`conflict`);return e}const ug=F.enum([`prepared`,`source-stop-requested`,`source-stopped`,`destination-start-requested`,`awaiting-approval`,`destination-ready`,`recovery-required`]),dg=F.strictObject({PATH:sg.refine(e=>e.split(`:`).every(e=>Zh.safeParse(e).success)),SHELLBELL_DIR:Zh,SHELLBELL_SERVICE_INSTANCE:F.uuid(),HERDR_SOCKET_PATH:Zh.optional(),XDG_CONFIG_HOME:Zh.optional()}),fg=F.strictObject({mode:eg,stateDir:Zh,computerFp:U,serviceInstance:F.uuid(),bundlePath:Zh,bundleId:F.literal(`sh.bilal.shellbell.host`),agentVersion:F.string().min(1),environment:dg}).refine(e=>e.environment.SHELLBELL_DIR===e.stateDir&&e.environment.SHELLBELL_SERVICE_INSTANCE===e.serviceInstance),pg=F.strictObject({id:F.uuid(),definitionPath:Zh,rawBase64:F.string().max(1398104).refine(e=>/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)&&Buffer.from(e,`base64`).byteLength<=1048576&&Buffer.from(e,`base64`).toString(`base64`)===e),sha256:og,wasLoaded:F.boolean(),stateDir:Zh,computerFp:U}),mg=F.strictObject({id:F.uuid(),action:F.enum([`start`,`stop`,`restart`,`remove`,`recover`]),phase:ug}),hg=mg.extend({source:fg.nullable(),destination:fg.nullable(),recoveryId:F.uuid().nullable(),restoreLegacy:F.strictObject({restartPrevious:F.boolean()}).optional()}).refine(e=>e.restoreLegacy===void 0||e.action===`recover`),gg=F.strictObject({v:F.literal(1),revision:ag,selection:fg.nullable(),transition:hg.nullable(),recovery:pg.nullable()}).refine(e=>e.transition?.recoveryId==null||e.transition.recoveryId===e.recovery?.id),_g=F.strictObject({registration:F.enum([`not-registered`,`enabled`,`requires-approval`,`not-found`,`unknown`]),loaded:F.boolean(),pid:ig.nullable(),bundlePath:Zh.nullable()}),vg=F.discriminatedUnion(`ok`,[F.strictObject({v:F.literal(1),ok:F.literal(!0),status:F.enum([`not-registered`,`enabled`,`requires-approval`,`not-found`])}),F.strictObject({v:F.literal(1),ok:F.literal(!1),error:F.strictObject({code:F.enum([`unavailable`,`denied`,`invalid-bundle`,`operation-failed`])})})]),yg=F.strictObject({revision:ag.nullable(),runtime:Ym.extend({stateDir:Zh}).nullable()}),bg=F.strictObject({revision:ag.nullable(),mode:F.enum([`desktop`,`headless`,`legacy-native`]).nullable(),consented:F.boolean(),startupEnabled:F.boolean().nullable(),transition:tg.nullable()}),xg=F.strictObject({desktopLogin:_g.shape.registration.optional(),desktop:_g.optional(),ownership:bg.optional(),revision:ag.nullable(),selection:fg.nullable(),transition:mg.nullable(),recoveryAvailable:F.boolean(),manualRecoveryAvailable:F.boolean().optional(),legacy:F.strictObject({installed:F.boolean(),loaded:F.boolean(),stateDir:Zh.nullable()}),manual:_g,persistent:_g,local:F.strictObject({kind:F.enum([`verified`,`foreign`,`absent`,`unverified`]),status:ah.status.safeExtend({process:Ym.extend({stateDir:Zh})}).nullable()})}),Sg=F.strictObject({saved:cp.strict(),savedRevision:og,appliedRevision:og.nullable(),applied:F.enum([`not-running`,`unknown`,`matches`,`restart-required`])}),Cg={hello:F.strictObject({version:F.literal(1),agentVersion:F.string().min(1),capabilities:F.tuple([F.literal(`status`),F.literal(`settings`),F.literal(`lifecycle`),F.literal(`pairing`),F.literal(`devices`),F.literal(`diagnostics`)])}),status:xg,"desktop.setup":xg,"desktop.login.set":xg,"desktop.start":xg,"desktop.stop":xg,"ownership.convert":xg,"ownership.recover":xg,"settings.get":Sg,"settings.set":Sg,"service.start":xg,"service.stop":xg,"service.restart":xg,"service.remove":xg,"service.recover":xg,diagnostics:F.strictObject({checks:F.array(F.strictObject({name:F.string().min(1).max(64),ok:F.boolean(),severity:F.enum([`pass`,`warning`,`error`]),detail:F.string().max(1024),fix:F.string().max(2048).optional(),required:F.boolean().optional()})).max(32)}),devices:ah.devices,terminals:F.strictObject({supported:F.boolean(),terminals:mu}),"terminals.connect":F.strictObject({supported:F.boolean(),started:F.boolean(),terminals:mu}),"devices.revoke":ah[`devices.revoke`],"pairing.open":ih,"pairing.close":ah[`pairing.close`],"pairing.confirm":ah[`pairing.confirm`]},$={v:F.literal(1),id:ig},wg=F.strictObject({expect:yg}),Tg=wg.extend({ownerRevision:ag.nullable()}),Eg=hh.options[0],Dg=Eg.shape.flowId,Og=F.discriminatedUnion(`cmd`,[F.strictObject({...$,cmd:F.literal(`desktop.login.set`),args:Tg.extend({enabled:F.boolean()})}),F.strictObject({...$,cmd:F.literal(`desktop.setup`),args:Tg.extend({consent:F.literal(!0)})}),F.strictObject({...$,cmd:F.literal(`desktop.start`),args:Tg}),F.strictObject({...$,cmd:F.literal(`desktop.stop`),args:Tg}),F.strictObject({...$,cmd:F.literal(`ownership.convert`),args:Tg.extend({target:Qh,consent:F.literal(!0)})}),F.strictObject({...$,cmd:F.literal(`ownership.recover`),args:Tg.extend({intentId:F.uuid()})}),F.strictObject({...$,cmd:F.literal(`hello`)}),F.strictObject({...$,cmd:F.literal(`status`)}),F.strictObject({...$,cmd:F.literal(`settings.get`)}),F.strictObject({...$,cmd:F.literal(`diagnostics`)}),F.strictObject({...$,cmd:F.literal(`devices`)}),F.strictObject({...$,cmd:F.literal(`terminals`)}),F.strictObject({...$,cmd:F.literal(`terminals.connect`),args:F.strictObject({name:Xl})}),F.strictObject({...$,cmd:F.literal(`settings.set`),args:wg.extend({configRevision:og,changes:F.array(F.strictObject({key:F.enum(Cm),value:sg})).min(1).max(Cm.length).refine(e=>new Set(e.map(e=>e.key)).size===e.length)})}),F.strictObject({...$,cmd:F.literal(`service.start`),args:wg.extend({mode:cg,consent:F.literal(!0),migrateLegacy:F.boolean(),stateDir:Zh.optional()})}),F.strictObject({...$,cmd:F.literal(`service.stop`),args:wg}),F.strictObject({...$,cmd:F.literal(`service.restart`),args:wg}),F.strictObject({...$,cmd:F.literal(`service.remove`),args:wg}),F.strictObject({...$,cmd:F.literal(`service.recover`),args:wg.extend({action:F.enum([`continue`,`restore-legacy`,`discard-backup`,`use-manual`]),restartPrevious:F.boolean(),consent:F.literal(!0)}).refine(e=>!e.restartPrevious||e.action===`restore-legacy`)}),F.strictObject({...$,cmd:F.literal(`devices.revoke`),args:wg.extend({phoneFp:U})}),F.strictObject({...$,cmd:F.literal(`pairing.open`),args:wg}),F.strictObject({...$,cmd:F.literal(`pairing.close`),args:wg.extend({flowId:Dg})}),F.strictObject({...$,cmd:F.literal(`pairing.confirm`),args:wg.extend({flowId:Dg,challengeId:Eg.shape.challengeId,phoneFp:U,accept:F.boolean()})})]),kg=F.enum([`bad-request`,`unsupported-version`,`handshake-required`,`busy`,`unavailable`,`conflict`,`unsafe-state`,`invalid-config`,`upgrade-required`,`startup-unavailable`,`delivery-unknown`,`approval-required`,`recovery-required`,`operation-failed`,`response-too-large`,`timeout`]);var Ag=class extends Error{code;constructor(e){super(e),this.code=e,this.name=`NativeControllerError`}};F.discriminatedUnion(`ok`,[F.strictObject({...$,ok:F.literal(!0),data:F.union(Object.values(Cg))}),F.strictObject({...$,ok:F.literal(!1),error:F.strictObject({code:kg})})]);const jg=F.discriminatedUnion(`event`,[Eg.extend({v:F.literal(1)}),hh.options[1].extend({v:F.literal(1)})]);function Mg(){throw new Ag(`unsafe-state`)}function Ng(e,t){return Xf(e,t)&&e.size===t.size&&e.mtimeMs===t.mtimeMs&&e.ctimeMs===t.ctimeMs&&e.mode===t.mode&&e.uid===t.uid}function Pg(e){return e instanceof Ag?e:new Ag(e instanceof Y?`unsafe-state`:`operation-failed`)}var Fg=class{options;root;path;uid;newId;constructor(e){this.options=e,(!Zh.safeParse(e.root).success||!Number.isSafeInteger(e.uid)||e.uid<0)&&Mg(),this.root=e.root.replace(/\/+$/,``)||`/`,this.path=N(this.root,e.filename),this.uid=e.uid,this.newId=e.newId??ce}inspect(){try{return this.checkAncestors(),X(this.root)?this.readSnapshot(Z(this.root,this.uid)).record:null}catch{return Mg()}}async mutate(e,t){let n,r,i=!0;try{this.checkAncestors(),X(this.root)||m(this.root,{recursive:!0,mode:448});let a=Z(this.root,this.uid);r=h(this.root,o.O_RDONLY|o.O_NOFOLLOW|o.O_NONBLOCK),Xf(a,l(r))||Mg(),n=this.acquireGuard(a);let s=this.readSnapshot(a);if((s.record?.revision??null)!==e)throw new Ag(`conflict`);return await t({get current(){return structuredClone(s.record)},publish:e=>{if(!i)throw new Ag(`operation-failed`);try{let t=this.options.schema.safeParse({...e,revision:this.newId()});(!t.success||t.data.revision===s.record?.revision)&&Mg();let i=Buffer.from(JSON.stringify(t.data));return i.length>this.options.maxBytes&&Mg(),this.publish(i,a,s,()=>n.assert()),u(r),s=this.readSnapshot(a),structuredClone(t.data)}catch(e){throw Pg(e)}}})}catch(e){throw Pg(e)}finally{i=!1;try{n?.release()}finally{r!==void 0&&a(r)}}}checkAncestors(){let e=this.root;for(;;){let t=X(e);t&&(!t.isDirectory()||t.isSymbolicLink())&&Mg();let n=j(e);if(n===e)return;e=n}}checkRoot(e){this.checkAncestors(),Xf(e,Z(this.root,this.uid))||Mg()}readSnapshot(e){this.checkRoot(e);let t=X(this.path);if(!t)return this.checkRoot(e),{record:null,stat:void 0,bytes:null};let n=$f(this.path,this.options.maxBytes,this.uid),r=X(this.path);(!r||!Ng(t,r))&&Mg(),this.checkRoot(e);let i;try{i=JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(n))}catch{return Mg()}let a=this.options.schema.safeParse(i);return a.success?{record:a.data,stat:r,bytes:n}:Mg()}checkSnapshot(e,t){let n=this.readSnapshot(e);(t.stat?!n.stat||!Ng(t.stat,n.stat)||!t.bytes?.equals(n.bytes):n.stat!==void 0)&&Mg()}publish(e,t,n,r){r(),this.checkSnapshot(t,n);let i=`${this.path}.tmp-${ce()}`,s,c;try{s=h(i,o.O_WRONLY|o.O_CREAT|o.O_EXCL|o.O_NOFOLLOW,384),c=l(s);let a=0;for(;a<e.length;){let t=T(s,e,a,e.length-a);if(t<=0)throw new Ag(`operation-failed`);a+=t}u(s);let d=l(s);this.checkSnapshot(t,n);let f=X(i);(!f||!Xf(c,d)||!Ng(d,f)||!f.isFile()||f.uid!==this.uid||(f.mode&4095)!=384||d.size!==e.length)&&Mg(),r(),b(i,this.path)}finally{s!==void 0&&a(s);try{this.checkRoot(t);let e=X(i);c&&e&&Xf(c,e)&&C(i)}catch{}}}acquireGuard(e){let t=`${this.path}.lock`,n=`owner-${process.pid}-${ce()}`,r=`${this.path}.lock-candidate-${n.slice(6)}`,i,o,s=!1,c=(r,i,a=n,s=o,c=!1)=>{try{if(this.checkRoot(e),!Xf(i,Z(r,this.uid)))return!1;let n=X(N(r,a));if(n&&(!s||!Ng(s,n)))return!1;if(r===t){if(!n||!s)return!1;let e=`${this.path}.lock-candidate-${a.slice(6)}`;if(X(e)||(b(r,e),r=e,!Xf(i,Z(r,this.uid)))||(n=X(N(r,a)),!n||!Ng(s,n)))return!1;if(c)return!0}return n&&C(N(r,a)),x(r),!0}catch{return!1}};try{this.checkRoot(e),m(r,{mode:448}),i=Z(r,this.uid);let u=h(N(r,n),`wx`,384);try{o=l(u)}finally{a(u)}for(let a=0;a<3;a++){if(this.checkRoot(e),X(t)){let e=Z(t,this.uid),n=v(t),r=n[0],i=r&&/^owner-([1-9][0-9]*)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/.exec(r),a=i&&Gf(i[1]);(n.length!==1||!r||!a)&&Mg();let o=X(N(t,r));if($f(N(t,r),0,this.uid),Kf(a))throw new Ag(`busy`);Xf(e,Z(t,this.uid))||Mg();let s=X(N(t,r));(!o||!s||!Ng(o,s))&&Mg(),c(t,e,r,o,!0)||Mg()}try{b(r,t),s=!0;let a=Z(t,this.uid);return Xf(i,a)||Mg(),{assert:()=>{this.checkRoot(e),Xf(a,Z(t,this.uid))||Mg();let r=X(N(t,n));(!r||!o||!Ng(o,r))&&Mg()},release:()=>c(t,a)}}catch(e){if(![`EEXIST`,`ENOTEMPTY`,`ENOENT`].includes(e.code??``))throw e}}throw new Ag(`busy`)}finally{!s&&i&&c(r,i)}}},Ig=class extends Fg{constructor(e){super({root:e.stateDir,uid:e.uid,filename:`service-owner.json`,maxBytes:16384,schema:ng})}};function Lg(e){if(e?.mode===`desktop`)throw Error(`Service is desktop-owned; use Shellbell or explicitly convert it to headless mode`);if(e?.transition)throw Error(`An ownership conversion needs explicit recovery before headless service changes`)}function Rg(e){let t=new Ig({...e,stateDir:Zf(e.stateDir)}).inspect(),n=t?.transition;t?.mode===`headless`&&n?.target===`headless`&&e.serviceInstance===n.id&&[`source-stopped`,`destination-started`].includes(n.phase)||Lg(t)}async function zg(e,t){let n=new Ig({...e,stateDir:Zf(e.stateDir)}),r=n.inspect();return Lg(r),n.mutate(r?.revision??null,async e=>(Lg(e.current),t()))}async function Bg(e,t){let n=new Ig(e),r=n.inspect();if(Lg(r),!e.create&&!r&&!s(e.stateDir))return t();let i=!1,a;return n.mutate(r?.revision??null,async n=>{Lg(n.current);let r;try{r=await t()}catch(e){throw i=!0,a=e,e}let o=e.startupPreference?e.startupPreference(r):r.startupEnabled;return o!==null&&(r.installed||n.current)&&(!n.current||n.current.startupEnabled!==o)&&n.publish({v:1,mode:`headless`,consented:!0,startupEnabled:o,transition:null}),r}).catch(e=>{throw i?a:e})}function Vg(e){try{return y(e)}catch(t){if(t.code===`ENOENT`)return P(e);throw Error(`Cannot resolve state directory ${e}`)}}function Hg(e,t){try{return e.process.computerFp===t.computerFp&&Vg(e.process.stateDir)===Vg(t.stateDir)&&(t.serviceInstance===void 0||e.process.serviceInstance===t.serviceInstance)&&(t.pid===void 0||e.process.pid===t.pid)}catch{return!1}}var Ug=class{clock;probe;constructor(e={}){this.clock=e.clock??{now:()=>de.now(),sleep:e=>new Promise(t=>setTimeout(t,e))},this.probe=e.probe??((e,t)=>Eh(e,`status`,void 0,{timeoutMs:t,maxResponseBytes:65536}))}async observe(e,t,n=500){let r;try{r=await this.probe(e,n)}catch(e){let t=e.code;return t===`ENOENT`||t===`ECONNREFUSED`?{kind:`absent`,local:null,diagnostic:`Local endpoint is absent`}:{kind:`unverified`,local:null,diagnostic:`Local endpoint did not return a bounded status response`}}let i=Fm.safeParse(r);return i.success?t&&!Hg(i.data,t)?{kind:`foreign`,local:i.data,diagnostic:`Local endpoint belongs to a different process, identity, state directory, or service instance`}:{kind:`verified`,local:i.data}:{kind:`unverified`,local:null,diagnostic:`Local endpoint uses an unsupported or malformed status protocol`}}async waitReady(e,t){return(await this.wait(e,t,!1)).local}async waitStopped(e){await this.wait(e,void 0,!0)}async wait(e,t,n){let r=this.clock.now()+1e4,i=`Local endpoint is absent`;for(;this.clock.now()<r;){let a=await this.observe(e,t,Math.min(500,r-this.clock.now()));if(n?a.kind===`absent`:a.kind===`verified`)return a;if(i=a.diagnostic??`Local endpoint is still responding`,!n&&a.kind===`foreign`)throw Error(`Service readiness conflict: ${i}; stop the foreground owner before retrying`);let o=r-this.clock.now();o>0&&await this.clock.sleep(Math.min(100,o))}throw Error(`${n?`Service stop`:`Service readiness`} timed out: ${i}`)}};const Wg=new Set([`.npm`,`_npx`,`dlx`]),Gg=[[`npm`,`config`,`cache`].join(`_`),`NPM_CONFIG_CACHE`];function Kg(e,t){throw Error(`Shellbell service runtime at ${e} ${t}; install a built Shellbell package in a durable directory, then rerun service install`)}function qg(e){try{return y(e)}catch{return ne(e)}}function Jg(){let e=[O(),`/tmp`,`/private/tmp`,`/var/tmp`,`/private/var/tmp`];for(let t of Gg){let n=process.env[t];n&&M(n)&&e.push(n)}return[...new Set(e.flatMap(e=>[ne(e),qg(e)]))]}function Yg(e,t){let n=re(t,e);return n===``||n!==`..`&&!n.startsWith(`..${ie}`)&&!M(n)}function Xg(e){let t=ne(e);(t.split(ie).some(e=>Wg.has(e))||Jg().some(e=>Yg(t,e)))&&Kg(e,`is in a temporary or package-manager cache location`)}function Zg(e,t){M(e)||Kg(e,`${t} path must be absolute`),Xg(e);let n;try{n=y(e)}catch{Kg(e,`${t} does not exist`)}return Xg(n),(()=>{try{return te(n)}catch{return Kg(n,`${t} does not exist`)}})().isFile()||Kg(n,`${t} must be a regular file`),n}function Qg(e,t,r){try{n(e,t)}catch{Kg(e,r)}}function $g(e){let t=`${e}${ie}package.json`,n=(()=>{try{return te(t)}catch{return Kg(t,`package.json is missing`)}})();n.isFile()||Kg(t,`package.json must be a regular file`),n.size>1048576&&Kg(t,`package.json exceeds 1 MiB`);let r;try{r=g(t,`utf8`)}catch{Kg(t,`package.json is not readable`)}let i;try{i=JSON.parse(r)}catch{Kg(t,`package.json is not valid JSON`)}return(typeof i!=`object`||!i||Array.isArray(i))&&Kg(t,`package.json is not a valid manifest`),i}function e_(e){let t=e.bin,n=typeof t==`string`?t:typeof t==`object`&&t&&!Array.isArray(t)?t.shellbell:void 0;return n===`dist/cli.js`||n===`./dist/cli.js`}function t_(e=process.execPath,t=process.argv[1]??``){let n=Number.parseInt(process.versions.node.split(`.`)[0]??``,10);(!Number.isInteger(n)||n<22)&&Kg(process.execPath,`requires the currently running Node.js major version to be at least 22`);let r=Zg(e,`Node executable`);Qg(r,o.X_OK,`Node executable is not executable`);let i=Zg(t,`CLI entrypoint`);Qg(i,o.R_OK,`CLI entrypoint is not readable`),(A(i)!==`cli.js`||A(j(i))!==`dist`)&&Kg(i,`is not an installed built CLI entrypoint`);let a=j(j(i)),c=`${a}${ie}src${ie}cli.ts`;s(c)&&Kg(a,`is a source checkout rather than an installed built package`);let l=$g(a);return l.name!==`shellbell`&&Kg(`${a}${ie}package.json`,`has the wrong package name`),e_(l)||Kg(`${a}${ie}package.json`,`does not declare the Shellbell bin entrypoint`),{nodePath:r,cliPath:i,packageRoot:a}}var n_=class extends Error{rollback=`not-needed`;rollbackDiagnostic;recoveryPath};function r_(e,t,n){let r=e.definition?.stateDir,i=Vg(r??(t||n));if(r&&t&&Vg(t)!==i)throw new n_(`SHELLBELL_DIR conflicts with the installed service state directory; state migration is not an implicit install operation`);return Ep(i)}function i_(e){return e instanceof n_?e:new n_(e instanceof Error?e.message.slice(0,600):`Service operation failed`)}async function a_(e,t,n){let r=j(e.definitionPath),i;try{return t&&m(r,{recursive:!0,mode:448}),s(r)&&(i=Yf(e.definitionPath)),await n(e)}finally{i?.()}}var o_=class{options;manager;readiness;constructor(e){this.options=e,this.manager=e.manager,this.readiness=new Ug(e)}selected(e){return r_(e,this.options.requestedStateDir,this.options.defaultStateDir)}definitionFor(e,t,n){let r=Rh({stateDir:t.dir,serviceInstance:n,nodePath:e.nodePath,env:this.options.env}),i={nodePath:e.nodePath,cliPath:e.cliPath,stateDir:t.dir,serviceInstance:n,environment:r,logPath:t.log};for(let e of Object.values(i))typeof e==`string`&&Ih(e);for(let[e,t]of Object.entries(r))Ih(e),Ih(t);return i}expected(e,t){let n=Oh(t);return n?{computerFp:n.fp,stateDir:t.dir,serviceInstance:e.definition?.serviceInstance??null}:void 0}result(e,t,n,r=null,i){let a=e.installed&&e.definition?.serviceInstance===null,o=e.installed&&e.loaded&&!!n&&t.kind===`verified`&&(!a||r!==null),s=i??(n?a&&r===null?`Legacy service cannot be verified by read-only status; run service install to upgrade`:void 0:`Local identity is missing; no keys were created`),c=e.definition&&!e.definition.environment.SHELLBELL_DIR?`Legacy definition assumes the historical ~/.shellbell state directory`:void 0;return{manager:this.manager.kind,definitionPath:this.manager.definitionPath,installed:e.installed,loaded:e.loaded,startupEnabled:e.startupEnabled??null,autostartConfigured:e.installed&&e.startupEnabled===!0,managedPid:r,ownership:t.kind===`foreign`?`foreign`:a&&!o?`legacy`:o?`verified`:`none`,local:t.local,ready:o,...t.diagnostic||s||c?{diagnostic:[t.diagnostic,s,c].filter(Boolean).join(`; `)}:{}}}async status(){let e=await this.manager.inspect(),t=this.selected(e),n=this.expected(e,t);return this.result(e,await this.readiness.observe(t.sock,n),n)}async serialized(e,t){try{let n=await this.manager.inspect();return await Bg({stateDir:Zf(this.selected(n).dir),uid:process.getuid(),create:e},()=>a_(this.manager,e,t))}catch(e){throw i_(e)}}assertAvailable(e,t,n){if(t.kind!==`absent`&&!(e.loaded&&e.definition?.serviceInstance===null&&t.kind===`unverified`)&&!(e.loaded&&n&&t.kind===`verified`))throw new n_(`Local endpoint ownership is unverified or foreign; stop the foreground owner before retrying service changes`)}async rollback(e,t,n,r,i){let a=i_(i);if(!r.unloadAttempted&&!r.written&&!r.loaded)throw a;try{if(r.loaded&&await this.manager.unload(),(r.unloadAttempted||r.loaded)&&await this.readiness.waitStopped(t.sock),r.written&&await this.manager.restore(e.raw),e.loaded){let r=await this.manager.load();e.definition?.serviceInstance&&n&&await this.readiness.waitReady(t.sock,{...n,pid:r})}a.rollback=`restored`}catch(t){if(a.rollback=`failed`,a.rollbackDiagnostic=i_(t).message,e.raw){let t=`${this.manager.definitionPath}.recovery-${ce()}`;try{w(t,e.raw,{mode:384,flag:`wx`}),a.recoveryPath=t}catch{a.rollbackDiagnostic+=`; could not save a private recovery definition`}}}throw a}async install(){try{let e=t_(),t=ce();return this.definitionFor(e,Ep(Vg(this.options.requestedStateDir||this.options.defaultStateDir)),t),await this.serialized(!0,async()=>{let n=await this.manager.inspect(),r=this.selected(n),i=this.definitionFor(e,r,t),a=this.expected(n,r);if(n.installed&&!a)throw new n_(`Installed service identity is missing at ${r.identity}; restore it before upgrading`);this.assertAvailable(n,await this.readiness.observe(r.sock,a),a);let o=Oh(r)??kh(r);Xh(r.log);let s={computerFp:o.fp,stateDir:r.dir,serviceInstance:t},c={unloadAttempted:!1,written:!1,loaded:!1};try{n.loaded&&(c.unloadAttempted=!0,await this.manager.unload(),await this.readiness.waitStopped(r.sock)),c.written=!0,await this.manager.write(i),c.loaded=!0;let e=await this.manager.load(),t=await this.readiness.waitReady(r.sock,{...s,pid:e}),a=await this.manager.inspect();if(!a.loaded)throw Error(`Service unloaded before readiness could be confirmed`);return this.result(a,{kind:`verified`,local:t},s,e)}catch(e){return this.rollback(n,r,a,c,e)}})}catch(e){throw i_(e)}}start(){return this.runInstalled(`start`)}restart(){return this.runInstalled(`restart`)}stop(){return this.runInstalled(`stop`)}enable(){return this.setStartup(!0)}disable(){return this.setStartup(!1)}async setStartup(e){return this.serialized(!1,async()=>{let t=await this.manager.inspect(),n=this.selected(t);if(!t.installed)throw new n_(`Service is not installed; run service install first`);await this.manager.setStartupEnabled(e);let r=await this.manager.inspect();if(r.startupEnabled!==e||r.loaded!==t.loaded)throw new n_(`Startup preference or current execution could not be verified`);let i=this.expected(r,n);return this.result(r,await this.readiness.observe(n.sock,i),i)})}uninstall(){return this.runInstalled(`uninstall`)}runInstalled(e){return this.serialized(!1,async()=>{let t=await this.manager.inspect(),n=this.selected(t),r=e===`stop`||e===`uninstall`,i,a;try{i=this.expected(t,n)}catch(e){if(!r)throw e;a=i_(e).message}let o=await this.readiness.observe(n.sock,i);if(!t.installed){if(!r)throw new n_(`Service is not installed; run service install first`);return this.result(t,o,i,null,a)}if(!r&&!i)throw new n_(`Local identity is missing at ${n.identity}; restore it before starting`);r&&t.loaded&&o.kind===`unverified`||this.assertAvailable(t,o,i);let s={unloadAttempted:!1,written:!1,loaded:!1};try{if(e!==`start`&&t.loaded&&(s.unloadAttempted=!0,await this.manager.unload(),await this.readiness.waitStopped(n.sock)),r){e===`uninstall`&&await this.manager.restore(null);let t=await this.manager.inspect();if(t.loaded)throw Error(`Service remains loaded after stop`);return this.result(t,{kind:`absent`,local:null,diagnostic:e===`stop`?`Service stopped; definition remains and it may start at next login`:`Service uninstalled; identity and pairings remain`},i,null,a)}s.loaded=!t.loaded||e===`restart`;let c=await this.manager.load();if(e===`restart`&&o.local?.process.pid===c)throw Error(`Service restart did not produce a new manager-certified process`);let l=await this.readiness.waitReady(n.sock,{...i,pid:c}),u=await this.manager.inspect();if(!u.loaded)throw Error(`Service unloaded before readiness could be confirmed`);return this.result(u,{kind:`verified`,local:l},i,c)}catch(e){if(r)throw i_(e);return this.rollback(t,n,i,s,e)}})}};export{lm as $,Kn as $n,au as $t,Oh as A,oc as An,Yf as At,Cm as B,br as Bn,Kd as Bt,lg as C,Qs as Cn,ep as Ct,Nh as D,vc as Dn,X as Dt,Yh as E,_c as En,Zf as Et,Ch as F,Ir as Fn,Vf as Ft,mm as G,ur as Gn,Td as Gt,Em as H,ir as Hn,vd as Ht,Gm as I,Lr as In,Bf as It,om as J,Yn as Jn,gd as Jt,_m as K,nr as Kn,wd as Kt,Um as L,Er as Ln,Tf as Lt,Dh as M,ya as Mn,Gf as Mt,Eh as N,Dr as Nn,Uf as Nt,Mh as O,lc as On,Z as Ot,Q as P,Or as Pn,Hf as Pt,cm as Q,V as Qn,Lu as Qt,Fm as R,xr as Rn,of as Rt,xg as S,yc as Sn,ap as St,Zh as T,uc as Tn,$f as Tt,xm as U,W as Un,Dd as Ut,Dm as V,rr as Vn,yd as Vt,bm as W,G as Wn,Cd as Wt,um as X,$n as Xn,ud as Xt,dm as Y,tr as Yn,_d as Yt,sm as Z,er as Zn,fd as Zt,jg as _,Nc as _n,xp as _t,t_ as a,nu as an,qp as at,Og as b,dc as bn,sp as bt,Ig as c,Hl as cn,Ip as ct,Bg as d,il as dn,Fp as dt,Xl as en,Gn as er,im as et,Fg as f,Rc as fn,Yp as ft,kg as g,wc as gn,Sp as gt,Cg as h,Sc as hn,gp as ht,a_ as i,Cu as in,Pp as it,Th as j,La as jn,Kf as jt,kh as k,ac as kn,Xf as kt,Rg as l,al as ln,Jp as lt,Ag as m,bc as mn,vp as mt,n_ as n,iu as nn,Zp as nt,Ug as o,xu as on,Dp as ot,rg as p,Vc as pn,Op as pt,gm as q,U as qn,hd as qt,r_ as r,ru as rn,zp as rt,Hg as s,Au as sn,Lp as st,o_ as t,Yl as tn,rm as tt,zg as u,sl as un,Ep as ut,vg as v,sc as vn,cp as vt,eg as w,tc as wn,Y as wt,fg as x,rc as xn,op as xt,gg as y,fc as yn,dp as yt,Im as z,wr as zn,af as zt};
29
+ `}function Kh(e,t){if(typeof e!=`string`||!e||!M(e))throw Error(`invalid service definition: ${t} must be an absolute path`);return Wh(e),e}function qh(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw Error(`invalid service definition`);let n=e;for(let e of Object.keys(n))if(!Uh.has(e))throw Error(`unrecognized service definition key: ${e}`);if(n.Label!==`sh.bilal.shellbell`||!Array.isArray(n.ProgramArguments)||n.ProgramArguments.length!==4||n.ProgramArguments[2]!==`start`||n.ProgramArguments[3]!==`--service`||n.RunAtLoad!==!0||n.KeepAlive!==!0||n.StandardOutPath!==n.StandardErrorPath)throw Error(`unrecognized Shellbell service definition`);let r=n.EnvironmentVariables;if(!r||typeof r!=`object`||Array.isArray(r))throw Error(`invalid service environment`);let i=r;for(let[e,t]of Object.entries(i)){if(!Hh.has(e))throw Error(`unrecognized service environment: ${e}`);if(typeof t!=`string`)throw Error(`invalid service environment: ${e}`);Wh(e),Wh(t),(e===`HERDR_SOCKET_PATH`||e===`XDG_CONFIG_HOME`)&&Kh(t,e)}if(typeof i.PATH!=`string`||!i.PATH||i.PATH.split(`:`).some(e=>!e||!M(e)))throw Error(`invalid service PATH`);let a=i.SHELLBELL_DIR===void 0?N(t,`.shellbell`):Kh(i.SHELLBELL_DIR,`SHELLBELL_DIR`),o=i.SHELLBELL_SERVICE_INSTANCE;if(o!==void 0&&(typeof o!=`string`||!Vh.test(o)))throw Error(`invalid service instance`);return{nodePath:Kh(n.ProgramArguments[0],`nodePath`),cliPath:Kh(n.ProgramArguments[1],`cliPath`),stateDir:a,serviceInstance:o??null,environment:i,logPath:Kh(n.StandardOutPath,`logPath`)}}function Jh(e){if(Kh(e.nodePath,`nodePath`),Kh(e.cliPath,`cliPath`),Kh(e.stateDir,`stateDir`),Kh(e.logPath,`logPath`),!e.serviceInstance||!Vh.test(e.serviceInstance))throw Error(`serviceInstance must be a UUID`);let t=e.environment;if(t.SHELLBELL_DIR!==e.stateDir||t.SHELLBELL_SERVICE_INSTANCE!==e.serviceInstance)throw Error(`service definition and environment disagree`);if(!t.PATH||t.PATH.split(`:`).some(e=>!e||!M(e)))throw Error(`invalid service PATH`);for(let[e,n]of Object.entries(t)){if(!Hh.has(e))throw Error(`unsupported service environment: ${e}`);if(typeof n!=`string`)throw Error(`invalid service environment: ${e}`);Wh(e),Wh(n),(e===`HERDR_SOCKET_PATH`||e===`XDG_CONFIG_HOME`)&&Kh(n,e)}}function Yh(e={}){let t=e.run??Nh,n=e.uid??k().uid;if(!Number.isSafeInteger(n)||n<0)throw Error(`invalid service UID`);let r=e.homeDir??E(),i=e.definitionPath??N(r,`Library`,`LaunchAgents`,`sh.bilal.shellbell.plist`),a=`gui/${n}`,o=`${a}/${zh}`,s;function c(e,t){return e===null||t===null?e===t:e.stat.dev===t.stat.dev&&e.stat.ino===t.stat.ino&&e.stat.uid===t.stat.uid&&e.stat.mode===t.stat.mode&&e.stat.size===t.stat.size&&e.stat.mtimeMs===t.stat.mtimeMs&&e.stat.ctimeMs===t.stat.ctimeMs&&e.raw.equals(t.raw)}function l(){let e;try{e=p(i)}catch(e){if(e.code===`ENOENT`)return null;throw e}return!e.isFile()||e.isSymbolicLink()||e.uid!==n||e.mode&18||e.size>Bh?{stat:e,raw:Buffer.alloc(0)}:{stat:e,raw:g(i)}}function u(e){if(!c(e,l()))throw Error(`service definition changed or was replaced during operation`)}function d(e){let t=l();if(!t?.raw.equals(e))throw Error(`service definition changed after publication`);s=t}async function f(e,n,r=!1,i){let a=await t(e,n,{input:i,timeoutMs:5e3,maxOutputBytes:e===`/usr/bin/plutil`?Bh:65536,captureOutput:r});if(!Number.isInteger(a.exitCode))throw Error(`${e} returned invalid exit status`);return a}async function h(e){let t=await f(`/usr/bin/plutil`,[`-convert`,`json`,`-o`,`-`,`-`],!0,e);if(t.exitCode!==0)throw Error(`plutil could not parse service definition`);let n;try{n=JSON.parse(t.stdout.toString(`utf8`))}catch{throw Error(`plutil returned invalid service definition JSON`)}return qh(n,r)}async function _(){let e;try{e=p(i)}catch(e){if(e.code===`ENOENT`)return null;throw e}if(!e.isFile()||e.isSymbolicLink()||e.uid!==n||e.mode&18||e.size>Bh)throw Error(`unsafe service definition metadata`);let t=g(i);if(t.length>Bh)throw Error(`service definition too large`);let r=await h(t),a={stat:e,raw:t};return u(a),{...a,definition:r}}async function v(){let e=await f(`/bin/launchctl`,[`print`,o]);if(e.exitCode===0)return!0;if(e.exitCode===113)return!1;throw Error(`launchctl print failed (${e.exitCode})`)}async function y(){try{let e=await f(`/bin/launchctl`,[`print-disabled`,a],!0),t=new TextDecoder(`utf-8`,{fatal:!0}).decode(e.stdout).trim().split(/\r?\n/).map(e=>e.trim());if(e.exitCode!==0||t.shift()!==`disabled services = {`||t.pop()!==`}`)return null;let n=t.filter(e=>e.includes(`"${zh}"`));return n.length===0?!0:n.length===1?n[0]===`"sh.bilal.shellbell" => disabled`||n[0]===`"sh.bilal.shellbell" => true`?!1:n[0]===`"sh.bilal.shellbell" => enabled`||n[0]===`"sh.bilal.shellbell" => false`||null:null}catch{return null}}let b={kind:`launchd`,definitionPath:i,async inspect(){let e=await _(),t=await v();if(u(e),!e&&t)throw Error(`loaded Shellbell job has no valid installed definition`);if(s!==void 0&&!c(s,e))throw Error(`service definition changed or was replaced after inspection`);return s===void 0&&(s=e),{installed:!!e,startupEnabled:e?await y():!1,loaded:t,raw:e?.raw??null,definition:e?.definition??null}},async setStartupEnabled(e){let t=await b.inspect();if(!t.installed)throw Error(`service is not installed`);if(t.startupEnabled!==e){if((await f(`/bin/launchctl`,[e?`enable`:`disable`,o])).exitCode!==0)throw Error(`launchctl startup preference change failed`);if((await b.inspect()).startupEnabled!==e)throw Error(`launchctl startup preference could not be verified`)}},async write(e){await Mh(t,n,r),Jh(e);let a=await _();if(s!==void 0&&!c(s,a))throw Error(`service definition changed or was replaced after inspection`);if(!a&&await v())throw Error(`loaded Shellbell job has no installed definition`);let o=Gh({...e});m(j(i),{recursive:!0,mode:448}),Op(i,o,()=>u(a)),d(Buffer.from(o))},async restore(e){if(e!==null&&e.length>Bh)throw Error(`service definition too large`);let a=await _();if(s!==void 0&&!c(s,a))throw Error(`service definition changed or was replaced after inspection`);if(e===null){if(!a)return;if(s===void 0)throw Error(`refusing to remove unexpected service definition replacement`);u(a),C(i),s=null;return}if(s===void 0)throw Error(`service definition changed unexpectedly`);if(await h(e),a)Op(i,e,()=>u(a));else if(await Mh(t,n,r),m(j(i),{recursive:!0,mode:448}),!Ap(i,e))throw Error(`service definition changed or was replaced after inspection`);d(e)},async load(){await Mh(t,n,r);let e=await b.inspect();if(!e.installed)throw Error(`service definition is not installed`);if(e.startupEnabled===null)throw Error(`service startup preference is unresolved`);let s=e.startupEnabled===!1;try{if(s&&await b.setStartupEnabled(!0),!e.loaded){let e=await f(`/bin/launchctl`,[`bootstrap`,a,i]);if(e.exitCode!==0)throw Error(`launchctl bootstrap failed (${e.exitCode})`)}let t=await f(`/bin/launchctl`,[`kickstart`,`-p`,o],!0);if(t.exitCode!==0)throw Error(`launchctl kickstart failed (${t.exitCode})`);let n=t.stdout.toString(`utf8`).trim();if(!/^[1-9][0-9]*$/.test(n))throw Error(`invalid launchctl PID output`);let r=Number(n);if(!Number.isSafeInteger(r)||r>2147483647)throw Error(`invalid launchctl PID output`);return r}finally{s&&await b.setStartupEnabled(!1)}},async unload(){if(!(await b.inspect()).loaded)return;let e=await f(`/bin/launchctl`,[`bootout`,o]);if(e.exitCode!==0)throw Error(`launchctl bootout failed (${e.exitCode})`);if(await v())throw Error(`launchctl bootout did not unload service`)}};return b}function Xh(e){s(e)?i(e,384):w(e,``,{mode:384})}const Zh=F.string().refine(e=>Buffer.byteLength(e,`utf8`)<=4096&&M(e)&&![...e].some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)),Qh=F.enum([`desktop`,`headless`]),$h=F.enum([`prepared`,`source-stopped`,`destination-started`,`recovery-required`]),eg=F.enum([`manual`,`persistent`,`desktop`]),tg=F.strictObject({id:F.uuid(),source:F.enum([`desktop`,`headless`,`legacy-native`]).nullable(),target:Qh,sourceManager:F.enum([`desktop-child`,`native-manual`,`native-persistent`,`launchd`,`systemd`]).nullable(),sourceInstance:F.uuid().nullable(),stateDir:Zh,computerFp:U,targetBundlePath:Zh.nullable(),targetVersion:F.string().min(1).max(256),phase:$h}),ng=F.strictObject({v:F.literal(1),revision:F.uuid(),mode:Qh,consented:F.boolean(),startupEnabled:F.boolean(),transition:tg.nullable()}),rg=2097152,ig=F.number().int().positive().max(2**53-1),ag=F.uuid(),og=F.string().regex(/^[0-9a-f]{64}$/),sg=F.string().refine(e=>Buffer.byteLength(e,`utf8`)<=4096),cg=F.enum([`manual`,`persistent`]);function lg(e){if(e===`desktop`)throw new Ng(`conflict`);return e}const ug=F.enum([`prepared`,`source-stop-requested`,`source-stopped`,`destination-start-requested`,`awaiting-approval`,`destination-ready`,`recovery-required`]),dg=F.strictObject({PATH:sg.refine(e=>e.split(`:`).every(e=>Zh.safeParse(e).success)),SHELLBELL_DIR:Zh,SHELLBELL_SERVICE_INSTANCE:F.uuid(),HERDR_SOCKET_PATH:Zh.optional(),XDG_CONFIG_HOME:Zh.optional()}),fg=F.strictObject({mode:eg,stateDir:Zh,computerFp:U,serviceInstance:F.uuid(),bundlePath:Zh,bundleId:F.literal(`sh.bilal.shellbell.host`),agentVersion:F.string().min(1),environment:dg}).refine(e=>e.environment.SHELLBELL_DIR===e.stateDir&&e.environment.SHELLBELL_SERVICE_INSTANCE===e.serviceInstance),pg=F.strictObject({id:F.uuid(),definitionPath:Zh,rawBase64:F.string().max(1398104).refine(e=>/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e)&&Buffer.from(e,`base64`).byteLength<=1048576&&Buffer.from(e,`base64`).toString(`base64`)===e),sha256:og,wasLoaded:F.boolean(),stateDir:Zh,computerFp:U}),mg=F.strictObject({id:F.uuid(),action:F.enum([`start`,`stop`,`restart`,`remove`,`recover`]),phase:ug}),hg=mg.extend({source:fg.nullable(),destination:fg.nullable(),recoveryId:F.uuid().nullable(),restoreLegacy:F.strictObject({restartPrevious:F.boolean()}).optional()}).refine(e=>e.restoreLegacy===void 0||e.action===`recover`),gg=F.strictObject({v:F.literal(1),revision:ag,selection:fg.nullable(),transition:hg.nullable(),recovery:pg.nullable()}).refine(e=>e.transition?.recoveryId==null||e.transition.recoveryId===e.recovery?.id),_g=F.strictObject({registration:F.enum([`not-registered`,`enabled`,`requires-approval`,`not-found`,`unknown`]),loaded:F.boolean(),pid:ig.nullable(),bundlePath:Zh.nullable()}),vg=F.discriminatedUnion(`ok`,[F.strictObject({v:F.literal(1),ok:F.literal(!0),status:F.enum([`not-registered`,`enabled`,`requires-approval`,`not-found`])}),F.strictObject({v:F.literal(1),ok:F.literal(!1),error:F.strictObject({code:F.enum([`unavailable`,`denied`,`invalid-bundle`,`operation-failed`])})})]),yg=F.strictObject({revision:ag.nullable(),runtime:Ym.extend({stateDir:Zh}).nullable()}),bg=F.strictObject({revision:ag.nullable(),mode:F.enum([`desktop`,`headless`,`legacy-native`]).nullable(),consented:F.boolean(),startupEnabled:F.boolean().nullable(),transition:tg.nullable()}),xg=F.strictObject({desktopLogin:_g.shape.registration.optional(),desktop:_g.optional(),ownership:bg.optional(),revision:ag.nullable(),selection:fg.nullable(),transition:mg.nullable(),recoveryAvailable:F.boolean(),manualRecoveryAvailable:F.boolean().optional(),legacy:F.strictObject({installed:F.boolean(),loaded:F.boolean(),stateDir:Zh.nullable()}),manual:_g,persistent:_g,local:F.strictObject({kind:F.enum([`verified`,`foreign`,`absent`,`unverified`]),status:ah.status.safeExtend({process:Ym.extend({stateDir:Zh})}).nullable()})}),Sg=F.strictObject({saved:cp.strict(),savedRevision:og,appliedRevision:og.nullable(),applied:F.enum([`not-running`,`unknown`,`matches`,`restart-required`])}),Cg=F.string().regex(/^[a-z][a-z0-9-]{0,31}$/),wg=F.strictObject({agents:F.array(F.strictObject({kind:Cg,name:F.string().min(1).max(64),state:F.enum([`ready`,`needs-setup`,`hooks-off`,`blocked`,`coming-soon`]),helper:F.boolean(),skipped:F.boolean(),detail:F.string().min(1).max(512).optional()})).max(32)}),Tg=F.strictObject({kinds:F.array(Cg).min(1).max(32)}),Eg={hello:F.strictObject({version:F.literal(1),agentVersion:F.string().min(1),capabilities:F.tuple([F.literal(`status`),F.literal(`settings`),F.literal(`lifecycle`),F.literal(`pairing`),F.literal(`devices`),F.literal(`diagnostics`)])}),status:xg,"desktop.setup":xg,"desktop.login.set":xg,"desktop.start":xg,"desktop.stop":xg,"ownership.convert":xg,"ownership.recover":xg,"settings.get":Sg,"settings.set":Sg,"service.start":xg,"service.stop":xg,"service.restart":xg,"service.remove":xg,"service.recover":xg,diagnostics:F.strictObject({checks:F.array(F.strictObject({name:F.string().min(1).max(64),ok:F.boolean(),severity:F.enum([`pass`,`warning`,`error`]),detail:F.string().max(1024),fix:F.string().max(2048).optional(),required:F.boolean().optional()})).max(32)}),devices:ah.devices,terminals:F.strictObject({supported:F.boolean(),terminals:mu}),"terminals.connect":F.strictObject({supported:F.boolean(),started:F.boolean(),terminals:mu}),agents:wg,"agents.setup":wg,"agents.skip":wg,"agents.remove":wg,"devices.revoke":ah[`devices.revoke`],"pairing.open":ih,"pairing.close":ah[`pairing.close`],"pairing.confirm":ah[`pairing.confirm`]},$={v:F.literal(1),id:ig},Dg=F.strictObject({expect:yg}),Og=Dg.extend({ownerRevision:ag.nullable()}),kg=hh.options[0],Ag=kg.shape.flowId,jg=F.discriminatedUnion(`cmd`,[F.strictObject({...$,cmd:F.literal(`desktop.login.set`),args:Og.extend({enabled:F.boolean()})}),F.strictObject({...$,cmd:F.literal(`desktop.setup`),args:Og.extend({consent:F.literal(!0)})}),F.strictObject({...$,cmd:F.literal(`desktop.start`),args:Og}),F.strictObject({...$,cmd:F.literal(`desktop.stop`),args:Og}),F.strictObject({...$,cmd:F.literal(`ownership.convert`),args:Og.extend({target:Qh,consent:F.literal(!0)})}),F.strictObject({...$,cmd:F.literal(`ownership.recover`),args:Og.extend({intentId:F.uuid()})}),F.strictObject({...$,cmd:F.literal(`hello`)}),F.strictObject({...$,cmd:F.literal(`status`)}),F.strictObject({...$,cmd:F.literal(`settings.get`)}),F.strictObject({...$,cmd:F.literal(`diagnostics`)}),F.strictObject({...$,cmd:F.literal(`devices`)}),F.strictObject({...$,cmd:F.literal(`terminals`)}),F.strictObject({...$,cmd:F.literal(`agents`)}),F.strictObject({...$,cmd:F.literal(`agents.setup`),args:Tg}),F.strictObject({...$,cmd:F.literal(`agents.skip`),args:Tg}),F.strictObject({...$,cmd:F.literal(`agents.remove`),args:F.strictObject({kind:Cg})}),F.strictObject({...$,cmd:F.literal(`terminals.connect`),args:F.strictObject({name:Xl})}),F.strictObject({...$,cmd:F.literal(`settings.set`),args:Dg.extend({configRevision:og,changes:F.array(F.strictObject({key:F.enum(Cm),value:sg})).min(1).max(Cm.length).refine(e=>new Set(e.map(e=>e.key)).size===e.length)})}),F.strictObject({...$,cmd:F.literal(`service.start`),args:Dg.extend({mode:cg,consent:F.literal(!0),migrateLegacy:F.boolean(),stateDir:Zh.optional()})}),F.strictObject({...$,cmd:F.literal(`service.stop`),args:Dg}),F.strictObject({...$,cmd:F.literal(`service.restart`),args:Dg}),F.strictObject({...$,cmd:F.literal(`service.remove`),args:Dg}),F.strictObject({...$,cmd:F.literal(`service.recover`),args:Dg.extend({action:F.enum([`continue`,`restore-legacy`,`discard-backup`,`use-manual`]),restartPrevious:F.boolean(),consent:F.literal(!0)}).refine(e=>!e.restartPrevious||e.action===`restore-legacy`)}),F.strictObject({...$,cmd:F.literal(`devices.revoke`),args:Dg.extend({phoneFp:U})}),F.strictObject({...$,cmd:F.literal(`pairing.open`),args:Dg}),F.strictObject({...$,cmd:F.literal(`pairing.close`),args:Dg.extend({flowId:Ag})}),F.strictObject({...$,cmd:F.literal(`pairing.confirm`),args:Dg.extend({flowId:Ag,challengeId:kg.shape.challengeId,phoneFp:U,accept:F.boolean()})})]),Mg=F.enum([`bad-request`,`unsupported-version`,`handshake-required`,`busy`,`unavailable`,`conflict`,`unsafe-state`,`invalid-config`,`upgrade-required`,`startup-unavailable`,`delivery-unknown`,`approval-required`,`recovery-required`,`operation-failed`,`response-too-large`,`timeout`]);var Ng=class extends Error{code;constructor(e){super(e),this.code=e,this.name=`NativeControllerError`}};F.discriminatedUnion(`ok`,[F.strictObject({...$,ok:F.literal(!0),data:F.union(Object.values(Eg))}),F.strictObject({...$,ok:F.literal(!1),error:F.strictObject({code:Mg})})]);const Pg=F.discriminatedUnion(`event`,[kg.extend({v:F.literal(1)}),hh.options[1].extend({v:F.literal(1)})]);function Fg(){throw new Ng(`unsafe-state`)}function Ig(e,t){return Xf(e,t)&&e.size===t.size&&e.mtimeMs===t.mtimeMs&&e.ctimeMs===t.ctimeMs&&e.mode===t.mode&&e.uid===t.uid}function Lg(e){return e instanceof Ng?e:new Ng(e instanceof Y?`unsafe-state`:`operation-failed`)}var Rg=class{options;root;path;uid;newId;constructor(e){this.options=e,(!Zh.safeParse(e.root).success||!Number.isSafeInteger(e.uid)||e.uid<0)&&Fg(),this.root=e.root.replace(/\/+$/,``)||`/`,this.path=N(this.root,e.filename),this.uid=e.uid,this.newId=e.newId??ce}inspect(){try{return this.checkAncestors(),X(this.root)?this.readSnapshot(Z(this.root,this.uid)).record:null}catch{return Fg()}}async mutate(e,t){let n,r,i=!0;try{this.checkAncestors(),X(this.root)||m(this.root,{recursive:!0,mode:448});let a=Z(this.root,this.uid);r=h(this.root,o.O_RDONLY|o.O_NOFOLLOW|o.O_NONBLOCK),Xf(a,l(r))||Fg(),n=this.acquireGuard(a);let s=this.readSnapshot(a);if((s.record?.revision??null)!==e)throw new Ng(`conflict`);return await t({get current(){return structuredClone(s.record)},publish:e=>{if(!i)throw new Ng(`operation-failed`);try{let t=this.options.schema.safeParse({...e,revision:this.newId()});(!t.success||t.data.revision===s.record?.revision)&&Fg();let i=Buffer.from(JSON.stringify(t.data));return i.length>this.options.maxBytes&&Fg(),this.publish(i,a,s,()=>n.assert()),u(r),s=this.readSnapshot(a),structuredClone(t.data)}catch(e){throw Lg(e)}}})}catch(e){throw Lg(e)}finally{i=!1;try{n?.release()}finally{r!==void 0&&a(r)}}}checkAncestors(){let e=this.root;for(;;){let t=X(e);t&&(!t.isDirectory()||t.isSymbolicLink())&&Fg();let n=j(e);if(n===e)return;e=n}}checkRoot(e){this.checkAncestors(),Xf(e,Z(this.root,this.uid))||Fg()}readSnapshot(e){this.checkRoot(e);let t=X(this.path);if(!t)return this.checkRoot(e),{record:null,stat:void 0,bytes:null};let n=$f(this.path,this.options.maxBytes,this.uid),r=X(this.path);(!r||!Ig(t,r))&&Fg(),this.checkRoot(e);let i;try{i=JSON.parse(new TextDecoder(`utf-8`,{fatal:!0}).decode(n))}catch{return Fg()}let a=this.options.schema.safeParse(i);return a.success?{record:a.data,stat:r,bytes:n}:Fg()}checkSnapshot(e,t){let n=this.readSnapshot(e);(t.stat?!n.stat||!Ig(t.stat,n.stat)||!t.bytes?.equals(n.bytes):n.stat!==void 0)&&Fg()}publish(e,t,n,r){r(),this.checkSnapshot(t,n);let i=`${this.path}.tmp-${ce()}`,s,c;try{s=h(i,o.O_WRONLY|o.O_CREAT|o.O_EXCL|o.O_NOFOLLOW,384),c=l(s);let a=0;for(;a<e.length;){let t=T(s,e,a,e.length-a);if(t<=0)throw new Ng(`operation-failed`);a+=t}u(s);let d=l(s);this.checkSnapshot(t,n);let f=X(i);(!f||!Xf(c,d)||!Ig(d,f)||!f.isFile()||f.uid!==this.uid||(f.mode&4095)!=384||d.size!==e.length)&&Fg(),r(),b(i,this.path)}finally{s!==void 0&&a(s);try{this.checkRoot(t);let e=X(i);c&&e&&Xf(c,e)&&C(i)}catch{}}}acquireGuard(e){let t=`${this.path}.lock`,n=`owner-${process.pid}-${ce()}`,r=`${this.path}.lock-candidate-${n.slice(6)}`,i,o,s=!1,c=(r,i,a=n,s=o,c=!1)=>{try{if(this.checkRoot(e),!Xf(i,Z(r,this.uid)))return!1;let n=X(N(r,a));if(n&&(!s||!Ig(s,n)))return!1;if(r===t){if(!n||!s)return!1;let e=`${this.path}.lock-candidate-${a.slice(6)}`;if(X(e)||(b(r,e),r=e,!Xf(i,Z(r,this.uid)))||(n=X(N(r,a)),!n||!Ig(s,n)))return!1;if(c)return!0}return n&&C(N(r,a)),x(r),!0}catch{return!1}};try{this.checkRoot(e),m(r,{mode:448}),i=Z(r,this.uid);let u=h(N(r,n),`wx`,384);try{o=l(u)}finally{a(u)}for(let a=0;a<3;a++){if(this.checkRoot(e),X(t)){let e=Z(t,this.uid),n=v(t),r=n[0],i=r&&/^owner-([1-9][0-9]*)-([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/.exec(r),a=i&&Gf(i[1]);(n.length!==1||!r||!a)&&Fg();let o=X(N(t,r));if($f(N(t,r),0,this.uid),Kf(a))throw new Ng(`busy`);Xf(e,Z(t,this.uid))||Fg();let s=X(N(t,r));(!o||!s||!Ig(o,s))&&Fg(),c(t,e,r,o,!0)||Fg()}try{b(r,t),s=!0;let a=Z(t,this.uid);return Xf(i,a)||Fg(),{assert:()=>{this.checkRoot(e),Xf(a,Z(t,this.uid))||Fg();let r=X(N(t,n));(!r||!o||!Ig(o,r))&&Fg()},release:()=>c(t,a)}}catch(e){if(![`EEXIST`,`ENOTEMPTY`,`ENOENT`].includes(e.code??``))throw e}}throw new Ng(`busy`)}finally{!s&&i&&c(r,i)}}},zg=class extends Rg{constructor(e){super({root:e.stateDir,uid:e.uid,filename:`service-owner.json`,maxBytes:16384,schema:ng})}};function Bg(e){if(e?.mode===`desktop`)throw Error(`Service is desktop-owned; use Shellbell or explicitly convert it to headless mode`);if(e?.transition)throw Error(`An ownership conversion needs explicit recovery before headless service changes`)}function Vg(e){let t=new zg({...e,stateDir:Zf(e.stateDir)}).inspect(),n=t?.transition;t?.mode===`headless`&&n?.target===`headless`&&e.serviceInstance===n.id&&[`source-stopped`,`destination-started`].includes(n.phase)||Bg(t)}async function Hg(e,t){let n=new zg({...e,stateDir:Zf(e.stateDir)}),r=n.inspect();return Bg(r),n.mutate(r?.revision??null,async e=>(Bg(e.current),t()))}async function Ug(e,t){let n=new zg(e),r=n.inspect();if(Bg(r),!e.create&&!r&&!s(e.stateDir))return t();let i=!1,a;return n.mutate(r?.revision??null,async n=>{Bg(n.current);let r;try{r=await t()}catch(e){throw i=!0,a=e,e}let o=e.startupPreference?e.startupPreference(r):r.startupEnabled;return o!==null&&(r.installed||n.current)&&(!n.current||n.current.startupEnabled!==o)&&n.publish({v:1,mode:`headless`,consented:!0,startupEnabled:o,transition:null}),r}).catch(e=>{throw i?a:e})}function Wg(e){try{return y(e)}catch(t){if(t.code===`ENOENT`)return P(e);throw Error(`Cannot resolve state directory ${e}`)}}function Gg(e,t){try{return e.process.computerFp===t.computerFp&&Wg(e.process.stateDir)===Wg(t.stateDir)&&(t.serviceInstance===void 0||e.process.serviceInstance===t.serviceInstance)&&(t.pid===void 0||e.process.pid===t.pid)}catch{return!1}}var Kg=class{clock;probe;constructor(e={}){this.clock=e.clock??{now:()=>de.now(),sleep:e=>new Promise(t=>setTimeout(t,e))},this.probe=e.probe??((e,t)=>Eh(e,`status`,void 0,{timeoutMs:t,maxResponseBytes:65536}))}async observe(e,t,n=500){let r;try{r=await this.probe(e,n)}catch(e){let t=e.code;return t===`ENOENT`||t===`ECONNREFUSED`?{kind:`absent`,local:null,diagnostic:`Local endpoint is absent`}:{kind:`unverified`,local:null,diagnostic:`Local endpoint did not return a bounded status response`}}let i=Fm.safeParse(r);return i.success?t&&!Gg(i.data,t)?{kind:`foreign`,local:i.data,diagnostic:`Local endpoint belongs to a different process, identity, state directory, or service instance`}:{kind:`verified`,local:i.data}:{kind:`unverified`,local:null,diagnostic:`Local endpoint uses an unsupported or malformed status protocol`}}async waitReady(e,t){return(await this.wait(e,t,!1)).local}async waitStopped(e){await this.wait(e,void 0,!0)}async wait(e,t,n){let r=this.clock.now()+1e4,i=`Local endpoint is absent`;for(;this.clock.now()<r;){let a=await this.observe(e,t,Math.min(500,r-this.clock.now()));if(n?a.kind===`absent`:a.kind===`verified`)return a;if(i=a.diagnostic??`Local endpoint is still responding`,!n&&a.kind===`foreign`)throw Error(`Service readiness conflict: ${i}; stop the foreground owner before retrying`);let o=r-this.clock.now();o>0&&await this.clock.sleep(Math.min(100,o))}throw Error(`${n?`Service stop`:`Service readiness`} timed out: ${i}`)}};const qg=new Set([`.npm`,`_npx`,`dlx`]),Jg=[[`npm`,`config`,`cache`].join(`_`),`NPM_CONFIG_CACHE`];function Yg(e,t){throw Error(`Shellbell service runtime at ${e} ${t}; install a built Shellbell package in a durable directory, then rerun service install`)}function Xg(e){try{return y(e)}catch{return ne(e)}}function Zg(){let e=[O(),`/tmp`,`/private/tmp`,`/var/tmp`,`/private/var/tmp`];for(let t of Jg){let n=process.env[t];n&&M(n)&&e.push(n)}return[...new Set(e.flatMap(e=>[ne(e),Xg(e)]))]}function Qg(e,t){let n=re(t,e);return n===``||n!==`..`&&!n.startsWith(`..${ie}`)&&!M(n)}function $g(e){let t=ne(e);(t.split(ie).some(e=>qg.has(e))||Zg().some(e=>Qg(t,e)))&&Yg(e,`is in a temporary or package-manager cache location`)}function e_(e,t){M(e)||Yg(e,`${t} path must be absolute`),$g(e);let n;try{n=y(e)}catch{Yg(e,`${t} does not exist`)}return $g(n),(()=>{try{return te(n)}catch{return Yg(n,`${t} does not exist`)}})().isFile()||Yg(n,`${t} must be a regular file`),n}function t_(e,t,r){try{n(e,t)}catch{Yg(e,r)}}function n_(e){let t=`${e}${ie}package.json`,n=(()=>{try{return te(t)}catch{return Yg(t,`package.json is missing`)}})();n.isFile()||Yg(t,`package.json must be a regular file`),n.size>1048576&&Yg(t,`package.json exceeds 1 MiB`);let r;try{r=g(t,`utf8`)}catch{Yg(t,`package.json is not readable`)}let i;try{i=JSON.parse(r)}catch{Yg(t,`package.json is not valid JSON`)}return(typeof i!=`object`||!i||Array.isArray(i))&&Yg(t,`package.json is not a valid manifest`),i}function r_(e){let t=e.bin,n=typeof t==`string`?t:typeof t==`object`&&t&&!Array.isArray(t)?t.shellbell:void 0;return n===`dist/cli.js`||n===`./dist/cli.js`}function i_(e=process.execPath,t=process.argv[1]??``){let n=Number.parseInt(process.versions.node.split(`.`)[0]??``,10);(!Number.isInteger(n)||n<22)&&Yg(process.execPath,`requires the currently running Node.js major version to be at least 22`);let r=e_(e,`Node executable`);t_(r,o.X_OK,`Node executable is not executable`);let i=e_(t,`CLI entrypoint`);t_(i,o.R_OK,`CLI entrypoint is not readable`),(A(i)!==`cli.js`||A(j(i))!==`dist`)&&Yg(i,`is not an installed built CLI entrypoint`);let a=j(j(i)),c=`${a}${ie}src${ie}cli.ts`;s(c)&&Yg(a,`is a source checkout rather than an installed built package`);let l=n_(a);return l.name!==`shellbell`&&Yg(`${a}${ie}package.json`,`has the wrong package name`),r_(l)||Yg(`${a}${ie}package.json`,`does not declare the Shellbell bin entrypoint`),{nodePath:r,cliPath:i,packageRoot:a}}var a_=class extends Error{rollback=`not-needed`;rollbackDiagnostic;recoveryPath};function o_(e,t,n){let r=e.definition?.stateDir,i=Wg(r??(t||n));if(r&&t&&Wg(t)!==i)throw new a_(`SHELLBELL_DIR conflicts with the installed service state directory; state migration is not an implicit install operation`);return Ep(i)}function s_(e){return e instanceof a_?e:new a_(e instanceof Error?e.message.slice(0,600):`Service operation failed`)}async function c_(e,t,n){let r=j(e.definitionPath),i;try{return t&&m(r,{recursive:!0,mode:448}),s(r)&&(i=Yf(e.definitionPath)),await n(e)}finally{i?.()}}var l_=class{options;manager;readiness;constructor(e){this.options=e,this.manager=e.manager,this.readiness=new Kg(e)}selected(e){return o_(e,this.options.requestedStateDir,this.options.defaultStateDir)}definitionFor(e,t,n){let r=Rh({stateDir:t.dir,serviceInstance:n,nodePath:e.nodePath,env:this.options.env}),i={nodePath:e.nodePath,cliPath:e.cliPath,stateDir:t.dir,serviceInstance:n,environment:r,logPath:t.log};for(let e of Object.values(i))typeof e==`string`&&Ih(e);for(let[e,t]of Object.entries(r))Ih(e),Ih(t);return i}expected(e,t){let n=Oh(t);return n?{computerFp:n.fp,stateDir:t.dir,serviceInstance:e.definition?.serviceInstance??null}:void 0}result(e,t,n,r=null,i){let a=e.installed&&e.definition?.serviceInstance===null,o=e.installed&&e.loaded&&!!n&&t.kind===`verified`&&(!a||r!==null),s=i??(n?a&&r===null?`Legacy service cannot be verified by read-only status; run service install to upgrade`:void 0:`Local identity is missing; no keys were created`),c=e.definition&&!e.definition.environment.SHELLBELL_DIR?`Legacy definition assumes the historical ~/.shellbell state directory`:void 0;return{manager:this.manager.kind,definitionPath:this.manager.definitionPath,installed:e.installed,loaded:e.loaded,startupEnabled:e.startupEnabled??null,autostartConfigured:e.installed&&e.startupEnabled===!0,managedPid:r,ownership:t.kind===`foreign`?`foreign`:a&&!o?`legacy`:o?`verified`:`none`,local:t.local,ready:o,...t.diagnostic||s||c?{diagnostic:[t.diagnostic,s,c].filter(Boolean).join(`; `)}:{}}}async status(){let e=await this.manager.inspect(),t=this.selected(e),n=this.expected(e,t);return this.result(e,await this.readiness.observe(t.sock,n),n)}async serialized(e,t){try{let n=await this.manager.inspect();return await Ug({stateDir:Zf(this.selected(n).dir),uid:process.getuid(),create:e},()=>c_(this.manager,e,t))}catch(e){throw s_(e)}}assertAvailable(e,t,n){if(t.kind!==`absent`&&!(e.loaded&&e.definition?.serviceInstance===null&&t.kind===`unverified`)&&!(e.loaded&&n&&t.kind===`verified`))throw new a_(`Local endpoint ownership is unverified or foreign; stop the foreground owner before retrying service changes`)}async rollback(e,t,n,r,i){let a=s_(i);if(!r.unloadAttempted&&!r.written&&!r.loaded)throw a;try{if(r.loaded&&await this.manager.unload(),(r.unloadAttempted||r.loaded)&&await this.readiness.waitStopped(t.sock),r.written&&await this.manager.restore(e.raw),e.loaded){let r=await this.manager.load();e.definition?.serviceInstance&&n&&await this.readiness.waitReady(t.sock,{...n,pid:r})}a.rollback=`restored`}catch(t){if(a.rollback=`failed`,a.rollbackDiagnostic=s_(t).message,e.raw){let t=`${this.manager.definitionPath}.recovery-${ce()}`;try{w(t,e.raw,{mode:384,flag:`wx`}),a.recoveryPath=t}catch{a.rollbackDiagnostic+=`; could not save a private recovery definition`}}}throw a}async install(){try{let e=i_(),t=ce();return this.definitionFor(e,Ep(Wg(this.options.requestedStateDir||this.options.defaultStateDir)),t),await this.serialized(!0,async()=>{let n=await this.manager.inspect(),r=this.selected(n),i=this.definitionFor(e,r,t),a=this.expected(n,r);if(n.installed&&!a)throw new a_(`Installed service identity is missing at ${r.identity}; restore it before upgrading`);this.assertAvailable(n,await this.readiness.observe(r.sock,a),a);let o=Oh(r)??kh(r);Xh(r.log);let s={computerFp:o.fp,stateDir:r.dir,serviceInstance:t},c={unloadAttempted:!1,written:!1,loaded:!1};try{n.loaded&&(c.unloadAttempted=!0,await this.manager.unload(),await this.readiness.waitStopped(r.sock)),c.written=!0,await this.manager.write(i),c.loaded=!0;let e=await this.manager.load(),t=await this.readiness.waitReady(r.sock,{...s,pid:e}),a=await this.manager.inspect();if(!a.loaded)throw Error(`Service unloaded before readiness could be confirmed`);return this.result(a,{kind:`verified`,local:t},s,e)}catch(e){return this.rollback(n,r,a,c,e)}})}catch(e){throw s_(e)}}start(){return this.runInstalled(`start`)}restart(){return this.runInstalled(`restart`)}stop(){return this.runInstalled(`stop`)}enable(){return this.setStartup(!0)}disable(){return this.setStartup(!1)}async setStartup(e){return this.serialized(!1,async()=>{let t=await this.manager.inspect(),n=this.selected(t);if(!t.installed)throw new a_(`Service is not installed; run service install first`);await this.manager.setStartupEnabled(e);let r=await this.manager.inspect();if(r.startupEnabled!==e||r.loaded!==t.loaded)throw new a_(`Startup preference or current execution could not be verified`);let i=this.expected(r,n);return this.result(r,await this.readiness.observe(n.sock,i),i)})}uninstall(){return this.runInstalled(`uninstall`)}runInstalled(e){return this.serialized(!1,async()=>{let t=await this.manager.inspect(),n=this.selected(t),r=e===`stop`||e===`uninstall`,i,a;try{i=this.expected(t,n)}catch(e){if(!r)throw e;a=s_(e).message}let o=await this.readiness.observe(n.sock,i);if(!t.installed){if(!r)throw new a_(`Service is not installed; run service install first`);return this.result(t,o,i,null,a)}if(!r&&!i)throw new a_(`Local identity is missing at ${n.identity}; restore it before starting`);r&&t.loaded&&o.kind===`unverified`||this.assertAvailable(t,o,i);let s={unloadAttempted:!1,written:!1,loaded:!1};try{if(e!==`start`&&t.loaded&&(s.unloadAttempted=!0,await this.manager.unload(),await this.readiness.waitStopped(n.sock)),r){e===`uninstall`&&await this.manager.restore(null);let t=await this.manager.inspect();if(t.loaded)throw Error(`Service remains loaded after stop`);return this.result(t,{kind:`absent`,local:null,diagnostic:e===`stop`?`Service stopped; definition remains and it may start at next login`:`Service uninstalled; identity and pairings remain`},i,null,a)}s.loaded=!t.loaded||e===`restart`;let c=await this.manager.load();if(e===`restart`&&o.local?.process.pid===c)throw Error(`Service restart did not produce a new manager-certified process`);let l=await this.readiness.waitReady(n.sock,{...i,pid:c}),u=await this.manager.inspect();if(!u.loaded)throw Error(`Service unloaded before readiness could be confirmed`);return this.result(u,{kind:`verified`,local:l},i,c)}catch(e){if(r)throw s_(e);return this.rollback(t,n,i,s,e)}})}};export{lm as $,Kn as $n,au as $t,Oh as A,oc as An,Yf as At,Cm as B,br as Bn,Kd as Bt,lg as C,Qs as Cn,ep as Ct,Nh as D,vc as Dn,X as Dt,Yh as E,_c as En,Zf as Et,Ch as F,Ir as Fn,Vf as Ft,mm as G,ur as Gn,Td as Gt,Em as H,ir as Hn,vd as Ht,Gm as I,Lr as In,Bf as It,om as J,Yn as Jn,gd as Jt,_m as K,nr as Kn,wd as Kt,Um as L,Er as Ln,Tf as Lt,Dh as M,ya as Mn,Gf as Mt,Eh as N,Dr as Nn,Uf as Nt,Mh as O,lc as On,Z as Ot,Q as P,Or as Pn,Hf as Pt,cm as Q,V as Qn,Lu as Qt,Fm as R,xr as Rn,of as Rt,xg as S,yc as Sn,ap as St,Zh as T,uc as Tn,$f as Tt,xm as U,W as Un,Dd as Ut,Dm as V,rr as Vn,yd as Vt,bm as W,G as Wn,Cd as Wt,um as X,$n as Xn,ud as Xt,dm as Y,tr as Yn,_d as Yt,sm as Z,er as Zn,fd as Zt,Pg as _,Nc as _n,xp as _t,i_ as a,nu as an,qp as at,jg as b,dc as bn,sp as bt,zg as c,Hl as cn,Ip as ct,Ug as d,il as dn,Fp as dt,Xl as en,Gn as er,im as et,Rg as f,Rc as fn,Yp as ft,Mg as g,wc as gn,Sp as gt,Eg as h,Sc as hn,gp as ht,c_ as i,Cu as in,Pp as it,Th as j,La as jn,Kf as jt,kh as k,ac as kn,Xf as kt,Vg as l,al as ln,Jp as lt,Ng as m,bc as mn,vp as mt,a_ as n,iu as nn,Zp as nt,Kg as o,xu as on,Dp as ot,rg as p,Vc as pn,Op as pt,gm as q,U as qn,hd as qt,o_ as r,ru as rn,zp as rt,Gg as s,Au as sn,Lp as st,l_ as t,Yl as tn,rm as tt,Hg as u,sl as un,Ep as ut,vg as v,sc as vn,cp as vt,eg as w,tc as wn,Y as wt,fg as x,rc as xn,op as xt,gg as y,fc as yn,dp as yt,Im as z,wr as zn,af as zt};