shellbell 0.13.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +39 -34
- package/dist/doctor-ChDZpdTd.js +86 -0
- package/dist/native-controller.js +2 -2
- package/dist/native-service.js +2 -2
- package/dist/service-entry-CRFCiWGq.js +11 -0
- package/dist/service-lifecycle-Cl7R7c5G.js +29 -0
- package/package.json +2 -2
- package/dist/doctor-D2Hd_mqM.js +0 -86
- package/dist/service-entry-Dz0BLRLS.js +0 -11
- package/dist/service-lifecycle-CCOIXXFm.js +0 -29
package/dist/cli.js
CHANGED
|
@@ -1,48 +1,53 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{$ as e,$n as t,$t as n,An as r,At as i,B as a,Bn as o,Bt as s,Cn as c,Ct as l,Dn as u,Dt as d,E as f,En as p,Et as m,F as h,Fn as g,Ft as _,G as v,Gn as y,Gt as b,Hn as x,Ht as S,In as C,It as ee,J as w,Jn as te,Jt as ne,K as re,Kn as ie,Kt as ae,Ln as oe,Lt as se,M as ce,Mn as le,Mt as ue,N as T,Nn as de,Nt as fe,On as pe,Ot as E,Pn as me,Pt as he,Q as ge,Qt as _e,Rn as D,Rt as ve,Sn as ye,St as be,Tn as xe,Tt as O,U as Se,Un as Ce,Ut as we,V as Te,Vn as Ee,Vt as De,W as Oe,Wn as k,Wt as ke,X as Ae,Xn as je,Xt as Me,Y as Ne,Yn as Pe,Yt as Fe,Z as A,Zn as Ie,Zt as Le,_n as Re,an as ze,at as Be,bn as Ve,bt as He,cn as Ue,ct as We,dt as Ge,en as Ke,er as qe,et as Je,fn as Ye,gn as Xe,gt as Ze,hn as Qe,ht as $e,in as et,ir as j,j as tt,jn as nt,jt as rt,k as it,kn as at,kt as ot,l as st,ln as ct,lt,mn as ut,mt as dt,n as ft,nn as pt,nr as mt,on as ht,ot as gt,pn as _t,pt as vt,q as yt,qn as M,qt as bt,rn as xt,rr as St,rt as N,sn as Ct,st as wt,t as Tt,tr as Et,tt as Dt,u as Ot,un as kt,ut as At,vt as jt,wn as Mt,xn as Nt,xt as Pt,yn as P,yt as Ft,z as It,zn as Lt,zt as Rt}from"./service-lifecycle-CCOIXXFm.js";import{$ as zt,A as Bt,B as Vt,C as Ht,D as Ut,E as Wt,F as Gt,G as Kt,H as qt,I as Jt,J as Yt,K as Xt,L as Zt,M as Qt,N as $t,O as en,P as tn,Q as nn,R as rn,S as an,T as on,U as sn,V as cn,W as ln,X as un,Y as dn,Z as fn,_ as pn,a as mn,at as hn,b as gn,c as _n,d as vn,et as yn,f as bn,g as xn,h as Sn,i as Cn,it as wn,j as Tn,k as En,l as Dn,m as On,n as kn,nt as An,o as jn,ot as Mn,p as Nn,q as Pn,r as Fn,rt as In,s as Ln,st as Rn,tt as zn,u as Bn,v as Vn,w as Hn,x as Un,y as Wn,z as Gn}from"./doctor-D2Hd_mqM.js";import{execFile as Kn,spawn as qn}from"node:child_process";import{closeSync as Jn,constants as Yn,existsSync as Xn,fstatSync as Zn,fsyncSync as Qn,lstatSync as $n,mkdirSync as er,openSync as tr,opendirSync as nr,readFileSync as rr,readSync as ir,realpathSync as ar,statSync as or}from"node:fs";import{homedir as F,hostname as sr,tmpdir as cr}from"node:os";import{basename as lr,dirname as I,isAbsolute as ur,join as L,normalize as dr,relative as fr,sep as pr}from"node:path";import{createInterface as mr}from"node:readline";import{fileURLToPath as hr,pathToFileURL as gr}from"node:url";import{z as R}from"zod";import{Command as _r}from"commander";import vr from"qrcode-terminal";import{createHash as z,randomUUID as yr,timingSafeEqual as br}from"node:crypto";import{EventEmitter as xr}from"node:events";import{connect as Sr,createConnection as Cr,isIP as wr}from"node:net";import{lstat as B,mkdtemp as Tr,open as Er,opendir as Dr,readFile as Or,readdir as kr,readlink as Ar,realpath as V,rm as jr}from"node:fs/promises";import Mr from"ws";import{promisify as Nr}from"node:util";import{create as H}from"@bufbuild/protobuf";import{importTerminalPlugin as Pr}from"#terminal-plugin-loader";import{createInterface as Fr}from"node:readline/promises";const Ir=e=>/^turns?:/.test(e),Lr=e=>!/:53(\?|$)/.test(e);function Rr(e=[]){let t=[{urls:[`stun:stun.cloudflare.com:3478`]}],n=3;for(let r of e){if(!r.username||!r.credential)continue;let e=r.urls.filter(e=>Ir(e)&&Lr(e)).slice(0,n);if(e.length!==0&&(n-=e.length,t.push({urls:e,username:r.username,credential:r.credential}),n===0))break}return t}var zr=class{relay=[];expiresAt=0;advertised=!1;lastRefresh=-1/0;get supported(){return this.advertised}update(e,t,n){this.relay=e.map(e=>({...e,urls:[...e.urls]})),this.expiresAt=n+t,this.advertised=!0}servers(e){return Rr(e<this.expiresAt?this.relay:[])}needsRefresh(e){return this.advertised&&this.expiresAt-e<=288e5}takeRefresh(e){return!this.advertised||e-this.lastRefresh<6e5?!1:(this.lastRefresh=e,!0)}},Br=class extends xr{opts;s=new Map;now;constructor(e){super(),this.opts=e,this.now=e.now??(()=>Date.now())}stateOf(e){return this.s.get(e)?.promptState??`unknown`}setPromptState(e,t,n){e.promptState!==t&&e.promptState!==`unknown`&&(e.stateSince=n),e.promptState=t}activityOf(e){let t=this.s.get(e);return{...t?.lastChangeAt?{activeAt:t.lastChangeAt}:{},...t?.stateSince==null?{}:{stateSince:t.stateSince},reportsAgentState:t?.agentState!=null}}forget(e){this.s.delete(e)}get(e){let t=this.s.get(e);return t||(t={blockedNotified:!1,promptState:`unknown`,commandStartedAt:null,command:``,lastChangeAt:0,activeSince:null,lastPromptRingAt:-1/0,agentState:null,workingSince:null,stateSince:null},this.s.set(e,t)),t}onBackendEvent(e){let t=this.now();switch(e.type){case`screen-changed`:{let n=this.get(e.sessionId);n.lastChangeAt=t,n.activeSince??=t;return}case`command-start`:{let n=this.get(e.sessionId);this.setPromptState(n,`running`,t),n.commandStartedAt=t,n.command=e.command;return}case`command-end`:{let n=this.get(e.sessionId);this.setPromptState(n,`finished`,t);let r=n.commandStartedAt===null?void 0:t-n.commandStartedAt;n.commandStartedAt=null,this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`prompt`,exitCode:e.exitCode,durationMs:r,command:n.command||void 0,at:t}),r!==void 0&&r>=this.opts.notifyMinCommandMs&&(n.lastPromptRingAt=t,n.activeSince=null,this.emit(`ring`,{reason:`command-finished`,sessionId:e.sessionId,kind:`prompt`,exitCode:e.exitCode,durationMs:r}));return}case`prompt`:{let n=this.get(e.sessionId),r=n.commandStartedAt===null?void 0:t-n.commandStartedAt;n.commandStartedAt=null,this.setPromptState(n,`editing`,t),r!==void 0&&r>=this.opts.notifyMinCommandMs&&(n.activeSince=null,n.lastPromptRingAt=t,this.emit(`ring`,{sessionId:e.sessionId,kind:`prompt`,reason:`prompt-returned`,durationMs:r}));return}case`agent-state`:{let n=this.get(e.sessionId),r=n.agentState;if(r===e.state)return;if(n.agentState=e.state,e.state===`working`){n.blockedNotified=!1,this.setPromptState(n,`running`,t),n.workingSince=t;return}if(e.state===`blocked`){this.setPromptState(n,`blocked`,t),n.workingSince=null,n.activeSince=null,n.lastPromptRingAt=t,this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`blocked`,at:t}),r!==null&&!n.blockedNotified&&this.emit(`ring`,{sessionId:e.sessionId,kind:`blocked`,reason:`agent-blocked`}),n.blockedNotified=!0;return}if(e.state===`idle`||e.state===`done`){this.setPromptState(n,`finished`,t);let i=n.workingSince;if(n.workingSince=null,r!==`working`||i===null)return;let a=t-i;this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`prompt`,durationMs:a,at:t}),a>=this.opts.notifyMinCommandMs&&(n.lastPromptRingAt=t,n.activeSince=null,this.emit(`ring`,{sessionId:e.sessionId,kind:`prompt`,reason:e.state===`done`?`agent-finished`:`quiet`,durationMs:a}));return}n.promptState=`unknown`,n.stateSince=null,n.workingSince=null;return}case`session-removed`:this.s.delete(e.sessionId),this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`exit`,at:t});return;default:return}}tick(){let e=this.now();for(let[t,n]of this.s){if(n.agentState!==null&&n.agentState!==`unknown`||n.activeSince===null||e-n.lastChangeAt<this.opts.idleQuietMs)continue;if(n.lastChangeAt-n.activeSince<this.opts.idleMinActiveMs){n.activeSince=null;continue}let r=n.lastChangeAt-n.activeSince;n.activeSince=null,this.emit(`event`,{type:`event`,sessionId:t,kind:`idle`,durationMs:r,at:e}),!(e-n.lastPromptRingAt<5e3+this.opts.idleQuietMs)&&n.promptState!==`editing`&&this.emit(`ring`,{sessionId:t,kind:`idle`,reason:`quiet`,durationMs:r})}}};function Vr(e){return e===`darwin`||e===`linux`||e===`win32`?e:`unknown`}function Hr(e){return{type:`notify`,sessionId:e.sessionId,kind:e.kind,exitCode:e.exitCode,durationMs:e.durationMs}}function Ur(e){let t={...e,context:{...e.context}};for(let e of[`branch`,`title`,`agentName`,`shell`,`customName`,`repository`]){if(Nt.safeParse(t).success)return t;delete t.context[e]}return Nt.safeParse(t).success?t:void 0}var Wr=class{options;cache=new WeakMap;constructor(e){this.options=e}prepare(e){let t=this.cache.get(e);if(t)return t();let n=new Map(this.options.pairings().map(e=>[e.phoneFp,e.kPair])),r=(this.options.now??Date.now)(),i=!1,a=performance.now(),o,s=new Promise(t=>{o=setTimeout(()=>{i=!0,t(Hr(e))},250)}),c=Promise.race([this.build(e,()=>i||performance.now()-a>=250,r),s]).catch(()=>Hr(e)).finally(()=>clearTimeout(o)),l=()=>c.then(t=>{let i=(this.options.now??Date.now)();if(t.type!==`notify-context`)return t;if(!this.options.capable()||i<r||i-r>=P.freshnessMs)return Hr(e);let a=this.options.pairings(),o=t.boxes.filter(e=>this.options.state.owns(e.phoneFp,e.generation)&&a.some(t=>t.phoneFp===e.phoneFp&&t.kPair===n.get(e.phoneFp)));return o.length?{...t,boxes:o}:Hr(e)});return this.cache.set(e,l),l()}async build(e,t,n){let r=this.options,i=r.now??Date.now,a=Hr(e);if(!r.capable()||!e.reason)return a;let o=k(C(16)),s=r.pairings().slice(0,10),c=await r.facts(e.sessionId);if(!c||t())return a;let l=async()=>{let t=await r.facts(e.sessionId);return t?.revision===c.revision&&t.sessionId===c.sessionId},u=await An(c,{computerName:r.computerName(),now:i,stillCurrent:l,git:r.git});if(t()||!r.capable()||!await l()||t())return a;let d=i();if(d-n>=P.freshnessMs||d<n||d<u.observedAt)return a;let f=[],p={type:`notify-context`,sessionId:e.sessionId,eventId:o,kind:e.kind,exitCode:e.exitCode,durationMs:e.durationMs,boxes:f};for(let i of s){if(t())break;if(!r.pairings().some(e=>e.phoneFp===i.phoneFp&&e.kPair===i.kPair))continue;let a=r.state.reserve(i.phoneFp);if(!a)continue;let s=Ur({computerFp:r.computerFp,phoneFp:i.phoneFp,generation:a.generation,sessionId:e.sessionId,eventId:o,sequence:a.sequence,issuedAt:d,expiresAt:n+P.freshnessMs,reason:e.reason,context:u,exitCode:e.exitCode,durationMs:e.durationMs,...c.instance&&r.state.instanceReader(i.phoneFp,a.generation)&&{instance:c.instance}});if(!s)continue;let l,m;try{l=x(i.kPair),m=Le(l,s),f.push(_e(m,s)),Buffer.byteLength(JSON.stringify(p),`utf8`)>16384&&f.pop()}catch{}finally{l?.fill(0),m?.fill(0)}}return f.length?p:a}};const Gr=R.string().regex(/^(0|[1-9][0-9]{0,19})$/).refine(e=>BigInt(e)<=18446744073709551615n),Kr=R.strictObject({generation:Ve,used:R.number().int().min(0).max(P.encryptions)}),qr=R.strictObject({version:R.literal(1),phones:R.array(R.strictObject({phoneFp:Ie,sequence:Gr,current:Kr,previous:R.strictObject({generation:Ve,expiresAt:R.number().int().nonnegative().max(2**53-1)}).optional()})).max(10).refine(e=>new Set(e.map(e=>e.phoneFp)).size===e.length)});var Jr=class{paths;now;data={version:1,phones:[]};healthy=!0;readsInstance=new Map;file;constructor(e,t=Date.now){this.paths=e,this.now=t,this.file=L(e.dir,`notifications.json`);try{wt(e);let t=L(e.dir,`notifications.initialized`),n=E(t)!==void 0;if(n&&m(t,8,process.getuid?.()).toString(`utf8`)!==`v1
|
|
3
|
-
`)throw Error(`invalid marker`);try{this.data=
|
|
4
|
-
`),this.syncDirectory())}catch{this.healthy=!1}}syncDirectory(){if(process.platform===`win32`)return;let e=tr(this.paths.dir,`r`);try{Qn(e)}finally{Jn(e)}}commit(e){if(!this.healthy)return!1;try{return wt(this.paths),dt(this.file,JSON.stringify(e)),this.syncDirectory(),this.data=e,!0}catch{return this.healthy=!1,!1}}enroll(e,t,n=[]){if(!this.healthy||!Ie.safeParse(e).success||!Ve.safeParse(t).success)return!1;n.includes(`notify-instance-v1`)?this.readsInstance.set(e,t):this.readsInstance.delete(e);let r=this.data.phones.find(t=>t.phoneFp===e);if(r?.current.generation===t)return r.current.used<P.encryptions;if(r?.previous?.generation===t||!r&&this.data.phones.length>=10)return!1;let i=structuredClone(this.data);return i.phones=i.phones.filter(t=>t.phoneFp!==e),i.phones.push({phoneFp:e,sequence:r?.sequence??`0`,current:{generation:t,used:0},...r?{previous:{generation:r.current.generation,expiresAt:this.now()+P.previousGenerationMs}}:{}}),this.commit(i)}reserve(e){if(!this.healthy)return;let t=structuredClone(this.data),n=t.phones.find(t=>t.phoneFp===e);if(!(!n||n.current.used>=P.encryptions||BigInt(n.sequence)>=18446744073709551615n))return n.sequence=String(BigInt(n.sequence)+1n),n.current.used++,n.previous&&n.previous.expiresAt<=this.now()&&delete n.previous,this.commit(t)?{generation:n.current.generation,sequence:n.sequence}:void 0}instanceReader(e,t){return this.readsInstance.get(e)===t}owns(e,t){return this.healthy&&this.data.phones.some(n=>n.phoneFp===e&&n.current.generation===t)}retain(e){if(this.data.phones.every(t=>e.has(t.phoneFp)))return;let t=structuredClone(this.data);t.phones=t.phones.filter(t=>e.has(t.phoneFp)),this.commit(t)}forget(e){this.readsInstance.delete(e);let t=structuredClone(this.data);t.phones=t.phones.filter(t=>t.phoneFp!==e),this.commit(t)}};const Yr=6e4;var Xr=class{send;log;now;prepare;last=new Map;constructor(e,t,n=()=>Date.now(),r){this.send=e,this.log=t,this.now=n,this.prepare=r}ring(e){let t=this.now(),n=this.last.get(e.sessionId);for(let[n,r]of this.last)n!==e.sessionId&&t-r>=Yr&&this.last.delete(n);return n!==void 0&&t-n<Yr?!1:(this.last.set(e.sessionId,t),this.prepare?this.prepare(e).then(e=>this.send(e)).catch(()=>{this.log.warn(`notification preparation failed`)}):this.send(Hr(e)),this.log.info(`ring`,{session:e.sessionId.slice(0,12),kind:e.kind}),!0)}forget(e){this.last.delete(e)}get size(){return this.last.size}};function Zr(e){return e.type===`input.line`||e.type===`input.text`||e.type===`input.key`||e.type===`input.mouse`||e.type===`input.terminal`||e.type===`input.paste`||e.type===`session.create`||e.type===`session.focus`}var Qr=class{completed=new Map;pending=new Map;get idle(){return this.pending.size===0}run(e,t){let n=this.completed.get(e);if(n)return Promise.resolve({...n});let r=this.pending.get(e);if(r)return r;if(this.pending.size>=256)return Promise.resolve({type:`ack`,reqId:e,ok:!1,error:`busy`});let i,a=new Promise(e=>{i=e});this.pending.set(e,a);let o=t=>{let n={...t};if(this.completed.set(e,n),this.completed.size>256){let e=this.completed.keys().next().value;e!==void 0&&this.completed.delete(e)}this.pending.delete(e),i({...n})},s=()=>o({type:`ack`,reqId:e,ok:!1,error:`delivery-unknown`});try{t().then(t=>{t.type!==`ack`||t.reqId!==e?s():o(t)},s)}catch{s()}return a}};const $r=R.instanceof(Uint8Array).refine(e=>e.length===32,{message:`expected 32 bytes`}),ei=R.instanceof(Uint8Array).refine(e=>e.length===64,{message:`expected 64 bytes`});function ti(e){return e.replace(/[\p{Cc}\p{Cs}\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/gu,` `).replace(/\s+/gu,` `).trim()||`Phone`}const ni=R.object({ed25519Pub:$r,x25519Pub:$r,name:R.string().min(1).max(64).transform(ti),platform:R.enum([`ios`,`android`]),bind:ei});var ri=class{opts;window=null;pending=null;now;log;constructor(e){this.opts=e,this.now=e.now??(()=>Date.now()),this.log=e.log.child({unit:`pairing`})}get isOpen(){return this.window!==null&&this.now()<this.window.expiresAt}openWindow(){this.window&&this.closeWindow(`replaced`);let e=C(16),t=C(16),n=this.now()+(this.opts.windowMs??3e5),r=ne({v:1,r:this.opts.relayUrl,c:this.opts.fp,e:k(this.opts.identity.ed25519.pub),n:this.opts.computerName.slice(0,40),p:k(e),g:k(t),b:1,x:Math.ceil(n/1e3)});Fe(r,{allowInsecure:!0}),this.window={code:e,gate:t,expiresAt:n,failures:0,requests:0};let i=this.opts.sendCtrl({type:`pairing-open`,gateHash:g(t),expiresAt:n});return this.log.debug(i?`pairing-open sent`:`pairing-open not sent yet; will re-advertise once authenticated`),this.log.info(`pairing window opened`),{qrText:r,expiresAt:n}}readvertise(){if(!this.window||this.now()>=this.window.expiresAt)return;if(this.window.requests>=5){this.log.info(`pairing window not re-advertised: admission cap reached`),this.closeIfExhausted(this.window);return}let e=this.opts.sendCtrl({type:`pairing-open`,gateHash:g(this.window.gate),expiresAt:this.window.expiresAt});this.log.debug(e?`pairing window re-advertised`:`pairing window re-advertise dropped`)}closeWindow(e=`closed`){if(!this.window)return;let t=this.window;t.code.fill(0),t.gate.fill(0),this.window=null,this.pending?.window===t&&(this.pending=null),this.opts.sendCtrl({type:`pairing-close`}),this.log.info(`pairing window closed`),this.opts.onClose?.(e)}closeIfExhausted(e){this.window!==e||e.requests<5||this.pending===null&&this.closeWindow()}tick(){this.window&&this.now()>=this.window.expiresAt&&this.closeWindow()}confirmWithTimeout(e,t){let n=this.opts.confirmTimeoutMs??6e4;return new Promise(r=>{let i=!1,a=setTimeout(()=>{i||(i=!0,this.log.warn(`confirmation timed out`,{phone:e.slice(0,8)}),r(!1))},n);typeof a.unref==`function`&&a.unref(),this.opts.confirm(e,t).then(e=>{i||(i=!0,clearTimeout(a),r(e))},()=>{i||(i=!0,clearTimeout(a),r(!1))})})}async handleRequest(e){let t=t=>{this.opts.sendCtrl({type:`pairing-reject`,phoneFp:e.phoneFp,reason:t}),this.log.warn(`pairing rejected`,{reason:t,phone:e.phoneFp.slice(0,8)})};if(!this.isOpen||!this.window)return t(`window-closed`);let n=this.window;if(n.requests>=5){t(`window-closed`),this.closeIfExhausted(n);return}if(n.requests+=1,this.opts.pairingCount()>=10||this.pending!==null){t(`too-many`),this.closeIfExhausted(n);return}let i=Mt(n.code,this.opts.fp),a;try{if(a=ni.parse(St(at(i,e.box,r(`request`,this.opts.fp,e.phoneFp)))),xe(a.ed25519Pub)!==e.phoneFp)throw Error(`fp mismatch`);let t=nt(`phone`,this.opts.fp,e.phoneFp,a.x25519Pub);if(!me(a.ed25519Pub,t,a.bind))throw Error(`unbound key`)}catch{n.failures+=1,t(`bad-code`),n.failures>=3?this.closeWindow():this.closeIfExhausted(n);return}let o={};this.pending={window:n,token:o};try{let s=await this.confirmWithTimeout(e.phoneFp,a.name);if(this.pending?.token!==o||!this.isOpen||this.window!==n)return;if(!s)return t(`declined`);let l;try{l=c(this.opts.identity.x25519.priv,a.x25519Pub,n.code,this.opts.fp,e.phoneFp)}catch{n.failures+=1,t(`bad-code`),n.failures>=3&&this.closeWindow();return}if(this.opts.relayOnline?.()===!1){this.log.warn(`pairing approved while the relay was unreachable`,{phone:e.phoneFp.slice(0,8)});return}this.opts.savePairing({phoneFp:e.phoneFp,name:a.name,platform:a.platform,ed25519Pub:k(a.ed25519Pub),x25519Pub:k(a.x25519Pub),kPair:k(l),pairedAt:new Date(this.now()).toISOString(),lastSeenAt:null}),this.opts.sendCtrl({type:`pairing-add`,phoneFp:e.phoneFp,ed25519Pub:a.ed25519Pub,name:a.name,pairId:Qe(l)});let u=le(i,j({x25519Pub:this.opts.identity.x25519.pub,computerName:this.opts.computerName,accent:this.opts.accent,bind:de(this.opts.identity.ed25519.priv,nt(`computer`,this.opts.fp,e.phoneFp,this.opts.identity.x25519.pub))}),r(`response`,this.opts.fp,e.phoneFp));this.opts.sendCtrl({type:`pairing-response`,phoneFp:e.phoneFp,box:u}),this.log.info(`paired`,{phone:e.phoneFp.slice(0,8)}),this.closeWindow()}finally{this.pending?.token===o&&(this.pending=null,this.closeIfExhausted(n))}}};const ii=e=>!/^turns:/.test(e)&&!/[?&]transport=tcp(?:&|$)/.test(e);function ai(e){return e.flatMap(e=>e.urls.filter(ii).map(t=>e.username&&e.credential?t.replace(/^(turns?):/,`$1:${encodeURIComponent(e.username)}:${encodeURIComponent(e.credential)}@`):t))}function oi(e){let t=e.trim().replace(/%.*$/,``).toLowerCase();if(wr(t)!==6)return t;try{return new URL(`http://[${t}]/`).hostname.slice(1,-1)}catch{return t}}function si(e){let t=e.trim().replace(/^a=/,``).split(/\s+/),n=t.indexOf(`typ`);return!t[0]?.startsWith(`candidate:`)||t.length<8||n!==6?null:{address:oi(t[4]),type:t[7]}}function ci(e,t={}){let n=t.turn!==!1;return t=>li(t,ai(n?e():Rr()),n)}ci(()=>Rr());const li=async(e,t,n=!0)=>{let{default:r}=await import(`#webrtc-native`),i=new r.PeerConnection(`shellbell-v2`,{iceServers:t}),a=null,o=!1,s=new Set,c=new Map,l=new Set,u=()=>{let e=i.getSelectedCandidatePair();if(!e||e.local.type===`relay`||e.remote.type===`relay`)return!1;let t=oi(e.remote.address);return s.has(t)&&!l.has(t)},d=n,f=null,p=[],m=()=>{f&&clearInterval(f),f=null},h=()=>{if(m(),!o)try{e.closed()}catch{}},g=e=>{if(!o)try{e()}catch{h()}};return i.onLocalDescription((t,n)=>{g(()=>{(n===`offer`||n===`answer`)&&e.description(t,n)})}),i.onLocalCandidate((t,n)=>{g(()=>e.candidate(t.replace(/^a=candidate:/,`candidate:`),n,null))}),i.onStateChange(e=>{(e===`failed`||e===`closed`||e===`disconnected`)&&h()}),i.onDataChannel(t=>{g(()=>{if(a||t.getLabel()!==`shellbell-v2`){t.close(),h();return}a=t,t.onOpen(()=>{g(()=>{if(n){e.open();return}let t=Date.now()+3e3,r=()=>g(()=>{if(u()){if(d)return;d=!0,e.open();for(let t of p.splice(0))e.message(t)}else(d||Date.now()>=t)&&h()});f=setInterval(r,250),f.unref?.(),r()})}),t.onClosed(h),t.onError(h),t.onMessage(t=>{g(()=>{if(typeof t==`string`){h();return}let n=(t instanceof ArrayBuffer,new Uint8Array(t));if(n.length>61e3){h();return}if(!d){p.length>=16?h():p.push(n);return}e.message(n)})})})}),{async offer(){throw Error(`computer is WebRTC responder`)},async answer(e){i.setRemoteDescription(e,`offer`)},async acceptAnswer(){throw Error(`computer is WebRTC responder`)},async candidate(e,t){let r=si(e);if(r&&c.get(r.address)!==`host`&&c.set(r.address,r.type),!n){if(!r)return;if(r.type===`relay`){l.add(r.address);return}(r.type===`host`||r.type===`srflx`)&&s.add(r.address)}i.addRemoteCandidate(e,t??`0`)},async routeStats(){if(o||!d)return null;let e=i.getSelectedCandidatePair();if(!e)return null;let t=i.rtt();return{path:De(e.local.type,c.get(oi(e.remote.address))??e.remote.type),...t>=0&&{rttMs:t}}},async remoteCertificate(e){if(!a?.isOpen()||i.state()!==`connected`)throw Error(`DTLS not connected`);let t=i.remoteFingerprint();if(t.algorithm.toLowerCase()!==`sha-256`)throw Error(`DTLS fingerprint algorithm`);let n=Ce(t.value.replaceAll(`:`,``));if(!Ee(e,n))throw Error(`DTLS fingerprint mismatch`);return n},send(e){if(o||!d||!a?.isOpen()||e.length>61e3||a.bufferedAmount()+e.length>262144)return!1;try{return a.sendMessageBinary(e)}catch{return!1}},close(){o||(o=!0,m(),a?.close(),a=null,i.close())}}};var ui=class{helloTimeoutMs=15e3;phoneFp;connId;name;relayConnId;openedAt=Date.now();handshaken=!1;routed=!1;broken=!1;dormant=!1;viewed=null;generation=0;awaitingDirectReady=!1;endpoint;log;constructor(e){this.log=e.log,this.phoneFp=e.phoneFp,this.connId=e.connId,this.relayConnId=e.connId,this.name=e.name,this.endpoint=new s({role:`computer`,computerFp:e.computerFp,phoneFp:e.phoneFp,keys:{staticPrivate:e.identity.x25519.priv,remoteStatic:e.remoteStatic,pairKey:e.kPair},sendRelay:e.send,commitFloor:e.commitFloor,prepareReady:e.prepareReady,native:e.native??ci(e.iceServers??(()=>Rr()),{turn:e.turn}),allowDirect:!0,terminal:(t,n)=>{let r;try{r=kt(St(t))}catch{return}this.awaitingDirectReady&&(this.awaitingDirectReady=!1,this.handshaken=!0,e.ready(this)),e.terminal(this,r,n)},routeChanged:t=>{this.awaitingDirectReady=t===`direct`,this.handshaken=!1,t&&(this.routed=!0),this.dormant=!1,this.viewed=null,this.generation+=1,e.log.info(`v2 terminal route changed`,{route:t,phone:e.phoneFp.slice(0,8)}),t===`direct`&&this.logDirectRoute(),e.ready(this)},failure:(t,n)=>{e.log.warn(`v2 transport failed`,{stage:t,...n?{code:n.code,phase:n.phase}:{},phone:e.phoneFp.slice(0,8)})}})}get transportDiagnostics(){return this.endpoint.diagnostics}get activeRoute(){return this.endpoint.activeRoute}get handshakeGeneration(){return this.generation}helloOverdue(e=Date.now()){return!this.handshaken&&!this.routed&&!this.dormant&&e-this.openedAt>=this.helloTimeoutMs}handleEnvelope(e){return this.endpoint.receiveRelay(e)}send(e){return!this.broken&&this.endpoint.sendTerminal(j(e))}relayLost(){this.endpoint.relayLost()}async logDirectRoute(){let e=await this.endpoint.routeStats();e&&!this.broken&&this.log.info(`v2 direct route`,{...e,setupMs:this.endpoint.diagnostics.directSetupMs,phone:this.phoneFp.slice(0,8)})}close(){this.broken=!0,this.handshaken=!1,this.endpoint.close()}},di=class{options;closed=!1;ended=!1;follower=null;operation=!1;epoch={};due=0;checkingShown=!1;generation=null;revision=0;appliedHistory=`complete`;applied=[];branch=null;projection=[];projectionClipped=!1;snapshot=null;snapshotCurrent=!1;discontinuity=0;pending=null;cursor=null;history=null;lastHistory=null;lastHistoryResult=null;clear=null;afterClear=null;controls=[];authorizedUntil=0;caughtUp=!1;lastStatusAt=0;lastSourceAt;unlinkedHistory=!1;historicalBranch=new Map;constructor(e){if(!te.safeParse(e.subscriptionId).success)throw TypeError(`Invalid conversation subscription`);this.options={...e},this.lastSourceAt=e.now(),this.status(`checking`)}get sessionId(){return this.options.sessionId}get subscriptionId(){return this.options.subscriptionId}get needsWork(){return!this.closed&&!this.ended&&!this.operation&&!this.clear&&this.options.enabled()&&this.options.now()>=this.due}close(){this.closed||(this.closed=!0,this.discard(),this.clear=null,this.controls=[])}invalidate(e){this.closed||(this.ended||=e===`ended`,this.ended&&(e=`ended`),this.discard(),this.controls=[],this.clear?.sent?this.clear.message.reason!==e&&(this.afterClear=e):this.clear={message:{type:`conversation.clear`,subscriptionId:this.subscriptionId,clearId:this.id(),reason:e},sent:!1,deadline:0},this.options.wake())}receive(e,t){if(!(this.closed||e.subscriptionId!==this.subscriptionId)){if(!Number.isSafeInteger(t)||t<1||t>D.envelopeBytes||!o.safeParse(e).success){this.invalidate(`unavailable`);return}if(e.type===`conversation.cancel`){this.close();return}if(e.type===`conversation.cleared`){if(this.clear?.sent&&e.clearId===this.clear.message.clearId){this.clear=null;let e=this.afterClear;if(this.afterClear=null,e){this.invalidate(e);return}this.due=this.options.now(),!this.options.enabled()&&!this.ended&&this.status(`disabled`)}return}if(e.type===`conversation.refresh`){this.clear?(this.clear.deadline=0,this.options.wake()):this.ended||this.invalidate(this.options.enabled()?`changed`:`disabled`);return}if(this.options.enabled()&&!this.clear){if(e.type===`conversation.applied`){this.appliedBatch(e);return}if(e.type===`conversation.history.get`){if(e.generation!==this.generation||this.history?.requestId===e.requestId)return;if(this.history){this.endHistory(e,`busy`);return}if(e.requestId===this.lastHistory&&this.lastHistoryResult?.requestId===e.requestId){this.queueControl(this.lastHistoryResult);return}if(e.requestId===this.lastHistory||e.cursor!==this.cursor?.id){this.endHistory(e,`changed`);return}this.history={...e},this.due=this.options.now()}}}}async work(){if(!this.needsWork)return;this.operation=!0;let e=this.epoch,t=()=>!this.closed&&this.epoch===e&&this.options.enabled()&&!this.clear;try{if(this.follower??=this.options.follow(),!this.follower){this.status(`checking`,`busy`),this.due=this.options.now()+1e3;return}let e=this.follower;if(this.pending?.sent&&this.options.now()<this.pending.deadline){this.due=this.pending.deadline;return}if(this.snapshotCurrent&&this.snapshot&&this.history&&!this.pending&&this.cursor?.anchor&&e.older&&this.applied[0]?.local===this.cursor.local&&this.projection.findIndex(e=>e.local===this.cursor.local)<=0){let n=await e.older(this.cursor.anchor);if(!t()||this.follower!==e)return;if(this.due=this.options.now()+200,n.status===`stopped`)this.stopped(n.reason);else if(n.status===`refresh`)this.snapshotCurrent=!1;else if(n.status===`busy`)this.waitingForSource();else if(n.status===`reading`)this.waitingForSource(),this.due=this.options.now();else if(n.status===`unavailable`)this.finishHistory(`unavailable`);else if(n.status===`page`){let e=n.branch?.kind===`claude`?n.branch.nodes:[],t=[this.historicalBranch,new Map(this.branch?.kind===`claude`?this.branch.nodes.map(e=>[e.id,e.start]):[]),new Map(this.snapshot.branch?.kind===`claude`?this.snapshot.branch.nodes.map(e=>[e.id,e.start]):[])];if(e.some(e=>t.some(t=>t.has(e.id)&&t.get(e.id)!==e.start))){this.invalidate(`changed`);return}if(new Set([...this.historicalBranch.keys(),...e.map(e=>e.id)]).size>4096){this.finishHistory(`unavailable`);return}if(this.unlinkedHistory||=n.history===`unlinked`,this.lastSourceAt=this.options.now(),this.authorizedUntil=this.options.now()+200,this.caughtUp=!1,!n.entries.length)this.finishHistory(n.history===`complete`&&!this.unlinkedHistory?`complete`:`unavailable`);else{let t=new Map([...this.applied,...this.projection].map(e=>[e.local,e.id])),r=n.entries.map(({entry:e,anchor:n})=>{let r=t.get(e.id)??this.id(),i=Object.freeze({...e,id:r}),a=j(i),o=z(`sha256`).update(a).digest(`base64url`);return a.fill(0),{local:e.id,id:r,hash:o,entry:i,anchor:n}}),i=this.history,a=this.applied[0],o=this.page(r,`prepend`,a.id,i.requestId);o.length?this.queue(`prepend`,o,this.applied,a.id,i.requestId,void 0,[],{history:this.unlinkedHistory?`unlinked`:n.history,more:o.length<r.length||(n.more??n.history!==`complete`),ancestors:e}):this.finishHistory(`unavailable`)}this.options.wake()}return}if(this.snapshotCurrent&&this.snapshot&&(this.pending||this.history||this.hasUpdate())){let n=await e.confirm(this.snapshot.revision);if(!t()||this.follower!==e)return;if(n.status===`confirmed`){this.lastSourceAt=this.options.now(),this.caughtUp=n.caughtUp,this.authorizedUntil=this.options.now()+200,this.prepare(),this.due=this.options.now()+200,this.options.wake();return}if(n.status===`stopped`){this.stopped(n.reason);return}if(n.status===`busy`){this.waitingForSource();return}this.pending?.sent?this.invalidate(`changed`):(this.pending=null,this.snapshotCurrent=!1,this.due=this.options.now()+200);return}let n=await e.poll();if(!t()||this.follower!==e)return;this.accept(n)}catch{t()&&this.invalidate(`unavailable`)}finally{this.operation=!1}}offer(){if(this.closed)return!1;let e=this.options.now();if(this.clear){let t=this.clear;if(t.sent&&e<t.deadline)return!1;let n=this.send(t.message);return this.clear===t&&n&&(t.sent=!0,t.deadline=e+D.progressMs),n}if(this.controls.length){let t=this.controls.find(e=>e.type===`conversation.history.end`)??this.controls[0];if(t.type===`conversation.status`&&t.state===`ready`&&(!this.options.enabled()||e>this.authorizedUntil))return!1;let n=this.send(t);return n&&(this.controls=this.controls.filter(e=>e!==t)),n}let t=this.pending;if(!t||!this.options.enabled()||e>this.authorizedUntil||t.sent&&e<t.deadline)return!1;let n=this.send(t.batch);return this.pending===t&&n&&(t.sent=!0,t.deadline=e+D.progressMs,this.due=t.deadline),n}tick(){this.closed||(!this.options.enabled()&&(this.follower||this.generation||this.pending)&&this.invalidate(`disabled`),(this.clear&&this.options.now()>=this.clear.deadline||this.controls.length)&&this.options.wake())}accept(e){if(this.due=this.options.now()+200,e.status===`busy`){this.waitingForSource();return}if(e.status===`stopped`){this.stopped(e.reason);return}if(e.discontinuity!==this.discontinuity&&this.generation){this.invalidate(`skipped`);return}if(this.discontinuity=e.discontinuity,e.status===`catching-up`){this.snapshotCurrent=!1,this.generation?this.waitingForSource():(this.checkingShown||this.status(`checking`),this.checkingShown=!0),e.pending&&(this.due=this.options.now());return}this.lastSourceAt=this.options.now();let t=e.snapshot;if(t.state!==`ready`||!t.branch){this.generation?this.invalidate(`unavailable`):(this.status(`unavailable`,t.state===`unsupported`?`unsupported`:`unbound`),this.due=this.options.now()+5e3);return}if(this.branch?.kind===`claude`){let e=this.branch.nodes.at(-1);if(t.branch.kind!==`claude`||!e||![...t.branch.nodes,...t.branch.parallel??[]].some(t=>t.id===e.id&&t.start===e.start)){let n=t.branch.kind===`claude`&&e&&t.history!==`complete`&&(t.branch.nodes[0]?.start??0)>e.start;this.invalidate(n?`skipped`:`changed`);return}let n=new Map(this.branch.nodes.map(e=>[e.id,e.start]));if(t.branch.nodes.some(e=>n.has(e.id)&&n.get(e.id)!==e.start||this.historicalBranch.has(e.id)&&this.historicalBranch.get(e.id)!==e.start)){this.invalidate(`changed`);return}}if(t.entries!==this.snapshot?.entries){let e=new Map([...this.applied,...this.projection].map(e=>[e.local,e.id])),n=[],r=0;this.projectionClipped=!1;for(let i=t.entries.length-1;i>=0;i--){let a=t.entries[i];if(a.id.startsWith(`history:`))continue;let o=e.get(a.id)??this.id(),s=Object.freeze({...a,id:o}),c=j(s);r+=c.byteLength;let l=z(`sha256`).update(c).digest(`base64url`);if(c.fill(0),r>D.queuedBytes-D.batchBytes||n.length>=D.retainedEntries){this.projectionClipped=!0;break}n.push({local:a.id,id:o,hash:l,entry:s})}n.reverse();let i=this.follower?.anchor;if(this.projectionClipped&&i){let e=n.findIndex(e=>i.call(this.follower,t.revision,e.local)!==null);e>0&&n.splice(0,e)}this.projection=n}this.snapshot=this.projectionClipped?{...t,history:`truncated`}:t,this.snapshotCurrent=!0,this.caughtUp=e.caughtUp,this.authorizedUntil=0,this.generation||=this.id(),!this.hasUpdate()&&!this.history&&(this.due=this.options.now()+1e3,this.options.now()-this.lastStatusAt>=2e3&&this.historyStatusProbe())}waitingForSource(){this.due=this.options.now()+200,this.options.now()-this.lastSourceAt>=D.progressMs&&this.status(`checking`,`busy`)}historyStatusProbe(){this.authorizedUntil=0,this.queueControl({type:`conversation.status`,subscriptionId:this.subscriptionId,state:`ready`,caughtUp:this.caughtUp}),this.due=this.options.now()}hasUpdate(){return!this.generation||this.revision===0||this.controls.some(e=>e.type===`conversation.status`&&e.state===`ready`)?!0:this.update()!==null}update(){if(!this.applied.length)return this.projection.length?{at:0,rows:this.projection,after:0}:null;let e=new Map(this.applied.map((e,t)=>[e.local,t])),t=this.projection.findIndex(t=>e.has(t.local));if(t<0)return{at:-1,rows:[],after:0,reset:`skipped`};let n=e.get(this.projection[t].local);if(this.appliedHistory===`complete`){if(this.snapshot?.history===`complete`&&(t>0||n>0))return{at:0,rows:this.projection.slice(0,t),after:n};if(t>0)return{at:n,rows:this.projection.slice(0,t),after:n}}for(;t<this.projection.length&&n<this.applied.length&&this.projection[t].local===this.applied[n].local&&this.projection[t].hash===this.applied[n].hash;)t++,n++;if(t===this.projection.length)return n===this.applied.length?null:{at:n,rows:[],after:this.applied.length};let r=this.projection[t];if(this.applied[n]?.local===r.local)return{at:n,rows:[r],after:n+1};let i=e.get(r.local);if(i!==void 0)return i>n?{at:n,rows:[],after:i}:{at:-1,rows:[],after:0,reset:`changed`};let a=t;for(;a<this.projection.length&&!e.has(this.projection[a].local);)a++;return{at:n,rows:this.projection.slice(t,a),after:n}}prepare(){if(this.pending||!this.snapshot?.branch||!this.generation)return;if(this.controls.some(e=>e.type===`conversation.status`&&e.state===`ready`)&&(this.queueControl({type:`conversation.status`,subscriptionId:this.subscriptionId,state:`ready`,caughtUp:this.caughtUp}),this.lastStatusAt=this.options.now()),this.history){let e=this.history,t=this.applied[0],n=this.projection.findIndex(e=>e.local===t?.local);if(!t||n<0||t.local!==this.cursor?.local){this.finishHistory(`changed`);return}if(n===0){this.finishHistory(this.snapshot.history===`complete`?`complete`:`unavailable`);return}let r=this.page(this.projection.slice(0,n),`prepend`,t.id,e.requestId);this.queue(`prepend`,r,this.applied,t.id,e.requestId);return}if(this.revision===0){this.queue(`reset`,this.page(this.projection,`reset`),[]);return}let e=this.update();if(!e){this.branch=this.snapshot.branch;return}if(e.at<0){this.invalidate(e.reset??`changed`);return}let t=this.applied[e.at-1]?.id??null,n=this.applied[e.after]?.id??null;this.queue(`patch`,this.page(e.rows,`patch`,t,void 0,n),this.applied.slice(0,e.at),t,void 0,n,this.applied.slice(e.after))}page(e,t,n,r,i){let a=[],o=t!==`patch`;for(let s=0;s<Math.min(e.length,D.entriesPerBatch);s++){let c=e[o?e.length-s-1:s],l=o?[c,...a]:[...a,c],u=this.message(t,l,n,r,`0`.repeat(22),i);if(j(u).byteLength>D.batchBytes)break;a.splice(0,a.length,...l)}return a}message(e,t,n,r,i=null,a){return{type:`conversation.batch`,subscriptionId:this.subscriptionId,generation:this.generation,batchId:`0`.repeat(22),baseRevision:this.revision,revision:this.revision+1,operation:e,...e!==`reset`&&{anchor:n??null},...r&&{requestId:r},...a!==void 0&&{after:a},entries:t.map(e=>e.entry),...e!==`patch`&&{olderCursor:i,history:i?`unloaded`:this.snapshot.history}}}queue(e,t,n,r,i,a,o=[],s){let c=t.map(({local:e,id:t,hash:n})=>({local:e,id:t,hash:n})),l=e===`prepend`?[...c,...n]:[...n,...c,...o];if(new Set(l.map(e=>e.local)).size!==l.length){e===`prepend`?this.finishHistory(`changed`):this.invalidate(`changed`);return}let u=this.projection.findIndex(e=>e.local===l[0]?.local),d=l[0],f=d?.local===`unlinked-side`?l[1]:d,p=f?t.find(e=>e.local===f.local)?.anchor??this.follower?.anchor?.(this.snapshot.revision,f.local)??null:null,m=s?s.more:u>0||this.snapshot.history!==`complete`,h=e===`patch`?void 0:d&&m&&(u>0||p)?{id:this.id(),local:d.local,anchor:p}:null,g={...this.message(e,t,r,i,h?.id,a),batchId:this.id(),...s&&{history:s.history===`unlinked`?`unlinked`:h||s.more?`unloaded`:s.history}};if(!Lt.safeParse(g).success){this.invalidate(`unavailable`);return}this.pending={batch:g,proposed:l,branch:this.snapshot.branch,cursor:h,sent:!1,deadline:0,...s?.ancestors&&{ancestors:s.ancestors}},this.queueControl({type:`conversation.status`,subscriptionId:this.subscriptionId,state:`ready`,caughtUp:this.caughtUp})}appliedBatch(e){let t=this.pending;if(!t?.sent||e.generation!==this.generation||e.batchId!==t.batch.batchId||e.revision!==t.batch.revision)return;let n=e.retainedCount===0?t.proposed.length:t.proposed.findIndex(t=>t.id===e.oldestId);if(n<0||t.proposed.length-n!==e.retainedCount||(t.proposed.at(-1)?.id??null)!==e.newestId){this.invalidate(`unavailable`);return}this.applied=t.proposed.slice(n);for(let e of t.ancestors??[])this.historicalBranch.set(e.id,e.start);this.branch=t.branch,this.revision=e.revision,t.batch.history!==void 0&&(this.appliedHistory=t.batch.history),n>0&&(this.appliedHistory=`unloaded`),t.cursor!==void 0&&(this.cursor=t.cursor),this.applied[0]?.local!==this.cursor?.local&&(this.cursor=null),t.batch.operation===`prepend`&&(this.lastHistory=t.batch.requestId,this.lastHistoryResult=null,this.history=null),this.pending=null,this.due=this.options.now()}finishHistory(e){this.follower?.cancelOlder?.(),e===`complete`?(this.appliedHistory=`complete`,this.cursor=null):e===`changed`&&(this.cursor=null);let t=this.history;this.history=null,this.lastHistory=t.requestId,this.endHistory(t,e),this.lastHistoryResult={type:`conversation.history.end`,subscriptionId:this.subscriptionId,generation:t.generation,requestId:t.requestId,reason:e}}endHistory(e,t){this.queueControl({type:`conversation.history.end`,subscriptionId:this.subscriptionId,generation:e.generation,requestId:e.requestId,reason:t})}stopped(e){this.generation?this.invalidate(e===`disabled`?`disabled`:e===`changed`?`changed`:`unavailable`):(this.discard(),this.status(e===`disabled`?`disabled`:`unavailable`,e===`unbound`?`unbound`:e===`unsupported`?`unsupported`:`source`),this.due=e===`unsupported`?1/0:this.options.now()+5e3)}status(e,t){this.queueControl({type:`conversation.status`,subscriptionId:this.subscriptionId,state:e,...t&&{reason:t}})}queueControl(e){if(e.type===`conversation.status`)this.controls=this.controls.filter(e=>e.type!==`conversation.status`);else if(e.type===`conversation.history.end`&&this.controls.some(t=>t.type===`conversation.history.end`&&t.generation===e.generation&&t.requestId===e.requestId))return;this.controls.length>=4&&(this.controls=this.controls.filter(e=>e.type!==`conversation.status`)),this.controls.length<4&&this.controls.push(e),this.options.wake()}discard(){this.checkingShown=!1,this.epoch={},this.follower?.close(),this.follower=null,this.generation=null,this.revision=0,this.appliedHistory=`complete`,this.applied=[],this.branch=null,this.projection=[],this.projectionClipped=!1,this.snapshot=null,this.snapshotCurrent=!1,this.pending=null,this.cursor=null,this.history=null,this.lastHistory=null,this.lastHistoryResult=null,this.authorizedUntil=0,this.discontinuity=0,this.unlinkedHistory=!1,this.historicalBranch.clear()}id(){let e=this.options.newId();if(!te.safeParse(e).success)throw TypeError(`Invalid conversation ID`);return e}send(e){try{let t=this.options.send(e);return t!==!0&&t!==!1?(Promise.resolve(t).catch(()=>{}),!1):t}catch{return!1}}};function fi(e){return async t=>{let n=()=>!t.aborted&&e.enabled();try{if(!n())return null;let r=await e.reference(t);if(!n()||!r||typeof r.owner!=`string`||!r.owner||r.owner.length>1024)return null;let i=Object.freeze({...r}),a=await e.locator.locate(i,t);if(!n()||a.status!==`candidate`)return null;let o=Object.freeze({agent:a.candidate.agent,path:a.candidate.path,session:a.candidate.session});if(o.agent!==i.agent||(i.kind===`path`?o.path!==i.value:o.session!==i.value.toLowerCase()))return null;let s=await e.reference(t);return!n()||!zt(i,s)||i.owner!==s?.owner?null:Object.freeze({...o,owner:i.owner})}catch{return null}}}const pi={claude:{name:`Claude Code`,from:`2.1.286`,through:`2.1.310`},codex:{name:`Codex`,from:`0.164.0`,through:`0.166.0`},gemini:{name:`Gemini CLI`,from:`0.62.0`,through:`0.62.0`}},mi=/^\d{1,6}(?:\.\d{1,6}){0,3}$/;function hi(e){return typeof e==`string`&&mi.test(e)?e:null}function gi(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<Math.max(n.length,r.length);e++){let t=(n[e]??0)-(r[e]??0);if(t)return Math.sign(t)}return 0}function _i(e,t){if(!Object.hasOwn(pi,e))return`tested`;let n=pi[e];return gi(t,n.through)>0?`newer`:gi(t,n.from)<0?`older`:`tested`}function vi(e,t){let n=_i(e,t);if(n===`tested`)return null;let r=pi[e].name;return n===`newer`?`${r} ${t} is newer than this computer has been checked with. Update Shellbell on your computer if parts of this conversation are missing.`:`${r} ${t} is older than this computer has been checked with. Some parts of this conversation may be missing.`}const yi=65536;function bi(e,t){return!!t&&e.agent===t.agent&&e.path===t.path&&e.session===t.session&&e.owner===t.owner}function xi(e,t){return e.dev===t.dev&&e.ino===t.ino}function Si(e){return ur(e)&&e.length<=4096&&!Array.from(e).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)}function Ci(e,t){let n=fr(e,t);return n!==``&&n!==`..`&&!n.startsWith(`..${pr}`)&&!ur(n)}function wi(e){return e.isFile()&&!e.isSymbolicLink()&&Number.isSafeInteger(e.size)&&e.size>=0&&(process.getuid===void 0||e.uid===process.getuid())}function Ti(e){if(e.fd===-1)return Promise.resolve();let t=e;return new Promise(n=>{let r=!1,i=()=>{r&&e.fd===-1&&(t.removeListener(`close`,i),n())},a=()=>{r=!0,i()};t.once(`close`,i);try{e.close().then(a,a)}catch{a()}})}var Ei=class e{options;path;file;identity;controller=new AbortController;reason=null;reading=!1;opening=!0;closeFinished=!1;finishClosed;closed=new Promise(e=>{this.finishClosed=e});fences=[];observed;onAbort=()=>{this.stop(`cancelled`)};constructor(e,t,n,r,i){this.options=e,this.path=n,this.file=r,this.identity=Object.freeze({...t}),this.observed=i,e.signal?.addEventListener(`abort`,this.onAbort,{once:!0}),e.signal?.aborted&&this.stop(`cancelled`)}static async open(t){let n,r;try{if(t.signal?.aborted)return{status:`stopped`,reason:`cancelled`};if(!t.enabled())return{status:`stopped`,reason:`disabled`};let i=await Di(t,t.signal);if(!i)return{status:`stopped`,reason:t.signal?.aborted?`cancelled`:`unbound`};let a={...i};if(![`claude`,`codex`,`gemini`].includes(a.agent)||!Si(a.path)||!a.path.endsWith(`.jsonl`)||!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,255}$/.test(a.session)||!a.owner||a.owner.length>1024)return{status:`stopped`,reason:`unsafe`};let o=t.roots[a.agent];if(!o?.length||o.length>8)return{status:`stopped`,reason:`unsafe`};let s=await V(a.path),c=!1;for(let e of o)if(Si(e))try{Ci(await V(e),s)&&(c=!0)}catch{}if(!c)return{status:`stopped`,reason:`unsafe`};let l=await B(a.path);if(!wi(l))return{status:`stopped`,reason:`unsafe`};n=await Er(s,Yn.O_RDONLY|Yn.O_NOFOLLOW|Yn.O_NONBLOCK);let u=await n.stat();if(!wi(u)||!xi(l,u))return{status:`stopped`,reason:`changed`};r=new e(t,a,s,n,u);let d=await r.validate();if(d)return{status:`stopped`,reason:d};if(!r.installFences(await r.captureFences(u.size)))return{status:`stopped`,reason:r.stopped};let f=await r.validate()??r.availability();return f?{status:`stopped`,reason:f}:(n=void 0,{status:`open`,file:r})}catch{return{status:`stopped`,reason:t.signal?.aborted?`cancelled`:`unreadable`}}finally{r?(n&&r.stop(`unreadable`),r.opening=!1,r.finishClosing(),n&&await r.closed):n&&await Ti(n)}}get stopped(){return this.reason}get size(){return this.observed.size}async read(e,t=yi){if(this.reason)return{status:`stopped`,reason:this.reason};if(this.reading)return{status:`busy`};if(!Number.isSafeInteger(e)||e<0||!Number.isSafeInteger(t)||t<1||t>65536)return this.stop(`unsafe`),{status:`stopped`,reason:`unsafe`};this.reading=!0;let n,r;try{let i=await this.validate();if(i)return this.stoppedRead(i);let a=this.observed.size;if(e>a)return this.stoppedRead(`unsafe`);n=Buffer.alloc(Math.min(t,a-e));let{bytesRead:o}=await this.file.read(n,0,n.length,e);if(o!==n.length)return this.stoppedRead(`changed`);r=await this.captureFences(a);let s=await this.validate(r);if(s)return this.stoppedRead(s);if(!this.installFences(r))return this.stoppedRead(this.reason);r=void 0;let c=n;return n=void 0,{status:`data`,bytes:c,offset:e,size:a}}catch{return this.stoppedRead(this.reason??`unreadable`)}finally{n?.fill(0);for(let e of r??[])e.bytes.fill(0);this.reading=!1,this.finishClosing()}}async verify(){if(this.reason)return{status:`stopped`,reason:this.reason};if(this.reading)return{status:`busy`};this.reading=!0;try{let e=await this.validate()??this.availability();return e?(this.stop(e),{status:`stopped`,reason:this.reason}):{status:`verified`,size:this.observed.size}}catch{return this.stop(this.reason??`unreadable`),{status:`stopped`,reason:this.reason}}finally{this.reading=!1,this.finishClosing()}}close(){this.stop(`cancelled`)}stoppedRead(e){return this.stop(e),{status:`stopped`,reason:this.reason}}stop(e){if(!this.reason){this.reason=e,this.controller.abort(),this.options.signal?.removeEventListener(`abort`,this.onAbort);for(let e of this.fences)e.bytes.fill(0);this.fences=[],Ti(this.file).then(()=>{this.closeFinished=!0,this.finishClosing()})}}finishClosing(){this.reason&&this.closeFinished&&!this.opening&&!this.reading&&this.finishClosed()}async validate(e=[]){if(this.reason)return this.reason;if(!this.options.enabled())return`disabled`;let t=await Di(this.options,this.controller.signal);if(this.reason)return this.reason;if(!this.options.enabled())return`disabled`;if(!t)return`unbound`;if(!bi(this.identity,t)||await V(this.identity.path)!==this.path)return`changed`;let[n,r]=await Promise.all([B(this.path),this.file.stat()]);if(!wi(n)||!xi(n,r)||!xi(r,this.observed)||r.size<this.observed.size||r.size===this.observed.size&&r.mtimeMs!==this.observed.mtimeMs)return`changed`;for(let t of[...this.fences,...e]){let e=Buffer.alloc(t.bytes.length);try{if((await this.file.read(e,0,e.length,t.offset)).bytesRead!==e.length||!e.equals(t.bytes))return`changed`}finally{e.fill(0)}}return this.reason?this.reason:this.options.enabled()?(this.observed=r,null):`disabled`}availability(){let e=this.options.enabled();return this.reason??(e?null:`disabled`)}installFences(e){let t=this.availability();if(t){for(let t of e)t.bytes.fill(0);return this.stop(t),!1}for(let e of this.fences)e.bytes.fill(0);return this.fences=e,!0}async captureFences(e){let t=Math.min(4096,e),n=[];try{for(let r of t===e?[0]:[0,e-t]){let e=Buffer.alloc(t);if(n.push({offset:r,bytes:e}),(await this.file.read(e,0,e.length,r)).bytesRead!==e.length||this.reason)throw Error(`invalidated`)}return n}catch(e){for(let e of n)e.bytes.fill(0);throw e}}};async function Di(e,t){if(t?.aborted||!e.enabled())return null;let n=new AbortController,r=()=>n.abort();t?.addEventListener(`abort`,r,{once:!0});let i;try{let t=new Promise(e=>{n.signal.addEventListener(`abort`,()=>e(null),{once:!0}),i=setTimeout(r,2e3)}),a=await Promise.race([e.identity(n.signal),t]);return a?{...a}:null}catch{return null}finally{clearTimeout(i),t?.removeEventListener(`abort`,r),n.abort()}}const Oi=16384,ki=Oi,Ai=ki*6,ji=/["\\\u0000-\u001f]/g,Mi=/^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)$/;var Ni=class{outline;decoder=new TextDecoder(`utf-8`,{fatal:!0});stack=[];mode=`value`;root;rooted=!1;failed=null;budget=131072;shortBudget=65536;recordBudget=16384;keyString=!1;keep=null;raw=``;length=0;escape=0;literal=``;constructor(e){this.outline=e}push(e){if(this.failed)return;let t;try{t=this.decoder.decode(e,{stream:!0})}catch{this.failed=`invalid-utf8`;return}this.scan(t)}finish(){if(!this.failed){let e;try{e=this.decoder.decode()}catch{this.failed=`invalid-utf8`,e=``}this.scan(e),this.mode===`literal`&&this.endLiteral()}let e=this.root;return this.root=void 0,this.raw=``,this.failed?{kind:`skipped`,reason:this.failed}:!this.rooted&&this.mode===`value`?null:this.stack.length||this.mode!==`after`||typeof e!=`object`||!e||Array.isArray(e)?{kind:`skipped`,reason:`invalid-json`}:{kind:`record`,value:e}}fail(){this.failed=`invalid-json`}scan(e){let t=0;for(;t<e.length&&!this.failed;){if(this.mode===`string`){t=this.string(e,t);continue}let n=e.charCodeAt(t);if(this.mode===`literal`){if(/[0-9a-zA-Z+.-]/.test(e[t])){this.literal+=e[t],this.literal.length>512&&this.fail(),t++;continue}if(this.endLiteral(),this.failed)break}if(t++,n===32||n===9||n===10||n===13)continue;let r=this.stack.at(-1);if(this.mode===`first-item`&&n===93){this.close();continue}switch(this.mode){case`first-item`:case`value`:n===123?this.open(!1):n===91?this.open(!0):n===34?this.beginString(!1):/[-0-9tfn]/.test(e[t-1])?(this.keep=this.slot(),this.literal=e[t-1],this.mode=`literal`):this.fail();break;case`first-key`:n===125?this.close():n===34?this.beginString(!0):this.fail();break;case`key`:n===34?this.beginString(!0):this.fail();break;case`colon`:n===58?this.mode=`value`:this.fail();break;case`after`:r?n===44?this.mode=r.array?`value`:`key`:n===(r.array?93:125)?this.close():this.fail():this.fail()}}}slot(){let e=this.stack.at(-1);return e?e.array?e.shape?.items&&e.count<65?e.shape.items:null:e.child:this.outline}open(e){if(this.stack.length>=512){this.fail();return}let t=this.slot();this.stack.push({array:e,value:t?e?[]:{}:null,shape:t,child:null,key:null,count:0}),this.mode=e?`first-item`:`first-key`}close(){let e=this.stack.pop();this.place(e.value,e.value!==null)}place(e,t){let n=this.stack.at(-1);this.mode=`after`,n?n.array?(t&&n.value.push(e),n.count++):t&&n.key!==null&&(n.value[n.key]=e):(this.root=e,this.rooted=!0)}beginString(e){this.keyString=e,this.keep=e?null:this.slot(),this.raw=``,this.length=0,this.escape=0,this.mode=`string`}append(e){this.length+=e.length,(this.keyString||this.keep)&&(this.length<=(this.keyString?256:Ai)?this.raw+=e:this.raw=``)}string(e,t){let n=t;for(;n<e.length;){if(this.escape===1){let t=e[n];if(t===`u`)this.escape=2;else if(`"\\/bfnrt`.includes(t))this.escape=0;else return this.fail(),n;this.append(t),n++;continue}if(this.escape>=2){if(!/[0-9a-fA-F]/.test(e[n]))return this.fail(),n;this.escape=this.escape===5?0:this.escape+1,this.append(e[n]),n++;continue}ji.lastIndex=n;let t=ji.exec(e),r=t?t.index:e.length;if(r>n&&this.append(e.slice(n,r)),n=r,!t)break;let i=e.charCodeAt(n);if(i===34)return this.endString(),n+1;if(i!==92)return this.fail(),n;this.append(`\\`),this.escape=1,n++}return n}endString(){let e=this.stack.at(-1),t=this.length>(this.keyString?256:Ai)||!this.keyString&&!this.keep?null:JSON.parse(`"${this.raw}"`),n=t!==null&&(this.keyString||t.length<=ki)?t:null;if(this.raw=``,this.keyString){let t=e.shape?.keys;e.key=n,e.child=n!==null&&t&&Object.hasOwn(t,n)?t[n]:null,this.mode=`colon`;return}if(!this.keep){this.place(void 0,!1);return}let r=this.stack.length===1&&n!==null&&n.length<=1024&&n.length<=this.recordBudget,i=!r&&n!==null&&n.length<=256&&n.length<=this.shortBudget,a=r||i||n!==null&&n.length<=this.budget;r?this.recordBudget-=n.length:i?this.shortBudget-=n.length:a&&(this.budget-=n.length),this.place(a?n:`Too large to show here`,!0)}endLiteral(){if(!Mi.test(this.literal)){this.fail();return}this.place(this.keep?JSON.parse(this.literal):void 0,this.keep!==null),this.literal=``}},Pi=class{outline;buffer=null;length=0;skipped;outlining=null;closed=!1;next;start;decoder=new TextDecoder(`utf-8`,{fatal:!0});constructor(e=0,t=!1,n=null){if(this.outline=n,!Number.isSafeInteger(e)||e<0)throw RangeError(`Invalid transcript cursor`);this.next=e,this.start=e,this.skipped=t?`partial-prefix`:null}get offset(){return this.next}get boundary(){return this.skipped===`partial-prefix`?null:this.start}get bufferedBytes(){return this.length}push(e,t=this.next){if(this.closed)throw Error(`Transcript decoder is closed`);if(t!==this.next||e.byteLength>65536||!Number.isSafeInteger(this.next+e.byteLength))throw this.close(),RangeError(`Invalid transcript window`);let n=Buffer.from(e.buffer,e.byteOffset,e.byteLength),r=[],i=0,a=0;for(;i<n.length&&a<64;){let e=n.indexOf(10,i),t=e===-1?n.length:e,o=t-i;this.outlining?this.outlining.push(n.subarray(i,t)):this.skipped||(this.length+o>131072?(this.outline?(this.outlining=new Ni(this.outline),this.length&&this.outlining.push(this.buffer.subarray(0,this.length)),this.outlining.push(n.subarray(i,t))):this.skipped=`line-too-large`,this.clearBuffer()):o&&(this.buffer??=Buffer.alloc(131072),n.copy(this.buffer,this.length,i,t),this.length+=o));let s=o+(e===-1?0:1);if(i+=s,this.next+=s,e!==-1){let e=this.finishLine();e&&r.push(e),this.clearBuffer(),this.skipped=null,this.outlining=null,this.start=this.next,a++}}return{consumed:i,lines:r}}close(){this.clearBuffer(),this.buffer=null,this.skipped=null,this.outlining=null,this.closed=!0}finishLine(){let e={start:this.start,end:this.next};if(this.skipped)return{...e,kind:`skipped`,reason:this.skipped};if(this.outlining){let t=this.outlining.finish();return t?t.kind===`record`?{...e,kind:`record`,value:t.value,outlined:!0}:{...e,...t}:null}if(!this.length)return null;let t;try{t=this.decoder.decode(this.buffer.subarray(0,this.length))}catch{return{...e,kind:`skipped`,reason:`invalid-utf8`}}if(/^[ \t\r\n]*$/.test(t))return null;try{let n=JSON.parse(t);if(typeof n==`object`&&n&&!Array.isArray(n))return{...e,kind:`record`,value:n}}catch{}return{...e,kind:`skipped`,reason:`invalid-json`}}clearBuffer(){this.buffer?.fill(0,0,this.length),this.length=0}};const Fi=Oi,Ii=8192,Li=new Set([`progress`,`system`,`attachment`,`file-history-snapshot`,`queue-operation`,`summary`,`custom-title`,`tag`,`last-prompt`,`ai-title`,`agent-name`,`agent-setting`,`mode`,`permission-mode`,`atis-latch`,`cost-state`,`pr-link`,`continued-in`,`file-history-delta`,`api-request`,`api-request-blob`,`api-request-shape`]),Ri=new Set([`token_count`,`agent_message`,`agent_reasoning`,`agent_reasoning_raw_content`,`thread_settings_applied`,`thread_goal_updated`,`context_compacted`,`patch_apply_end`,`mcp_tool_call_end`,`web_search_end`,`image_generation_end`,`item_completed`]),zi=new Set([`reasoning`,`additional_tools`,`configuration_update`,`compaction`,`context_compaction`]),Bi={task_started:`Working`,turn_started:`Working`,task_complete:`Complete`,turn_complete:`Complete`,turn_aborted:`Stopped`,error:`Agent reported an error`},Vi=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Hi=/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,255}$/;function U(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}function W(e){return typeof e==`string`&&e.trim()===e&&Hi.test(e)?e:null}function Ui(e){return typeof e==`string`&&e.length===36&&Vi.test(e)?e.toLowerCase():null}function G(e,t){if(!Number.isSafeInteger(t)||t<0||t>Fi)throw RangeError(`Invalid transcript text budget`);let n=``,r=0,i=0;for(let a of e){let e=a.codePointAt(0);if(i>=t*4)break;if(e<32&&e!==9&&e!==10||e>=127&&e<=159){i+=a.length;continue}let o=e>=55296&&e<=57343?`�`:a,s=Buffer.byteLength(o);if(r+s>t)break;n+=o,r+=s,i+=a.length}return{text:n,truncated:i<e.length}}var Wi=class{offset;outlined;items=[];bytes=2;clipped=!1;scopeStart=0;constructor(e,t=!1){this.offset=e,this.outlined=t}scope(e){this.offset=e,this.scopeStart=this.items.length}get full(){return this.items.length>=31||this.bytes>=65024}add(e,t,n,r=!1,i=!1){if(this.full){this.clipped=!0;return}let a=G(t,Fi),o=n===void 0?void 0:G(n,Ii);this.outlined&&(t.includes(`Too large to show here`)||n?.includes(`Too large to show here`))&&(i=!0);let s={id:`${this.offset}:${this.items.length-this.scopeStart}`,kind:e,text:a.text,...o&&{detail:o.text},...r&&{collapsed:!0},...(i||a.truncated||o?.truncated)&&{truncated:!0}},c=Buffer.byteLength(JSON.stringify(s))+1;if(c+this.bytes>65024){this.clipped=!0;return}return this.items.push(Object.freeze(s)),this.bytes+=c,s}unknown(){return this.add(`unsupported`,`(Something this version can't show)`)}finish(){return this.clipped&&this.items.push(Object.freeze({id:`${this.offset}:${this.items.length-this.scopeStart}`,kind:`status`,text:`Additional content omitted to keep this entry small.`,truncated:!0})),Object.freeze(this.items)}};function Gi(e,t){return Array.isArray(e)?(e.length>64&&(t.clipped=!0),e.slice(0,64)):null}function Ki(e){return typeof e==`string`&&G(e,128).text||`Tool`}function qi(e,t){let n=G(e,Ii),r=n.text.trim().split(`
|
|
5
|
-
`,1)[0].trim(),i=G(r,120),a=!i.truncated&&r===n.text&&!n.truncated;return{text:t?`${t}: ${n.text}`:n.text,clipped:n.truncated,...r&&{summary:a?i.text:`${i.text}…`},...a&&{complete:!0}}}const
|
|
6
|
-
`));return{text:o.text,clipped:a||o.truncated}}function
|
|
7
|
-
`).map(e=>e.trim()).find(Boolean);switch(n){case`task-notification`:e.add(`status`,r(`summary`)??`A background task finished`);return;case`command-name`:case`command-message`:{let t=r(`command-name`)??`/${r(`command-message`)??``}`;e.add(`user`,[t,r(`command-args`)].filter(Boolean).join(` `));return}case`bash-input`:e.add(`user`,`! ${r(`bash-input`)??``}`);return;case`local-command-stdout`:case`local-command-stderr`:case`bash-stdout`:case`bash-stderr`:{let t=i(r(n))??i(r(`bash-stderr`));t&&e.add(`status`,t);return}case`local-command-caveat`:case`system-reminder`:return;default:e.add(`user`,t)}}function
|
|
8
|
-
`):null}function
|
|
9
|
-
`,1)[0].trim(),n=G(t,120);return n.truncated||t!==e.trim()?`${n.text}…`:n.text}function
|
|
2
|
+
import{$ as e,$n as t,$t as n,A as r,An as i,At as a,B as o,Bn as s,Bt as c,Ct as l,D as u,Dn as d,Dt as f,En as p,Et as m,Fn as h,Ft as g,G as _,Gn as v,Gt as y,H as b,Hn as x,Ht as ee,I as te,In as S,It as C,J as ne,Jn as re,Jt as ie,Kn as ae,Kt as oe,Ln as se,Lt as ce,M as le,Mn as ue,Mt as de,N as fe,Nn as pe,Nt as w,On as me,Ot as he,P as ge,Pn as _e,Pt as ve,Q as T,Qn as E,Qt as ye,Rn as be,Rt as xe,Sn as Se,Tn as Ce,Tt as we,U as Te,Un as D,Ut as Ee,V as De,Vn as Oe,Vt as ke,W as Ae,Wn as je,Wt as Me,X as Ne,Xn as Pe,Xt as Fe,Y as Ie,Yn as O,Yt as Le,Z as Re,Zn as ze,Zt as Be,_n as Ve,_t as He,a as Ue,an as We,ar as Ge,at as Ke,bn as qe,bt as Je,cn as Ye,cr as Xe,d as Ze,dn as Qe,dt as $e,en as et,er as tt,et as nt,fn as rt,ft as it,hn as at,ht as ot,in as st,ir as ct,it as lt,jn as ut,jt as dt,kn as ft,l as pt,ln as mt,lr as k,lt as ht,mn as gt,mt as _t,n as vt,nn as yt,nr as bt,nt as xt,or as St,pn as Ct,pt as wt,q as Tt,qn as A,qt as Et,rn as Dt,rt as Ot,sn as kt,sr as At,st as j,t as jt,tn as Mt,tr as Nt,tt as M,u as Pt,un as Ft,ut as It,vn as Lt,vt as Rt,wn as zt,wt as Bt,xn as Vt,xt as Ht,yn as Ut,yt as Wt,zn as Gt,zt as Kt}from"./service-lifecycle-Cl7R7c5G.js";import{$ as qt,A as Jt,B as Yt,C as Xt,D as Zt,E as Qt,F as $t,G as en,H as tn,I as nn,J as rn,K as an,L as on,M as sn,N as cn,O as ln,P as un,Q as dn,R as fn,S as pn,T as mn,U as hn,V as gn,W as _n,X as vn,Y as yn,Z as bn,_ as xn,a as Sn,at as Cn,b as wn,c as Tn,ct as En,d as Dn,et as On,f as kn,g as An,h as jn,i as Mn,it as Nn,j as Pn,k as Fn,l as In,m as Ln,n as Rn,nt as zn,o as Bn,ot as Vn,p as Hn,q as Un,r as Wn,rt as Gn,s as Kn,st as qn,tt as Jn,u as Yn,v as Xn,w as Zn,x as Qn,y as $n,z as er}from"./doctor-ChDZpdTd.js";import{execFile as tr,spawn as nr}from"node:child_process";import{closeSync as rr,constants as ir,existsSync as ar,fstatSync as or,fsyncSync as sr,lstatSync as cr,mkdirSync as lr,openSync as ur,opendirSync as dr,readFileSync as fr,readSync as pr,realpathSync as mr,statSync as hr,watch as gr}from"node:fs";import{homedir as N,hostname as _r,tmpdir as vr,userInfo as yr}from"node:os";import{basename as br,dirname as P,isAbsolute as F,join as I,normalize as xr,relative as Sr,sep as Cr}from"node:path";import{createInterface as wr}from"node:readline";import{fileURLToPath as Tr,pathToFileURL as Er}from"node:url";import{z as L}from"zod";import{Command as Dr,Option as Or}from"commander";import kr from"qrcode-terminal";import{createHash as R,randomUUID as Ar,timingSafeEqual as jr}from"node:crypto";import{EventEmitter as Mr}from"node:events";import{connect as Nr,createConnection as Pr,isIP as Fr}from"node:net";import{lstat as z,mkdtemp as Ir,open as Lr,opendir as Rr,readFile as zr,readdir as Br,readlink as Vr,realpath as B,rm as Hr}from"node:fs/promises";import Ur from"ws";import{promisify as Wr}from"node:util";import{create as V}from"@bufbuild/protobuf";import{importTerminalPlugin as Gr}from"#terminal-plugin-loader";import{createInterface as Kr}from"node:readline/promises";function qr(e){return e?e.r.map(e=>e.t).join(``):``}const Jr=[[/\bIs this a project you (?:created or one you )?trust\?/i,`Is this a project you trust?`],[/\bTrust this folder\?/i,`Trust this folder?`],[/\bDo you trust the files in this folder\?/i,`Do you trust the files in this folder?`]],Yr=/^[❯›▶➤▸]\s*\S/u,Xr=/\b(?:enter to confirm|enter continue|press enter to (?:confirm|continue))\b/i;function Zr(e){if(!e.some(e=>Yr.test(e.text))||!e.some(e=>Xr.test(e.text)))return null;let t=e.map(e=>e.text).join(` `);for(let[e,n]of Jr)if(e.test(t))return n;return null}const Qr=/^(?:([❯›▶➤▸])\s*)?([1-9])[.)]\s+(\S.*)$/u,$r=/^\s*[│┃║▌▐]/u,ei=/[│┃║▌▐]\s*$/u;function ti(e){return ni.test(e)}const ni=/^[\s─━═┄┈╌╭╮╰╯┌┐└┘├┤┬┴┼-]*$/u,ri=/\s+\((?:esc|enter|tab|shift\+tab|ctrl\+[a-z]|[a-z])\)$/i,ii=/\s+\((esc|enter|[a-z])\)$/i,ai=/(?:\[(?:y\/n|n\/y|yes\/no|no\/yes)\]|\((?:y\/n|n\/y|yes\/no|no\/yes)\))\s*[:?]?\s*$/i;function oi(e){let t=e.replace($r,``).replace(ei,``).trimEnd(),n=t.trimStart();return{indent:t.length-n.length,text:ti(n)?``:n}}function si(e,t){let n=e.replace(/\s+/g,` `).trim(),r=Array.from(n);return r.length>t?`${r.slice(0,t-1).join(``).trimEnd()}…`:n}function ci(e){let t=[];for(let n=0;n<e.length;n++){if(Qr.exec(e[n].text)?.[2]!==`1`)continue;let r={first:n,options:[],markers:0},i=e[n].indent,a=n;for(;a<e.length;a++){let t=e[a],o=Qr.exec(t.text);if(o&&o[2]===String(r.options.length+1)){o[1]&&r.markers++,i=o[1]?t.indent+2:t.indent;let e=o[3].replace(ri,``),n=ii.exec(o[3])?.[1],a=n?.length===1?n:n?.toLowerCase();r.options.push({digit:o[2],label:si(e,48),...a&&(a!==`enter`||o[1])&&{shortcut:a}});continue}if(!(a>n&&t.text&&!o&&t.indent>i))break}t.push(r),n=a-1}return t}function li(e){if(!e||e.lines.length===0)return{question:null,options:null};let t=e.lines.map(e=>oi(qr(e))),n=t.length-1;for(;n>0&&!t[n].text;)n--;let r=e.cursor.y>=0&&e.cursor.y<t.length?e.cursor.y:-1,i=Math.max(0,(r>=0?r:n)-20),a=Math.min(t.length-1,r>=0?r+20:n),o=t.slice(i,a+1),s=ci(o).filter(e=>e.options.length>=2&&e.markers>0),c=s.length===1&&s[0].markers===1?s[0]:null,l=Zr(o);if(c)return{question:l??ui(o,c.first),options:c.options,...l?{trust:l}:{}};let u=r>=0?t[r]?.text:void 0,d=u&&ai.exec(u)?.[0];return{question:di(t,r>=0?r:n),options:null,...d?{yesNo:/yes|no/i.test(d)?`yes/no`:`y/n`}:{},...l?{trust:l}:{}}}function ui(e,t){let n=null;for(let r=t-1;r>=Math.max(0,t-8);r--){let t=e[r].text;if(t){if(Qr.test(t))break;if(/\?\s*$/.test(t))return si(t,120);n??=t}}return n===null?null:si(n,120)}function di(e,t){for(let n=t;n>=Math.max(0,t-3);n--){let t=e[n]?.text;if(t)return si(t,120)}return null}function fi(e){return e.options?`menu`:e.yesNo?`yes-no`:null}const pi=e=>/^turns?:/.test(e),mi=e=>!/:53(\?|$)/.test(e);function hi(e=[]){let t=[{urls:[`stun:stun.cloudflare.com:3478`]}],n=3;for(let r of e){if(!r.username||!r.credential)continue;let e=r.urls.filter(e=>pi(e)&&mi(e)).slice(0,n);if(e.length!==0&&(n-=e.length,t.push({urls:e,username:r.username,credential:r.credential}),n===0))break}return t}var gi=class{relay=[];expiresAt=0;advertised=!1;lastRefresh=-1/0;get supported(){return this.advertised}update(e,t,n){this.relay=e.map(e=>({...e,urls:[...e.urls]})),this.expiresAt=n+t,this.advertised=!0}servers(e){return hi(e<this.expiresAt?this.relay:[])}needsRefresh(e){return this.advertised&&this.expiresAt-e<=288e5}takeRefresh(e){return!this.advertised||e-this.lastRefresh<6e5?!1:(this.lastRefresh=e,!0)}},_i=class extends Mr{opts;s=new Map;now;constructor(e){super(),this.opts=e,this.now=e.now??(()=>Date.now())}stateOf(e){return this.s.get(e)?.promptState??`unknown`}setPromptState(e,t,n){e.promptState!==t&&e.promptState!==`unknown`&&(e.stateSince=n),e.promptState=t}activityOf(e){let t=this.s.get(e);return{...t?.lastChangeAt?{activeAt:t.lastChangeAt}:{},...t?.stateSince==null?{}:{stateSince:t.stateSince},reportsAgentState:t?.agentState!=null}}forget(e){this.s.delete(e)}get(e){let t=this.s.get(e);return t||(t={blockedNotified:!1,promptState:`unknown`,commandStartedAt:null,command:``,lastChangeAt:0,activeSince:null,lastPromptRingAt:-1/0,agentState:null,workingSince:null,stateSince:null},this.s.set(e,t)),t}onBackendEvent(e){let t=this.now();switch(e.type){case`screen-changed`:{let n=this.get(e.sessionId);n.lastChangeAt=t,n.activeSince??=t;return}case`command-start`:{let n=this.get(e.sessionId);this.setPromptState(n,`running`,t),n.commandStartedAt=t,n.command=e.command;return}case`command-end`:{let n=this.get(e.sessionId);this.setPromptState(n,`finished`,t);let r=n.commandStartedAt===null?void 0:t-n.commandStartedAt;n.commandStartedAt=null,this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`prompt`,exitCode:e.exitCode,durationMs:r,command:n.command||void 0,at:t}),r!==void 0&&r>=this.opts.notifyMinCommandMs&&(n.lastPromptRingAt=t,n.activeSince=null,this.emit(`ring`,{reason:`command-finished`,sessionId:e.sessionId,kind:`prompt`,exitCode:e.exitCode,durationMs:r}));return}case`prompt`:{let n=this.get(e.sessionId),r=n.commandStartedAt===null?void 0:t-n.commandStartedAt;n.commandStartedAt=null,this.setPromptState(n,`editing`,t),r!==void 0&&r>=this.opts.notifyMinCommandMs&&(n.activeSince=null,n.lastPromptRingAt=t,this.emit(`ring`,{sessionId:e.sessionId,kind:`prompt`,reason:`prompt-returned`,durationMs:r}));return}case`agent-state`:{let n=this.get(e.sessionId),r=n.agentState;if(r===e.state)return;if(n.agentState=e.state,e.state===`working`){n.blockedNotified=!1,this.setPromptState(n,`running`,t),n.workingSince=t;return}if(e.state===`blocked`){this.setPromptState(n,`blocked`,t),n.workingSince=null,n.activeSince=null,n.lastPromptRingAt=t,this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`blocked`,at:t}),r!==null&&!n.blockedNotified&&this.emit(`ring`,{sessionId:e.sessionId,kind:`blocked`,reason:`agent-blocked`}),n.blockedNotified=!0;return}if(e.state===`idle`||e.state===`done`){this.setPromptState(n,`finished`,t);let i=n.workingSince;if(n.workingSince=null,r!==`working`||i===null)return;let a=t-i;this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`prompt`,durationMs:a,at:t}),a>=this.opts.notifyMinCommandMs&&(n.lastPromptRingAt=t,n.activeSince=null,this.emit(`ring`,{sessionId:e.sessionId,kind:`prompt`,reason:e.state===`done`?`agent-finished`:`quiet`,durationMs:a}));return}n.promptState=`unknown`,n.stateSince=null,n.workingSince=null;return}case`session-removed`:this.s.delete(e.sessionId),this.emit(`event`,{type:`event`,sessionId:e.sessionId,kind:`exit`,at:t});return;default:return}}tick(){let e=this.now();for(let[t,n]of this.s){if(n.agentState!==null&&n.agentState!==`unknown`||n.activeSince===null||e-n.lastChangeAt<this.opts.idleQuietMs)continue;if(n.lastChangeAt-n.activeSince<this.opts.idleMinActiveMs){n.activeSince=null;continue}let r=n.lastChangeAt-n.activeSince;n.activeSince=null,this.emit(`event`,{type:`event`,sessionId:t,kind:`idle`,durationMs:r,at:e}),!(e-n.lastPromptRingAt<5e3+this.opts.idleQuietMs)&&n.promptState!==`editing`&&this.emit(`ring`,{sessionId:t,kind:`idle`,reason:`quiet`,durationMs:r})}}};function vi(e){return e===`darwin`||e===`linux`||e===`win32`?e:`unknown`}function yi(e){return{type:`notify`,sessionId:e.sessionId,kind:e.kind,exitCode:e.exitCode,durationMs:e.durationMs}}function bi(e){let t={...e,context:{...e.context}};for(let e of[`branch`,`title`,`agentName`,`shell`,`customName`,`repository`]){if(p.safeParse(t).success)return t;delete t.context[e]}return p.safeParse(t).success?t:void 0}var xi=class{options;cache=new WeakMap;constructor(e){this.options=e}prepare(e){let t=this.cache.get(e);if(t)return t();let n=new Map(this.options.pairings().map(e=>[e.phoneFp,e.kPair])),r=(this.options.now??Date.now)(),i=!1,a=performance.now(),o,s=new Promise(t=>{o=setTimeout(()=>{i=!0,t(yi(e))},250)}),c=Promise.race([this.build(e,()=>i||performance.now()-a>=250,r),s]).catch(()=>yi(e)).finally(()=>clearTimeout(o)),l=()=>c.then(t=>{let i=(this.options.now??Date.now)();if(t.type!==`notify-context`)return t;if(!this.options.capable()||i<r||i-r>=zt.freshnessMs)return yi(e);let a=this.options.pairings(),o=t.boxes.filter(e=>this.options.state.owns(e.phoneFp,e.generation)&&a.some(t=>t.phoneFp===e.phoneFp&&t.kPair===n.get(e.phoneFp)));return o.length?{...t,boxes:o}:yi(e)});return this.cache.set(e,l),l()}async build(e,t,n){let r=this.options,i=r.now??Date.now,a=yi(e);if(!r.capable()||!e.reason)return a;let o=O(Oe(16)),s=r.pairings().slice(0,10),c=await r.facts(e.sessionId);if(!c||t())return a;let l=async()=>{let t=await r.facts(e.sessionId);return t?.revision===c.revision&&t.sessionId===c.sessionId},u=await Gn(c,{computerName:r.computerName(),now:i,stillCurrent:l,git:r.git});if(t()||!r.capable()||!await l()||t())return a;let d=i();if(d-n>=zt.freshnessMs||d<n||d<u.observedAt)return a;let f=[],p={type:`notify-context`,sessionId:e.sessionId,eventId:o,kind:e.kind,exitCode:e.exitCode,durationMs:e.durationMs,boxes:f};for(let i of s){if(t())break;if(!r.pairings().some(e=>e.phoneFp===i.phoneFp&&e.kPair===i.kPair))continue;let a=r.state.reserve(i.phoneFp);if(!a)continue;let s=bi({computerFp:r.computerFp,phoneFp:i.phoneFp,generation:a.generation,sessionId:e.sessionId,eventId:o,sequence:a.sequence,issuedAt:d,expiresAt:n+zt.freshnessMs,reason:e.reason,context:u,exitCode:e.exitCode,durationMs:e.durationMs,...c.instance&&r.state.instanceReader(i.phoneFp,a.generation)&&{instance:c.instance}});if(!s)continue;let l,m;try{l=A(i.kPair),m=yt(l,s),f.push(Dt(m,s)),Buffer.byteLength(JSON.stringify(p),`utf8`)>16384&&f.pop()}catch{}finally{l?.fill(0),m?.fill(0)}}return f.length?p:a}};const Si=L.string().regex(/^(0|[1-9][0-9]{0,19})$/).refine(e=>BigInt(e)<=18446744073709551615n),Ci=L.strictObject({generation:Ce,used:L.number().int().min(0).max(zt.encryptions)}),wi=L.strictObject({version:L.literal(1),phones:L.array(L.strictObject({phoneFp:bt,sequence:Si,current:Ci,previous:L.strictObject({generation:Ce,expiresAt:L.number().int().nonnegative().max(2**53-1)}).optional()})).max(10).refine(e=>new Set(e.map(e=>e.phoneFp)).size===e.length)});var Ti=class{paths;now;data={version:1,phones:[]};healthy=!0;readsInstance=new Map;file;constructor(e,t=Date.now){this.paths=e,this.now=t,this.file=I(e.dir,`notifications.json`);try{$e(e);let t=I(e.dir,`notifications.initialized`),n=w(t)!==void 0;if(n&&dt(t,8,process.getuid?.()).toString(`utf8`)!==`v1
|
|
3
|
+
`)throw Error(`invalid marker`);try{this.data=wi.parse(JSON.parse(dt(this.file,16384,process.getuid?.()).toString(`utf8`)))}catch(e){if(n||!(e instanceof a&&e.kind===`missing`))throw e;if(!this.commit(this.data))return}n||(Rt(t,`v1
|
|
4
|
+
`),this.syncDirectory())}catch{this.healthy=!1}}syncDirectory(){if(process.platform===`win32`)return;let e=ur(this.paths.dir,`r`);try{sr(e)}finally{rr(e)}}commit(e){if(!this.healthy)return!1;try{return $e(this.paths),Rt(this.file,JSON.stringify(e)),this.syncDirectory(),this.data=e,!0}catch{return this.healthy=!1,!1}}enroll(e,t,n=[]){if(!this.healthy||!bt.safeParse(e).success||!Ce.safeParse(t).success)return!1;n.includes(`notify-instance-v1`)?this.readsInstance.set(e,t):this.readsInstance.delete(e);let r=this.data.phones.find(t=>t.phoneFp===e);if(r?.current.generation===t)return r.current.used<zt.encryptions;if(r?.previous?.generation===t||!r&&this.data.phones.length>=10)return!1;let i=structuredClone(this.data);return i.phones=i.phones.filter(t=>t.phoneFp!==e),i.phones.push({phoneFp:e,sequence:r?.sequence??`0`,current:{generation:t,used:0},...r?{previous:{generation:r.current.generation,expiresAt:this.now()+zt.previousGenerationMs}}:{}}),this.commit(i)}reserve(e){if(!this.healthy)return;let t=structuredClone(this.data),n=t.phones.find(t=>t.phoneFp===e);if(!(!n||n.current.used>=zt.encryptions||BigInt(n.sequence)>=18446744073709551615n))return n.sequence=String(BigInt(n.sequence)+1n),n.current.used++,n.previous&&n.previous.expiresAt<=this.now()&&delete n.previous,this.commit(t)?{generation:n.current.generation,sequence:n.sequence}:void 0}instanceReader(e,t){return this.readsInstance.get(e)===t}owns(e,t){return this.healthy&&this.data.phones.some(n=>n.phoneFp===e&&n.current.generation===t)}retain(e){if(this.data.phones.every(t=>e.has(t.phoneFp)))return;let t=structuredClone(this.data);t.phones=t.phones.filter(t=>e.has(t.phoneFp)),this.commit(t)}forget(e){this.readsInstance.delete(e);let t=structuredClone(this.data);t.phones=t.phones.filter(t=>t.phoneFp!==e),this.commit(t)}};const Ei=6e4;var Di=class{send;log;now;prepare;last=new Map;constructor(e,t,n=()=>Date.now(),r){this.send=e,this.log=t,this.now=n,this.prepare=r}ring(e){let t=this.now(),n=this.last.get(e.sessionId);for(let[n,r]of this.last)n!==e.sessionId&&t-r>=Ei&&this.last.delete(n);return n!==void 0&&t-n<Ei?!1:(this.last.set(e.sessionId,t),this.prepare?this.prepare(e).then(e=>this.send(e)).catch(()=>{this.log.warn(`notification preparation failed`)}):this.send(yi(e)),this.log.info(`ring`,{session:e.sessionId.slice(0,12),kind:e.kind}),!0)}forget(e){this.last.delete(e)}get size(){return this.last.size}};function Oi(e){return e.type===`input.line`||e.type===`input.text`||e.type===`input.key`||e.type===`input.mouse`||e.type===`input.terminal`||e.type===`input.paste`||e.type===`session.create`||e.type===`session.focus`}var ki=class{completed=new Map;pending=new Map;get idle(){return this.pending.size===0}run(e,t){let n=this.completed.get(e);if(n)return Promise.resolve({...n});let r=this.pending.get(e);if(r)return r;if(this.pending.size>=256)return Promise.resolve({type:`ack`,reqId:e,ok:!1,error:`busy`});let i,a=new Promise(e=>{i=e});this.pending.set(e,a);let o=t=>{let n={...t};if(this.completed.set(e,n),this.completed.size>256){let e=this.completed.keys().next().value;e!==void 0&&this.completed.delete(e)}this.pending.delete(e),i({...n})},s=()=>o({type:`ack`,reqId:e,ok:!1,error:`delivery-unknown`});try{t().then(t=>{t.type!==`ack`||t.reqId!==e?s():o(t)},s)}catch{s()}return a}};const Ai=L.instanceof(Uint8Array).refine(e=>e.length===32,{message:`expected 32 bytes`}),ji=L.instanceof(Uint8Array).refine(e=>e.length===64,{message:`expected 64 bytes`});function Mi(e){return e.replace(/[\p{Cc}\p{Cs}\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/gu,` `).replace(/\s+/gu,` `).trim()||`Phone`}const Ni=L.object({ed25519Pub:Ai,x25519Pub:Ai,name:L.string().min(1).max(64).transform(Mi),platform:L.enum([`ios`,`android`]),bind:ji});var Pi=class{opts;window=null;pending=null;now;log;constructor(e){this.opts=e,this.now=e.now??(()=>Date.now()),this.log=e.log.child({unit:`pairing`})}get isOpen(){return this.window!==null&&this.now()<this.window.expiresAt}openWindow(){this.window&&this.closeWindow(`replaced`);let e=Oe(16),t=Oe(16),r=this.now()+(this.opts.windowMs??3e5),i=n({v:1,r:this.opts.relayUrl,c:this.opts.fp,e:O(this.opts.identity.ed25519.pub),n:this.opts.computerName.slice(0,40),p:O(e),g:O(t),b:1,x:Math.ceil(r/1e3)});et(i,{allowInsecure:!0}),this.window={code:e,gate:t,expiresAt:r,failures:0,requests:0};let a=this.opts.sendCtrl({type:`pairing-open`,gateHash:s(t),expiresAt:r});return this.log.debug(a?`pairing-open sent`:`pairing-open not sent yet; will re-advertise once authenticated`),this.log.info(`pairing window opened`),{qrText:i,expiresAt:r}}readvertise(){if(!this.window||this.now()>=this.window.expiresAt)return;if(this.window.requests>=5){this.log.info(`pairing window not re-advertised: admission cap reached`),this.closeIfExhausted(this.window);return}let e=this.opts.sendCtrl({type:`pairing-open`,gateHash:s(this.window.gate),expiresAt:this.window.expiresAt});this.log.debug(e?`pairing window re-advertised`:`pairing window re-advertise dropped`)}closeWindow(e=`closed`){if(!this.window)return;let t=this.window;t.code.fill(0),t.gate.fill(0),this.window=null,this.pending?.window===t&&(this.pending=null),this.opts.sendCtrl({type:`pairing-close`}),this.log.info(`pairing window closed`),this.opts.onClose?.(e)}closeIfExhausted(e){this.window!==e||e.requests<5||this.pending===null&&this.closeWindow()}tick(){this.window&&this.now()>=this.window.expiresAt&&this.closeWindow()}confirmWithTimeout(e,t){let n=this.opts.confirmTimeoutMs??6e4;return new Promise(r=>{let i=!1,a=setTimeout(()=>{i||(i=!0,this.log.warn(`confirmation timed out`,{phone:e.slice(0,8)}),r(!1))},n);typeof a.unref==`function`&&a.unref(),this.opts.confirm(e,t).then(e=>{i||(i=!0,clearTimeout(a),r(e))},()=>{i||(i=!0,clearTimeout(a),r(!1))})})}async handleRequest(e){let t=t=>{this.opts.sendCtrl({type:`pairing-reject`,phoneFp:e.phoneFp,reason:t}),this.log.warn(`pairing rejected`,{reason:t,phone:e.phoneFp.slice(0,8)})};if(!this.isOpen||!this.window)return t(`window-closed`);let n=this.window;if(n.requests>=5){t(`window-closed`),this.closeIfExhausted(n);return}if(n.requests+=1,this.opts.pairingCount()>=10||this.pending!==null){t(`too-many`),this.closeIfExhausted(n);return}let r=ft(n.code,this.opts.fp),a;try{if(a=Ni.parse(Xe(_e(r,e.box,h(`request`,this.opts.fp,e.phoneFp)))),i(a.ed25519Pub)!==e.phoneFp)throw Error(`fp mismatch`);let t=S(`phone`,this.opts.fp,e.phoneFp,a.x25519Pub);if(!Gt(a.ed25519Pub,t,a.bind))throw Error(`unbound key`)}catch{n.failures+=1,t(`bad-code`),n.failures>=3?this.closeWindow():this.closeIfExhausted(n);return}let o={};this.pending={window:n,token:o};try{let i=await this.confirmWithTimeout(e.phoneFp,a.name);if(this.pending?.token!==o||!this.isOpen||this.window!==n)return;if(!i)return t(`declined`);let s;try{s=me(this.opts.identity.x25519.priv,a.x25519Pub,n.code,this.opts.fp,e.phoneFp)}catch{n.failures+=1,t(`bad-code`),n.failures>=3&&this.closeWindow();return}if(this.opts.relayOnline?.()===!1){this.log.warn(`pairing approved while the relay was unreachable`,{phone:e.phoneFp.slice(0,8)});return}this.opts.savePairing({phoneFp:e.phoneFp,name:a.name,platform:a.platform,ed25519Pub:O(a.ed25519Pub),x25519Pub:O(a.x25519Pub),kPair:O(s),pairedAt:new Date(this.now()).toISOString(),lastSeenAt:null}),this.opts.sendCtrl({type:`pairing-add`,phoneFp:e.phoneFp,ed25519Pub:a.ed25519Pub,name:a.name,pairId:qe(s)});let c=se(r,k({x25519Pub:this.opts.identity.x25519.pub,computerName:this.opts.computerName,accent:this.opts.accent,bind:be(this.opts.identity.ed25519.priv,S(`computer`,this.opts.fp,e.phoneFp,this.opts.identity.x25519.pub))}),h(`response`,this.opts.fp,e.phoneFp));this.opts.sendCtrl({type:`pairing-response`,phoneFp:e.phoneFp,box:c}),this.log.info(`paired`,{phone:e.phoneFp.slice(0,8)}),this.closeWindow(`paired`)}finally{this.pending?.token===o&&(this.pending=null,this.closeIfExhausted(n))}}};const Fi=e=>!/^turns:/.test(e)&&!/[?&]transport=tcp(?:&|$)/.test(e);function Ii(e){return e.flatMap(e=>e.urls.filter(Fi).map(t=>e.username&&e.credential?t.replace(/^(turns?):/,`$1:${encodeURIComponent(e.username)}:${encodeURIComponent(e.credential)}@`):t))}function Li(e){let t=e.trim().replace(/%.*$/,``).toLowerCase();if(Fr(t)!==6)return t;try{return new URL(`http://[${t}]/`).hostname.slice(1,-1)}catch{return t}}function Ri(e){let t=e.trim().replace(/^a=/,``).split(/\s+/),n=t.indexOf(`typ`);return!t[0]?.startsWith(`candidate:`)||t.length<8||n!==6?null:{address:Li(t[4]),type:t[7]}}function zi(e,t={}){let n=t.turn!==!1;return t=>Bi(t,Ii(n?e():hi()),n)}zi(()=>hi());const Bi=async(e,t,n=!0)=>{let{default:r}=await import(`#webrtc-native`),i=new r.PeerConnection(`shellbell-v2`,{iceServers:t}),a=null,o=!1,s=new Set,c=new Map,l=new Set,u=()=>{let e=i.getSelectedCandidatePair();if(!e||e.local.type===`relay`||e.remote.type===`relay`)return!1;let t=Li(e.remote.address);return s.has(t)&&!l.has(t)},d=n,f=null,p=[],m=()=>{f&&clearInterval(f),f=null},h=()=>{if(m(),!o)try{e.closed()}catch{}},g=e=>{if(!o)try{e()}catch{h()}};return i.onLocalDescription((t,n)=>{g(()=>{(n===`offer`||n===`answer`)&&e.description(t,n)})}),i.onLocalCandidate((t,n)=>{g(()=>e.candidate(t.replace(/^a=candidate:/,`candidate:`),n,null))}),i.onStateChange(e=>{(e===`failed`||e===`closed`||e===`disconnected`)&&h()}),i.onDataChannel(t=>{g(()=>{if(a||t.getLabel()!==`shellbell-v2`){t.close(),h();return}a=t,t.onOpen(()=>{g(()=>{if(n){e.open();return}let t=Date.now()+3e3,r=()=>g(()=>{if(u()){if(d)return;d=!0,e.open();for(let t of p.splice(0))e.message(t)}else(d||Date.now()>=t)&&h()});f=setInterval(r,250),f.unref?.(),r()})}),t.onClosed(h),t.onError(h),t.onMessage(t=>{g(()=>{if(typeof t==`string`){h();return}let n=(t instanceof ArrayBuffer,new Uint8Array(t));if(n.length>61e3){h();return}if(!d){p.length>=16?h():p.push(n);return}e.message(n)})})})}),{async offer(){throw Error(`computer is WebRTC responder`)},async answer(e){i.setRemoteDescription(e,`offer`)},async acceptAnswer(){throw Error(`computer is WebRTC responder`)},async candidate(e,t){let r=Ri(e);if(r&&c.get(r.address)!==`host`&&c.set(r.address,r.type),!n){if(!r)return;if(r.type===`relay`){l.add(r.address);return}(r.type===`host`||r.type===`srflx`)&&s.add(r.address)}i.addRemoteCandidate(e,t??`0`)},async routeStats(){if(o||!d)return null;let e=i.getSelectedCandidatePair();if(!e)return null;let t=i.rtt();return{path:oe(e.local.type,c.get(Li(e.remote.address))??e.remote.type),...t>=0&&{rttMs:t}}},async remoteCertificate(e){if(!a?.isOpen()||i.state()!==`connected`)throw Error(`DTLS not connected`);let t=i.remoteFingerprint();if(t.algorithm.toLowerCase()!==`sha-256`)throw Error(`DTLS fingerprint algorithm`);let n=re(t.value.replaceAll(`:`,``));if(!ae(e,n))throw Error(`DTLS fingerprint mismatch`);return n},send(e){if(o||!d||!a?.isOpen()||e.length>61e3||a.bufferedAmount()+e.length>262144)return!1;try{return a.sendMessageBinary(e)}catch{return!1}},close(){o||(o=!0,m(),a?.close(),a=null,i.close())}}};var Vi=class{helloTimeoutMs=15e3;phoneFp;connId;name;relayConnId;openedAt=Date.now();handshaken=!1;routed=!1;broken=!1;dormant=!1;viewed=null;generation=0;awaitingDirectReady=!1;endpoint;log;constructor(e){this.log=e.log,this.phoneFp=e.phoneFp,this.connId=e.connId,this.relayConnId=e.connId,this.name=e.name,this.endpoint=new y({role:`computer`,computerFp:e.computerFp,phoneFp:e.phoneFp,keys:{staticPrivate:e.identity.x25519.priv,remoteStatic:e.remoteStatic,pairKey:e.kPair},sendRelay:e.send,commitFloor:e.commitFloor,prepareReady:e.prepareReady,native:e.native??zi(e.iceServers??(()=>hi()),{turn:e.turn}),allowDirect:!0,terminal:(t,n)=>{let r;try{r=at(Xe(t))}catch{return}this.awaitingDirectReady&&(this.awaitingDirectReady=!1,this.handshaken=!0,e.ready(this)),e.terminal(this,r,n)},routeChanged:t=>{this.awaitingDirectReady=t===`direct`,this.handshaken=!1,t&&(this.routed=!0),this.dormant=!1,this.viewed=null,this.generation+=1,e.log.info(`v2 terminal route changed`,{route:t,phone:e.phoneFp.slice(0,8)}),t===`direct`&&this.logDirectRoute(),e.ready(this)},failure:(t,n)=>{e.log.warn(`v2 transport failed`,{stage:t,...n?{code:n.code,phase:n.phase}:{},phone:e.phoneFp.slice(0,8)})}})}get transportDiagnostics(){return this.endpoint.diagnostics}get activeRoute(){return this.endpoint.activeRoute}get handshakeGeneration(){return this.generation}helloOverdue(e=Date.now()){return!this.handshaken&&!this.routed&&!this.dormant&&e-this.openedAt>=this.helloTimeoutMs}handleEnvelope(e){return this.endpoint.receiveRelay(e)}send(e){return!this.broken&&this.endpoint.sendTerminal(k(e))}relayLost(){this.endpoint.relayLost()}async logDirectRoute(){let e=await this.endpoint.routeStats();e&&!this.broken&&this.log.info(`v2 direct route`,{...e,setupMs:this.endpoint.diagnostics.directSetupMs,phone:this.phoneFp.slice(0,8)})}close(){this.broken=!0,this.handshaken=!1,this.endpoint.close()}};function Hi(e){return async t=>{let n=()=>!t.aborted&&e.enabled();try{if(!n())return null;let r=await e.reference(t);if(!n()||!r||typeof r.owner!=`string`||!r.owner||r.owner.length>1024)return null;let i=Object.freeze({...r}),a=await e.locator.locate(i,t);if(!n()||a.status!==`candidate`)return null;let o=Object.freeze({agent:a.candidate.agent,path:a.candidate.path,session:a.candidate.session});if(o.agent!==i.agent||(i.kind===`path`?o.path!==i.value:o.session!==i.value.toLowerCase()))return null;let s=await e.reference(t);return!n()||!On(i,s)||i.owner!==s?.owner?null:Object.freeze({...o,owner:i.owner,reference:i})}catch{return null}}}const Ui=new Set([`claude`,`codex`,`agy`,`gemini`]),H=e=>JSON.stringify([e.agent,e.kind,e.value]),Wi=(e,t)=>e.state===t.state&&e.id===t.id&&e.agent===t.agent&&e.reason===t.reason;var Gi=class{options;sessions=new Map;timer=null;probing=null;closed=!1;constructor(e){this.options={...e}}status(e){if(!this.closed&&this.options.enabled())return this.sessions.get(e)?.info}update(e){if(this.closed)return;let t=!1,n=new Set;for(let r of e){n.add(r.id);let e=this.sessions.get(r.id),i=r.agent?.kind;if(i){if(e?.present&&e.agent===i)continue;this.sessions.set(r.id,this.fresh(r.id,i,e)),t=!0}else if(e?.present){e.present=!1,e.generation=null,e.epoch++,e.due=1/0,this.cancel(r.id);let n=this.set(e,{state:`none`,agent:e.agent,reason:`agent-exited`});t||=n}}for(let e of[...this.sessions.keys()])n.has(e)||(this.sessions.delete(e),this.cancel(e));t&&this.notify(),this.schedule()}invalidate(e){let t=this.sessions.get(e);!this.closed&&t?.present&&this.lookable(e,t.agent)&&(t.epoch++,t.unsettled=0,t.due=this.now(),this.cancel(e),this.set(t,{state:`finding`,agent:t.agent})&&this.notify(),this.schedule())}recheck(e){let t=this.sessions.get(e);if(!this.closed&&t?.present&&this.lookable(e,t.agent)){if(t.info.state!==`found`){this.invalidate(e);return}t.epoch++,t.unsettled=0,t.due=this.now(),this.cancel(e),this.schedule()}}settled(){if(this.closed)return;let e=!1;for(let t of this.sessions.values())t.present&&t.unsettled>0&&t.due>this.now()&&(t.due=this.now(),e=!0);e&&this.schedule()}remove(e){this.sessions.delete(e)&&this.cancel(e)}wake(){if(!this.closed){if(!this.options.enabled()){this.cancel();for(let[e,t]of this.sessions)t.present?this.sessions.set(e,this.fresh(e,t.agent,t)):this.sessions.delete(e)}this.schedule()}}async check(e,t,n){let r=this.sessions.get(e),i=r?.generation,a={result:`conversation-changed`};if(this.closed||!this.options.enabled()||!r||!i||i.id!==t&&i.alias!==t)return a;let o=r.epoch,s=await this.options.reference(e,n).catch(()=>null),c=!this.closed&&this.options.enabled()&&this.sessions.get(e)===r&&r.epoch===o&&r.generation===i&&!n.aborted;return c&&s&&H(s)===i.key?{result:`ok`,...typeof s.waiting==`boolean`&&{waiting:s.waiting}}:!this.closed&&this.sessions.get(e)===r&&r.generation===i&&(!s||!c&&H(s)===i.key&&r.epoch!==o)?{result:`unchecked`}:(this.sessions.get(e)===r&&r.generation===i&&(s&&H(s)!==i.key&&this.options.replaced?.(e),this.invalidate(e)),a)}idFor(e,t){let n=this.sessions.get(e);if(this.closed||!this.options.enabled()||!n?.present)return;let r=H(t);return(n.generation?.key!==r||n.generation.kind!==`found`)&&(n.generation=this.found(n.generation,r),n.unsettled=0,n.due=this.now()+(this.options.refreshMs??1e4)),this.set(n,{state:`found`,id:n.generation.id,agent:t.agent})&&this.notify(),n.generation.id}knownId(e,t){let n=this.sessions.get(e)?.generation;return!this.closed&&this.options.enabled()&&n?.kind===`found`&&n.key===H(t)?n.id:void 0}holds(e,t){let n=this.sessions.get(e)?.generation;return!this.closed&&this.options.enabled()&&!!n&&(n.id===t||n.alias===t)}found(e,t){return{id:this.newId(),key:t,kind:`found`,...e?.kind===`not-started`&&e.key===t&&{alias:e.id}}}close(){this.closed=!0,this.cancel(),this.timer&&clearTimeout(this.timer),this.timer=null,this.sessions.clear()}fresh(e,t,n){n&&this.cancel(e);let r=this.lookable(e,t);return{agent:t,present:!0,info:r?{state:`finding`,agent:t}:{state:`none`,agent:t,reason:`not-supported`},generation:null,due:r?this.now():1/0,epoch:(n?.epoch??0)+1,unsettled:0}}lookable(e,t){return Ui.has(t)&&this.options.supported(e)}set(e,t){return!Wi(e.info,t)&&(e.info=t,!0)}notify(){this.options.enabled()&&this.options.changed()}now(){return this.options.now?.()??Date.now()}cancel(e){this.probing&&(e===void 0||this.probing.sessionId===e)&&(this.probing.controller.abort(),this.probing=null)}schedule(){if(this.closed||this.probing||(this.timer&&clearTimeout(this.timer),this.timer=null,!this.options.enabled()||!this.options.active()))return;let e=1/0;for(let t of this.sessions.values())e=Math.min(e,t.due);e!==1/0&&(this.timer=setTimeout(()=>{this.timer=null,this.pump()},Math.max(0,e-this.now())),this.timer.unref?.())}pump(){if(this.closed||this.probing||!this.options.enabled()||!this.options.active())return;let e=this.now(),t=null;for(let n of this.sessions){let[r,i]=n;if(i.due>e)continue;if(!t){t=n;continue}let a=this.options.viewed(r);(a===this.options.viewed(t[0])?i.due<t[1].due:a)&&(t=n)}if(!t){this.schedule();return}let[n,r]=t,i=new AbortController,a={sessionId:n,controller:i};this.probing=a,this.probe(n,r,i.signal).finally(()=>{this.probing===a&&(this.probing=null),this.schedule()})}async probe(e,t,n){let r=t.epoch,i=()=>!this.closed&&!n.aborted&&this.options.enabled()&&this.sessions.get(e)===t&&t.epoch===r,a=t.info.state===`found`?t.generation:null;if(a?.kind===`found`){let r=await this.within(n,t=>this.options.reference(e,t).catch(()=>null));if(!i())return;if(r&&H(r)===a.key){t.unsettled=0,t.due=this.now()+(this.options.refreshMs??1e4);return}}let o,s,c=Hi({enabled:i,reference:async t=>{let n=await this.options.reference(e,t);return o===void 0&&(o=n),n},locator:{locate:async(e,t)=>(s=await this.options.locator.locate(e,t),s)}}),l=await this.within(n,c);if(!i())return;let u=this.now(),d=u+(this.options.refreshMs??1e4),f=()=>{t.due=u+1e3},p=null;if(l&&o){let n=H(o);if(t.generation?.key!==n||t.generation.kind!==`found`){let r=t.generation;t.generation=this.found(r,n),r?.kind===`found`&&this.options.replaced?.(e)}t.unsettled=0,p={state:`found`,id:t.generation.id,agent:l.agent}}else if(s?.status===`busy`)f();else if(o===null)t.unsettled++===0?f():(t.generation=null,p={state:`none`,agent:t.agent,reason:`no-history`});else if(s?.status===`unavailable`){let n=s.reason;if(n===`unbound`&&o){let n=H(o);(t.generation?.key!==n||t.generation.kind!==`not-started`)&&(t.generation?.kind===`found`&&this.options.replaced?.(e),t.generation={id:this.newId(),key:n,kind:`not-started`}),p={state:`none`,agent:t.agent,reason:`not-started`,id:t.generation.id}}else n===`limit`||n===`ambiguous`||n===`unbound`?(t.generation=null,p={state:`none`,agent:t.agent,reason:n===`limit`?`lookup-limit`:n===`ambiguous`?`ambiguous`:`no-history`}):f()}else f();p&&(o&&(t.unsettled=0),t.due=d,this.set(t,p)&&this.notify())}async within(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(),5e3),i=()=>n.abort();e.addEventListener(`abort`,i,{once:!0});try{return await t(n.signal)}finally{clearTimeout(r),e.removeEventListener(`abort`,i)}}newId(){let e=this.options.newId?.()??O(Oe(16));if(e.length<1||e.length>32)throw TypeError(`Invalid chat id`);return e}};const Ki=1e3,qi=5e3;var Ji=class{options;closed=!1;ended=!1;follower=null;operation=!1;epoch={};due=0;checkingShown=!1;generation=null;revision=0;appliedHistory=`complete`;applied=[];branch=null;projection=[];projectionClipped=!1;snapshot=null;snapshotCurrent=!1;discontinuity=0;pending=null;cursor=null;history=null;lastHistory=null;lastHistoryResult=null;clear=null;afterClear=null;controls=[];authorizedUntil=0;caughtUp=!1;reportedBusy=!1;queuedSent=null;retries=0;retrying=!1;replacingUntil=0;heldStatus=null;lastSourceAt;unlinkedHistory=!1;historicalBranch=new Map;constructor(e){if(!t.safeParse(e.subscriptionId).success)throw TypeError(`Invalid conversation subscription`);this.options={...e},this.lastSourceAt=e.now(),this.status(`checking`)}get sessionId(){return this.options.sessionId}get subscriptionId(){return this.options.subscriptionId}get needsWork(){return!this.closed&&!this.ended&&!this.operation&&!this.clear&&this.options.enabled()&&this.options.now()>=this.due}close(){this.closed||(this.closed=!0,this.discard(),this.clear=null,this.controls=[])}invalidate(e){this.closed||(this.ended||=e===`ended`,this.ended&&(e=`ended`),e===`changed`||e===`skipped`?this.generation&&(this.replacingUntil=this.options.now()+D.progressMs):(this.replacingUntil=0,this.heldStatus=null),this.discard(),this.controls=[],this.clear?.sent?this.clear.message.reason!==e&&(this.afterClear=e):this.clear={message:{type:`conversation.clear`,subscriptionId:this.subscriptionId,clearId:this.id(),reason:e},sent:!1,deadline:0},this.options.wake())}receive(e,t){if(!(this.closed||e.subscriptionId!==this.subscriptionId)){if(!Number.isSafeInteger(t)||t<1||t>D.envelopeBytes||!v.safeParse(e).success){this.invalidate(`unavailable`);return}if(e.type===`conversation.cancel`){this.close();return}if(e.type===`conversation.cleared`){if(this.clear?.sent&&e.clearId===this.clear.message.clearId){this.clear=null;let e=this.afterClear;if(this.afterClear=null,e){this.invalidate(e);return}this.due=this.options.now(),this.replacingUntil&&=this.options.now()+D.progressMs,!this.options.enabled()&&!this.ended&&this.status(`disabled`)}return}if(e.type===`conversation.refresh`){this.clear?(this.clear.deadline=0,this.options.wake()):this.ended||this.invalidate(this.options.enabled()?`changed`:`disabled`);return}if(this.options.enabled()&&!this.clear){if(e.type===`conversation.applied`){this.appliedBatch(e);return}if(e.type===`conversation.history.get`){if(e.generation!==this.generation||this.history?.requestId===e.requestId)return;if(this.history){this.endHistory(e,`busy`);return}if(e.requestId===this.lastHistory&&this.lastHistoryResult?.requestId===e.requestId){this.queueControl(this.lastHistoryResult);return}if(e.requestId===this.lastHistory||e.cursor!==this.cursor?.id){this.endHistory(e,`changed`);return}this.history={...e},this.due=this.options.now()}}}}async work(){if(!this.needsWork)return;this.operation=!0;let e=this.epoch,t=()=>!this.closed&&this.epoch===e&&this.options.enabled()&&!this.clear;try{if(!this.follower){this.follower=this.options.follow();let e=this.follower;e?.onChange?.(()=>{this.closed||this.follower!==e||(this.due=Math.min(this.due,this.options.now()),this.options.due?.())})}if(!this.follower){this.status(`checking`,`busy`),this.due=this.options.now()+1e3;return}let e=this.follower;if(this.pending?.sent&&this.options.now()<this.pending.deadline){this.due=this.pending.deadline;return}if(this.pending&&!this.pending.sent&&this.options.now()<=this.authorizedUntil){this.due=this.authorizedUntil+1,this.options.wake();return}if(this.snapshotCurrent&&this.snapshot&&this.history&&!this.pending&&this.cursor?.anchor&&e.older&&this.applied[0]?.local===this.cursor.local&&this.projection.findIndex(e=>e.local===this.cursor.local)<=0){let n=await e.older(this.cursor.anchor);if(!t()||this.follower!==e)return;if(this.due=this.options.now()+200,n.status===`stopped`)this.stopped(n.reason);else if(n.status===`refresh`)this.snapshotCurrent=!1;else if(n.status===`busy`)this.waitingForSource();else if(n.status===`reading`)this.waitingForSource(),this.due=this.options.now();else if(n.status===`unavailable`)this.finishHistory(`unavailable`);else if(n.status===`page`){let e=n.branch?.kind===`claude`?n.branch.nodes:[],t=[this.historicalBranch,new Map(this.branch?.kind===`claude`?this.branch.nodes.map(e=>[e.id,e.start]):[]),new Map(this.snapshot.branch?.kind===`claude`?this.snapshot.branch.nodes.map(e=>[e.id,e.start]):[])];if(e.some(e=>t.some(t=>t.has(e.id)&&t.get(e.id)!==e.start))){this.invalidate(`changed`);return}if(new Set([...this.historicalBranch.keys(),...e.map(e=>e.id)]).size>4096){this.finishHistory(`unavailable`);return}if(this.unlinkedHistory||=n.history===`unlinked`,this.lastSourceAt=this.options.now(),this.authorizedUntil=this.options.now()+200,this.caughtUp=!1,!n.entries.length)this.finishHistory(n.history===`complete`&&!this.unlinkedHistory?`complete`:`unavailable`);else{let t=new Map([...this.applied,...this.projection].map(e=>[e.local,e.id])),r=n.entries.map(({entry:e,anchor:n})=>{let r=t.get(e.id)??this.id(),i=Object.freeze({...e,id:r}),a=k(i),o=R(`sha256`).update(a).digest(`base64url`);return a.fill(0),{local:e.id,id:r,hash:o,entry:i,anchor:n}}),i=this.history,a=this.applied[0],o=this.page(r,`prepend`,a.id,i.requestId);o.length?this.queue(`prepend`,o,this.applied,a.id,i.requestId,void 0,[],{history:this.unlinkedHistory?`unlinked`:n.history,more:o.length<r.length||(n.more??n.history!==`complete`),ancestors:e}):this.finishHistory(`unavailable`)}this.options.wake()}return}if(this.snapshotCurrent&&this.snapshot&&(this.pending||this.history||this.hasUpdate())){let n=await e.confirm(this.snapshot.revision);if(!t()||this.follower!==e)return;if(n.status===`confirmed`){this.lastSourceAt=this.options.now(),this.caughtUp=n.caughtUp,this.authorizedUntil=this.options.now()+200,this.recovered(),this.prepare(),this.due=this.options.now(),this.options.wake();return}if(n.status===`stopped`){this.stopped(n.reason);return}if(n.status===`busy`){this.waitingForSource();return}this.pending?.sent?this.invalidate(`changed`):(this.pending=null,this.snapshotCurrent=!1,this.due=this.options.now()+200);return}if(this.snapshotCurrent&&this.snapshot&&!this.pending&&!this.history&&!this.reportedBusy&&e.idle){let n=await e.idle();if(!t()||this.follower!==e)return;if(n){this.lastSourceAt=this.options.now(),this.due=this.options.now()+Ki;return}}let n=await e.poll();if(!t()||this.follower!==e)return;this.accept(n)}catch{t()&&this.invalidate(`unavailable`)}finally{this.operation=!1}}offer(){if(this.closed)return!1;let e=this.options.now();if(this.clear){let t=this.clear;if(t.sent&&e<t.deadline)return!1;let n=this.send(t.message);return this.clear===t&&n&&(t.sent=!0,t.deadline=e+D.progressMs),n}let t=this.pending,n=()=>!!t&&this.options.enabled()&&e<=this.authorizedUntil&&!(t.sent&&e<t.deadline),r=this.controls.every(e=>e.type===`conversation.status`&&e.state===`ready`);if(this.controls.length&&!(r&&t&&!t.sent&&n())){let t=this.controls.find(e=>e.type===`conversation.history.end`)??this.controls[0];if(t.type===`conversation.status`&&t.state===`ready`&&(!this.options.enabled()||e>this.authorizedUntil))return!1;let n=this.send(t);return n&&(this.controls=this.controls.filter(e=>e!==t)),n}if(!t||!n())return!1;let i=this.send(t.batch);return this.pending===t&&i&&(t.sent=!0,t.deadline=e+D.progressMs,this.due=t.deadline),i}retry(){this.closed||this.ended||!this.retrying||(this.due=Math.min(this.due,this.options.now()),this.options.due?.())}tick(){this.closed||(this.replacingUntil&&this.options.now()>=this.replacingUntil&&this.endReplacing(),!this.options.enabled()&&(this.follower||this.generation||this.pending)&&this.invalidate(`disabled`),(this.clear&&this.options.now()>=this.clear.deadline||this.controls.length)&&this.options.wake())}accept(e){if(this.due=this.options.now()+200,e.status===`busy`){this.waitingForSource();return}if(e.status===`stopped`){this.stopped(e.reason);return}if(e.discontinuity!==this.discontinuity&&this.generation){this.invalidate(`skipped`);return}if(this.discontinuity=e.discontinuity,e.status===`catching-up`){this.snapshotCurrent=!1,this.generation?this.waitingForSource():(this.checkingShown||this.status(`checking`),this.checkingShown=!0),e.pending&&(this.due=this.options.now());return}this.lastSourceAt=this.options.now();let t=e.snapshot;if(t.state!==`ready`||!t.branch){this.generation?this.invalidate(`unavailable`):(this.status(`unavailable`,t.state===`unsupported`?`unsupported`:`unbound`),this.due=this.options.now()+qi);return}if(this.branch?.kind===`claude`){let e=this.branch.nodes.at(-1);if(t.branch.kind!==`claude`||!e||![...t.branch.nodes,...t.branch.parallel??[]].some(t=>t.id===e.id&&t.start===e.start)){let n=t.branch.kind===`claude`&&e&&t.history!==`complete`&&(t.branch.nodes[0]?.start??0)>e.start;this.invalidate(n?`skipped`:`changed`);return}let n=new Map(this.branch.nodes.map(e=>[e.id,e.start]));if(t.branch.nodes.some(e=>n.has(e.id)&&n.get(e.id)!==e.start||this.historicalBranch.has(e.id)&&this.historicalBranch.get(e.id)!==e.start)){this.invalidate(`changed`);return}}if(t.entries!==this.snapshot?.entries){let e=new Map([...this.applied,...this.projection].map(e=>[e.local,e.id])),n=[],r=0;this.projectionClipped=!1;for(let i=t.entries.length-1;i>=0;i--){let a=t.entries[i];if(a.id.startsWith(`history:`))continue;let o=e.get(a.id)??this.id(),s=Object.freeze({...a,id:o}),c=k(s);r+=c.byteLength;let l=R(`sha256`).update(c).digest(`base64url`);if(c.fill(0),r>D.queuedBytes-D.batchBytes||n.length>=D.retainedEntries){this.projectionClipped=!0;break}n.push({local:a.id,id:o,hash:l,entry:s})}n.reverse();let i=this.follower?.anchor;if(this.projectionClipped&&i){let e=n.findIndex(e=>i.call(this.follower,t.revision,e.local)!==null);e>0&&n.splice(0,e)}this.projection=n}this.snapshot=this.projectionClipped?{...t,history:`truncated`}:t,this.snapshotCurrent=!0,this.caughtUp=e.caughtUp,this.generation||=this.id(),this.retries=0,this.retrying=!1,this.recovered(),this.hasUpdate()||this.history?(this.authorizedUntil=this.options.now()+200,this.prepare(),this.due=this.options.now(),this.options.wake()):(this.authorizedUntil=0,this.due=this.options.now()+Ki)}recovered(){this.reportedBusy&&(this.reportedBusy=!1,this.queueControl(this.readyStatus()))}waitingForSource(){this.due=this.options.now()+200,this.options.now()-this.lastSourceAt>=D.progressMs&&(this.status(`checking`,`busy`),this.reportedBusy=this.generation!==null)}hasUpdate(){return!this.generation||this.revision===0||this.controls.some(e=>e.type===`conversation.status`&&e.state===`ready`)||this.queuedKey()!==this.queuedSent?!0:this.update()!==null}queuedKey(e=this.options.chat?.known()){return JSON.stringify([this.snapshot?.queued??[],e??null])}readyStatus(){let e=this.options.chat?.adopt();this.queuedSent=this.queuedKey(e);let t={type:`conversation.status`,subscriptionId:this.subscriptionId,state:`ready`,caughtUp:this.caughtUp},n=(this.snapshot?.queued??[]).map(e=>({...e}));return{...t,...n.length?{queued:n}:{},...e!==void 0&&{chat:e}}}update(){if(!this.applied.length)return this.projection.length?{at:0,rows:this.projection,after:0}:null;let e=new Map(this.applied.map((e,t)=>[e.local,t])),t=this.projection.findIndex(t=>e.has(t.local));if(t<0)return{at:-1,rows:[],after:0,reset:`skipped`};let n=e.get(this.projection[t].local);if(this.appliedHistory===`complete`){if(this.snapshot?.history===`complete`&&(t>0||n>0))return{at:0,rows:this.projection.slice(0,t),after:n};if(t>0)return{at:n,rows:this.projection.slice(0,t),after:n}}for(;t<this.projection.length&&n<this.applied.length&&this.projection[t].local===this.applied[n].local&&this.projection[t].hash===this.applied[n].hash;)t++,n++;if(t===this.projection.length)return n===this.applied.length?null:{at:n,rows:[],after:this.applied.length};let r=this.projection[t];if(this.applied[n]?.local===r.local)return{at:n,rows:[r],after:n+1};let i=e.get(r.local);if(i!==void 0)return i>n?{at:n,rows:[],after:i}:{at:-1,rows:[],after:0,reset:`changed`};let a=t;for(;a<this.projection.length&&!e.has(this.projection[a].local);)a++;return{at:n,rows:this.projection.slice(t,a),after:n}}prepare(){if(this.pending||!this.snapshot?.branch||!this.generation)return;if(this.controls.some(e=>e.type===`conversation.status`&&e.state===`ready`)&&this.queueControl(this.readyStatus()),this.history){let e=this.history,t=this.applied[0],n=this.projection.findIndex(e=>e.local===t?.local);if(!t||n<0||t.local!==this.cursor?.local){this.finishHistory(`changed`);return}if(n===0){this.finishHistory(this.snapshot.history===`complete`?`complete`:`unavailable`);return}let r=this.page(this.projection.slice(0,n),`prepend`,t.id,e.requestId);this.queue(`prepend`,r,this.applied,t.id,e.requestId);return}if(this.revision===0){this.queue(`reset`,this.page(this.projection,`reset`),[]);return}let e=this.update();if(!e){this.branch=this.snapshot.branch,this.queuedKey()!==this.queuedSent&&this.queueControl(this.readyStatus());return}if(e.at<0){this.invalidate(e.reset??`changed`);return}let t=this.applied[e.at-1]?.id??null,n=this.applied[e.after]?.id??null;this.queue(`patch`,this.page(e.rows,`patch`,t,void 0,n),this.applied.slice(0,e.at),t,void 0,n,this.applied.slice(e.after))}page(e,t,n,r,i){let a=[],o=t!==`patch`;for(let s=0;s<Math.min(e.length,D.entriesPerBatch);s++){let c=e[o?e.length-s-1:s],l=o?[c,...a]:[...a,c],u=this.message(t,l,n,r,`0`.repeat(22),i);if(k(u).byteLength>D.batchBytes)break;a.splice(0,a.length,...l)}return a}message(e,t,n,r,i=null,a){return{type:`conversation.batch`,subscriptionId:this.subscriptionId,generation:this.generation,batchId:`0`.repeat(22),baseRevision:this.revision,revision:this.revision+1,operation:e,...e!==`reset`&&{anchor:n??null},...r&&{requestId:r},...a!==void 0&&{after:a},entries:t.map(e=>e.entry),...e!==`patch`&&{olderCursor:i,history:i?`unloaded`:this.snapshot.history}}}queue(e,t,n,r,i,a,o=[],s){let c=t.map(({local:e,id:t,hash:n})=>({local:e,id:t,hash:n})),l=e===`prepend`?[...c,...n]:[...n,...c,...o];if(new Set(l.map(e=>e.local)).size!==l.length){e===`prepend`?this.finishHistory(`changed`):this.invalidate(`changed`);return}let u=this.projection.findIndex(e=>e.local===l[0]?.local),d=l[0],f=d?.local===`unlinked-side`?l[1]:d,p=f?t.find(e=>e.local===f.local)?.anchor??this.follower?.anchor?.(this.snapshot.revision,f.local)??null:null,m=s?s.more:u>0||this.snapshot.history!==`complete`,h=e===`patch`?void 0:d&&m&&(u>0||p)?{id:this.id(),local:d.local,anchor:p}:null,g={...this.message(e,t,r,i,h?.id,a),batchId:this.id(),...s&&{history:s.history===`unlinked`?`unlinked`:h||s.more?`unloaded`:s.history}};if(!je.safeParse(g).success){this.invalidate(`unavailable`);return}e===`reset`&&this.endReplacing(),this.pending={batch:g,proposed:l,branch:this.snapshot.branch,cursor:h,sent:!1,deadline:0,...s?.ancestors&&{ancestors:s.ancestors}},this.queueControl(this.readyStatus())}appliedBatch(e){let t=this.pending;if(!t?.sent||e.generation!==this.generation||e.batchId!==t.batch.batchId||e.revision!==t.batch.revision)return;let n=e.retainedCount===0?t.proposed.length:t.proposed.findIndex(t=>t.id===e.oldestId);if(n<0||t.proposed.length-n!==e.retainedCount||(t.proposed.at(-1)?.id??null)!==e.newestId){this.invalidate(`unavailable`);return}this.applied=t.proposed.slice(n);for(let e of t.ancestors??[])this.historicalBranch.set(e.id,e.start);this.branch=t.branch,this.revision=e.revision,t.batch.history!==void 0&&(this.appliedHistory=t.batch.history),n>0&&(this.appliedHistory=`unloaded`),t.cursor!==void 0&&(this.cursor=t.cursor),this.applied[0]?.local!==this.cursor?.local&&(this.cursor=null),t.batch.operation===`prepend`&&(this.lastHistory=t.batch.requestId,this.lastHistoryResult=null,this.history=null),this.pending=null,this.due=this.options.now()}finishHistory(e){this.follower?.cancelOlder?.(),e===`complete`?(this.appliedHistory=`complete`,this.cursor=null):e===`changed`&&(this.cursor=null);let t=this.history;this.history=null,this.lastHistory=t.requestId,this.endHistory(t,e),this.lastHistoryResult={type:`conversation.history.end`,subscriptionId:this.subscriptionId,generation:t.generation,requestId:t.requestId,reason:e}}endHistory(e,t){this.queueControl({type:`conversation.history.end`,subscriptionId:this.subscriptionId,generation:e.generation,requestId:e.requestId,reason:t})}stopped(e){this.generation?this.invalidate(e===`disabled`?`disabled`:e===`changed`?`changed`:`unavailable`):(this.discard(),this.status(e===`disabled`?`disabled`:`unavailable`,e===`unbound`?`unbound`:e===`unsupported`?`unsupported`:`source`),e===`unsupported`?this.due=1/0:(this.retrying=!0,this.due=this.options.now()+Math.min(qi,250*2**Math.min(this.retries++,5))))}status(e,t){let n={type:`conversation.status`,subscriptionId:this.subscriptionId,state:e,...t&&{reason:t}};if(e!==`disabled`&&this.replacingUntil>this.options.now()){this.heldStatus=n;return}this.queueControl(n)}endReplacing(){this.replacingUntil=0;let e=this.heldStatus;this.heldStatus=null,e&&!this.generation&&this.queueControl(e)}queueControl(e){if(e.type===`conversation.status`)this.controls=this.controls.filter(e=>e.type!==`conversation.status`);else if(e.type===`conversation.history.end`&&this.controls.some(t=>t.type===`conversation.history.end`&&t.generation===e.generation&&t.requestId===e.requestId))return;this.controls.length>=4&&(this.controls=this.controls.filter(e=>e.type!==`conversation.status`)),this.controls.length<4&&this.controls.push(e),this.options.wake()}discard(){this.checkingShown=!1,this.queuedSent=null,this.reportedBusy=!1,this.epoch={},this.follower?.close(),this.follower=null,this.generation=null,this.revision=0,this.appliedHistory=`complete`,this.applied=[],this.branch=null,this.projection=[],this.projectionClipped=!1,this.snapshot=null,this.snapshotCurrent=!1,this.pending=null,this.cursor=null,this.history=null,this.lastHistory=null,this.lastHistoryResult=null,this.authorizedUntil=0,this.discontinuity=0,this.unlinkedHistory=!1,this.historicalBranch.clear()}id(){let e=this.options.newId();if(!t.safeParse(e).success)throw TypeError(`Invalid conversation ID`);return e}send(e){try{let t=this.options.send(e);return t!==!0&&t!==!1?(Promise.resolve(t).catch(()=>{}),!1):t}catch{return!1}}};const Yi=65536;function Xi(e,t){return!!t&&e.agent===t.agent&&e.path===t.path&&e.session===t.session&&e.owner===t.owner&&(e.reference===t.reference||!!e.reference&&!!t.reference&&On(e.reference,t.reference)&&e.reference.owner===t.reference.owner)}function Zi(e,t){return e.dev===t.dev&&e.ino===t.ino}function Qi(e){return F(e)&&e.length<=4096&&!Array.from(e).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)}function $i(e,t){let n=Sr(e,t);return n!==``&&n!==`..`&&!n.startsWith(`..${Cr}`)&&!F(n)}function ea(e){return e.isFile()&&!e.isSymbolicLink()&&Number.isSafeInteger(e.size)&&e.size>=0&&(process.getuid===void 0||e.uid===process.getuid())}function ta(e){if(e.fd===-1)return Promise.resolve();let t=e;return new Promise(n=>{let r=!1,i=()=>{r&&e.fd===-1&&(t.removeListener(`close`,i),n())},a=()=>{r=!0,i()};t.once(`close`,i);try{e.close().then(a,a)}catch{a()}})}var na=class e{options;path;file;identity;controller=new AbortController;reason=null;reading=!1;opening=!0;closeFinished=!1;finishClosed;closed=new Promise(e=>{this.finishClosed=e});fences=[];observed;onAbort=()=>{this.stop(`cancelled`)};constructor(e,t,n,r,i){this.options=e,this.path=n,this.file=r,this.identity=Object.freeze({...t}),this.observed=i,e.signal?.addEventListener(`abort`,this.onAbort,{once:!0}),e.signal?.aborted&&this.stop(`cancelled`)}static async open(t){let n,r;try{if(t.signal?.aborted)return{status:`stopped`,reason:`cancelled`};if(!t.enabled())return{status:`stopped`,reason:`disabled`};let i=await ra(t,t.signal);if(!i)return{status:`stopped`,reason:t.signal?.aborted?`cancelled`:`unbound`};let a={...i};if(![`claude`,`codex`,`gemini`].includes(a.agent)||!Qi(a.path)||!a.path.endsWith(`.jsonl`)||!/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,255}$/.test(a.session)||!a.owner||a.owner.length>1024)return{status:`stopped`,reason:`unsafe`};let o=t.roots[a.agent];if(!o?.length||o.length>8)return{status:`stopped`,reason:`unsafe`};let s=await B(a.path),c=!1;for(let e of o)if(Qi(e))try{$i(await B(e),s)&&(c=!0)}catch{}if(!c)return{status:`stopped`,reason:`unsafe`};let l=await z(a.path);if(!ea(l))return{status:`stopped`,reason:`unsafe`};n=await Lr(s,ir.O_RDONLY|ir.O_NOFOLLOW|ir.O_NONBLOCK);let u=await n.stat();if(!ea(u)||!Zi(l,u))return{status:`stopped`,reason:`changed`};r=new e(t,a,s,n,u);let d=await r.validate();if(d)return{status:`stopped`,reason:d};if(!r.installFences(await r.captureFences(u.size)))return{status:`stopped`,reason:r.stopped};let f=await r.validate()??r.availability();return f?{status:`stopped`,reason:f}:(n=void 0,{status:`open`,file:r})}catch{return{status:`stopped`,reason:t.signal?.aborted?`cancelled`:`unreadable`}}finally{r?(n&&r.stop(`unreadable`),r.opening=!1,r.finishClosing(),n&&await r.closed):n&&await ta(n)}}get stopped(){return this.reason}get size(){return this.observed.size}async read(e,t=Yi){if(this.reason)return{status:`stopped`,reason:this.reason};if(this.reading)return{status:`busy`};if(!Number.isSafeInteger(e)||e<0||!Number.isSafeInteger(t)||t<1||t>65536)return this.stop(`unsafe`),{status:`stopped`,reason:`unsafe`};this.reading=!0;let n,r;try{let i=await this.file.stat();if(this.reason)return this.stoppedRead(this.reason);if(!ea(i)||!Zi(i,this.observed)||i.size<this.observed.size)return this.stoppedRead(`changed`);let a=i.size;if(e>a)return this.stoppedRead(`unsafe`);n=Buffer.alloc(Math.min(t,a-e));let{bytesRead:o}=await this.file.read(n,0,n.length,e);if(o!==n.length)return this.stoppedRead(`changed`);r=await this.captureFences(a);let s=await this.validate(r);if(s)return this.stoppedRead(s);if(this.observed.size<a)return this.stoppedRead(`changed`);if(!this.installFences(r))return this.stoppedRead(this.reason);r=void 0;let c=n;return n=void 0,{status:`data`,bytes:c,offset:e,size:a}}catch{return this.stoppedRead(this.reason??`unreadable`)}finally{n?.fill(0);for(let e of r??[])e.bytes.fill(0);this.reading=!1,this.finishClosing()}}async verify(){if(this.reason)return{status:`stopped`,reason:this.reason};if(this.reading)return{status:`busy`};this.reading=!0;try{let e=await this.validate()??this.availability();return e?(this.stop(e),{status:`stopped`,reason:this.reason}):{status:`verified`,size:this.observed.size}}catch{return this.stop(this.reason??`unreadable`),{status:`stopped`,reason:this.reason}}finally{this.reading=!1,this.finishClosing()}}async unchanged(){if(this.reason||this.reading)return!1;try{let e=await z(this.path),t=this.observed;return!this.reason&&e.dev===t.dev&&e.ino===t.ino&&e.size===t.size&&e.mtimeMs===t.mtimeMs&&e.ctimeMs===t.ctimeMs}catch{return!1}}get watchPath(){return this.path}close(){this.stop(`cancelled`)}stoppedRead(e){return this.stop(e),{status:`stopped`,reason:this.reason}}stop(e){if(!this.reason){this.reason=e,this.controller.abort(),this.options.signal?.removeEventListener(`abort`,this.onAbort);for(let e of this.fences)e.bytes.fill(0);this.fences=[],ta(this.file).then(()=>{this.closeFinished=!0,this.finishClosing()})}}finishClosing(){this.reason&&this.closeFinished&&!this.opening&&!this.reading&&this.finishClosed()}async validate(e=[]){if(this.reason)return this.reason;if(!this.options.enabled())return`disabled`;let t=await ra(this.options,this.controller.signal);if(this.reason)return this.reason;if(!this.options.enabled())return`disabled`;if(!t)return`unbound`;if(!Xi(this.identity,t)||await B(this.identity.path)!==this.path)return`changed`;let[n,r]=await Promise.all([z(this.path),this.file.stat()]);if(!ea(n)||!Zi(n,r)||!Zi(r,this.observed)||r.size<this.observed.size||r.size===this.observed.size&&r.mtimeMs!==this.observed.mtimeMs)return`changed`;for(let t of[...this.fences,...e]){let e=Buffer.alloc(t.bytes.length);try{if((await this.file.read(e,0,e.length,t.offset)).bytesRead!==e.length||!e.equals(t.bytes))return`changed`}finally{e.fill(0)}}return this.reason?this.reason:this.options.enabled()?(this.observed=r,null):`disabled`}availability(){let e=this.options.enabled();return this.reason??(e?null:`disabled`)}installFences(e){let t=this.availability();if(t){for(let t of e)t.bytes.fill(0);return this.stop(t),!1}for(let e of this.fences)e.bytes.fill(0);return this.fences=e,!0}async captureFences(e){let t=Math.min(4096,e),n=[];try{for(let r of t===e?[0]:[0,e-t]){let e=Buffer.alloc(t);if(n.push({offset:r,bytes:e}),(await this.file.read(e,0,e.length,r)).bytesRead!==e.length||this.reason)throw Error(`invalidated`)}return n}catch(e){for(let e of n)e.bytes.fill(0);throw e}}};async function ra(e,t){if(t?.aborted||!e.enabled())return null;let n=new AbortController,r=()=>n.abort();t?.addEventListener(`abort`,r,{once:!0});let i;try{let t=new Promise(e=>{n.signal.addEventListener(`abort`,()=>e(null),{once:!0}),i=setTimeout(r,2e3)}),a=await Promise.race([e.identity(n.signal),t]);return a?{...a}:null}catch{return null}finally{clearTimeout(i),t?.removeEventListener(`abort`,r),n.abort()}}const ia=16384,aa=ia,oa=aa*6,sa=/["\\\u0000-\u001f]/g,ca=/^(?:true|false|null|-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)$/;var la=class{outline;decoder=new TextDecoder(`utf-8`,{fatal:!0});stack=[];mode=`value`;root;rooted=!1;failed=null;budget=131072;shortBudget=65536;recordBudget=16384;keyString=!1;keep=null;raw=``;length=0;escape=0;literal=``;constructor(e){this.outline=e}push(e){if(this.failed)return;let t;try{t=this.decoder.decode(e,{stream:!0})}catch{this.failed=`invalid-utf8`;return}this.scan(t)}finish(){if(!this.failed){let e;try{e=this.decoder.decode()}catch{this.failed=`invalid-utf8`,e=``}this.scan(e),this.mode===`literal`&&this.endLiteral()}let e=this.root;return this.root=void 0,this.raw=``,this.failed?{kind:`skipped`,reason:this.failed}:!this.rooted&&this.mode===`value`?null:this.stack.length||this.mode!==`after`||typeof e!=`object`||!e||Array.isArray(e)?{kind:`skipped`,reason:`invalid-json`}:{kind:`record`,value:e}}fail(){this.failed=`invalid-json`}scan(e){let t=0;for(;t<e.length&&!this.failed;){if(this.mode===`string`){t=this.string(e,t);continue}let n=e.charCodeAt(t);if(this.mode===`literal`){if(/[0-9a-zA-Z+.-]/.test(e[t])){this.literal+=e[t],this.literal.length>512&&this.fail(),t++;continue}if(this.endLiteral(),this.failed)break}if(t++,n===32||n===9||n===10||n===13)continue;let r=this.stack.at(-1);if(this.mode===`first-item`&&n===93){this.close();continue}switch(this.mode){case`first-item`:case`value`:n===123?this.open(!1):n===91?this.open(!0):n===34?this.beginString(!1):/[-0-9tfn]/.test(e[t-1])?(this.keep=this.slot(),this.literal=e[t-1],this.mode=`literal`):this.fail();break;case`first-key`:n===125?this.close():n===34?this.beginString(!0):this.fail();break;case`key`:n===34?this.beginString(!0):this.fail();break;case`colon`:n===58?this.mode=`value`:this.fail();break;case`after`:r?n===44?this.mode=r.array?`value`:`key`:n===(r.array?93:125)?this.close():this.fail():this.fail()}}}slot(){let e=this.stack.at(-1);return e?e.array?e.shape?.items&&e.count<65?e.shape.items:null:e.child:this.outline}open(e){if(this.stack.length>=512){this.fail();return}let t=this.slot();this.stack.push({array:e,value:t?e?[]:{}:null,shape:t,child:null,key:null,count:0}),this.mode=e?`first-item`:`first-key`}close(){let e=this.stack.pop();this.place(e.value,e.value!==null)}place(e,t){let n=this.stack.at(-1);this.mode=`after`,n?n.array?(t&&n.value.push(e),n.count++):t&&n.key!==null&&(n.value[n.key]=e):(this.root=e,this.rooted=!0)}beginString(e){this.keyString=e,this.keep=e?null:this.slot(),this.raw=``,this.length=0,this.escape=0,this.mode=`string`}append(e){this.length+=e.length,(this.keyString||this.keep)&&(this.length<=(this.keyString?256:oa)?this.raw+=e:this.raw=``)}string(e,t){let n=t;for(;n<e.length;){if(this.escape===1){let t=e[n];if(t===`u`)this.escape=2;else if(`"\\/bfnrt`.includes(t))this.escape=0;else return this.fail(),n;this.append(t),n++;continue}if(this.escape>=2){if(!/[0-9a-fA-F]/.test(e[n]))return this.fail(),n;this.escape=this.escape===5?0:this.escape+1,this.append(e[n]),n++;continue}sa.lastIndex=n;let t=sa.exec(e),r=t?t.index:e.length;if(r>n&&this.append(e.slice(n,r)),n=r,!t)break;let i=e.charCodeAt(n);if(i===34)return this.endString(),n+1;if(i!==92)return this.fail(),n;this.append(`\\`),this.escape=1,n++}return n}endString(){let e=this.stack.at(-1),t=this.length>(this.keyString?256:oa)||!this.keyString&&!this.keep?null:JSON.parse(`"${this.raw}"`),n=t!==null&&(this.keyString||t.length<=aa)?t:null;if(this.raw=``,this.keyString){let t=e.shape?.keys;e.key=n,e.child=n!==null&&t&&Object.hasOwn(t,n)?t[n]:null,this.mode=`colon`;return}if(!this.keep){this.place(void 0,!1);return}let r=this.stack.length===1&&n!==null&&n.length<=1024&&n.length<=this.recordBudget,i=!r&&n!==null&&n.length<=256&&n.length<=this.shortBudget,a=r||i||n!==null&&n.length<=this.budget;r?this.recordBudget-=n.length:i?this.shortBudget-=n.length:a&&(this.budget-=n.length),this.place(a?n:`Too large to show here`,!0)}endLiteral(){if(!ca.test(this.literal)){this.fail();return}this.place(this.keep?JSON.parse(this.literal):void 0,this.keep!==null),this.literal=``}},ua=class{outline;buffer=null;length=0;skipped;outlining=null;closed=!1;next;start;decoder=new TextDecoder(`utf-8`,{fatal:!0});constructor(e=0,t=!1,n=null){if(this.outline=n,!Number.isSafeInteger(e)||e<0)throw RangeError(`Invalid transcript cursor`);this.next=e,this.start=e,this.skipped=t?`partial-prefix`:null}get offset(){return this.next}get boundary(){return this.skipped===`partial-prefix`?null:this.start}get bufferedBytes(){return this.length}push(e,t=this.next){if(this.closed)throw Error(`Transcript decoder is closed`);if(t!==this.next||e.byteLength>65536||!Number.isSafeInteger(this.next+e.byteLength))throw this.close(),RangeError(`Invalid transcript window`);let n=Buffer.from(e.buffer,e.byteOffset,e.byteLength),r=[],i=0,a=0;for(;i<n.length&&a<64;){let e=n.indexOf(10,i),t=e===-1?n.length:e,o=t-i;this.outlining?this.outlining.push(n.subarray(i,t)):this.skipped||(this.length+o>131072?(this.outline?(this.outlining=new la(this.outline),this.length&&this.outlining.push(this.buffer.subarray(0,this.length)),this.outlining.push(n.subarray(i,t))):this.skipped=`line-too-large`,this.clearBuffer()):o&&(this.buffer??=Buffer.alloc(131072),n.copy(this.buffer,this.length,i,t),this.length+=o));let s=o+(e===-1?0:1);if(i+=s,this.next+=s,e!==-1){let e=this.finishLine();e&&r.push(e),this.clearBuffer(),this.skipped=null,this.outlining=null,this.start=this.next,a++}}return{consumed:i,lines:r}}close(){this.clearBuffer(),this.buffer=null,this.skipped=null,this.outlining=null,this.closed=!0}finishLine(){let e={start:this.start,end:this.next};if(this.skipped)return{...e,kind:`skipped`,reason:this.skipped};if(this.outlining){let t=this.outlining.finish();return t?t.kind===`record`?{...e,kind:`record`,value:t.value,outlined:!0}:{...e,...t}:null}if(!this.length)return null;let t;try{t=this.decoder.decode(this.buffer.subarray(0,this.length))}catch{return{...e,kind:`skipped`,reason:`invalid-utf8`}}if(/^[ \t\r\n]*$/.test(t))return null;try{let n=JSON.parse(t);if(typeof n==`object`&&n&&!Array.isArray(n))return{...e,kind:`record`,value:n}}catch{}return{...e,kind:`skipped`,reason:`invalid-json`}}clearBuffer(){this.buffer?.fill(0,0,this.length),this.length=0}};const da=`Earlier content is not loaded`,fa=ia,pa=8192,ma=new Set([`progress`,`system`,`attachment`,`file-history-snapshot`,`queue-operation`,`summary`,`custom-title`,`tag`,`last-prompt`,`ai-title`,`agent-name`,`agent-setting`,`mode`,`permission-mode`,`atis-latch`,`cost-state`,`pr-link`,`continued-in`,`file-history-delta`,`api-request`,`api-request-blob`,`api-request-shape`]),ha=new Set([`token_count`,`agent_message`,`agent_reasoning`,`agent_reasoning_raw_content`,`thread_settings_applied`,`thread_goal_updated`,`context_compacted`,`patch_apply_end`,`mcp_tool_call_end`,`web_search_end`,`image_generation_end`,`item_completed`]),ga=new Set([`reasoning`,`additional_tools`,`configuration_update`,`compaction`,`context_compaction`]),_a={task_started:`Working`,turn_started:`Working`,task_complete:`Complete`,turn_complete:`Complete`,turn_aborted:`Stopped`,error:`Agent reported an error`},va=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,ya=/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,255}$/,ba=[`enqueue`,`dequeue`,`remove`,`popAll`];function xa(e){let t=ba.find(t=>t===e.operation);if(!t)return null;let n=e.content,r=``,i=!1;if(typeof n==`string`)r=n;else if(Array.isArray(n))for(let e of n.slice(0,64)){let t=U(e);t?.type===`text`&&typeof t.text==`string`?r+=t.text:t&&(i=!0)}else if(n!=null)return null;let a=Array.from(r.trim()).slice(0,D.queuedChars).join(``);return Object.freeze({operation:t,...n!=null&&{content:R(`sha256`).update(typeof n==`string`?n:JSON.stringify(n)).digest(`base64url`)},...a&&{text:a},...i&&{attachment:!0}})}function U(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}function W(e){return typeof e==`string`&&e.trim()===e&&ya.test(e)?e:null}function Sa(e){return typeof e==`string`&&e.length===36&&va.test(e)?e.toLowerCase():null}function G(e,t){if(!Number.isSafeInteger(t)||t<0||t>fa)throw RangeError(`Invalid transcript text budget`);let n=``,r=0,i=0;for(let a of e){let e=a.codePointAt(0);if(i>=t*4)break;if(e<32&&e!==9&&e!==10||e>=127&&e<=159){i+=a.length;continue}let o=e>=55296&&e<=57343?`�`:a,s=Buffer.byteLength(o);if(r+s>t)break;n+=o,r+=s,i+=a.length}return{text:n,truncated:i<e.length}}var Ca=class{offset;outlined;items=[];bytes=2;clipped=!1;scopeStart=0;constructor(e,t=!1){this.offset=e,this.outlined=t}scope(e){this.offset=e,this.scopeStart=this.items.length}get full(){return this.items.length>=31||this.bytes>=65024}add(e,t,n,r=!1,i=!1){if(this.full){this.clipped=!0;return}let a=G(t,fa),o=n===void 0?void 0:G(n,pa);this.outlined&&(t.includes(`Too large to show here`)||n?.includes(`Too large to show here`))&&(i=!0);let s={id:`${this.offset}:${this.items.length-this.scopeStart}`,kind:e,text:a.text,...o&&{detail:o.text},...r&&{collapsed:!0},...(i||a.truncated||o?.truncated)&&{truncated:!0}},c=Buffer.byteLength(JSON.stringify(s))+1;if(c+this.bytes>65024){this.clipped=!0;return}return this.items.push(Object.freeze(s)),this.bytes+=c,s}unknown(){return this.add(`unsupported`,`(Something this version can't show)`)}finish(){return this.clipped&&this.items.push(Object.freeze({id:`${this.offset}:${this.items.length-this.scopeStart}`,kind:`status`,text:`Additional content omitted to keep this entry small.`,truncated:!0})),Object.freeze(this.items)}};function wa(e,t){return Array.isArray(e)?(e.length>64&&(t.clipped=!0),e.slice(0,64)):null}function Ta(e){return typeof e==`string`&&G(e,128).text||`Tool`}function Ea(e,t){let n=G(e,pa),r=n.text.trim().split(`
|
|
5
|
+
`,1)[0].trim(),i=G(r,120),a=!i.truncated&&r===n.text&&!n.truncated;return{text:t?`${t}: ${n.text}`:n.text,clipped:n.truncated,...r&&{summary:a?i.text:`${i.text}…`},...a&&{complete:!0}}}const Da=[`command`,`cmd`,`file_path`,`path`,`pattern`,`query`,`url`,`description`,`prompt`];function Oa(e){if(typeof e==`string`)return Ea(e);let t=U(e);if(t)for(let e of Da){let n=t[e];if(typeof n==`string`)return Ea(n,e)}return{text:`Structured arguments omitted.`,clipped:!1}}function ka(e){if(e===`Too large to show here`)return{text:`Arguments too large to show here.`,clipped:!0};if(typeof e==`string`)try{let t=JSON.parse(e);if(U(t))return Oa(t)}catch{}return{text:`Structured arguments omitted.`,clipped:!1}}function Aa(e,t,n){let r=Ta(t);return e.add(`tool-call`,n.summary?`${r} · ${n.summary}`:r,n.complete?void 0:n.text,!0,n.clipped)}function ja(e,t){if(!Number.isSafeInteger(t)||t<0||t>fa)throw RangeError(`Invalid transcript text budget`);let n=[],r=0,i=0,a=e.length;for(;a>0&&i<t*4;){let o=e.charCodeAt(a-1),s=a>1?e.charCodeAt(a-2):0,c=o>=56320&&o<=57343&&s>=55296&&s<=56319?2:1,l=e.slice(a-c,a),u=l.codePointAt(0);if(!(u<32&&u!==9&&u!==10||u>=127&&u<=159)){let e=u>=55296&&u<=57343?`�`:l,i=Buffer.byteLength(e);if(r+i>t)break;n.push(e),r+=i}a-=c,i+=c}return{text:n.reverse().join(``),truncated:a>0}}function Ma(e,t=pa,n=!1){let r=e=>n?ja(e,t):G(e,t);if(typeof e==`string`){let t=r(e);return{text:t.text,clipped:t.truncated}}if(!Array.isArray(e))return null;let i=[],a=e.length>64;for(let t of e.slice(0,64)){let e=U(t);if(!e){a=!0;continue}i.push((e.type===`text`||e.type===`input_text`||e.type===`output_text`)&&typeof e.text==`string`?e.text:`[Non-text content omitted]`)}let o=r(i.join(`
|
|
6
|
+
`));return{text:o.text,clipped:a||o.truncated}}function Na(e,t,n=!1){let r=n?Ma(t,pa,!0):Ma(t,1024);return r?e.add(`tool-result`,n?`Tool error`:`Tool result`,r.text,!0,r.clipped):e.unknown()}const Pa=/^\s*<([a-z-]+)>/;function Fa(e,t){let n=Pa.exec(t)?.[1],r=e=>RegExp(`<${e}>([\\s\\S]*?)</${e}>`).exec(t)?.[1]?.trim()||void 0,i=e=>e?.split(`
|
|
7
|
+
`).map(e=>e.trim()).find(Boolean);switch(n){case`task-notification`:e.add(`status`,r(`summary`)??`A background task finished`);return;case`command-name`:case`command-message`:{let t=r(`command-name`)??`/${r(`command-message`)??``}`;e.add(`user`,[t,r(`command-args`)].filter(Boolean).join(` `));return}case`bash-input`:e.add(`user`,`! ${r(`bash-input`)??``}`);return;case`local-command-stdout`:case`local-command-stderr`:case`bash-stdout`:case`bash-stderr`:{let t=i(r(n))??i(r(`bash-stderr`));t&&e.add(`status`,t);return}case`local-command-caveat`:case`system-reminder`:return;default:e.add(`user`,t)}}function Ia(e){return e.uuid!==void 0||e.message!==void 0||e.content!==void 0||e.text!==void 0||e.toolUseResult!==void 0}function La(e,t){let n=e.value,r=U(n.message),i=W(n.uuid),a=[],o=[],s=n.isSidechain===!0||typeof n.agentId==`string`||typeof n.teamName==`string`,c=n.isMeta===!0||r?.channel===`analysis`,l=n.type===`system`&&n.subtype===`compact_boundary`,u=n.isCompactSummary===!0||l,d=!0,f=!1,p=n.type===`user`||n.type===`assistant`?n.type:`other`,m=()=>i?Object.freeze({id:i,parent:n.parentUuid===null?l?W(n.logicalParentUuid)??null:null:W(n.parentUuid)??void 0,session:Sa(n.sessionId),role:p,response:W(r?.id),scope:s?`side:${W(n.agentId)??W(n.teamName)??`unknown`}`:`main`,meta:c,mainMessage:f&&!c&&!s,compact:u,sourceAssistant:W(n.sourceToolAssistantUUID),calls:Object.freeze(a),results:Object.freeze(o),resultsOnly:d&&o.length>0,timestamp:typeof n.timestamp==`string`&&n.timestamp.endsWith(`Z`)&&/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?Z$/.test(n.timestamp)?n.timestamp:null}):void 0,h=`ignored`;if(!c){if(p!==`other`&&r?.channel!==void 0&&r.channel!==null&&r.channel!==`final`&&r.channel!==`commentary`)t.unknown(),h=`unsupported`;else if(u&&i){let e=n.type===`system`&&n.subtype===`compact_boundary`;if(f=p!==`other`&&r?.role===p&&(typeof r.content==`string`||Array.isArray(r.content)),e||f){let n=e?null:Ma(r?.content);e||t.add(`group`,`Conversation summary`,n?.text,!0,n?.clipped),h=`compaction`}else t.unknown(),h=`unsupported`}else if(p!==`other`){if(h=`message`,!i||!r||r.role!==p)t.unknown(),h=`unsupported`;else if(!c){if(f=typeof r.content==`string`||Array.isArray(r.content),typeof r.content==`string`)p===`user`?Fa(t,r.content):t.add(p,r.content),d=!1;else{let e=wa(r.content,t);e||(t.unknown(),h=`unsupported`);for(let n of e??[]){if(t.full){t.clipped=!0;break}let e=U(n);if(!e){t.unknown(),d=!1;continue}if(e.type===`tool_result`&&p===`user`){let n=W(e.tool_use_id),r=Na(t,e.content??``,e.is_error===!0);n&&r&&o.push(Object.freeze({id:n,entry:r.id}))}else if(d=!1,e.type===`text`&&typeof e.text==`string`)p===`user`?Fa(t,e.text):t.add(p,e.text);else if(e.type===`tool_use`&&p===`assistant`){let n=W(e.id),r=Aa(t,e.name,Oa(e.input));n&&r&&a.push(Object.freeze({id:n,entry:r.id}))}else e.type===`server_tool_use`&&p===`assistant`?Aa(t,e.name,Oa(e.input)):typeof e.type==`string`&&e.type.endsWith(`_tool_result`)&&p===`assistant`?Ma(e.content??``)?Na(t,e.content??``):t.add(`tool-result`,`Tool result`,`[Non-text content omitted]`,!0):e.type===`thinking`||e.type===`redacted_thinking`||(e.type===`image`||e.type===`document`?t.add(`status`,`Non-text content omitted`):t.unknown())}}}}else(typeof n.type!=`string`||!ma.has(n.type)&&Ia(n))&&(t.unknown(),h=`unsupported`)}let g=n.type===`queue-operation`?xa(n):null,_=m();return{kind:h,..._&&{node:_},...g&&{queue:g}}}function Ra(e,t){let n=e.value,r=U(n.payload),i=U(n.metadata);if(n.type===`session_meta`)return{kind:`session`,session:Sa(r?.id),supported:!!r&&(r.history_mode===void 0||r.history_mode===`legacy`||r.history_mode===`paginated`)&&r.history_base==null&&r.subagent_history_start_ordinal==null};if(n.type===`turn_context`||n.type===`token_usage_record`||n.type===`world_state`||n.type===`security_risk_score`||n.type===`retained_context`||n.type===`realtime_item`)return{kind:`ignored`};if(n.type===`compacted`&&r)return t.add(`group`,`Conversation summary`,typeof r.message==`string`?r.message:void 0,!0),{kind:`compaction`};if(n.type===`inter_agent_communication`||n.type===`inter_agent_communication_metadata`)return t.add(`group`,`Subagent activity`,`This activity is recorded separately from the main conversation.`,!0),{kind:`status`};if(n.type===`event_msg`&&r){if(r.type===`user_message`)return r.kind!==void 0&&r.kind!==`plain`?{kind:`ignored`}:(typeof r.message==`string`?t.add(`user`,r.message):t.unknown(),{kind:`message`});if(r.type===`thread_rolled_back`)return t.unknown(),{kind:`unsupported`,invalidates:!0};if(typeof r.type==`string`&&Object.hasOwn(_a,r.type))return t.add(`status`,_a[r.type]),{kind:`status`};if(typeof r.type==`string`&&ha.has(r.type))return{kind:`ignored`};if(r.type===`sub_agent_activity`)return t.add(`group`,`Subagent activity`,void 0,!0),{kind:`status`}}if(n.type===`response_item`&&r){if(i?.inherited_user_message===!0||i?.delivered_assistant_message!=null||typeof r.type==`string`&&ga.has(r.type))return{kind:`ignored`};if(r.type===`tool_search_call`)return t.add(`tool-call`,`Tool search`,void 0,!0),{kind:`message`};let e={local_shell_call:`Shell command`,web_search_call:`Web search`,image_generation_call:`Image generation`};if(typeof r.type==`string`&&Object.hasOwn(e,r.type))return t.add(`group`,e[r.type],void 0,!0),{kind:`message`};if(r.type===`tool_search_output`)return t.add(`tool-result`,`Tool search result`,void 0,!0),{kind:`message`};if(r.type===`agent_message`)return t.add(`group`,`Subagent activity`,void 0,!0),{kind:`message`};if(r.type===`message`){let e=U(U(i?.retained_source)?.id);if(r.role===`user`&&e?.role===`user`&&typeof i?.user_input_order==`number`&&i.client_authored!==!0){let e=wa(r.content,t);e||t.unknown();for(let n of e??[]){let e=U(n);e?.type===`input_text`&&typeof e.text==`string`?t.add(`user`,e.text):e?.type===`input_image`||e?.type===`input_audio`?t.add(`status`,`Non-text content omitted`):t.unknown()}return{kind:`message`}}if(r.role===`system`||r.role===`developer`||r.role===`user`||r.channel===`analysis`)return{kind:`ignored`};if(r.role===`assistant`&&(r.channel===void 0||r.channel===null||r.channel===`final`||r.channel===`commentary`)&&(r.phase===void 0||r.phase===null||r.phase===`commentary`||r.phase===`partial_answer`||r.phase===`final_answer`)){if(i?.compaction_output===!0){let e=Ma(r.content);return t.add(`group`,`Conversation summary`,e?.text,!0,e?.clipped),{kind:`compaction`}}let e=wa(r.content,t);e||t.unknown();for(let n of e??[]){if(t.full){t.clipped=!0;break}let e=U(n);e&&(e.type===`input_text`||e.type===`output_text`)&&typeof e.text==`string`?t.add(r.role,e.text):e?.type===`input_image`||e?.type===`input_audio`?t.add(`status`,`Non-text content omitted`):t.unknown()}return{kind:`message`}}}else if(r.type===`function_call`||r.type===`custom_tool_call`)return Aa(t,r.name,r.type===`function_call`?ka(r.arguments):Oa(r.input)),{kind:`message`};else if(r.type===`function_call_output`||r.type===`custom_tool_call_output`)return Na(t,r.output),{kind:`message`}}return t.unknown(),{kind:`unsupported`}}const za=/^\s*<(session_context)>[\s\S]*<\/\1>\s*$/;function Ba(e,t){if(typeof e==`string`)return e;let n=wa(e,t);return n?n.map(e=>{let t=U(e)?.text;return typeof t==`string`?t:`[Non-text content omitted]`}).join(`
|
|
8
|
+
`):null}function Va(e,t){if(e.type===`user`){let n=Ba(e.displayContent??e.content,t);n===null?t.unknown():!za.test(n)&&n.trim()&&t.add(`user`,n);return}if(e.type===`info`||e.type===`warning`||e.type===`error`){let n=Ba(e.content,t);n?.trim()&&t.add(`status`,n);return}if(e.type!==`gemini`){t.unknown();return}let n=Ba(e.content,t);n?.trim()&&t.add(`assistant`,n);let r=wa(e.toolCalls??[],t)??[];for(let e of r){let n=U(e);if(!n){t.unknown();continue}if(n.name===`invoke_agent`){t.add(`group`,`Subagent activity`,void 0,!0);continue}let r=typeof n.description==`string`&&n.description.trim()?Ea(n.description):Oa(n.args);if(Aa(t,n.displayName??n.name,r),n.status===`scheduled`||n.status===`executing`||n.status===`validating`)continue;let i=n.status===`error`||n.status===`cancelled`,a=U(U(U((Array.isArray(n.result)?n.result:[])[0])?.functionResponse)?.response),o=n.resultDisplay,s=typeof o==`string`?o:U(o)&&typeof U(o).fileName==`string`?`${String(U(o).fileName).split(`/`).pop()}`:a?.error??a?.output;Na(t,typeof s==`string`?s:``,i)}}function Ha(e,t){let n=e.value;if(e.start===0&&`sessionId`in n&&`projectHash`in n)return{kind:`session`,session:Sa(n.sessionId),supported:n.kind===void 0||n.kind===`main`};if(typeof n.$rewindTo==`string`){let e=W(n.$rewindTo);return e?{kind:`status`,rewind:e}:{kind:`unsupported`,invalidates:!0}}let r=U(n.$set);if(r){if(!Array.isArray(r.messages))return{kind:`ignored`};let n=new Set;for(let[i,a]of(wa(r.messages,t)??[]).entries()){let r=U(a),o=W(r?.id);t.scope(o&&!n.has(o)?`gemini:${o}`:`${e.start}.${i}`),o&&n.add(o),r?Va(r,t):t.unknown()}return{kind:`message`,resets:!0}}let i=W(n.id);return!i||typeof n.type!=`string`?(t.unknown(),{kind:`unsupported`}):(Va(n,t),{kind:`message`,message:i})}const Ua={};function K(e,t={}){return{keys:{...Object.fromEntries(e.map(e=>[e,Ua])),...t}}}const Wa=K(Da),Ga={items:K([`type`,`text`])},Ka=K([`id`,`type`],{content:{items:K([`text`])},displayContent:{items:K([`text`])},toolCalls:{items:K([`name`,`displayName`,`description`,`status`],{args:Wa,resultDisplay:K([`fileName`]),result:{items:K([],{functionResponse:K([],{response:K([`output`,`error`])})})}})}}),qa={gemini:{keys:{...Ka.keys,sessionId:Ua,projectHash:Ua,kind:Ua,$rewindTo:Ua,$set:K([],{messages:{items:Ka}})}},claude:K([`uuid`,`parentUuid`,`logicalParentUuid`,`type`,`subtype`,`sessionId`,`timestamp`,`isSidechain`,`agentId`,`teamName`,`isMeta`,`isCompactSummary`,`sourceToolAssistantUUID`,`version`,`operation`],{content:Ga,message:K([`role`,`channel`,`id`],{content:{items:K([`type`,`text`,`id`,`name`,`tool_use_id`,`is_error`],{input:Wa,content:Ga})}})}),codex:K([`type`],{payload:K([`id`,`history_mode`,`history_base`,`subagent_history_start_ordinal`,`type`,`kind`,`message`,`role`,`channel`,`phase`,`name`,`arguments`,`cli_version`],{content:Ga,input:Wa,output:Ga}),metadata:K([`inherited_user_message`,`delivered_assistant_message`,`compaction_output`,`user_input_order`,`client_authored`],{retained_source:K([],{id:K([`role`])})})})};[...ba,...ma,...ha,...ga,...Object.keys(_a)];const Ja=new Set([`claude`,`codex`,`gemini`]);function Ya(e){if(!Ja.has(e))throw TypeError(`Unsupported transcript agent`);return qa[e]}function Xa(e,t){if(!Ja.has(e))throw TypeError(`Unsupported transcript agent`);if(!Number.isSafeInteger(t.start)||!Number.isSafeInteger(t.end)||t.start<0||t.end<=t.start)throw RangeError(`Invalid transcript record range`);let n=t.kind===`record`&&t.outlined===!0,r=e===`gemini`&&t.kind===`record`&&typeof t.value.$set!=`object`?W(t.value.id):null,i=new Ca(r?`gemini:${r}`:t.start,n),a;if(t.kind===`skipped`)i.add(`status`,t.reason===`partial-prefix`?da:`A transcript entry could not be read`,void 0,!1,!0),a={kind:`skipped`};else if(!n&&t.end-t.start>131073)i.add(`status`,`A transcript entry exceeded the read limit`,void 0,!1,!0),a={kind:`skipped`};else{a=e===`claude`?La(t,i):e===`codex`?Ra(t,i):Ha(t,i);let n=Te(e===`claude`?t.value.version:U(t.value.payload)?.cli_version);n&&(e===`claude`||a.kind===`session`)&&(a={...a,version:n})}return Object.freeze({start:t.start,end:t.end,...a,entries:i.finish()})}var Za=class{state=`pending`;expected;constructor(e){let t=Sa(e);if(!t)throw TypeError(`Invalid transcript session identity`);this.expected=t}get status(){return this.state}observe(e){this.state===`pending`&&(this.state=e.start!==0||e.kind!==`session`||!e.session||e.supported!==!0?`unsupported`:e.session===this.expected?`verified`:`mismatch`)}close(){this.state=`closed`}};const Qa={user:14,reply:15,error:17,context:90,notice:101,tool:132},$a=new Set([3,4,6,7,9]),eo=new Set([Qa.context,23]),to=8192;function no(e,t=0){if(t>12)return null;let n=[],r=0,i=!0,a=()=>{let t=0;i=!0;for(let n=0;n<70;n+=7){if(r>=e.length)return null;let a=e[r++];if(n<49?t+=(a&127)*2**n:a&127&&(i=!1),a<128)return t}return null};for(;r<e.length;){if(n.length>=4096)return null;let t=a();if(t===null||!i)return null;let o=Math.floor(t/8),s=t%8;if(o<1)return null;if(s===0){let e=a();if(e===null)return null;n.push({number:o,wire:s,value:e})}else if(s===2){let t=a();if(t===null||!i||r+t>e.length)return null;n.push({number:o,wire:s,value:e.subarray(r,r+t)}),r+=t}else if(s===1||s===5){if(r+=s===1?8:4,r>e.length)return null}else return null}return n}const ro=new TextDecoder(`utf-8`,{fatal:!0});function io(e,t){let n=[e];for(let[e,r]of t.entries()){let t=[];for(let i of n)for(let n of no(i,e)??[])n.number===r&&n.wire===2&&t.push(n.value);n=t}return n}function q(e,t){let[n]=io(e,t);if(!n)return null;try{return ro.decode(n)}catch{return null}}function ao(e,t){return io(e,t).flatMap(e=>{try{return[ro.decode(e)]}catch{return[]}})}const oo=`(Something this version can't show)`;function so(e){let t=e.trim().split(`
|
|
9
|
+
`,1)[0].trim(),n=G(t,120);return n.truncated||t!==e.trim()?`${n.text}…`:n.text}function co(e){let t=e.replace(/_/g,` `).trim();return t?t.charAt(0).toUpperCase()+t.slice(1):`Tool`}const lo=[`toolSummary`,`CommandLine`,`Path`,`Query`,`Url`,`SearchPath`];function uo(e,t,n,r,i,a={}){let o=G(r,16384),s=i===void 0?void 0:(a.tail?ja:G)(i,a.tail?to:n===`tool-result`?1024:to);return Object.freeze({id:`agy:${e}:${t}`,kind:n,text:o.text,...s&&{detail:s.text},...a.collapsed&&{collapsed:!0},...(a.truncated||o.truncated||s?.truncated)&&{truncated:!0}})}function fo(e){let t=[],n=[],r=()=>({kind:`entries`,entries:Object.freeze(t),calls:n});if(eo.has(e.type))return r();let i=(...n)=>t.push(uo(e.idx,t.length,...n)),a=e.payload;if(!a)return i(`status`,`A step was too large to show here`,void 0,{truncated:!0}),r();if(e.type===Qa.user){let e=q(a,[19,2]);e?.trim()?i(`user`,e):i(`unsupported`,oo)}else if(e.type===Qa.reply){let e=q(a,[20,1]);e?.trim()&&i(`assistant`,e);for(let e of io(a,[20,7]))n.push(co(q(e,[2])??``))}else if(e.type===Qa.tool){let t=ao(a,[140,1,1]),n=ao(a,[140,1,2]),r=new Map(t.map((e,t)=>[e,n[t]??``])),i=lo.map(e=>r.get(e)).find(e=>e?.trim()),o=$a.has(e.status),s;if(o){let t=e.status!==3,n=t?q(a,[31,2])??q(a,[140,2,1])??``:q(a,[140,2,1])??``;s=uo(e.idx,1,`tool-result`,t?`Tool error`:`Tool result`,n,{collapsed:!0,tail:t})}return{kind:`tool`,idx:e.idx,summary:i===void 0?void 0:so(i),final:o,result:s}}else if(e.type===Qa.error){let e=q(a,[24,3,2]);i(`status`,e?so(e):`Agent reported an error`)}else if(e.type===Qa.notice){let e=q(a,[114,2,1]);i(`group`,e?`Background task · ${so(e)}`:`Background task`,void 0,{collapsed:!0})}else i(`unsupported`,oo);return r()}function po(e){let t=[],n=[];for(let r of e){if(r.kind===`entries`){t.push(...r.entries),n.push(...r.calls);continue}let e=(r.final?n.shift():n[0])??`Tool`,i=r.summary?`${e} · ${r.summary}`:e;t.push(uo(r.idx,0,`tool-call`,i,void 0,{collapsed:!0})),r.result&&t.push(r.result)}return t}const mo=2e3,ho=1048576,go=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;let _o=null;function vo(){return _o??=(async()=>{let e=process.emitWarning;process.emitWarning=((t,...n)=>{let r=typeof t==`string`?t:t.message;if(!/SQLite/i.test(r))return e.call(process,t,...n)});try{let{DatabaseSync:e}=await import(`node:sqlite`);return t=>new e(t,{readOnly:!0})}catch{return null}finally{process.emitWarning=e}})(),_o}var yo=class{options;identity;database=null;inode=null;version=void 0;latest=null;cache=new Map;hash=``;revision=0;files=null;constructor(e,t){this.options=e,this.identity=t}async proven(e){let t=await this.options.identity(e);if(t?.agent!==`agy`||t.path!==this.identity.path||t.session!==this.identity.session||t.owner!==this.identity.owner||t.reference!==this.identity.reference&&(!t.reference||!this.identity.reference||!On(t.reference,this.identity.reference)||t.reference.owner!==this.identity.reference.owner))return{status:`stopped`,reason:`changed`};let n=await z(this.identity.path);return!n.isFile()||n.isSymbolicLink()||process.getuid&&n.uid!==process.getuid()?{status:`stopped`,reason:`unsafe`}:this.inode&&(n.dev!==this.inode.dev||n.ino!==this.inode.ino)?{status:`stopped`,reason:`changed`}:(this.inode={dev:n.dev,ino:n.ino},null)}async open(){let{path:e,session:t}=this.identity;if(!go.test(t)||br(e)!==`${t}.db`)return{status:`stopped`,reason:`unsafe`};let n=this.options.roots.agy??[],r=!1;for(let t of n)try{let n=await B(t);P(e)===n&&(r=!0)}catch{}if(!r||await B(e)!==e)return{status:`stopped`,reason:`unsafe`};let i=await vo();return i?(this.database=i(e),null):{status:`stopped`,reason:`unsupported`}}async read(e){try{if(!this.database){let t=await this.proven(e);if(t)return t;let n=await this.open();if(n)return n}let t=this.database,n=t.prepare(`PRAGMA data_version`).get().data_version;if(this.latest&&n===this.version){let t=await this.fileStamp();return await this.proven(e)||(this.files=t,this.latest.change!==`unchanged`&&(this.latest=Object.freeze({...this.latest,change:`unchanged`})),{status:`snapshot`,snapshot:this.latest})}let r=await this.fileStamp(),{parsed:i,truncated:a,fingerprint:o}=this.steps(t),s=await this.proven(e);if(s)return s;let c=po(i);a&&c.unshift(Object.freeze({id:`history:unloaded`,kind:`status`,text:`Earlier conversation is not loaded.`}));let l=R(`sha256`).update(o).digest(`base64url`),u=l!==this.hash;u&&this.revision++,this.hash=l,this.version=n,this.files=r;let d=Object.freeze({state:`ready`,entries:Object.freeze(c),history:a?`unloaded`:`complete`,change:u?`replace`:`unchanged`,revision:this.revision,branch:Object.freeze({kind:`rows`})});return this.latest=d,{status:`snapshot`,snapshot:d}}catch{return{status:`stopped`,reason:`unreadable`}}}steps(e){let t=e.prepare(`SELECT idx, step_type AS type, status, length(step_payload) AS size
|
|
10
10
|
FROM steps ORDER BY idx DESC LIMIT ?`).all(2001),n=e.prepare(`SELECT CASE WHEN length(step_payload) <= ? THEN step_payload END AS payload,
|
|
11
11
|
length(step_payload) AS size
|
|
12
|
-
FROM steps WHERE idx = ?`),r=t.length>
|
|
13
|
-
`,r++),n+=o.text,r+=Buffer.byteLength(o.text),i||=o.truncated||e.truncated===!0,!a){i=!0;break outer}}return n?Object.freeze({id:t,kind:`group`,text:`Subagent conversation`,detail:n,collapsed:!0,...i&&{truncated:!0}}):null}var Wa=class{agent;expected;header;records=[];bytes=0;base=0;through=0;revision=0;evicted=!1;invalidated=!1;closed=!1;previous=null;entryFingerprints=new WeakMap;latest=null;latestUnanchored=!1;cutKnown=null;version=null;precedingEnd=new Map;folded=new Map;unplacedMain=-1;coveredThrough=0;lookups=null;constructor(e,t){this.agent=e;let n=Ui(t);if(!n||e!==`claude`&&e!==`codex`&&e!==`gemini`)throw TypeError(`Invalid transcript document identity`);this.expected=n,this.header=e===`claude`?null:new _a(n)}get retainedBytes(){return this.bytes}get retainedRecords(){return this.records.length}get cursor(){return this.through}beginWindow(e){if(this.closed||!Number.isSafeInteger(e)||e<0)throw RangeError(`Invalid transcript window`);this.records=[],this.bytes=0,this.base=this.through=e,this.coveredThrough=e,this.unplacedMain=-1,this.evicted=!1,this.previous=null,this.latest=null,this.entryFingerprints=new WeakMap,this.precedingEnd.clear(),this.folded.clear(),this.revision++}append(e){if(this.closed||e.length>64)throw RangeError(`Invalid transcript document batch`);let t=this.through;for(let n of e){if(!Number.isSafeInteger(n.start)||!Number.isSafeInteger(n.end)||n.start<t||n.end<=n.start)throw RangeError(`Invalid transcript document order`);t=n.end}for(let t of e.flatMap(za)){if(this.header?.observe(t),t.version&&(this.version=t.version),this.invalidated||=t.invalidates===!0,t.resets&&this.drop(0),t.rewind){let e=this.records.findIndex(({record:e})=>e.message===t.rewind);this.drop(e<0?0:e)}if(!t.node&&!t.entries.length)continue;let e=t,n=this.records.at(-1);if(n&&Ba(n.record)&&Ba(e)&&Va(n.record,e)){let t=this.parentOf(n.record.node);this.folded.set(n.record.node.id,t),this.folded.size>16384&&this.folded.delete(this.folded.keys().next().value),e=Object.freeze({...e,node:Object.freeze({...e.node,parent:t})}),this.records.pop(),this.bytes-=n.bytes}let r=Buffer.byteLength(JSON.stringify(e));if(r>262144){this.forgetUnseen(e),this.evicted=!0;continue}let i=e.message?this.records.findIndex(t=>t.record.message===e.message):-1;for(i>=0?(this.bytes+=r-this.records[i].bytes,this.records[i]={record:e,bytes:r}):(this.records.push({record:e,bytes:r}),this.bytes+=r);this.bytes>262144||this.records.length>2048;){let e=this.records.shift();this.forgetUnseen(e.record),this.bytes-=e.bytes,this.evicted=!0}}this.through=t,e.length&&(this.latest=null,this.revision++)}drop(e){for(let t of this.records.splice(e))this.bytes-=t.bytes}close(){this.closed=!0,this.header?.close(),this.records=[],this.bytes=0,this.previous=null,this.latest=null,this.entryFingerprints=new WeakMap,this.precedingEnd.clear(),this.folded.clear(),this.lookups=null,this.cutKnown=null,this.revision++}hasCut(){let e=this.latest;if(e?.state!==`ready`)return!1;if(this.cutKnown?.revision===e.revision)return this.cutKnown.value;let t=e.entries.some(t=>!t.id.startsWith(`history:`)&&this.cut(t,e.branch)!==null);return this.cutKnown={revision:e.revision,value:t},t}windowGap(e,t){return e.kind===`skipped`&&t!==`complete`&&e.start===this.base&&e.entries[0]?.text===`Earlier content is not loaded`}anchor(e){let t=this.latest;if(t?.state!==`ready`)return null;let n=t.entries.find(t=>t.id===e);return n?this.cut(n,t.branch):null}cut(e,t){if(this.agent===`gemini`)return null;let n=e.id,r=this.index().records.get(n),i=r?.entries.find(e=>e.id===n);return!r||!i||i!==e&&J(i)!==J(e)||r.kind===`skipped`||!this.header&&(t?.kind!==`claude`||!r.node?.mainMessage||r.node.meta||!this.turnStart(r,n)||(this.precedingEnd.get(n)??1/0)>r.end||this.unplacedMain>=r.end||!t.nodes.some(e=>e.id===r.node.id&&e.start===r.start))?null:Object.freeze({agent:this.agent,start:r.start,end:r.end,recordHash:J(r),entryId:n,entryHash:J(e),nodeId:r.node?.id??null})}turnStart(e,t){let n=e.node;if(n.role===`user`)return n.results.length===0;if(n.role!==`assistant`||!n.response||e.entries[0]?.id!==t)return!1;let{main:r,replies:i,calls:a}=this.index();if(i.get(n.response)!==e.start)return!1;let o=this.parentRecord(n,r),s=e.start;for(;o&&o.start<s&&!o.entries.length&&!o.node.calls.length&&!o.node.results.length&&(o.node.role!==`assistant`||o.node.response===n.response);)s=o.start,o=this.parentRecord(o.node,r);return!o?.node.mainMessage||o.start>=s?!1:o.node.role===`assistant`?o.node.response!==n.response:o.node.role===`user`&&o.node.results.every(({id:e})=>{let t=o.node.sourceAssistant?r.get(o.node.sourceAssistant):a.get(e);return!!t?.node.response&&t.node.response!==n.response&&t.node.calls.some(t=>t.id===e)})}parentOf(e){let t=e.parent;return t&&this.folded.has(t)?this.folded.get(t):t}parentRecord(e,t){let n=this.parentOf(e);return n?t.get(n):void 0}index(){if(this.lookups?.revision===this.revision)return this.lookups;let e=new Map,t=new Map,n=new Map,r=new Map;for(let{record:i}of this.records){for(let t of i.entries)e.set(t.id,i);if(i.node?.scope!==`main`)continue;let a=i;if(t.set(a.node.id,a),a.node.role===`assistant`){a.node.response&&a.entries.length&&!n.has(a.node.response)&&n.set(a.node.response,a.start);for(let e of a.node.calls)r.set(e.id,r.has(e.id)?null:a)}}return this.lookups={revision:this.revision,records:e,main:t,replies:n,calls:r},this.lookups}permits(e){if(this.latest?.state!==`ready`||e.agent!==this.agent||e.agent===`claude`&&this.unplacedMain>=e.end||this.latest.branch?.kind===`claude`&&this.latest.branch.nodes.some(t=>t.id===e.nodeId&&t.start!==e.start))return!1;if(this.records.some(({record:t})=>t.start===e.start)){let t=this.anchor(e.entryId);return t!==null&&t.recordHash===e.recordHash&&t.entryHash===e.entryHash}return e.end<=(this.records[0]?.record.start??this.base)}snapshot(e){if(!e&&this.latest&&this.latestUnanchored)return this.latest.change!==`unchanged`&&(this.latest=Object.freeze({...this.latest,change:`unchanged`})),this.latest;this.latest=null,this.latestUnanchored=!e;let t=this.evicted?`truncated`:this.base>0?`unloaded`:`complete`;if(this.closed)return this.finish(`closed`,[],t);if(this.invalidated)return this.finish(`unsupported`,[],t);if(e){let n=this.records.find(({record:t})=>t.start===e.start)?.record;if(e.agent!==this.agent||this.through!==e.end||!n||n.end!==e.end||J(n)!==e.recordHash||!n.entries.some(t=>t.id===e.entryId&&J(t)===e.entryHash)||(n.node?.id??null)!==e.nodeId)return this.finish(`unbound`,[],t)}return this.header?this.header.status===`verified`?this.finish(`ready`,this.records.flatMap(({record:e})=>this.windowGap(e,t)?[]:e.entries),t,this.agent===`gemini`?{kind:`rows`}:{kind:`codex`}):this.finish(this.header.status===`unsupported`?`unsupported`:`unbound`,[],t):this.claudeSnapshot(t,e)}claudeSnapshot(e,t){let n=new Map;for(let{record:e}of this.records)e.node&&n.set(e.node.id,e);let r=new Map([...n].filter(([,e])=>e.node.scope===`main`)),i=new Set([...r.values()].flatMap(e=>{let t=this.parentOf(e.node);return t?[t]:[]})),a=new Map,o=null;for(let e of r.values()){if(i.has(e.node.id))continue;let t=e,n=[],s=new Set,c=null;for(;t&&!s.has(t.node.id);){let e=t.node.id;if(t.node.mainMessage){c=t;break}if(a.has(e)){c=a.get(e);break}s.add(e),n.push(e),t=this.parentRecord(t.node,r)}for(let e of n)a.set(e,c);c&&(!o||c.start>o.start)&&(o=c)}if(t&&(o=t.nodeId?r.get(t.nodeId)??null:null),!o)return this.finish(r.size&&[...r.values()].some(e=>e.node.mainMessage)?`unsupported`:`unbound`,[],e);if(!t&&o.node.session!==this.expected)return this.finish(`unbound`,[],e);let s=[],c=new Set,l=o,u=!0,d=!1;for(;l;){if(c.has(l.node.id))return this.finish(`unsupported`,[],`unlinked`);if(c.add(l.node.id),s.push(l),this.parentOf(l.node)===null){d=!0;break}let e=this.parentRecord(l.node,r);if(!e){u=!1;break}l=e}s.reverse();let{entries:f,after:p}=this.mainEntries(r,s,c),m=new Set(f.map(e=>e.id));for(let e of r.values())e.entries.some(e=>!m.has(e.id))&&(this.unplacedMain=Math.max(this.unplacedMain,e.start));let h=new Map,g=new Map,_=!1;for(let e of n.values()){if(e.node.scope===`main`||!e.entries.length)continue;let t=e,r=new Set,i=null,a=e;for(;t&&t.node.scope!==`main`&&!r.has(t.node.id);){if(g.has(t.node.id)){i=g.get(t.node.id);break}r.add(t.node.id),a=t,t=this.parentRecord(t.node,n)}t?.node.scope===`main`&&(i={main:t,root:a});for(let e of r)g.set(e,i);if(!i){_=!0;continue}if(!c.has(i.main.node.id))continue;let o=e.node.scope===`side:unknown`?`side:unknown:${i.root.node.id}`:e.node.scope,s=h.get(o)??{records:[],anchor:i.main.node.id};s.records.push(e),h.set(o,s)}let v=[],y=new Map;for(let{records:e,anchor:t}of h.values()){e.sort((e,t)=>e.start-t.start);let n=Ua(e,`side:${e[0].start}`);n&&(v.push({at:p.get(t)??0,start:e[0].start,entry:n}),y.set(n.id,Math.max(...e.map(e=>e.end))))}_&&v.push({at:0,start:0,entry:Object.freeze({id:`unlinked-side`,kind:`unsupported`,text:`Some subagent activity could not be linked to this conversation.`})});let b=new Map(this.records.flatMap(({record:e})=>e.entries.map(t=>[t.id,e.start])));for(let{record:t}of this.records){if(t.node||t.kind!==`unsupported`&&t.kind!==`skipped`||this.windowGap(t,e))continue;let n=f.findIndex(e=>(b.get(e.id)??1/0)>=t.start);for(let e of t.entries)v.push({at:n===-1?f.length:n,start:t.start,entry:e})}v.sort((e,t)=>t.at-e.at||t.start-e.start);for(let{at:e,entry:t}of v)f.splice(e,0,t);let x=new Set(s.map(e=>e.node.id));return this.finish(`ready`,f,!u&&e===`complete`?`unlinked`:d&&e===`unloaded`?`complete`:e,{kind:`claude`,nodes:Object.freeze(s.map(e=>Object.freeze({id:e.node.id,start:e.start}))),parallel:Object.freeze([...c].filter(e=>!x.has(e)).flatMap(e=>{let t=r.get(e);return t?[Object.freeze({id:e,start:t.start})]:[]}))},y)}mainEntries(e,t,n){let r=new Map;for(let e of t)e.node.role===`assistant`&&e.node.mainMessage&&e.node.response&&r.set(e.node.response,e);let i=new Map,a=new Map;for(let t of e.values())if(t.node.mainMessage&&t.node.role===`assistant`){for(let e of t.node.calls)a.set(e.id,a.has(e.id)?null:t);if(t.node.response&&r.has(t.node.response)){let e=i.get(t.node.response)??[];e.push(t),i.set(t.node.response,e)}}let o=new Map,s=new Map;for(let t of e.values())if(!(t.node.meta||t.node.role!==`user`||!n.has(t.node.id)&&!t.node.resultsOnly))for(let i of t.node.results){let c=t.node.sourceAssistant?e.get(t.node.sourceAssistant):void 0;if(t.node.sourceAssistant&&!c?.node.calls.some(e=>e.id===i.id))continue;if(!c){let n=this.parentRecord(t.node,e);c=n?.node.calls.some(e=>e.id===i.id)?n:a.get(i.id)??void 0}let l=c?.node.response;if(!c?.node.mainMessage||!l||!r.has(l))continue;let u=t.entries.find(e=>e.id===i.entry);if(!u)continue;s.set(u.id,`${l}/${i.id}`);let d=o.get(l)??new Map,f=d.get(i.id);(!f||n.has(t.node.id)&&!n.has(f.record.node.id)||n.has(t.node.id)===n.has(f.record.node.id)&&Ha(t,f.record)<0)&&d.set(i.id,{record:t,entry:u,call:i.id}),o.set(l,d)}let c=new Set;for(let e of o.values())for(let t of e.values())c.add(t.entry.id);let l=[],u=new Set,d=e=>{(!s.has(e.id)||c.has(e.id))&&(u.has(e.id)||(u.add(e.id),l.push(e)))},f=new Set(n),p=new Map;for(let e of t){if(!e.node.meta)for(let t of e.entries)d(t);p.set(e.node.id,l.length);let t=e.node.response;if(t&&r.get(t)===e){for(let e of(i.get(t)??[]).sort(Ha))if(!f.has(e.node.id)){n.add(e.node.id);for(let t of e.entries)d(t);p.set(e.node.id,l.length)}for(let e of[...o.get(t)?.values()??[]].sort((e,t)=>Ha(e.record,t.record)))f.has(e.record.node.id)||(n.add(e.record.node.id),d(e.entry),p.set(e.record.node.id,l.length))}}return{entries:l,after:p}}finish(e,t,n,r=null,i){let a=[],o=2;if(e===`ready`){for(let e=t.length-1;e>=0;e--){let r=t[e],i=Buffer.byteLength(JSON.stringify(r))+1;if(a.length>=1999||o+i>261632){n=`truncated`;break}a.push(r),o+=i}a.reverse()}let s=new Map(this.records.flatMap(({record:e})=>e.node?.mainMessage&&!e.node.meta&&e.entries[0]&&this.turnStart(e,e.entries[0].id)?e.entries.map(t=>[t.id,e.end]):[])),c=new Map(this.records.flatMap(({record:e})=>e.entries.map(t=>[t.id,e.end])));for(let[e,t]of i??[])c.set(e,t);let l=new Set(a.map(e=>e.id));this.precedingEnd.clear();let u=0;for(let e of t){e.id!==`unlinked-side`&&!e.id.startsWith(`history:`)&&(u=Math.max(u,c.get(e.id)??1/0)),l.has(e.id)&&this.precedingEnd.set(e.id,u);let t=s.get(e.id);t!==void 0&&u>t&&(this.unplacedMain=Math.max(this.unplacedMain,t))}if(e===`ready`&&this.latestUnanchored&&(n===`unloaded`||n===`truncated`)){let e=a.findIndex(e=>e.id!==`unlinked-side`&&this.cut(e,r)!==null);e>0&&(a=a.filter((t,n)=>n>=e||t.id===`unlinked-side`))}if(e===`ready`){let e={unloaded:`Earlier conversation is not loaded.`,truncated:`Earlier conversation omitted to save memory.`,unlinked:`Some earlier conversation entries could not be linked.`};e[n]&&a.unshift(Object.freeze({id:`history:${n}`,kind:`status`,text:e[n]}));let t=this.latestUnanchored&&this.version?vi(this.agent,this.version):null;t&&a.push(Object.freeze({id:`format`,kind:`status`,text:t}))}let d=a.map(e=>{let t=this.entryFingerprints.get(e);return t===void 0&&(t=J(e),this.entryFingerprints.set(e,t)),t}),f=this.previous!==null&&this.previous.length<=d.length&&this.previous.every((e,t)=>e===d[t])?this.previous.length===d.length?`unchanged`:`append`:`replace`;return this.previous=d,this.coveredThrough=this.through,this.latest=Object.freeze({state:e,entries:Object.freeze(a),history:n,change:f,revision:this.revision,branch:r&&e===`ready`?Object.freeze(r):null}),this.latest}forgetUnseen(e){e.end>this.coveredThrough&&e.node?.scope===`main`&&(e.node.results.length||e.node.role===`assistant`)&&(this.unplacedMain=Math.max(this.unplacedMain,e.start))}};const Ga=8388608,Ka=D.batchBytes-2048;var qa=class{session;header;document;decoder;anchor;raw=null;consumed=0;closed=!1;reach=262144;target=0;windowStart=0;decoded=[];decodedChars=0;carry=[];constructor(e,t,n){this.session=t,this.header=n,this.anchor=Object.freeze({...e}),this.target=this.anchor.end,this.begin()}begin(){this.document=new Wa(this.anchor.agent,this.session),this.anchor.agent===`codex`&&this.header&&this.document.append([this.header]);let e=Math.max(0,this.anchor.end-this.reach);this.windowStart=e,this.decoded=[],this.decodedChars=0,this.document.beginWindow(e),this.decoder=new Pi(e,e>0,ha(this.anchor.agent))}keep(e){if(this.decoded){for(let t of e)for(let e of t.entries)this.decodedChars+=e.text.length+(e.detail?.length??0);if(this.decoded.length+e.length>2048||this.decodedChars>4194304){this.decoded=null;return}this.decoded.push(...e)}}joinCarry(){if(this.raw||this.decoder.offset<this.target||!this.carry.length)return;let e=this.carry;this.carry=[];for(let t=0;t<e.length;t+=64)this.document.append(e.slice(t,t+64));this.keep(e),this.target=this.anchor.end,this.decoder.close(),this.decoder=new Pi(this.target,!1,ha(this.anchor.agent))}widen(){if(this.reach>=8388608||this.anchor.end<=this.reach)return null;this.reach=Math.min(Ga,this.reach*2);let e=this.decoded?.filter(e=>!(e.start===this.windowStart&&this.windowStart>0));return e?.length?(this.carry=e,this.target=e[0].start):(this.carry=[],this.target=this.anchor.end),this.raw?.fill(0),this.raw=null,this.consumed=0,this.decoder.close(),this.document.close(),this.begin(),{status:`reading`}}close(){this.closed=!0,this.raw?.fill(0),this.raw=null,this.document.close(),this.decoder.close()}async next(e){if(this.closed)return{status:`unavailable`};if(!this.raw){this.joinCarry();let t=this.target-this.decoder.offset;if(t<=0)return this.finish();let n=await e(this.decoder.offset,Math.min(t,yi));if(this.closed)return n.status===`data`&&n.bytes.fill(0),{status:`unavailable`};if(n.status!==`data`)return n;if(!n.bytes.byteLength||n.offset!==this.decoder.offset||n.bytes.byteLength>t)return n.bytes.fill(0),this.close(),{status:`unavailable`};this.raw=n.bytes,this.consumed=0}for(let e=0;e<4&&this.raw;e++){let e=this.raw.subarray(this.consumed),t=this.decoder.push(e);e.fill(0,0,t.consumed),this.consumed+=t.consumed;let n=t.lines.map(e=>ga(this.anchor.agent,e));this.document.append(n),this.keep(n),this.consumed===this.raw.byteLength&&(this.raw.fill(0),this.raw=null,this.consumed=0)}return this.joinCarry(),this.raw||this.decoder.offset<this.target?{status:`reading`}:this.finish()}finish(){let e=this.document.snapshot(this.anchor),t=e.entries.findIndex(e=>e.id===this.anchor.entryId);if(e.state!==`ready`||t<0)return this.widen()||(this.close(),{status:`unavailable`});let n=e.entries.slice(0,t).filter(e=>!e.id.startsWith(`history:`)&&e.id!==`unlinked-side`),r=[],i=0;for(let e=n.length-1;e>=0;e--){let t=n[e],a=Buffer.byteLength(JSON.stringify(t));if(r.length>=D.entriesPerBatch||i+a>Ka)break;r.push(Object.freeze({entry:t,anchor:this.document.anchor(t.id)})),i+=a}r.reverse();let a=r.findIndex(e=>e.anchor);a>0&&r.splice(0,a);let o=e.history===`complete`&&r.length<n.length?`unloaded`:e.history;if(a<0&&o!==`complete`){let e=this.widen();if(e)return e}let s=e.entries.some(e=>e.id===`unlinked-side`)?`unlinked`:o;return this.close(),!r.length&&(n.length||s!==`complete`)?{status:`unavailable`}:Object.freeze({status:`page`,entries:Object.freeze(r),history:s,more:o!==`complete`,branch:e.branch})}};const Ja=262144;var Ya=class{sources=new Map;working=null;closed=!1;get active(){return this.sources.size}get busy(){return this.working!==null}create(e){if(this.closed||this.sources.size>=10)return null;let t={};this.sources.set(t,null);try{let n=new Xa(e,{begin:()=>this.closed||this.working?!1:(this.working=n,!0),end:()=>{this.working===n&&(this.working=null)},release:()=>{this.sources.delete(t)}});return this.closed?(n.close(),null):(this.sources.set(t,n),n.activate(),n)}catch{return this.sources.delete(t),null}}close(){this.closed=!0;for(let e of[...this.sources.values()])e?.close()}},Xa=class{admission;controller=new AbortController;options;onAbort=()=>this.close();reason=null;file=null;antigravity=null;document=null;decoder=null;header=null;canonicalHeader=null;anchors=new WeakSet;history=null;raw=null;consumed=0;pending=!1;fileClosed=!0;released=!1;discontinuity=0;windowStart=0;reach=Ja;currentRevision=null;target=null;timer;finishStopped;stopped=new Promise(e=>{this.finishStopped=e});finishDrained;drained=new Promise(e=>{this.finishDrained=e});constructor(e,t){this.admission=t;let n=e=>{let t=e.length;if(!Array.isArray(e)||!Number.isSafeInteger(t)||t<0||t>8)throw TypeError(`Invalid transcript roots`);let n=[];for(let r=0;r<t;r++)n.push(e[r]);return n};this.options={enabled:e.enabled.bind(e),identity:e.identity.bind(e),signal:e.signal,roots:{claude:n(e.roots.claude),codex:n(e.roots.codex),...e.roots.agy&&{agy:n(e.roots.agy)},...e.roots.gemini&&{gemini:n(e.roots.gemini)}}}}activate(){this.options.signal?.addEventListener(`abort`,this.onAbort,{once:!0}),this.available()}close(){this.stop(`cancelled`)}poll(){return this.run(()=>this.advance())}confirm(e){return this.run(async()=>{if(this.antigravity){if(this.currentRevision!==e)return{status:`changed`};let t=await this.antigravity.changed(this.controller.signal);return this.available()?t===null?this.stop(`changed`):(t&&(this.currentRevision=null),t?{status:`changed`}:{status:`confirmed`,caughtUp:!0}):this.stopResult()}if(!Number.isSafeInteger(e)||e<0||this.currentRevision!==e||!this.file||!this.decoder)return{status:`changed`};let t=await this.file.verify();return this.available()?t.status===`stopped`?this.stop(t.reason):t.status===`busy`?t:this.raw||this.header||t.size<this.decoder.offset||this.currentRevision!==e?(this.currentRevision=null,{status:`changed`}):{status:`confirmed`,caughtUp:t.size===this.decoder.offset}:this.stopResult()})}anchor(e,t){if(!this.available()||e!==this.currentRevision)return null;let n=this.document?.anchor(t)??null;return n&&this.anchors.add(n),n}older(e){return this.run(async()=>{if(!this.file||!this.anchors.has(e))return{status:`unavailable`};this.history?.anchor!==e&&(this.history?.reader.close(),this.history={anchor:e,reader:new qa(e,this.file.identity.session,this.canonicalHeader)});let t=this.history,n=await this.file.verify();if(!this.available())return this.stopResult();if(n.status===`stopped`)return this.stop(n.reason);if(n.status===`busy`)return n;if(this.raw||this.header||n.size!==this.decoder?.offset)return{status:`refresh`};if(!this.document?.permits(e))return this.cancelOlder(),{status:`unavailable`};let r=await t.reader.next((e,t)=>this.file.read(e,t));if(!this.available())return this.stopResult();if(this.history!==t)return{status:`unavailable`};if(r.status===`stopped`)return this.stop(r.reason);if(this.file.size!==this.decoder?.offset)return this.cancelOlder(),{status:`refresh`};if(r.status===`page`)for(let e of r.entries)e.anchor&&this.anchors.add(e.anchor);return r.status!==`reading`&&r.status!==`busy`&&(t.reader.close(),this.history=null),r})}cancelOlder(){this.history?.reader.close(),this.history=null}async run(e){if(!this.available())return this.stopResult();if(this.pending||!this.admission.begin())return{status:`busy`};this.pending=!0,this.timer=setTimeout(()=>this.stop(`timeout`),1e4);let t=Promise.resolve().then(async()=>{try{return this.available()?await e():this.stopResult()}catch{return this.stop(`unreadable`)}finally{clearTimeout(this.timer),this.timer=void 0,this.pending=!1,this.admission.end(),this.finish()}}),n=await Promise.race([t,this.stopped]);return this.available()?n:this.stopResult()}async advance(){if(this.antigravity)return this.readAntigravity();if(!this.file){let e=await this.options.identity(this.controller.signal).catch(()=>null);if(!this.available())return this.stopResult();if(e?.agent===`agy`)return this.antigravity=new Ra(this.options,e),this.readAntigravity();let t=await Ei.open({...this.options,signal:this.controller.signal});if(t.status===`stopped`)return this.stop(t.reason);if(this.file=t.file,this.fileClosed=!1,t.file.closed.then(()=>{this.fileClosed=!0,this.finish()}),!this.available())return t.file.close(),this.stopResult();if(!Ui(t.file.identity.session))return this.stop(`unbound`);this.document=new Wa(t.file.identity.agent,t.file.identity.session),t.file.identity.agent===`claude`?this.window(Math.max(0,t.file.size-Ja)):(this.header=new _a(t.file.identity.session),this.decoder=new Pi(0,!1,ha(t.file.identity.agent)))}let e=this.file;if(this.raw){let t=await e.verify();if(!this.available())return this.stopResult();if(t.status===`stopped`)return this.stop(t.reason);if(t.status===`busy`)return t}else{this.target===this.decoder.offset&&(this.target=null);let t=this.target===null?yi:this.target-this.decoder.offset,n=await e.read(this.decoder.offset,Math.max(1,Math.min(yi,t)));if(!this.available())return n.status===`data`&&n.bytes.fill(0),this.stopResult();if(n.status===`stopped`)return this.stop(n.reason);if(n.status===`busy`)return n;this.raw=n.bytes,this.consumed=0,this.target??=n.size}for(let t=0;t<4&&this.raw;t++){let t=this.raw.subarray(this.consumed),n=this.decoder.push(t);if(t.fill(0,0,n.consumed),this.consumed+=n.consumed,this.consumed===this.raw.byteLength&&this.clearRaw(),this.header&&n.lines.length){let t=ga(e.identity.agent,n.lines[0]);if(this.header.observe(t),this.header.status!==`verified`)return this.stop(this.header.status===`mismatch`?`unbound`:`unsupported`);if(this.canonicalHeader=t,this.header=null,this.document.append([t]),e.size>262144)return this.window(e.size-Ja),this.catchingUp();this.document.append(n.lines.slice(1).map(t=>ga(e.identity.agent,t)))}else!this.header&&n.lines.length&&this.document.append(n.lines.map(t=>ga(e.identity.agent,t)));if(n.lines.length&&(this.currentRevision=null),this.header&&this.decoder.offset>131073)return this.stop(`unsupported`)}if(!this.available())return this.stopResult();if(!this.header&&this.lagged()||this.header||this.raw||this.decoder.offset!==this.target)return this.catchingUp();let t=this.document.snapshot();return t.state===`unsupported`?this.stop(`unsupported`):(t.state===`unbound`||this.unpageable(t))&&this.widen()?this.catchingUp():(this.currentRevision=t.state===`ready`?t.revision:null,this.target=null,{status:`snapshot`,snapshot:t,discontinuity:this.discontinuity,caughtUp:this.decoder.offset===e.size})}async readAntigravity(){let e=await this.antigravity.read(this.controller.signal);return this.available()?e.status===`stopped`?this.stop(e.reason):(this.currentRevision=e.snapshot.revision,{status:`snapshot`,snapshot:e.snapshot,discontinuity:0,caughtUp:!0}):this.stopResult()}lagged(){return this.file.size-this.decoder.offset<=Math.max(this.reach,4194304)?!1:this.discontinuity===2**53-1?(this.stop(`unsafe`),!0):(this.discontinuity++,this.reach=Ja,this.window(Math.max(0,this.file.size-yi)),!0)}unpageable(e){return e.state===`ready`&&e.history===`unloaded`&&!this.document.hasCut()}widen(){return this.file.identity.agent!==`claude`||this.windowStart===0||this.reach>=8388608?!1:(this.reach=Math.min(Ga,this.reach*2),this.window(Math.max(0,this.file.size-this.reach)),!0)}window(e){this.windowStart=e,this.anchors=new WeakSet,this.cancelOlder(),this.clearRaw(),this.decoder?.close(),this.decoder=new Pi(e,e>0,ha(this.file.identity.agent)),this.document.beginWindow(e),this.target=this.file.size,this.currentRevision=null}clearRaw(){this.raw?.fill(0),this.raw=null,this.consumed=0}catchingUp(){if(this.reason)return this.stopResult();let e=this.raw!==null||this.file!==null&&this.decoder!==null&&this.decoder.offset<this.file.size;return{status:`catching-up`,discontinuity:this.discontinuity,pending:e}}available(){if(this.reason)return!1;try{this.options.signal?.aborted?this.stop(`cancelled`):this.options.enabled()||this.stop(`disabled`)}catch{this.stop(`unreadable`)}return this.reason===null}stopResult(){return{status:`stopped`,reason:this.reason}}stop(e){return this.reason||(this.reason=e,clearTimeout(this.timer),this.controller.abort(),this.options.signal?.removeEventListener(`abort`,this.onAbort),this.file?.close(),this.antigravity?.close(),this.antigravity=null,this.document?.close(),this.decoder?.close(),this.header?.close(),this.canonicalHeader=null,this.history?.reader.close(),this.history=null,this.clearRaw(),this.currentRevision=null,this.finishStopped(this.stopResult()),this.finish()),this.stopResult()}finish(){this.reason&&!this.pending&&this.fileClosed&&!this.released&&(this.released=!0,this.file=null,this.document=null,this.decoder=null,this.header=null,this.admission.release(),this.finishDrained())}};const Za=2e3,Qa=`[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`,$a=RegExp(`^${Qa}$`,`i`),eo=RegExp(`^(${Qa})\\.jsonl$`,`i`),to=RegExp(`^(${Qa})\\.db$`,`i`),no=RegExp(`^rollout-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-(${Qa})(?:_(${Qa}))?\\.jsonl$`,`i`),ro=/^session-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-([0-9a-f]{8})\.jsonl$/i,io=[/^\d{4}$/,/^(0[1-9]|1[0-2])$/,/^(0[1-9]|[12]\d|3[01])$/];var Y=class extends Error{reason;constructor(e){super(e),this.reason=e}};function ao(e){return ur(e)&&e.length<=4096&&dr(e)===e&&!Array.from(e).some(e=>{let t=e.charCodeAt(0);return t<32||t>=127&&t<=159||e.length===1&&t>=55296&&t<=57343})}function oo(e,t){return e.dev===t.dev&&e.ino===t.ino}function so(e,t){return oo(e,t)&&e.mtimeNs===t.mtimeNs&&e.ctimeNs===t.ctimeNs}function co(e){return process.getuid===void 0||e.uid===BigInt(process.getuid())}function lo(e){return e?.code===`ENOENT`}function uo(e,t){return e===`agy`?to.exec(t)?.[1]?.toLowerCase()??null:t.endsWith(`.jsonl`)?(e===`claude`?eo:no).exec(t)?.[1]?.toLowerCase()??null:null}function fo(e,t){return io[t]?.test(e)??!1}function po(e,t){let n=t.split(pr);return ur(t)||n.some(e=>e===``||e===`.`||e===`..`)||!uo(e,n.at(-1))?!1:e===`claude`?n.length===2:e===`agy`?n.length===1:n.length===1||n.length===4&&n.slice(0,3).every(fo)}var mo=class{options;busy=!1;constructor(e){this.options=e}async locate(e,t){let n=()=>{if(t?.aborted)return`cancelled`;try{return this.options.enabled()?null:`disabled`}catch{return`unreadable`}},r=n();if(r)return{status:`unavailable`,reason:r};if(this.busy)return{status:`busy`};this.busy=!0;let i=new AbortController,a=null,o,s=new Promise(e=>{o=t=>{a||(a=n()??t,i.abort(),e({status:`unavailable`,reason:a}))}}),c=()=>o(`cancelled`),l=setTimeout(()=>o(`limit`),Za);t?.addEventListener(`abort`,c,{once:!0}),t?.aborted&&c();let u=(async()=>{try{let t=await new ho(this.options,{...e},i.signal).run(),r=n()??a;return r?{status:`unavailable`,reason:r}:t}catch(e){return{status:`unavailable`,reason:n()??a??(e instanceof Y?e.reason:`unreadable`)}}finally{this.busy=!1}})();try{let e=await Promise.race([u,s]),t=n()??a;return t?{status:`unavailable`,reason:t}:e}finally{clearTimeout(l),t?.removeEventListener(`abort`,c)}}},ho=class{options;reference;signal;deadline=performance.now()+Za;directories=new Map;candidates=new Map;missingRoots=new Set;entries=0;session=``;constructor(e,t,n){this.options=e,this.reference=t,this.signal=n}check(){if(this.signal?.aborted)throw new Y(`cancelled`);if(!this.options.enabled())throw new Y(`disabled`);if(performance.now()>=this.deadline)throw new Y(`limit`)}async run(){this.check();let{agent:e,kind:t,value:n}=this.reference;if(e!==`claude`&&e!==`codex`&&e!==`agy`&&e!==`gemini`||t!==`id`&&t!==`path`||e===`gemini`&&t!==`id`||typeof n!=`string`)throw new Y(`unsafe`);if(this.session=t===`id`?n.toLowerCase():uo(e,lr(n))??``,!$a.test(this.session)||t===`path`&&!ao(n))throw new Y(`unbound`);let r=this.options.roots[e];if(!Array.isArray(r)||!r.length||r.length>8)throw new Y(`unsafe`);let i=[...r],a=new Set;for(let e of i){if(this.check(),!ao(e))throw new Y(`unsafe`);let t=!1;try{let n=await V(e);if(t=!0,this.check(),await this.directory(n),[...a].some(e=>e!==n&&(n.startsWith(e.endsWith(pr)?e:`${e}${pr}`)||e.startsWith(n.endsWith(pr)?n:`${n}${pr}`))))throw new Y(`unsafe`);a.add(n)}catch(n){if(!lo(n))throw n;if(t)throw new Y(`changed`);try{throw await B(e),new Y(`unsafe`)}catch(e){if(!lo(e))throw e}this.check(),this.missingRoots.add(e)}}if(t===`path`){let t=[...a].find(t=>po(e,fr(t,n)));if(!t)throw new Y(`unsafe`);let r=await B(n,{bigint:!0}).catch(e=>{throw lo(e)?new Y(`unbound`):e});if(this.check(),!r.isFile()||!co(r))throw new Y(`unsafe`);let i=await V(n);if(this.check(),i!==n)throw new Y(`unsafe`);let o=I(i);for(;o!==t;)await this.directory(o),o=I(o);await this.candidate(i);let s=this.candidates.get(i);if(!s||!oo(r,s))throw new Y(`changed`)}else for(let t of a)e===`claude`?await this.claude(t):e===`agy`?await this.candidate(L(t,`${this.session}.db`)):e===`gemini`?await this.gemini(t):await this.codex(t,0);for(let[e,t]of this.directories){this.check();let n=await B(e,{bigint:!0});if(this.check(),!n.isDirectory()||!so(t,n)||await V(e)!==e)throw new Y(`changed`)}for(let e of this.missingRoots){this.check();try{throw await B(e,{bigint:!0}),new Y(`changed`)}catch(e){if(!lo(e))throw e}}if(!this.candidates.size)throw new Y(`unbound`);let[o,s]=[...this.candidates][0],c=await B(o,{bigint:!0});if(this.check(),!c.isFile()||!co(c)||!oo(s,c))throw new Y(`changed`);return{status:`candidate`,candidate:Object.freeze({agent:e,path:o,session:this.session})}}async directory(e){if(this.check(),this.directories.has(e))return;if(this.directories.size>=512)throw new Y(`limit`);if(!ao(e))throw new Y(`unsafe`);let t=await B(e,{bigint:!0});if(this.check(),!t.isDirectory()||!co(t)||await V(e)!==e)throw new Y(`unsafe`);this.check(),this.directories.set(e,t)}async candidate(e){if(this.check(),!ao(e))throw new Y(`unsafe`);let t;try{t=await B(e,{bigint:!0})}catch(e){if(lo(e))return;throw e}if(this.check(),!t.isFile()||!co(t)||await V(e)!==e)throw new Y(`unsafe`);if(this.check(),this.candidates.set(e,t),this.candidates.size>1)throw new Y(`ambiguous`)}async visit(e,t){await this.directory(e),this.check();let n=await Dr(e,{bufferSize:32});try{for(;;){this.check();let e=await n.read();if(this.check(),!e)break;if(++this.entries>16384)throw new Y(`limit`);await t(e.name)}}finally{await n.close()}}async claude(e){await this.visit(e,async t=>{let n=L(e,t),r=await B(n,{bigint:!0});if(this.check(),r.isSymbolicLink())throw new Y(`unsafe`);r.isDirectory()&&(await this.directory(n),await this.candidate(L(n,`${this.session}.jsonl`)))})}async gemini(e){let t=this.session.slice(0,8);await this.visit(e,async n=>{let r=L(e,n),i=await B(r,{bigint:!0});if(this.check(),i.isSymbolicLink())throw new Y(`unsafe`);if(!i.isDirectory())return;let a=L(r,`chats`),o=await B(a,{bigint:!0}).catch(e=>{if(lo(e))return null;throw e});if(this.check(),o){if(o.isSymbolicLink()||!o.isDirectory())throw new Y(`unsafe`);await this.visit(a,async e=>{ro.exec(e)?.[1]?.toLowerCase()===t&&await this.candidate(L(a,e))})}})}async codex(e,t){await this.visit(e,async n=>{let r=L(e,n);if((t===0||t===3)&&uo(`codex`,n)===this.session)await this.candidate(r);else if((t===0||t===3)&&n.toLowerCase().startsWith(`rollout-`)&&n.toLowerCase().includes(this.session))throw new Y(`unbound`);else t<3&&fo(n,t)&&await this.codex(r,t+1)})}},go=class{options;roots;followers;locator;entries=new Set;off;timer=null;working=null;closed=!1;constructor(e){this.options={...e},this.roots=e.roots??{claude:[L(process.env.CLAUDE_CONFIG_DIR||L(F(),`.claude`),`projects`)],codex:[L(process.env.CODEX_HOME||L(F(),`.codex`),`sessions`)],agy:[L(F(),`.gemini`,`antigravity-cli`,`conversations`)],gemini:[L(process.env.GEMINI_CLI_HOME||F(),`.gemini`,`tmp`)]},this.followers=e.followers??new Ya,this.locator=e.locator??new mo({roots:this.roots,enabled:()=>!this.closed&&this.options.enabled()}),this.off=e.backend.on(e=>{if(e.type===`conversation-changed`||e.type===`session-removed`){for(let t of this.entries)t.source?.sessionId===e.sessionId&&t.source.invalidate(e.type===`session-removed`?`ended`:`changed`);this.schedule()}})}attach(e){if(this.closed||this.entries.size>=10)return{focus(){},receive(){},close(){}};let t={focused:null,source:null,current:e.current,send:e.send,lane:e.background(()=>this.current(t)?t.source?.offer()??!1:!1)};return this.entries.add(t),{focus:e=>{this.current(t)&&t.focused!==e&&(t.focused=e,t.source?.close(),t.source=null)},receive:(e,n)=>{if(!this.current(t))return;let r=o.safeParse(e);if(!(!r.success||!Number.isSafeInteger(n)||n<1||n>D.envelopeBytes)){if(e=r.data,e.type===`conversation.subscribe`){if(t.source?.subscriptionId===e.subscriptionId)return;t.source?.close(),t.source=null;let n=e.sessionId;t.focused=n;let r,i=()=>this.current(t)&&t.source===r&&t.focused===n&&this.options.enabled();r=new di({subscriptionId:e.subscriptionId,sessionId:n,now:()=>this.options.now?.()??performance.now(),newId:()=>this.options.newId?.()??k(C(16)),enabled:i,follow:()=>this.followers.create({enabled:i,roots:this.roots,identity:fi({enabled:i,locator:this.locator,reference:e=>this.options.backend.conversationReference(n,e)})}),send:e=>this.current(t)&&t.source===r&&t.send(e),wake:()=>t.lane.wake()}),t.source=r,this.options.enabled()||r.invalidate(`disabled`),t.lane.wake()}else t.source?.receive(e,n),e.type===`conversation.cancel`&&t.source?.subscriptionId===e.subscriptionId&&(t.source=null);this.schedule()}},close:()=>this.retire(t)}}consentChanged(){if(!this.closed){for(let e of this.entries)e.source&&e.source.invalidate(this.options.enabled()?`changed`:`disabled`);this.schedule()}}close(){if(!this.closed){this.closed=!0,this.off(),this.timer&&clearTimeout(this.timer),this.timer=null;for(let e of this.entries)this.retire(e);this.followers.close()}}current(e){return!this.closed&&this.entries.has(e)&&e.current()}retire(e){this.entries.delete(e)&&(e.source?.close(),e.source=null,e.lane.close())}schedule(e=!1){if(!this.closed&&[...this.entries].some(e=>e.source)){if(this.timer){if(!e)return;clearTimeout(this.timer)}this.timer=setTimeout(()=>{this.timer=null,this.pump()},e?0:200),this.timer.unref?.()}}pump(){if(!this.closed){for(let e of this.entries)e.current()?e.source?.tick():this.retire(e);if(!this.working){let e=[...this.entries].find(e=>e.source?.needsWork);if(e?.source){this.entries.delete(e),this.entries.add(e);let t={};this.working=t,e.source.work().finally(()=>{this.working===t&&(this.working=null),this.schedule([...this.entries].some(e=>e.source?.needsWork))})}}this.schedule()}}};const _o=new Set([`bad-sig`,`fp-mismatch`]),vo=M.unacked*M.envelopeBytes;function yo(e){if(e.t!==`ctrl`)return!1;let t=e.body;return typeof t==`object`&&!!t&&t.type===`auth`}function bo(e){if(e.t!==`ctrl`)return e.t;let t=e.body;return typeof t==`object`&&t&&typeof t.type==`string`?t.type:`ctrl`}function xo(e,t,n){let r=t*2**e,i=r*.2*(Math.random()*2-1);return Math.min(n,Math.max(0,r+i))}var So=class extends xr{opts;ws=null;stopped=!0;attempt=0;reconnectTimer=null;pingTimer=null;pongTimer=null;authTimer=null;authed=!1;relayWithholdsTurn=!1;ice=new zr;log;constructor(e){super(),this.opts=e,this.log=e.log.child({unit:`relay`})}get online(){return this.authed&&this.ws?.readyState===Mr.OPEN}start(){this.stopped&&(this.stopped=!1,this.attempt=0,this.connect())}stop(){this.stopped=!0,this.clearTimers();let e=this.ws,t=this.online;this.ws=null,this.authed=!1,e?.terminate(),t&&this.emit(`down`)}iceServers(){return this.refreshIceIfDue(),this.ice.servers(Date.now())}refreshIceIfDue(){let e=Date.now();this.authed&&this.ice.needsRefresh(e)&&this.ice.takeRefresh(e)&&this.sendCtrl({type:`ice-refresh`})}sendCtrl(e){return this.sendEnvelope({v:1,t:`ctrl`,from:this.opts.fp,seq:0,body:e})}sendEnvelope(e){return!this.authed&&!yo(e)?(this.log.debug(`dropped send: not authenticated`,{type:bo(e)}),!1):this.ws?.readyState===Mr.OPEN?(this.ws.send(e.v===2?Et(e):qe(e),{binary:!0}),!0):(this.log.debug(`dropped send: socket not open`,{type:bo(e)}),!1)}sendBoundedEnvelope(e){let t=this.ws;if(!this.authed||t?.readyState!==Mr.OPEN)return!1;let n=e.v===2?Et(e):qe(e);if(n.byteLength>M.envelopeBytes)return!1;let r=t.bufferedAmount;return typeof r!=`number`||!Number.isFinite(r)||r<0||r>vo-n.byteLength?!1:(t.send(n,{binary:!0}),!0)}connect(){if(this.stopped)return;let e=Me(this.opts.relayUrl,this.opts.fp);this.log.info(`connecting`,{attempt:this.attempt});let n=new Mr(e,{handshakeTimeout:1e4}),r=n;this.ws=n,n.on(`open`,()=>{this.ws===r&&(this.log.debug(`socket open`),this.authTimer=setTimeout(()=>{this.ws!==r||this.authed||(this.log.warn(`relay did not finish sign-in; reconnecting`),r.terminate())},this.opts.authTimeoutMs??2e4))}),n.on(`message`,(e,n)=>{if(this.ws!==r||!n)return;let i=new Uint8Array(e),a;try{a=t(i)}catch(e){this.log.warn(`malformed frame from relay`,{code:e instanceof mt?e.code:N(e)});return}if(a.t===`e2e`){this.authed&&this.emit(`e2e`,a,i.byteLength);return}let o;try{o=ut(a.body)}catch(e){this.log.warn(`malformed ctrl from relay`,{code:e instanceof mt?e.code:N(e)});return}this.onCtrl(o)}),n.on(`pong`,()=>{this.ws===r&&(this.pongTimer&&clearTimeout(this.pongTimer),this.pongTimer=null)}),n.on(`close`,e=>{this.ws===r&&this.onClose(e)}),n.on(`error`,e=>{this.ws===r&&this.log.warn(`socket error`,{name:N(e)})})}onCtrl(e){if(e.type===`challenge`){let t=de(this.opts.identity.ed25519.priv,ye(e.connId,`agent`,this.opts.fp,e.nonce));this.sendCtrl({type:`auth`,role:`agent`,fp:this.opts.fp,ed25519Pub:this.opts.identity.ed25519.pub,sig:t,name:this.opts.name,appVersion:this.opts.appVersion,...this.opts.turn===!1&&{turn:!1}});return}if(e.type===`auth-ok`){this.authed=!0,this.authTimer&&clearTimeout(this.authTimer),this.authTimer=null,this.ice=new zr,e.iceServers&&this.ice.update(e.iceServers,e.iceExpiresInMs??0,Date.now()),this.attempt=0,this.startPing(),this.log.info(`authenticated`,{minFrameMs:e.minFrameMs}),this.relayWithholdsTurn=e.turnOff===!0,this.opts.turn===!1&&!this.relayWithholdsTurn&&this.log.warn(`relay does not withhold TURN from phones; update the relay to 0.3.0`),this.emit(`auth-ok`,e);return}if(e.type===`ice-servers`){this.ice.update(e.iceServers,e.iceExpiresInMs,Date.now());return}if(e.type===`auth-fail`){this.log.error(`auth failed`,{reason:e.reason}),_o.has(e.reason)&&(this.stopped=!0),this.emit(`auth-fail`,e.reason);return}this.emit(`ctrl`,e)}onClose(e){let t=this.authed;if(this.authed=!1,this.clearTimers(),this.ws=null,e===4005){this.log.warn(`connection superseded by a newer agent`,{code:e}),this.stopped=!0,this.emit(`superseded`),this.emit(`down`);return}e===4413||e===4429?this.log.error(`relay closed connection`,{code:e}):this.log.info(`socket closed`,{code:e}),t&&this.emit(`down`),!this.stopped&&this.scheduleReconnect()}scheduleReconnect(){let e=this.opts.backoffMinMs??1e3,t=this.opts.backoffMaxMs??3e4,n=xo(this.attempt,e,t);this.attempt=Math.min(this.attempt+1,10),this.reconnectTimer=setTimeout(()=>this.connect(),n)}startPing(){if(this.pingTimer)return;let e=this.opts.pingIntervalMs??45e3,t=this.opts.pongTimeoutMs??1e4,n=this.ws;this.pingTimer=setInterval(()=>{this.ws===n&&n?.readyState===Mr.OPEN&&(this.refreshIceIfDue(),this.pongTimer&&clearTimeout(this.pongTimer),n.ping(),this.pongTimer=setTimeout(()=>{this.log.warn(`pong timeout; terminating socket`),n.terminate()},t))},e)}clearTimers(){this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.pingTimer&&clearInterval(this.pingTimer),this.pongTimer&&clearTimeout(this.pongTimer),this.authTimer&&clearTimeout(this.authTimer),this.reconnectTimer=this.pingTimer=this.pongTimer=this.authTimer=null}},Co=class{options;sender;startedAt;open=!0;admitted=!1;sending=!1;refusalAt=null;pending=null;nativeHistory=null;timedOutHistory=null;latestHistoryRequestId;historyRevoked=!1;anchor;anchorBound=!1;lastAcknowledgedGeneration;snapshotAccepted=!1;snapshotRequested=!1;refreshRequested=!1;constructor(e){if(!te.safeParse(e.subscriptionId).success||!je.safeParse(e.sessionId).success)throw Error(`Invalid screen stream identity`);let t=e.now();if(!Number.isFinite(t))throw Error(`Invalid screen stream clock`);this.options={...e,...e.history?{history:{...e.history}}:{}},this.startedAt=t,this.sender=new _({subscriptionId:e.subscriptionId,sessionId:e.sessionId,now:()=>this.readClock(),newTransferId:()=>this.options.newTransferId(),send:e=>this.admitChunk(e)})}offer(e,t){if(!this.canOfferScreen()||e.sessionId!==this.options.sessionId||e.gen!==t.generation||e.scrollbackTotal!==t.reported)return!1;if(e.type===`screen.diff`){if(!this.snapshotAccepted||this.lastAcknowledgedGeneration===void 0||e.gen!==this.lastAcknowledgedGeneration+1)return this.requestFreshSnapshot(),!1}else if(this.lastAcknowledgedGeneration!==void 0&&(e.gen<this.lastAcknowledgedGeneration||e.gen===this.lastAcknowledgedGeneration&&!this.refreshRequested))return!1;let n;try{if(e.type===`screen.snapshot`){let{type:t,sessionId:r,...i}=e,a=se(i);if(!a.ok)return this.close(a.code),!1;n=a.bytes}else{let{type:t,sessionId:r,...i}=e;n=ee(i)}}catch{return e.type===`screen.diff`?this.requestFreshSnapshot():this.close(`invalid-transfer`),!1}if(!this.open)return!1;try{let t=this.sender.offer({kind:e.type===`screen.snapshot`?`snapshot`:`diff`,generation:e.gen},n);if(!this.reconcileSender())return!1;if(!t.accepted)return t.reason===`too-large`&&this.close(`screen-too-large`),!1}catch{return this.close(`invalid-transfer`),!1}return this.open?(this.pending={kind:e.type===`screen.snapshot`?`snapshot`:`diff`,generation:t.generation,reported:t.reported,...e.type===`screen.snapshot`&&t.capture!==void 0?{capture:t.capture}:{},finalSequence:null},e.type===`screen.snapshot`&&(this.snapshotAccepted=!0,this.snapshotRequested=!1,this.refreshRequested=!1),!0):!1}canOfferScreen(){if(this.tick(),!this.open||this.pending||this.sender.inFlight>=M.unacked)return!1;let e;try{e=this.sender.canOffer(`snapshot`)}catch{return this.close(`invalid-transfer`),!1}return!(!this.reconcileSender()||!e)}receive(e,t){if(!this.open||e.subscriptionId!==this.options.subscriptionId||(this.tick(),!this.open))return;if(!Number.isSafeInteger(t)||t<1||t>M.envelopeBytes||!Pe.safeParse(e).success){this.close(`invalid-transfer`);return}if(e.type===`stream.cancel`){this.cancel();return}if(e.type===`stream.refresh`){this.refreshRequested=!0,this.requestFreshSnapshot();return}if(e.type===`stream.history.get`){this.requestHistory(e);return}if(e.type!==`stream.ack`){this.close(`invalid-transfer`);return}let n;try{n=this.sender.acknowledge(e.subscriptionId,e.through)}catch{this.close(`invalid-transfer`);return}if(!this.reconcileSender())return;if(n===`invalid`){this.close(`invalid-transfer`);return}if(n!==`advanced`)return;if(this.pending?.finalSequence!==null&&this.pending?.finalSequence!==void 0&&e.through>=this.pending.finalSequence){let e=this.pending;this.pending=null,this.lastAcknowledgedGeneration=e.generation,!this.anchorBound&&e.kind===`snapshot`&&(this.anchor=Object.freeze({generation:e.generation,reported:e.reported,...e.capture===void 0?{}:{capture:e.capture}}),this.anchorBound=!0)}let r=this.nativeHistory;r?.phase===`transfer`&&r.finalSequence!==null&&e.through>=r.finalSequence&&this.finishHistory(r)}requestHistory(e){let t=this.options.history;if(!t){this.close(`invalid-transfer`);return}if(e.requestId===this.nativeHistory?.requestId||e.requestId===this.latestHistoryRequestId)return;if(this.nativeHistory||this.timedOutHistory){this.sendHistoryError(e.requestId,`history-unavailable`);return}let n=this.anchor,r;try{r=this.sender.canOffer(`history`)}catch{this.close(`invalid-transfer`);return}if(!this.reconcileSender())return;if(this.historyRevoked||n&&!n.capture){this.latestHistoryRequestId=e.requestId,this.sendHistoryError(e.requestId,`history-reset`);return}if(!n?.capture||e.before>n.reported||this.sender.inFlight>=M.unacked||!r){this.latestHistoryRequestId=e.requestId,this.sendHistoryError(e.requestId,`history-unavailable`);return}let i;try{i=this.readClock()}catch{this.close(`invalid-transfer`);return}let a={requestId:e.requestId,before:e.before,count:e.count,anchor:n,controller:new AbortController,phase:`reading`,readDeadline:i+M.totalMs,readyDeadline:null,finalSequence:null};this.nativeHistory=a;let o;try{o=t.read(this.options.sessionId,{capture:n.capture,reported:n.reported,before:a.before,count:a.count,signal:a.controller.signal})}catch(e){this.failHistoryRead(a,e);return}Promise.resolve(o).then(e=>this.completeHistoryRead(a,e),e=>this.failHistoryRead(a,e)).catch(()=>{this.open&&this.nativeHistory===a&&this.close(`invalid-transfer`)})}completeHistoryRead(e,t){if(this.timedOutHistory===e){this.timedOutHistory=null;return}if(!this.open||this.nativeHistory!==e||e.phase!==`reading`)return;if(this.tick(),this.timedOutHistory===e){this.timedOutHistory=null;return}if(!this.open||this.nativeHistory!==e)return;if(typeof t!=`object`||!t){this.close(`invalid-transfer`);return}if(t.status===`reset`){this.historyRevoked=!0,this.finishHistory(e,`history-reset`);return}if(t.status===`unavailable`){if(![`unsupported`,`unanchored`,`busy`,`changed`,`fetch-window`].includes(t.reason)){this.close(`invalid-transfer`);return}this.finishHistory(e,`history-unavailable`,t.reason===`fetch-window`?`fetch-window`:void 0);return}if(t.status===`cancelled`){this.finishHistory(e,`history-unavailable`);return}if(t.status!==`page`&&t.status!==`boundary`){this.close(`invalid-transfer`);return}if(t.status===`page`&&(!Array.isArray(t.lines)||t.lines.length>e.count)){this.close(`invalid-transfer`);return}let n=ve({...t,kind:`history`,generation:e.anchor.generation,requestId:e.requestId,before:e.before});if(!n.ok){n.code===`history-line-too-large`?this.finishHistory(e,`history-line-too-large`):this.close(`invalid-transfer`);return}try{let t=this.sender.offer({kind:`history`,generation:e.anchor.generation,requestId:e.requestId,before:e.before},n.bytes);if(!this.reconcileSender())return;if(!t.accepted){this.close(`invalid-transfer`);return}e.phase=`transfer`,e.readDeadline=null,e.readyDeadline=this.readClock()+M.progressMs}catch{this.close(`invalid-transfer`);return}if(this.open&&this.nativeHistory===e)try{wo(this.options.history?.onReady(),()=>{this.open&&this.close(`invalid-transfer`)})}catch{this.open&&this.close(`invalid-transfer`)}}failHistoryRead(e,t){if(this.timedOutHistory===e){this.timedOutHistory=null;return}if(this.open&&this.nativeHistory===e&&e.phase===`reading`){if(this.tick(),this.timedOutHistory===e){this.timedOutHistory=null;return}this.open&&this.nativeHistory===e&&(t instanceof A?this.close(`session-gone`):this.finishHistory(e,`history-unavailable`))}}finishHistory(e,t,n){this.open&&this.nativeHistory===e&&(this.nativeHistory=null,this.latestHistoryRequestId=e.requestId,e.readDeadline=null,e.readyDeadline=null,t&&this.sendHistoryError(e.requestId,t,n))}sendHistoryError(e,t,n){if(!this.open)return;let r;try{r=this.options.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,requestId:e,code:t,...n?{historyReason:n}:{}})}catch{this.close(`invalid-transfer`);return}r!==!0&&r!==!1&&(wo(r),this.close(`invalid-transfer`))}sendOne(){if(this.sending||(this.tick(),!this.open))return!1;this.sending=!0;try{return this.sender.pump(),this.reconcileSender(),this.chunkAdmitted}catch{throw this.close(`invalid-transfer`),Error(`Screen stream send failed`)}finally{this.chunkAdmitted=!1,this.sending=!1}}chunkAdmitted=!1;tick(){if(this.open)try{let e=this.readClock(),t=this.nativeHistory;if(t?.phase===`reading`&&t.readDeadline!==null&&e>=t.readDeadline&&(this.nativeHistory=null,this.timedOutHistory=t,this.latestHistoryRequestId=t.requestId,t.readDeadline=null,t.controller.abort(),this.sendHistoryError(t.requestId,`history-unavailable`)),!this.open)return;let n=this.nextDeadline();n!==null&&e>=n&&this.close(`stalled`)}catch{this.close(`invalid-transfer`)}}nextDeadline(){if(!this.open)return null;let e=[this.sender.nextDeadline()];this.admitted||e.push(this.startedAt+M.progressMs),this.refusalAt!==null&&e.push(this.refusalAt+M.progressMs),this.nativeHistory?.readDeadline!==null&&this.nativeHistory?.readDeadline!==void 0&&e.push(this.nativeHistory.readDeadline),this.nativeHistory?.readyDeadline!==null&&this.nativeHistory?.readyDeadline!==void 0&&e.push(this.nativeHistory.readyDeadline);let t=e.filter(e=>e!==null);return t.length===0?null:Math.min(...t)}historyAnchor(){return this.anchor}cancel(){this.close(`cancelled`)}hasAcceptedSnapshot(){return this.snapshotAccepted}terminate(e){if(e!==`session-gone`&&e!==`invalid-transfer`&&e!==`stalled`)throw TypeError(`Invalid screen stream termination reason`);this.close(e)}readClock(){let e=this.options.now();if(!Number.isFinite(e))throw Error(`Invalid screen stream clock`);return e}reconcileSender(){if(!this.open)return!1;try{let e=this.sender.tick();this.open&&e!==`open`&&this.close(e===`stalled`?`stalled`:`invalid-transfer`)}catch{this.close(`invalid-transfer`)}return this.open}admitChunk(e){if(!this.open||this.chunkAdmitted||(this.tick(),!this.open))return!1;let t;try{t=this.options.sendChunk(e)}catch{throw this.close(`invalid-transfer`),Error(`Screen stream send failed`)}if(t!==!0&&t!==!1)throw wo(t),this.close(`invalid-transfer`),Error(`Screen stream send failed`);if(t)this.chunkAdmitted=!0,this.admitted=!0,this.refusalAt=null,e.meta.kind===`history`&&this.nativeHistory?.phase===`transfer`&&e.meta.requestId===this.nativeHistory.requestId?(this.nativeHistory.readyDeadline=null,e.index===e.count-1&&(this.nativeHistory.finalSequence=e.sequence)):e.meta.kind!==`history`&&this.pending&&e.meta.generation===this.pending.generation&&e.index===e.count-1&&(this.pending.finalSequence=e.sequence);else if(this.open&&this.refusalAt===null)try{this.refusalAt=this.readClock()}catch{this.close(`invalid-transfer`)}return t}requestFreshSnapshot(){if(this.open&&!this.snapshotRequested){this.snapshotRequested=!0;try{wo(this.options.requestSnapshot(),()=>{this.open&&this.close(`invalid-transfer`)})}catch{this.close(`invalid-transfer`)}}}close(e){if(!this.open)return;this.open=!1;let t=this.nativeHistory;if(this.nativeHistory=null,this.timedOutHistory=null,this.sender.cancel(),this.pending=null,this.anchor=void 0,this.anchorBound=!1,this.refusalAt=null,this.snapshotRequested=!1,this.refreshRequested=!1,t?.controller.abort(),e!==`cancelled`)try{wo(this.options.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,code:e}))}catch{}try{wo(this.options.onClosed(e))}catch{}}};function wo(e,t){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>t?.())}var To=class{options;anchor=null;request=null;reading=null;latestRequest=null;open=!0;constructor(e){this.options=e}bind(e,t,n){this.retire(),this.anchor=n?{capture:e,generation:t,native:n,before:n.from,applied:!1}:null}retire(){this.request?.controller.abort(),this.request?.phase===`reading`&&(this.request=null),this.latestRequest=null,this.anchor=null}applied(e,t){this.anchor?.capture===e&&this.anchor.generation===t&&(this.anchor.applied=!0)}receive(e){if(!this.open||this.request?.id===e.requestId||this.latestRequest===e.requestId)return;let t=this.anchor;if(!t||e.capture!==t.capture||e.generation!==t.generation){this.error(e.requestId,`history-reset`);return}if(!t.applied||this.request||this.reading||!this.options.sender.canOffer(`history`)){this.error(e.requestId,`history-unavailable`);return}if(e.before!==t.before){this.error(e.requestId,`history-reset`);return}let n={id:e.requestId,anchor:t,before:e.before,count:e.count,controller:new AbortController,deadline:this.options.now()+M.totalMs,finalSequence:null,nextBefore:null,phase:`reading`};this.request=this.reading=n;let r;try{r=this.options.source.read({capture:t.native.capture,reported:t.native.to,before:e.before,count:e.count,signal:n.controller.signal})}catch{this.complete(n,{status:`unavailable`,reason:`changed`});return}Promise.resolve(r).then(e=>this.complete(n,e),()=>this.complete(n,{status:`unavailable`,reason:`changed`})).catch(()=>{this.open&&this.options.invalid()})}admit(e){let t=this.request;t&&e.meta.kind===`history`&&e.meta.requestId===t.id&&(t.deadline=null,e.index===e.count-1&&(t.finalSequence=e.sequence))}acknowledge(e){let t=this.request;!t||t.finalSequence===null||e<t.finalSequence||(this.anchor===t.anchor&&(t.nextBefore===null?this.anchor=null:this.anchor.before=t.nextBefore),this.finish(t))}tick(){let e=this.request;if(!(!e||e.deadline===null||this.options.now()<e.deadline)){if(e.phase===`transfer`){this.options.stalled();return}e.controller.abort(),this.finish(e,`history-unavailable`)}}get deadline(){return this.request?.deadline??null}close(){this.open=!1,this.request?.controller.abort(),this.reading?.controller.abort(),this.request=null,this.anchor=null}complete(e,t){if(this.reading===e&&(this.reading=null),!this.open||this.request!==e||this.anchor!==e.anchor||(this.tick(),this.request!==e))return;if(t.status===`reset`){this.anchor=null,this.finish(e,`history-reset`);return}if(t.status===`unavailable`||t.status===`cancelled`){this.finish(e,`history-unavailable`,t.status===`unavailable`&&t.reason===`fetch-window`?`fetch-window`:void 0);return}if(t.status!==`page`&&t.status!==`boundary`){this.options.invalid();return}if(t.status===`page`&&(!Array.isArray(t.lines)||t.lines.length>e.count)){this.options.invalid();return}let n={kind:`history`,generation:e.anchor.generation,requestId:e.id,before:e.before},r=ve({...t,...n});if(!r.ok){r.code===`history-line-too-large`?this.finish(e,r.code):this.options.invalid();return}if(!this.options.sender.offer({...n,capture:e.anchor.capture},r.bytes).accepted){this.options.invalid();return}e.phase=`transfer`,e.nextBefore=r.record.status===`page`?r.record.nextBefore:null,e.deadline=this.options.now()+M.progressMs,this.options.ready()}finish(e,t,n){this.request===e&&(this.request=null,this.latestRequest=e.id,e.deadline=null,t&&this.error(e.id,t,n))}error(e,t,n){this.options.error({type:`stream.error`,subscriptionId:this.options.subscriptionId,requestId:e,code:t,...n?{historyReason:n}:{}})}},Eo=class{delivered=null;applied=null;admit(e){if(e.index!==e.count-1)return;let t=e.meta;if(t.kind===`vt-seed`)this.delivered={generation:t.generation,capture:t.capture,offset:0},this.applied=null;else if(t.kind===`vt`&&this.delivered?.generation===t.generation){if(t.offset!==this.delivered.offset)throw Error(`Noncontiguous delivery`);let n=t.offset+e.totalBytes;if(!Number.isSafeInteger(n))throw Error(`Stream offset exhausted`);this.delivered={...this.delivered,offset:n}}}receive(e){let t=this.delivered;return t?e.generation<t.generation?`ignored`:e.generation!==t.generation||e.capture!==t.capture||e.offset>t.offset||this.applied!==null&&e.offset<this.applied.offset?`invalid`:e.offset===this.applied?.offset?`ignored`:(this.applied={...t,offset:e.offset},`advanced`):`invalid`}get boundary(){return this.delivered?{...this.delivered}:null}matches(e,t,n){return this.applied?.generation===e&&this.applied.capture===t&&this.applied.offset===n}};const Do=new TextEncoder;var Oo=class{options;sender;history;refreshHistory=!1;open=!0;sending=!1;chunkAdmitted=!1;generation=0;state=null;backlog=[];backlogBytes=0;offset=0;behind=!1;reseedRequested=!1;historyLines=2e3;extensions;negotiationPending;negotiationDeadline=null;progress=new Eo;nextProbeAt=null;probeDeadline=null;probeToken=0;probePending=!1;probeExpired=!1;status=null;controlRetryAt=null;seeded=!1;constructor(e){this.options=e,this.extensions=Rt(e.extensions,e.source.continuation?[...y,...e.source.history?[ie]:[]]:[]),this.negotiationPending=e.extensions!==void 0,this.sender=new _({subscriptionId:e.subscriptionId,sessionId:e.sessionId,now:()=>this.readClock(),newTransferId:()=>e.newTransferId(),send:e=>this.admitChunk(e)}),this.history=this.extensions.includes(`native-history-v1`)?new To({subscriptionId:e.subscriptionId,source:e.source.history,sender:this.sender,now:()=>this.readClock(),ready:()=>this.ready(),error:e=>this.sendControl(e),invalid:()=>this.close(`invalid-transfer`),stalled:()=>this.close(`stalled`)}):null,this.history&&e.source.history.enable();let{source:t}=e;t.on(`seed`,r=>{if(!this.open)return;let i=this.extensions.length>0;if(i&&!r.continuation){this.close(`invalid-transfer`);return}let a=this.refreshHistory,o=a||r.continuation?.reason===`herdr-idle`,s=this.seeded||e.retained===!0,c=this.history&&(!s||o)?r.nativeHistory:void 0,l=c?n(r.cols,c.lines.map(e=>e.r.map(e=>e.t).join(``))):null,u=Do.encode(i&&s&&!o?r.continuation.data:l?c.replay:r.data);if(u.length>M.screenBytes){this.history?.retire(),this.historyLines>1?(this.historyLines=Math.max(1,Math.floor(this.historyLines/2)),t.reseed(this.historyLines)):this.close(`invalid-transfer`);return}this.generation=r.generation;let d=i?e.newTransferId():void 0;d&&this.history?.bind(d,r.generation,l?c:void 0);let f={generation:r.generation,cols:r.cols,rows:r.rows};this.state={meta:i?{kind:`vt-seed`,...f,capture:d,disposition:s?o?`replace`:`discontinuity`:`initial`,reason:s?o?a?`refresh`:`herdr-idle`:this.seeded?this.behind?`overflow`:r.continuation.reason:`reconnect`:`start`,cursor:t.continuation.cursor,alternate:t.continuation.alternate,...l?{historyBefore:c.from,historyRows:c.lines.length,historyProof:l}:{}}:{kind:`vt-state`,...f},bytes:u},this.status=null,i&&!this.probePending&&(this.nextProbeAt=this.readClock()+2e3),this.backlog=[],this.backlogBytes=0,this.offset=0,this.behind=!1,this.reseedRequested=!1,this.ready()}),t.on(`bytes`,(e,t)=>{if(e.length!==0&&this.open&&!this.behind&&t===this.generation){if(this.backlogBytes+e.length>262144){this.behind=!0,this.backlog=[],this.backlogBytes=0,this.ready();return}this.backlog.push(new Uint8Array(e)),this.backlogBytes+=e.length,this.status=null,this.extensions.length&&!this.probePending&&(this.nextProbeAt=this.readClock()+2e3),this.ready()}}),t.on(`end`,e=>this.close(ko(e)))}start(){return this.negotiationPending&&(this.negotiationDeadline=this.readClock()+M.progressMs),this.extensions.length&&(this.nextProbeAt=this.readClock()+2e3),this.options.source.start(this.historyLines)}receive(e,t){if(!this.open||e.subscriptionId!==this.options.subscriptionId||(this.tick(),!this.open))return;if(!Number.isSafeInteger(t)||t<1||t>M.envelopeBytes||!Pe.safeParse(e).success){this.close(`invalid-transfer`);return}if(e.type===`stream.cancel`){this.cancel();return}if(e.type===`stream.refresh`){e.history&&this.history&&(this.refreshHistory=!0),this.requestReseed();return}if(e.type===`stream.history.get`){if(this.history){this.history.receive(e);return}this.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,requestId:e.requestId,code:`history-unavailable`});return}if(e.type===`stream.applied`){this.negotiationPending||this.extensions.length===0||this.progress.receive(e)===`invalid`?this.close(`invalid-transfer`):this.history?.applied(e.capture,e.generation);return}if(e.type!==`stream.ack`){this.close(`invalid-transfer`);return}let n;try{n=this.sender.acknowledge(e.subscriptionId,e.through)}catch{this.close(`invalid-transfer`);return}n===`invalid`?this.close(`invalid-transfer`):n===`advanced`&&(this.history?.acknowledge(e.through),this.ready())}sendOne(){if(this.sending||(this.tick(),!this.open))return!1;this.sending=!0;try{let e=this.flushControl();return e===`ready`?(this.sender.canOffer(`vt`)&&this.offerNext(),this.open?(this.sender.pump(),this.reconcileSender(),this.history?.tick(),this.chunkAdmitted):!1):e===`sent`}catch{return this.close(`invalid-transfer`),!1}finally{this.chunkAdmitted=!1,this.sending=!1}}tick(){if(this.open)try{this.reconcileSender(),this.open&&this.history?.tick(),this.negotiationDeadline!==null&&this.readClock()>=this.negotiationDeadline&&this.close(`stalled`),this.open&&this.probe()}catch{this.close(`invalid-transfer`)}}nextDeadline(){if(!this.open)return null;let e=[this.sender.nextDeadline(),this.nextProbeAt,this.probeDeadline,this.controlRetryAt,this.negotiationDeadline,this.history?.deadline??null].filter(e=>e!==null);return e.length?Math.min(...e):null}cancel(){this.close(`cancelled`)}terminate(e){this.close(e)}offerNext(){if(this.state){let{meta:e,bytes:t}=this.state;this.sender.offer(e,t).accepted&&(e.kind===`vt-seed`&&e.disposition===`replace`&&e.reason===`refresh`&&(this.refreshHistory=!1),this.state=null,this.seeded=!0);return}if(this.behind){this.requestReseed();return}if(this.backlogBytes===0)return;let e=new Uint8Array(this.backlogBytes),t=0;for(let n of this.backlog)e.set(n,t),t+=n.length;this.sender.offer({kind:`vt`,generation:this.generation,offset:this.offset},e).accepted&&(this.offset+=e.length,this.backlog=[],this.backlogBytes=0)}requestReseed(){this.reseedRequested||(this.reseedRequested=!0,this.options.source.reseed(this.historyLines))}ready(){try{this.options.onReady()}catch{}}readClock(){let e=this.options.now();if(!Number.isFinite(e))throw Error(`Invalid vt stream clock`);return e}reconcileSender(){let e=this.sender.tick();this.open&&e!==`open`&&this.close(e===`stalled`?`stalled`:`invalid-transfer`)}admitChunk(e){if(!this.open||this.chunkAdmitted)return!1;let t=this.options.sendChunk(e);return t&&(this.chunkAdmitted=!0,this.history?.admit(e),this.extensions.length&&this.progress.admit(e)),t}flushControl(){let e=this.negotiationPending?{type:`stream.accepted`,subscriptionId:this.options.subscriptionId,extensions:this.extensions}:this.status;if(!e)return this.controlRetryAt=null,`ready`;if(this.controlRetryAt!==null&&this.readClock()<this.controlRetryAt)return this.negotiationPending?`blocked`:`ready`;let t=!1;try{t=this.options.sendControl(e)===!0}catch{}return t?(this.controlRetryAt=null,this.negotiationPending?(this.negotiationPending=!1,this.negotiationDeadline=null):this.status===e&&(this.status=null),`sent`):(this.controlRetryAt=this.readClock()+100,this.negotiationPending?`blocked`:`ready`)}probe(){if(!this.extensions.length)return;let e=this.readClock();if(this.probeDeadline!==null&&e>=this.probeDeadline&&(this.probeDeadline=null,this.probeExpired=!0,this.publishStatus(`paused`)),this.probePending||this.nextProbeAt===null||e<this.nextProbeAt)return;this.nextProbeAt=null,this.probeDeadline=e+2e3,this.probePending=!0,this.probeExpired=!1;let t=++this.probeToken;Promise.resolve().then(()=>this.options.source.continuation.probe()).then(e=>{if(!this.open||t!==this.probeToken)return;if(this.probePending=!1,this.probeDeadline=null,this.nextProbeAt=this.readClock()+2e3,this.probeExpired){this.ready();return}let n=e.quiescent&&e.generation===this.generation&&!this.state&&!this.behind&&this.backlogBytes===0&&this.sender.canOffer(`vt`);this.publishStatus(n?`quiescent`:`catching-up`)},()=>{this.open&&t===this.probeToken&&(this.probePending=!1,this.probeDeadline=null,this.nextProbeAt=this.readClock()+2e3,this.publishStatus(`paused`))}).catch(()=>{this.open&&t===this.probeToken&&this.close(`invalid-transfer`)})}publishStatus(e){let t=this.progress.boundary;t&&(this.status={type:`stream.status`,subscriptionId:this.options.subscriptionId,...t,state:e}),this.ready()}sendControl(e){try{this.options.sendControl(e)}catch{}}close(e){if(this.open){this.open=!1,++this.probeToken,this.status=null,this.negotiationDeadline=null,this.probeDeadline=null,this.nextProbeAt=null,this.controlRetryAt=null,this.sender.cancel(),this.history?.close(),this.state=null,this.backlog=[],this.backlogBytes=0,this.options.source.close(),e!==`cancelled`&&this.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,code:e});try{this.options.onClosed(e)}catch{}}}};function ko(e){return e===`pane-gone`?`session-gone`:e===`herdr-unreadable`?`stalled`:`unsupported`}const Ao=.6;var jo=class{opts;offerPrepared(e,t){if(this.opts.delivery!==`scheduled`||this.stopped)return!1;let n=this.viewerSession.get(e);if(!n)return!1;let r=this.sessions.get(n),i=r?.viewers.get(e),a=r?.prepared;if(!r||!i||!a||i.offering)return!1;if(i.needsHistory&&!a.historyViewers.has(i))return r.dirty=!0,!1;if(i.lastSentGen===a.gen&&!i.forceSnapshot)return!1;let o=()=>!this.stopped&&this.sessions.get(n)===r&&r.prepared===a&&r.viewers.get(e)===i;i.offering=!0;try{let e=i.preparation===`bounded`,n=!e&&i.skipped>=3,r=i.lastSentGen===a.gen-1&&!i.forceSnapshot&&!a.forceSnapshotAll&&!n,s=t(r?a.diff:e?a.fullSnapshot():a.snapshotFor(n),r?a.diffContext:a.snapshotContext);if(s!==!0&&s!==!1)throw Mo(s),TypeError(`scheduled screen offer requires a synchronous boolean`);return s===!0?(o()&&(i.lastSentGen=a.gen,i.forceSnapshot=!1,i.skipped=0,r||(i.needsHistory=!1)),!0):(o()&&(i.forceSnapshot=!0),!1)}catch{throw o()&&(i.forceSnapshot=!0),TypeError(`scheduled screen offer failed`)}finally{i.offering=!1}}sessions=new Map;sessionOffset=0;scheduledCycle=0;lastReadinessCycle=0;viewerSession=new Map;budget;unsubscribe=null;timer=null;intervalMs;stopped=!0;watchedKey=``;now;log;constructor(e){this.opts=e,this.intervalMs=Math.max(125,e.intervalMs??125),this.now=e.now??(()=>Date.now()),this.log=e.log.child({unit:`tracker`}),this.budget={tokens:0,last:this.now()}}start(){this.timer||=(this.stopped=!1,this.unsubscribe??=this.opts.backend.on(e=>{e.type===`screen-changed`||e.type===`input-accepted`?this.markDirty(e.sessionId):e.type===`session-removed`&&this.sessionRemoved(e.sessionId)}),setInterval(()=>void this.tick(),this.intervalMs))}stop(){this.stopped=!0;for(let e of this.sessions.values())e.prepared=null,e.inflightViewers?.clear(),e.inflightViewers=null,e.viewers.size>0&&(e.dirty=!0);this.timer&&clearInterval(this.timer),this.timer=null,this.unsubscribe?.(),this.unsubscribe=null,this.watchedKey=`stopped`;try{this.opts.backend.setWatched?.([])}catch(e){this.log.warn(`setWatched failed`,{err:N(e)})}}setIntervalMs(e){let t=Math.max(125,e);t!==this.intervalMs&&(this.intervalMs=t,this.timer&&=(clearInterval(this.timer),setInterval(()=>void this.tick(),this.intervalMs)))}setViewed(e,t,n){if(t){let e=n?.preparation===void 0?`legacy`:n.preparation;if(e!==`legacy`&&e!==`bounded`)throw TypeError(`invalid screen preparation`);if(e===`bounded`&&this.opts.delivery!==`scheduled`)throw TypeError(`bounded screen preparation requires scheduled delivery`)}let r=this.viewerSession.get(e);if(r){let t=this.sessions.get(r),n=t?.viewers.get(e);n&&(t?.prepared?.historyViewers.delete(n),t?.inflightViewers?.delete(n)),t?.viewers.delete(e),t?.viewers.size===0&&(t.prepared=null,t.inflightViewers=null,this.retireUnused(r,t)),this.viewerSession.delete(e)}if(t){let r=this.state(t);r.viewers.set(e,{lastSentGen:-1,forceSnapshot:!0,skipped:0,needsHistory:n?.history===!0,offering:!1,preparation:n?.preparation??`legacy`}),r.dirty=!0,this.viewerSession.set(e,t)}this.pushWatched()}dropViewer(e){this.setViewed(e,null)}viewedBy(e){return[...this.sessions.get(e)?.viewers.keys()??[]]}markDirty(e){let t=this.sessions.get(e);t&&t.viewers.size>0&&(t.dirty=!0)}forceSnapshot(e,t){let n=this.sessions.get(t)?.viewers.get(e);n&&(n.forceSnapshot=!0,this.sessions.get(t).dirty=!0)}sessionRemoved(e){let t=this.sessions.get(e);if(t&&(t.prepared=null,t.inflightViewers?.clear(),t.inflightViewers=null),!t)return;let n=[...t.viewers.keys()];for(let e of n)this.viewerSession.delete(e);this.sessions.delete(e),this.pushWatched();try{Mo(this.opts.onSessionGone?.(e,n))}catch{}}pushWatched(){let e=[...this.sessions.entries()].filter(([,e])=>e.viewers.size>0).map(([e])=>e).sort(),t=e.join(` `);if(t!==this.watchedKey){this.watchedKey=t;try{this.opts.backend.setWatched?.(e)}catch(e){this.log.warn(`setWatched failed`,{err:N(e)})}}}retireUnused(e,t){t.viewers.size===0&&!t.inflight&&t.lastBackendScrollback===null&&this.sessions.get(e)===t&&this.sessions.delete(e)}state(e){let t=this.sessions.get(e);return t||(t={viewers:new Map,dirty:!1,inflight:!1,lastKeys:[],lastCols:0,lastRows:0,lastCursor:null,lastBackendScrollback:null,reported:0,gen:0,rrOffset:0,oversizeWarned:!1,prepared:null,inflightViewers:null},this.sessions.set(e,t)),t}async tick(){if(this.opts.delivery===`scheduled`){this.tickScheduled();return}let e=[...this.sessions.entries()];if(e.length===0)return;let t=this.sessionOffset%e.length,n=e.slice(t).concat(e.slice(0,t));for(let t of n){let[n,r]=t;if(this.stopped)return;if(r.viewers.size===0&&this.retireUnused(n,r),r.inflight||r.viewers.size===0)continue;if(r.dirty){r.inflight=!0,r.dirty=!1;let e=new Set([...r.viewers.values()].filter(e=>e.needsHistory)),t=e.size>0;r.inflightViewers=e;let i;try{i=t?await this.opts.backend.getScreen(n,{history:!0}):await this.opts.backend.getScreen(n)}catch(t){if(!this.stopped&&this.sessions.get(n)===r&&r.inflightViewers===e){if(t instanceof A)this.log.warn(`getScreen: session gone; dropping`,{session:n.slice(0,12)}),this.sessionRemoved(n);else{this.opts.onCaptureResult?.(n,t),this.log.warn(`getScreen failed; will retry`,{session:n.slice(0,12),err:N(t)});for(let e of r.viewers.values())e.forceSnapshot=!0;r.dirty=!0}}r.inflightViewers=null,r.inflight=!1;continue}if(this.stopped||this.sessions.get(n)!==r||r.inflightViewers!==e){r.inflight=!1;continue}this.opts.onCaptureResult?.(n);try{this.processScreen(n,r,i,e,t)}catch(e){this.log.error(`processScreen threw; will resync every viewer next tick`,{session:n.slice(0,12),err:N(e)});for(let e of r.viewers.values())e.forceSnapshot=!0;r.dirty=!0;continue}finally{r.inflightViewers=null,r.inflight=!1}}let i=!1;try{i=this.deliver(n,r)}catch(e){i=!0,this.log.error(`screen delivery threw; will retry prepared generation`,{session:n.slice(0,12),err:N(e)})}i&&(this.sessionOffset=(e.indexOf(t)+1)%e.length)}}tickScheduled(){let e=[...this.sessions.entries()];if(e.length===0)return;let t=this.sessionOffset%e.length,n=++this.scheduledCycle,r=(t+1)%e.length;for(let i of e.slice(t).concat(e.slice(0,t))){let[e,t]=i;if(this.stopped)return;t.viewers.size===0&&this.retireUnused(e,t),!(t.inflight||t.viewers.size===0)&&(t.dirty?this.captureScheduled(e,t,n,r):this.notifyScheduled(e,t,n,r))}}async captureScheduled(e,t,n,r){t.inflight=!0,t.dirty=!1;let i=new Set([...t.viewers.values()].filter(e=>e.needsHistory));t.inflightViewers=i;try{let n=i.size>0?await this.opts.backend.getScreen(e,{history:!0}):await this.opts.backend.getScreen(e);if(this.stopped||this.sessions.get(e)!==t||t.inflightViewers!==i)return;this.opts.onCaptureResult?.(e);try{this.processScreen(e,t,n,i,i.size>0)}catch{this.log.error(`processScreen failed; will resync prepared screen`);for(let e of t.viewers.values())e.forceSnapshot=!0;t.dirty=!0;return}}catch(n){if(this.stopped||this.sessions.get(e)!==t||t.inflightViewers!==i)return;if(n instanceof A)this.sessionRemoved(e);else{this.opts.onCaptureResult?.(e,n),this.log.warn(`getScreen failed; will retry`,{session:e.slice(0,12),err:N(n)});for(let e of t.viewers.values())e.forceSnapshot=!0;t.dirty=!0}return}finally{t.inflightViewers=null,t.inflight=!1}this.notifyScheduled(e,t,n,r)}notifyScheduled(e,t,n,r){if(this.opts.delivery!==`scheduled`||this.stopped)return;let i=t.prepared;if(!i||this.sessions.get(e)!==t)return;let a=[...t.viewers.entries()].filter(([,e])=>e.needsHistory&&!i.historyViewers.has(e)?(t.dirty=!0,!1):e.lastSentGen!==i.gen||e.forceSnapshot);if(a.length!==0){try{Mo(this.opts.onReady(e))}catch{this.log.error(`scheduled screen readiness failed`)}for(let[n,r]of a)!this.stopped&&this.sessions.get(e)===t&&t.prepared===i&&t.viewers.get(n)===r&&(r.lastSentGen!==i.gen||r.forceSnapshot)&&(r.skipped+=1);n>this.lastReadinessCycle&&(this.lastReadinessCycle=n,this.sessionOffset=r)}}processScreen(e,t,n,r,i){if(t.viewers.size===0)return;let a=this.opts.backend.capabilitiesOf?.(e)?.absoluteLines??this.opts.backend.capabilities.absoluteLines,o=n.lines.map(ke),s=n.rows,c=0,l=!1,u=t.lastKeys.length===0||t.lastCols!==n.cols||t.lastRows!==n.rows;if(t.lastBackendScrollback===null)t.reported=n.scrollbackTotal;else{let e=n.scrollbackTotal-t.lastBackendScrollback;if(e<0)l=!0,u=!0,t.reported=n.scrollbackTotal;else if(e>=s)u=!0,t.reported+=e;else if(e>0)c=e,t.reported+=e;else if(!a&&!u&&No(o,t.lastKeys,0)>Ao*s){let e=Po(o,t.lastKeys,s);e>0&&(c=e,t.reported+=e)}}t.lastBackendScrollback=n.scrollbackTotal,this.opts.backend.setReported?.(e,t.reported);let d=[];if(!u){for(let e=0;e<s;e++){let r=e+c<t.lastKeys.length?t.lastKeys[e+c]:void 0;(r===void 0||r!==o[e])&&d.push({i:e,line:n.lines[e]})}d.length>Ao*s&&(u=!0)}let f=!t.lastCursor||t.lastCursor.x!==n.cursor.x||t.lastCursor.y!==n.cursor.y,p=!u&&c===0&&d.length===0&&!f;p||(t.gen+=1);let m=p&&t.prepared?.gen===t.gen&&![...r].some(e=>e.needsHistory),h=this.opts.delivery===`scheduled`&&p&&t.prepared?.gen===t.gen?t.prepared:null;if(t.lastKeys=o,t.lastCols=n.cols,t.lastRows=n.rows,t.lastCursor=n.cursor,m)return;let g={sessionId:e,cursor:n.cursor,scrollbackTotal:t.reported,gen:t.gen},_=this.opts.maxEncodedBytes??262144,v,y,b,x=()=>(v??={type:`screen.snapshot`,...g,cols:n.cols,rows:n.rows,lines:n.lines,reset:l||void 0},v),S=()=>{if(!b&&(b={...x(),lines:n.lines.map(ae),degraded:!0},!t.oversizeWarned)){let n=j(b).byteLength;n>_&&(this.log.warn(`screen.snapshot exceeds maxEncodedBytes even after stripStyles`,{session:e.slice(0,12),bytes:n,maxEncodedBytes:_}),t.oversizeWarned=!0)}return b},C=e=>e?S():(y??=j(x()).byteLength,y>_?S():x()),ee={type:`screen.diff`,...g,scroll:c,changed:d},w=Object.freeze({generation:t.gen,reported:t.reported,historyRequested:i}),te=Object.freeze({...w,...n.historyCapture?{capture:n.historyCapture}:{}});t.prepared={gen:t.gen,diff:h?.diff??ee,forceSnapshotAll:h?.forceSnapshotAll??(u||p),snapshotFor:C,fullSnapshot:x,snapshotContext:te,diffContext:h?.diffContext??w,historyViewers:r}}deliver(e,t){if(this.opts.delivery===`scheduled`)return!1;let n=t.prepared;if(!n||t.viewers.size===0)return!1;let r=()=>!this.stopped&&this.sessions.get(e)===t&&t.prepared===n,{gen:i,diff:a,forceSnapshotAll:o,snapshotFor:s}=n,c=!1,l=[...t.viewers.entries()],u=l.length,d=t.rrOffset%u,f=l.slice(d).concat(l.slice(0,d)).map((e,t)=>({entry:e,idx:t})).sort((e,t)=>t.entry[1].skipped-e.entry[1].skipped||e.idx-t.idx).map(e=>e.entry);t.rrOffset=(t.rrOffset+1)%u;for(let[e,l]of f){if(!r())break;if(t.viewers.get(e)!==l)continue;if(l.needsHistory&&!n.historyViewers.has(l)){t.dirty=!0;continue}if(l.lastSentGen===i&&!l.forceSnapshot)continue;if(!this.spend()){l.skipped+=1;continue}c=!0;let u=l.skipped>=3,d=l.lastSentGen===i-1&&!l.forceSnapshot&&!o&&!u;try{let i=d?a:s(u),o=this.opts.sink(e,i,d?n.diffContext:n.snapshotContext);if(!r())break;if(t.viewers.get(e)!==l)continue;if(o===!1){l.skipped+=1,l.forceSnapshot=!0;continue}}catch(n){if(!r())break;if(t.viewers.get(e)!==l)continue;l.skipped+=1,l.forceSnapshot=!0,this.log.error(`screen sink threw; will retry prepared generation`,{conn:e.slice(0,12),err:N(n)});continue}l.lastSentGen=i,l.forceSnapshot=!1,l.skipped=0,d||(l.needsHistory=!1)}return c}spend(){let e=this.opts.maxFramesPerSecond??40,t=this.now(),n=Math.max(0,t-this.budget.last);return this.budget.tokens=Math.min(e,this.budget.tokens+n*e/1e3),this.budget.last=t,this.budget.tokens<1?!1:(--this.budget.tokens,!0)}};function Mo(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}function No(e,t,n){let r=0;for(let i=0;i<e.length;i++)t[i+n]!==e[i]&&r++;return r}function Po(e,t,n){for(let r=1;r<=Math.min(n-1,16);r++){let i=n-r;if(i<=0)break;let a=0;for(let n=0;n<i;n++)e[n]===t[n+r]&&a++;if(a>=.8*i)return r}return 0}var Fo=class{now;rate;onError;registrations=new Map;ownership={};pumping=!1;tokens=0;last;constructor(e){if(this.now=e.now,this.rate=e.maxFramesPerSecond??40,this.onError=e.onError,!Number.isSafeInteger(this.rate)||this.rate<=0)throw RangeError(`wire scheduler rate must be a positive safe integer`);this.last=this.readClock()}register(e,t,n=`terminal`){if(e.length===0)throw RangeError(`wire scheduler key must not be empty`);if(n!==`terminal`&&n!==`background`)throw RangeError(`invalid wire scheduler priority`);let r=Symbol(),i={identity:r,sendOne:t,priority:n};return this.registrations.set(e,i),()=>this.remove(e,r)}pump(){if(this.pumping)return 0;this.pumping=!0;try{this.refill();let e=this.ownership,t=[...this.registrations],n=t.filter(([,e])=>e.priority===`terminal`),r=new Set(n.map(([,e])=>e)),i=t.filter(([,e])=>e.priority===`background`),a=n,o=0;for(;this.tokens>=1&&this.ownership===e;){if(a.length===0){let e=i.shift();if(!e)break;let[t,n]=e;if(this.registrations.get(t)!==n)continue;this.offer(t,n)&&(o++,i.push(e)),a=[...this.registrations].filter(([,e])=>r.has(e));continue}let t=[];for(let[n,r]of a){if(this.tokens<1||this.ownership!==e)break;this.registrations.get(n)===r&&this.offer(n,r)&&(o++,t.push([n,r]))}a=t}return o}finally{this.pumping=!1}}nextBudgetAt(){return this.pumping||this.refill(),this.registrations.size===0||this.tokens>=1?null:this.last+(1-this.tokens)*1e3/this.rate}clear(){this.registrations.clear(),this.ownership={}}remove(e,t){this.registrations.get(e)?.identity===t&&this.registrations.delete(e)}offer(e,t){this.registrations.delete(e),this.registrations.set(e,t),--this.tokens;try{let e=t.sendOne();if(e===!0)return!0;if(e===!1)this.tokens+=1;else throw Io(e),TypeError(`wire producer must return a synchronous boolean`)}catch(n){this.remove(e,t.identity);try{Io(this.onError?.(n))}catch{}}return!1}readClock(){let e=this.now();if(!Number.isFinite(e))throw RangeError(`wire scheduler clock must be finite`);return e}refill(){let e=Math.max(this.last,this.readClock());this.tokens=Math.min(this.rate,this.tokens+(e-this.last)*this.rate/1e3),this.last=e}};function Io(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}var Lo=class{options;tracker;scheduler;entries=new Map;viewerOwners=new Map;attachTokens=new Map;herdrCaptureFailures=new Map;started=!1;lifecycle=0;pumping=!1;timer=null;timerEpoch=0;nextViewer=0;constructor(e){if(!(e.backend instanceof re))throw TypeError(`Service view backend must be a BackendRegistry`);if(!Number.isFinite(e.now()))throw RangeError(`Service view clock must be finite`);this.options={...e},this.scheduler=new Fo({now:()=>this.options.now(),onError:()=>this.notifyError()}),this.tracker=new jo({backend:this.options.backend,log:this.options.log,now:()=>this.options.now(),delivery:`scheduled`,onReady:()=>{this.pump()},onSessionGone:(e,t)=>this.sessionGone(e,t),onCaptureResult:(e,t)=>this.captureResult(e,t)})}start(){if(!this.started){if(!Number.isFinite(this.options.now()))throw RangeError(`Service view clock must be finite`);this.lifecycle++,this.started=!0,this.tracker.start()}}stop(){if(!this.started)return;this.lifecycle++,this.started=!1,this.clearTimer();for(let e of this.herdrCaptureFailures.values())clearTimeout(e);this.herdrCaptureFailures.clear();let e=[...this.entries.values()];this.entries.clear();for(let t of e)t.unregister(),this.dropBackground(t);this.tracker.stop();for(let t of e)this.dropView(t)}attach(e,t){if(!this.started)throw TypeError(`Service view coordinator is stopped`);if(typeof e!=`string`||e.length===0||e.length>256||!t)throw TypeError(`Invalid service view connection`);if(!this.entries.has(e)&&this.entries.size>=10)throw RangeError(`Too many service view connections`);let n=this.lifecycle,r={};this.attachTokens.set(e,r);try{let i=this.entries.get(e);i&&this.retire(i);let a={id:e,connection:{...t},view:null,closingView:null,unregister:()=>{},background:null,revision:0};if(this.started&&this.lifecycle===n&&this.attachTokens.get(e)===r&&!this.entries.has(e)){if(this.entries.size>=10)throw RangeError(`Too many service view connections`);this.entries.set(e,a),a.unregister=this.scheduler.register(`terminal:${e}`,()=>this.produce(a))}let o=this;return{get viewedSessionId(){return o.current(a)?a.view?.sessionId??null:null},receive:(e,t)=>this.receive(a,e,t),background:e=>this.background(a,e),close:()=>this.retire(a)}}finally{this.attachTokens.get(e)===r&&this.attachTokens.delete(e)}}setIntervalMs(e){if(!Number.isFinite(e))throw TypeError(`Invalid service view interval`);this.tracker.setIntervalMs(e)}pump(){if(!this.started||this.pumping)return 0;this.pumping=!0;let e=0;try{if(!Number.isFinite(this.options.now()))throw RangeError(`Service view clock must be finite`);for(let e of[...this.entries.values()])this.current(e)&&e.view&&e.view.stream.tick();return this.started&&(e=this.scheduler.pump()),e}catch{return this.stop(),this.notifyError(),0}finally{this.pumping=!1,this.arm()}}current(e){return this.started&&this.entries.get(e.id)===e}background(e,t){if(typeof t!=`function`)throw TypeError(`Invalid background producer`);if(!this.current(e))return{wake(){},close(){}};this.dropBackground(e);let n={producer:t,unregister:null,ready:!1,revision:{}};e.background=n;let r=()=>this.current(e)&&e.background===n,i=()=>{if(!r()||!n.ready||!n.producer)return!1;let e=n.revision;try{let t=n.producer();return t===!1&&e===n.revision&&this.suspendBackground(n),typeof t!=`boolean`&&(this.suspendBackground(n),n.producer=null),t}catch(e){throw this.suspendBackground(n),n.producer=null,e}};return this.arm(),{wake:()=>{r()&&n.producer&&(n.revision={},n.ready=!0,n.unregister??=this.scheduler.register(`background:${e.id}`,i,`background`),this.pump())},close:()=>{e.background===n&&(this.dropBackground(e),this.arm())}}}dropBackground(e){let t=e.background;t&&(e.background=null,this.suspendBackground(t),t.producer=null)}suspendBackground(e){e.ready=!1;let t=e.unregister;e.unregister=null,t?.()}receive(e,t,n){if(!this.current(e))return;let r=e.revision,i=e.view,a=null;try{if(Number.isSafeInteger(n)&&n>=1&&n<=M.envelopeBytes){let e=Pe.safeParse(t);e.success&&(a=e.data)}}catch{}if(this.current(e)&&e.revision===r&&e.view===i){if(!a){i?.stream.terminate(`invalid-transfer`);return}if(a.type===`stream.subscribe`){let t=e.view;if(t&&t.subscriptionId===a.subscriptionId){t.sessionId!==a.sessionId&&t.stream.terminate(`invalid-transfer`);return}let n=++e.revision;if(this.dropView(e),!this.current(e)||e.revision!==n)return;let r={sessionId:a.sessionId,subscriptionId:a.subscriptionId,trackerKey:this.viewerKey(),stream:null};if(a.mode===`vt`&&this.openVtView(e,r,n,a.extensions,a.retained))return;if(r.stream=new Co({subscriptionId:r.subscriptionId,sessionId:r.sessionId,now:()=>this.options.now(),newTransferId:()=>this.options.newTransferId(),sendChunk:t=>this.current(e)&&e.view===r&&e.connection.sendChunk(t),sendControl:t=>this.current(e)&&(e.view===r||e.closingView===r)&&e.connection.sendControl(t),requestSnapshot:()=>{this.current(e)&&e.view===r&&this.tracker.forceSnapshot(r.trackerKey,r.sessionId)},onClosed:()=>{this.current(e)&&e.view===r&&this.dropView(e)},history:{read:(e,t)=>this.options.backend.getHistoryPage(e,t),onReady:()=>{this.current(e)&&e.view===r&&this.pump()}}}),!this.current(e)||e.revision!==n){r.stream.cancel();return}if(e.view=r,this.viewerOwners.set(r.trackerKey,{entry:e,view:r}),this.tracker.setViewed(r.trackerKey,r.sessionId,{history:!0,preparation:`bounded`}),!this.current(e)||e.revision!==n||e.view!==r)return;this.arm();return}if(i?.subscriptionId===a.subscriptionId){try{i.stream.receive(t,n)}catch{this.current(e)&&e.revision===r&&e.view===i&&i.stream.terminate(`invalid-transfer`)}this.pump()}}}openVtView(e,t,n,r,i){if(!this.options.backend.capabilitiesOf(t.sessionId)?.vtStream)return!1;let a;try{a=new Oo({subscriptionId:t.subscriptionId,sessionId:t.sessionId,source:this.options.backend.openVtStream(t.sessionId),extensions:r,retained:i,now:()=>this.options.now(),newTransferId:()=>this.options.newTransferId(),sendChunk:n=>this.current(e)&&e.view===t&&e.connection.sendChunk(n),sendControl:n=>this.current(e)&&(e.view===t||e.closingView===t)&&e.connection.sendControl(n),onReady:()=>{this.current(e)&&e.view===t&&this.pump()},onClosed:()=>{this.current(e)&&e.view===t&&this.dropView(e)}})}catch{return!1}return!this.current(e)||e.revision!==n?(a.cancel(),!0):(t.stream=a,e.view=t,this.viewerOwners.set(t.trackerKey,{entry:e,view:t}),a.start().catch(()=>a.terminate(`invalid-transfer`)),this.arm(),!0)}produce(e){if(!this.current(e))return!1;try{let t=e.view;return!t||(t.stream instanceof Co&&t.stream.canOfferScreen()&&this.tracker.offerPrepared(t.trackerKey,(e,n)=>e.type!==`screen.snapshot`&&e.type!==`screen.diff`?!1:t.stream instanceof Co&&t.stream.offer(e,n)),!this.current(e)||e.view!==t)?!1:t.stream.sendOne()}catch{throw this.retire(e),Error(`Service view producer failed`)}}viewerKey(){return`service-view-${++this.nextViewer}`}dropView(e){let t=e.view;t&&(e.view=null,this.viewerOwners.get(t.trackerKey)?.view===t&&this.viewerOwners.delete(t.trackerKey),this.tracker.dropViewer(t.trackerKey),t.stream.cancel())}retire(e){this.entries.get(e.id)===e&&(this.entries.delete(e.id),e.unregister(),this.dropBackground(e),this.dropView(e),this.arm())}captureResult(e,t){if(yt(e)?.name!==`herdr`)return;let n=this.herdrCaptureFailures.get(e);if(t===void 0){n&&clearTimeout(n),this.herdrCaptureFailures.delete(e);return}if(n||!this.started)return;let r=[...this.entries.values()].flatMap(t=>{let n=t.view;return n&&n.sessionId===e&&this.current(t)&&n.stream instanceof Co&&n.stream.hasAcceptedSnapshot()?[{entry:t,view:n,stream:n.stream}]:[]});if(r.length===0)return;let i=setTimeout(()=>{if(this.herdrCaptureFailures.get(e)===i){this.herdrCaptureFailures.delete(e);for(let{entry:e,view:t,stream:n}of r)this.current(e)&&e.view===t&&n.terminate(`stalled`)}},3e3);i.unref?.(),this.herdrCaptureFailures.set(e,i)}sessionGone(e,t){let n=this.herdrCaptureFailures.get(e);n&&clearTimeout(n),this.herdrCaptureFailures.delete(e);let r=[];for(let n of t){let t=this.viewerOwners.get(n);t&&t.view.sessionId===e&&this.current(t.entry)&&t.entry.view===t.view&&(this.viewerOwners.delete(n),t.entry.view=null,r.push(t))}for(let{entry:e,view:t}of r)e.closingView=t,t.stream.terminate(`session-gone`),e.closingView===t&&(e.closingView=null);if(r.length>0)try{Ro(this.options.onSessionGone?.(e))}catch{}this.arm()}notifyError(){try{Ro(this.options.onError?.())}catch{}}clearTimer(){this.timerEpoch++,this.timer&&clearTimeout(this.timer),this.timer=null}arm(){if(this.clearTimer(),this.started)try{let e=[...this.entries.values()].flatMap(e=>e.view?[e.view]:[]);if(e.length===0&&![...this.entries.values()].some(e=>e.background?.ready))return;let t=this.options.now();if(!Number.isFinite(t))throw RangeError(`Service view clock must be finite`);let n=[this.scheduler.nextBudgetAt(),...e.map(e=>e.stream.nextDeadline())],r=25;for(let e of n)e!==null&&e>t&&(r=Math.min(r,e-t));let i=this.timerEpoch;this.timer=setTimeout(()=>{this.started&&i===this.timerEpoch&&(this.timer=null,this.pump())},Math.max(1,r))}catch{this.stop(),this.notifyError()}}};function Ro(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}function zo(e){return`no conn.hello within ${e/1e3}s; ignoring this link until one arrives`}var Bo=class{o;relay;views;conversations;viewLeases=new Map;events;notifier;notificationState;notificationRelayCapable=!1;relayWithheldTurn=!1;pairing;links=new Map;connByFp=new Map;pairings;pairRequests=new Map;sessions=[];activityPublished=0;aliveSent=0;stateSeen=new Map;tick=null;sessionsDebounce=null;sessionsDueAt=0;sessionsRefreshedAt=0;sessionsRefreshes=0;sessionsPublished=0;lastSeenSavedAt=new Map;log;localProcess;projects;stopped=!1;conversationsEnabled;get agentConversationsEnabled(){return!this.stopped&&this.conversationsEnabled}get configurationRevision(){return Te({...this.o.config,showAgentConversations:this.conversationsEnabled})}applyConversationSetting(e){if(this.stopped)throw Error(`Agent stopped`);try{return We(this.o.paths,t=>(t.showAgentConversations===!1&&this.setConversationConsent(!1),Te(t)===e?(this.setConversationConsent(t.showAgentConversations!==!1),this.configurationRevision):null))}catch(e){throw this.setConversationConsent(!1),e}}setConversationConsent(e){let t=this.conversationsEnabled!==e;this.conversationsEnabled=e,(!e||t)&&(this.conversations.consentChanged(),this.broadcast(this.helloMessage()))}backendsKey=null;constructor(e){this.o=e,e={...e,config:Object.freeze(Ft.parse(e.config))},this.o=e,this.conversationsEnabled=e.config.showAgentConversations!==!1,this.log=e.log.child({unit:`agent`}),this.pairings=At(e.paths);let t=yn();this.projects=new Xt(t,()=>{this.stopped||this.scheduleSessions()}),e.registry.onSetupChanged(()=>{this.stopped||this.scheduleSessions()}),this.localProcess={pid:process.pid,agentVersion:e.appVersion,computerFp:e.fp,stateDir:ar(e.paths.dir),serviceInstance:e.serviceInstance??null};let n=e.relayUrlOverride??e.config.relayUrl;this.relay=e.relay??new So({relayUrl:n,fp:e.fp,identity:e.identity,name:e.config.computerName,appVersion:e.appVersion,log:e.log,...e.config.turn===!1&&{turn:!1}}),this.views=new Lo({backend:e.registry,log:e.log,now:()=>Date.now(),newTransferId:()=>k(C(16)),onSessionGone:()=>this.scheduleSessions(),onError:()=>this.log.warn(`terminal-view-delivery-failed`)}),this.conversations=new go({backend:e.registry,enabled:()=>this.agentConversationsEnabled}),this.events=new Br({notifyMinCommandMs:e.config.notifyMinCommandMs,idleQuietMs:e.config.idleQuietMs,idleMinActiveMs:e.config.idleMinActiveMs}),this.notificationState=new Jr(e.paths),this.notificationState.retain(new Set(this.pairings.map(e=>e.phoneFp)));let r=new Wr({state:this.notificationState,computerFp:e.fp,computerName:()=>e.config.computerName,capable:()=>this.notificationRelayCapable,pairings:()=>this.pairings,facts:t=>e.registry.notificationFacts(t),git:t});this.notifier=new Xr(e=>this.relay.sendCtrl(e),e.log,Date.now,e=>r.prepare(e)),this.pairing=new ri({identity:e.identity,fp:e.fp,computerName:e.config.computerName,accent:e.config.accent,relayUrl:e.config.relayUrl,sendCtrl:e=>this.relay.sendCtrl(e),savePairing:e=>this.addPairing(e),relayOnline:()=>this.relay.online,confirm:e.confirm,pairingCount:()=>this.pairings.length,log:e.log,onClose:e=>this.o.onPairingClosed?.(e)}),this.relay.on(`auth-ok`,e=>{this.notificationRelayCapable=e.features?.includes(`notify-context-v1`)??!1,this.safe(`auth-ok`,()=>{this.views.setIntervalMs(Math.max(125,e.minFrameMs));let t=e.turnOff===!0;if(t&&!this.relayWithheldTurn)for(let e of[...this.links.values()])this.dropLinkFor(e.phoneFp);this.relayWithheldTurn=t,this.pairing.readvertise()})}),this.relay.on(`ctrl`,e=>this.safe(`ctrl`,()=>this.onCtrl(e))),this.relay.on(`e2e`,e=>this.safe(`e2e`,()=>this.onE2E(e))),this.relay.on(`down`,()=>{this.notificationRelayCapable=!1,this.safe(`down`,()=>{for(let e of[...this.links.values()])e.relayLost(),e.activeRoute!==`direct`&&this.dropLinkFor(e.phoneFp)})}),this.relay.on(`superseded`,()=>{this.safe(`superseded`,()=>{this.log.warn(`relay connection superseded by a newer agent instance; stopping`),this.stop(),this.o.onSuperseded?.()})}),e.registry.on(e=>this.safe(`backend-event`,()=>this.onBackendEvent(e))),this.events.on(`event`,e=>this.safe(`events-event`,()=>this.broadcast(e))),this.events.on(`ring`,e=>this.safe(`events-ring`,()=>{this.notifier.ring(e)}))}safe(e,t){try{let n=t();n&&typeof n.then==`function`&&n.catch(t=>this.logHandlerFailure(e,t))}catch(t){this.logHandlerFailure(e,t)}}logHandlerFailure(e,t){this.log.error(`handler failed`,{where:e,error:N(t)})}start(){this.stopped=!1,this.views.start(),this.relay.start(),this.tick=setInterval(()=>{this.safe(`tick`,()=>{this.events.tick(),this.pairing.tick(),this.sweepHandshakes(),this.sendAlive()})},1e3),this.safe(`refresh-sessions`,()=>this.refreshSessions())}stop(){this.stopped=!0,this.conversations.close(),this.tick&&clearInterval(this.tick),this.tick=null,this.sessionsDebounce&&clearTimeout(this.sessionsDebounce),this.sessionsDebounce=null,this.pairing.closeWindow();for(let e of this.links.values())this.closeLease(e),e.close();this.links.clear(),this.connByFp.clear(),this.views.stop(),this.pairRequests.clear(),this.relay.stop()}sweepHandshakes(){let e=Date.now();for(let t of this.links.values())t.helloOverdue(e)&&(t.dormant=!0,this.log.warn(zo(t.helloTimeoutMs),{phone:t.phoneFp.slice(0,8),conn:t.connId.slice(0,6)}))}get relayOnline(){return this.relay.online}get localStatus(){let e=this.o.registry.status();return{controlVersion:1,process:this.localProcess,backends:e,terminalReady:e.some(e=>e.connected)}}terminalSetup(){return this.o.registry.terminalSetup()}connectTerminal(e){let t=this.o.registry.connectTerminal(e);return t&&this.o.registry.notifySetupChanged(),t}get pairingList(){return this.pairings}get sessionList(){return this.sessions}get connectedPhones(){return[...this.links.values()].map(e=>({phoneFp:e.phoneFp,name:e.name,viewed:this.viewLeases.get(e)?.lease.viewedSessionId??null,transport:e.transportDiagnostics}))}linkForPhone(e){let t=this.connByFp.get(e);return t?this.links.get(t):void 0}openPairing(){return this.pairing.openWindow()}closePairing(){this.pairing.closeWindow()}get pairingOpen(){return this.pairing.tick(),this.pairing.isOpen}unpair(e){if(!e)return!1;let t=this.pairings.filter(t=>t.phoneFp.startsWith(e)||t.name===e);if(t.length>1)throw Error(`Ambiguous phone target; use a longer or complete fingerprint`);let n=t[0];return n?this.removePairing(n):!1}unpairExact(e){let t=this.pairings.find(t=>t.phoneFp===e);return t?this.removePairing(t):!1}raisePairProtocolFloor(e,t,n){let r=this.pairings.find(t=>t.phoneFp===e),i=At(this.o.paths).find(t=>t.phoneFp===e);if(!r||!i||t.length!==32)throw Error(`shellbell: pairing changed before protocol upgrade`);let a=x(i.kPair);if(a.length!==32||r.kPair!==i.kPair||r.ed25519Pub!==i.ed25519Pub||r.x25519Pub!==i.x25519Pub||!br(Buffer.from(a),Buffer.from(t)))throw Error(`shellbell: pairing changed before protocol upgrade`);let o=this.pairings.map(t=>t.phoneFp===e?{...t,minProtocolVersion:2}:t);this.pairings=vt(this.o.paths,o),n!==this.linkForPhone(e)&&this.dropLinkFor(e)}removePairing(e){let t=this.pairings.filter(t=>t!==e);return this.pairings=vt(this.o.paths,t),this.relay.sendCtrl({type:`unpair`,phoneFp:e.phoneFp}),this.retirePhone(e.phoneFp),!0}retirePhone(e){this.notificationState.forget(e),this.pairRequests.delete(e),this.dropLinkFor(e),this.lastSeenSavedAt.delete(e)}dropLinkFor(e){let t=this.connByFp.get(e);if(t===void 0)return;let n=this.links.get(t);n&&(this.closeLease(n),n.close()),this.links.delete(t),this.connByFp.delete(e)}addPairing(e){let t=this.pairings.find(t=>t.phoneFp===e.phoneFp),n=He(t,e),r=[...this.pairings.filter(t=>t.phoneFp!==e.phoneFp),n];this.pairings=vt(this.o.paths,r),t?.kPair!==e.kPair||t?.ed25519Pub!==e.ed25519Pub||t?.x25519Pub!==e.x25519Pub?this.retirePhone(e.phoneFp):this.notificationState.forget(e.phoneFp)}acceptsRelayUnpair(e,t){if(e.minProtocolVersion!==2)return!0;if(!t)return!1;try{return Xe(t,{computerFp:this.o.fp,phoneFp:e.phoneFp,kPair:x(e.kPair),phoneEd25519Pub:x(e.ed25519Pub)})}catch{return!1}}forgetPairing(e,t){let n=this.pairings.find(t=>t.phoneFp===e);if(n&&!this.acceptsRelayUnpair(n,t))return this.log.warn(`ignored unsigned or invalid relay unpair for upgraded pairing`,{phone:e.slice(0,8)}),!1;let r=this.pairings.length,i=this.pairings.filter(t=>t.phoneFp!==e);return i.length!==r&&(this.pairings=vt(this.o.paths,i)),this.retirePhone(e),!0}async onCtrl(e){switch(e.type){case`unpaired`:if(e.phoneFps.length){let t=new Map(e.proofs?.map(e=>[e.phoneFp,e])),n=(e.proofs??[]).filter(t=>{if(!e.phoneFps.includes(t.phoneFp))return!1;let n=this.pairings.find(e=>e.phoneFp===t.phoneFp);return!n||this.acceptsRelayUnpair(n,t)}),r=e.phoneFps.filter(e=>this.pairings.some(n=>n.phoneFp===e&&this.acceptsRelayUnpair(n,t.get(e))));if(r.length){let e=this.pairings.filter(e=>!r.includes(e.phoneFp));this.pairings=vt(this.o.paths,e);for(let e of r)this.retirePhone(e);this.log.info(`applied verified or legacy unpair tombstones`,{count:r.length})}for(let e of n)this.relay.sendCtrl({type:`revocation-ack`,phoneFp:e.phoneFp,pairId:e.pairId})}this.relay.sendCtrl({type:`pairings-sync`,phones:this.pairings.slice(0,10).map(e=>({phoneFp:e.phoneFp,ed25519Pub:x(e.ed25519Pub),name:e.name,pairId:Qe(x(e.kPair))}))});return;case`phones`:for(let t of e.connected)this.attach(t.phoneFp,t.connId,t.name);return;case`phone-connected`:this.attach(e.phoneFp,e.connId,e.name);return;case`phone-disconnected`:{let t=[...this.links.values()].find(t=>t.relayConnId===e.connId);if(!t||(t.relayLost(),t.activeRoute===`direct`))return;t.close(),this.closeLease(t),this.links.delete(t.connId),this.connByFp.get(t.phoneFp)===t.connId&&this.connByFp.delete(t.phoneFp);return}case`pairing-request`:await this.pairing.handleRequest(e);return;case`unpair`:this.forgetPairing(e.phoneFp,e.proof)&&e.proof&&this.relay.sendCtrl({type:`revocation-ack`,phoneFp:e.phoneFp,pairId:e.proof.pairId});return;case`error`:this.log.warn(`relay error`,{code:e.code===`too-many-pairings`?e.code:`unknown`});return;default:return}}attach(e,t,n){let r=this.pairings.find(t=>t.phoneFp===e);if(!r){this.log.warn(`relay announced an unknown phone; ignoring`,{phone:e.slice(0,8)});return}let i=this.linkForPhone(e);if(i&&!i.broken){i.relayConnId=t;return}this.dropLinkFor(e);let a=this.newV2Link(r,t,n);this.links.set(t,a),this.connByFp.set(e,t),r.lastSeenAt=new Date().toISOString();let o=Date.now();o-(this.lastSeenSavedAt.get(e)??0)>=6e4&&(this.lastSeenSavedAt.set(e,o),this.pairings=vt(this.o.paths,this.pairings))}newV2Link(e,t,n){let r=x(e.kPair),i;return i=new ui({phoneFp:e.phoneFp,connId:t,name:n,computerFp:this.o.fp,identity:this.o.identity,native:this.o.directFactory,iceServers:()=>this.relay.iceServers(),turn:this.o.config.turn!==!1,kPair:r,remoteStatic:x(e.x25519Pub),send:e=>this.relay.sendBoundedEnvelope(e),commitFloor:async()=>this.raisePairProtocolFloor(e.phoneFp,r,i),prepareReady:()=>this.pairRequests.get(e.phoneFp)?.idle!==!1,terminal:(e,t,n)=>this.safe(`v2-terminal`,()=>this.onInner(e,t,n)),ready:e=>this.onLinkReady(e),log:this.o.log}),i}onLinkReady(e){this.closeLease(e),this.ownsHandshake(e,e.handshakeGeneration)&&(this.installLease(e,e.handshakeGeneration),this.ownsHandshake(e,e.handshakeGeneration)&&(e.send(this.helloMessage()),this.ownsHandshake(e,e.handshakeGeneration)&&e.send(Pn(this.sessions))))}helloMessage(e=this.o.registry.connected()){return{type:`hello`,features:[Re,oe,Ke],conversationEnabled:this.agentConversationsEnabled,agentVersion:this.o.appVersion,hostPlatform:Vr(process.platform),backends:e.filter(e=>v.includes(e.name)),launchableBackends:this.o.registry.launchable().filter(e=>v.includes(e)),backendCatalog:this.o.registry.catalog(),sessionLaunchTargets:this.o.registry.launchTargets(),sessionLaunchIssues:this.o.registry.launchIssues(),terminalSetup:this.o.registry.terminalSetup(),computerName:this.o.config.computerName,accent:this.o.config.accent}}onE2E(e){let t=this.connByFp.get(e.from);return(t===void 0?void 0:this.links.get(t))?.handleEnvelope(e)}closeLease(e){let t=this.viewLeases.get(e);t&&(this.viewLeases.delete(e),t.conversation?.close(),t.lease.close())}installLease(e,t){let n=null,r=()=>this.ownsHandshake(e,t)&&this.viewLeases.get(e)?.lease===n;if(n=this.views.attach(e.connId,{sendChunk:t=>r()&&e.send(t),sendControl:t=>r()&&e.send(t)}),!this.ownsHandshake(e,t)){n.close();return}this.viewLeases.set(e,{generation:t,lease:n});let i=this.conversations.attach({current:r,send:t=>r()&&e.send(t),background:e=>n.background(e)}),a=this.viewLeases.get(e);a?.lease===n&&r()?a.conversation=i:i.close()}ownsHandshake(e,t){return this.links.get(e.connId)===e&&e.handshaken&&!e.broken&&e.handshakeGeneration===t}async onInner(e,t,n){let r=e.handshakeGeneration;if(this.ownsHandshake(e,r)){if(t.type.startsWith(`conversation.`)){let i=this.viewLeases.get(e);i?.generation===r&&i.conversation?.receive(t,n);return}if(t.type===`notification.enroll`){this.notificationState.enroll(e.phoneFp,t.generation,t.features)&&this.ownsHandshake(e,r)&&e.send({type:`notification.enrolled`,generation:t.generation});return}if(t.type===`stream.subscribe`||t.type===`stream.ack`||t.type===`stream.applied`||t.type===`stream.accepted`||t.type===`stream.status`||t.type===`stream.history.get`||t.type===`stream.cancel`||t.type===`stream.refresh`||t.type===`stream.chunk`||t.type===`stream.error`){let i=this.viewLeases.get(e);i?.generation===r&&(t.type===`stream.subscribe`&&i.conversation?.focus(t.sessionId),i.lease.receive(t,n));return}if(!(`reqId`in t)){await this.execute(e,t,r);return}if(Zr(t)){let n=this.pairRequests.get(e.phoneFp);n||(n=new Qr,this.pairRequests.set(e.phoneFp,n));let i=await n.run(t.reqId,async()=>{let n=await this.execute(e,t,r);if(!n)throw Error(`paired request produced no outcome`);return n});this.ownsHandshake(e,r)&&e.send(i)}}}async execute(t,n,r){let i=this.o.registry,a=()=>this.ownsHandshake(t,r),o=(e,t={})=>({type:`ack`,reqId:e,ok:!0,...t}),s=(e,t)=>({type:`ack`,reqId:e,ok:!1,error:t});try{switch(n.type){case`input.line`:return this.log.info(`input`,{kind:`line`,len:n.text.length}),await i.sendText(n.sessionId,`${n.text}\r`,a),o(n.reqId);case`input.text`:return this.log.info(`input`,{kind:`text`,len:n.text.length}),await i.sendText(n.sessionId,n.text,a),o(n.reqId);case`input.key`:return await i.sendText(n.sessionId,_t(n.key),a),o(n.reqId);case`input.terminal`:return await i.sendInput(n.sessionId,n.data,a),o(n.reqId);case`input.paste`:return await i.paste(n.sessionId,n.text,n.submit,a),o(n.reqId);case`input.mouse`:return await i.clickMouse(n.sessionId,n,a),o(n.reqId);case`session.create`:{let e=await i.createSession(n.in);return this.scheduleSessions(),o(n.reqId,{sessionId:e})}case`session.focus`:{let e=i.capabilitiesOf(n.sessionId);if(e===null)throw new A(n.sessionId);return e.focus?(await i.focus(n.sessionId),o(n.reqId)):s(n.reqId,`unsupported`)}default:return null}}catch(t){let r=t instanceof Ae?t.message:t instanceof A?`session-gone`:t instanceof e?`unsupported`:t instanceof Ne?`bad-window`:t instanceof ge?t.code:`failed`;return this.log.warn(`inner message failed`,{type:n.type,error:r,err:N(t)}),`reqId`in n?s(n.reqId,r):null}}sendAlive(e=Date.now()){if(!(e-this.aliveSent<5e3)){this.aliveSent=e;for(let e of this.links.values())e.activeRoute===`direct`&&e.send({type:`alive`})}}broadcast(e){for(let t of this.links.values())t.send(e)}onBackendEvent(e){switch(this.events.onBackendEvent(e),e.type){case`screen-changed`:Date.now()-this.activityPublished>=6e4&&(this.activityPublished=Date.now(),this.scheduleSessions());return;case`session-removed`:this.notifier.forget(e.sessionId),this.events.forget(e.sessionId),this.scheduleSessions();return;case`title-changed`:this.scheduleSessions(1e3);return;case`layout-changed`:case`session-added`:case`focus-changed`:case`command-start`:case`command-end`:case`prompt`:case`agent-state`:this.scheduleSessions();return;default:return}}scheduleSessions(e=0){let t=Date.now(),n=Math.max(t+100,this.sessionsRefreshedAt+e);this.sessionsDebounce&&this.sessionsDueAt<=n||(this.sessionsDebounce&&clearTimeout(this.sessionsDebounce),this.sessionsDueAt=n,this.sessionsDebounce=setTimeout(()=>{this.sessionsDebounce=null,this.sessionsRefreshedAt=Date.now(),this.refreshSessions()},n-t))}broadcastHelloIfBackendProfilesChanged(){let e=this.o.registry.connected(),t=JSON.stringify([this.o.registry.catalog().map(({capabilities:e,...t})=>({...t,capabilities:Object.entries(e).sort(([e],[t])=>e.localeCompare(t))})),this.o.registry.launchTargets(),this.o.registry.launchIssues(),this.o.registry.terminalSetup()]);if(t===this.backendsKey)return;let n=this.backendsKey===null;this.backendsKey=t,!n&&this.broadcast(this.helloMessage(e))}async refreshSessions(){let e=++this.sessionsRefreshes;try{let t=await this.o.registry.listSessions();if(e<this.sessionsPublished)return;this.sessionsPublished=e;let n=Date.now(),r=new Map;this.sessions=t.map(e=>{let t=this.o.registry.projectFolder(e.id),i=t?this.projects.lookup(t):void 0,a=i?{...e,project:i}:e,o=this.events.stateOf(a.id),s=o===`unknown`?a.state:o,{activeAt:c,stateSince:l,reportsAgentState:u}=this.events.activityOf(a.id),d=this.stateSeen.get(a.id),f=d===void 0?void 0:d.state===s?d.since:n,p=l??f;return r.set(a.id,{state:s,...p===void 0?{}:{since:p}}),{...a,state:s,...a.agent&&u?{agent:{...a.agent,reportsState:!0}}:{},...p===void 0?{}:{stateSince:p},...c===void 0?{}:{activeAt:c}}}),this.stateSeen=r,this.broadcast(Pn(this.sessions))}catch(e){this.log.warn(`listSessions failed`,{err:N(e)})}finally{this.broadcastHelloIfBackendProfilesChanged()}}};const Vo=Nr(Kn);var Ho=class{opts;granted;paused;explicit=!1;allowance=!1;current=`not-running`;listeners=new Set;constructor(e){this.opts=e;let t=this.readRecord();this.granted=t?.approved??!!e.assumeApproved,this.paused=e.interactive?void 0:t?.paused,this.paused&&(this.current=this.paused),(!t||t.paused!==this.paused)&&this.persist()}get issue(){return this.current}get connecting(){return this.explicit}onChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}async connect(e){if(!this.explicit){this.explicit=!0,this.allowance=!0;try{await e()}finally{this.explicit=!1,this.allowance=!1,this.emit()}}}cookieProvider=async e=>{if(!await(this.opts.isRunning??Wo)())throw this.set(`not-running`),new Ut(`iTerm2 is not running`,`not-running`);if(!await(this.opts.apiListening??Go)(this.opts.socketPath))throw this.set(`api-off`),Error(`iTerm2 Python API is off`);let t=this.allowance;if(!(t||!this.paused&&(this.granted||this.opts.interactive)))throw this.set(this.paused??`needs-consent`),new Ut(`waiting for Connect iTerm2`,`unknown`);this.allowance=!1,t&&this.set(`connecting`);try{let t=await(this.opts.requestCookie??en)(this.opts.appName??`Shellbell`,e);return this.granted=!0,this.paused=void 0,this.persist(),this.set(void 0),t}catch(e){let t=Uo(e);throw(t===`iterm2-denied`||t===`timed-out`)&&(this.paused=t,this.persist()),this.set(t),e}};set(e){e!==this.current&&(this.current=e,this.emit())}emit(){for(let e of this.listeners)try{e()}catch{}}readRecord(){if(this.opts.recordPath)try{let e=JSON.parse(rr(this.opts.recordPath,`utf8`));if(typeof e?.approved!=`boolean`)return;let t=e.paused===`iterm2-denied`||e.paused===`timed-out`?e.paused:void 0;return{approved:e.approved,paused:t}}catch{return}}persist(){if(this.opts.recordPath)try{dt(this.opts.recordPath,`${JSON.stringify({v:1,approved:this.granted,...this.paused?{paused:this.paused}:{},at:new Date(this.opts.now?.()??Date.now()).toISOString()})}\n`)}catch{}}};function Uo(e){return e instanceof Ut?e.kind===`too-old`?`too-old`:e.kind===`not-running`?`not-running`:/-1743\b|Not authori[sz]ed to send Apple events/i.test(e.message)?`automation-denied`:/timed out/i.test(e.message)?`timed-out`:e.kind===`denied`?`iterm2-denied`:`failed`:`failed`}async function Wo(){try{let e=process.getuid?.();return await Vo(`/usr/bin/pgrep`,[...e===void 0?[]:[`-U`,String(e)],`-x`,`iTerm2`],{timeout:2e3}),!0}catch{return!1}}async function Go(e){try{if(!or(e).isSocket())return!1}catch{return!1}return new Promise(t=>{let n=Sr({path:e}),r=e=>{n.destroy(),t(e)};n.setTimeout(1e3,()=>r(!1)),n.once(`connect`,()=>r(!0)),n.once(`error`,()=>r(!1))})}const Ko=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,qo=/^\/dev\/(ttys\d{1,5}|pts\/\d{1,6})$/;function Jo(e,t,n){return new Promise((r,i)=>{Kn(e,[...t],{signal:n,timeout:2e3,maxBuffer:1048576,env:{PATH:`/usr/bin:/bin:/usr/sbin:/sbin`,TZ:`UTC`,LC_ALL:`C`}},(e,t)=>e?i(e):r(t))})}async function Yo(e,t,n){let r=await n(`ps`,[`-t`,e.slice(5),`-o`,`pid=,stat=,lstart=,comm=`],t),i=[];for(let e of r.split(`
|
|
14
|
-
`)){let t=/^\s*(\d+)\s+(\S+)\s+(\S+ \S+\s+\d+ \d\d:\d\d:\d\d \d{4})\s+(.+?)\s*$/.exec(e);if(!t||!t[2].includes(`+`))continue;if(i.length>=256)break;let n=t[4].split(`/`).pop();i.push({pid:Number(t[1]),start:t[3].replace(/\s+/g,` `),command:n})}return i}async function
|
|
15
|
-
`).filter(e=>e.startsWith(`n`)).map(e=>e.slice(1))}async function Qo(e,t,n,r,i){let a=L(t,`presence`),o=await Zo(e.pid,n,r,i.platform??process.platform),s=new Set(o.flatMap(e=>{if(!e.startsWith(`${a}/`))return[];let t=e.slice(a.length+1),n=t.endsWith(`.lock`)?t.slice(0,-5):``;return Ko.test(n)?[n.toLowerCase()]:[]}));return s.size===1?[...s][0]:null}async function $o(e,t,n={}){if(!qo.test(e)||t.aborted)return null;let r=n.run??Jo;try{let i=new Map;for(let a of await Yo(e,t,r)){if(t.aborted)return null;let o=`process:${e}:${a.pid}:${a.start}`,s=nn(a.command),c=n.codexPane?(n.geminiSessions??ln(`gemini`)).find({...n.codexPane,tty:e.slice(5)},{pid:a.pid,start:a.start}):null;if(c)i.set(`gemini:${c.session}`,{agent:`gemini`,kind:`id`,value:c.session,owner:`${o}:${c.session}`});else if(s===`codex`){let t=n.codexPane?(n.codexSessions??ln(`codex`)).find({...n.codexPane,tty:e.slice(5)},{pid:a.pid,start:a.start}):null,r=!t&&n.codexTitle?await n.codexTitle():void 0,s=t?.session??(r?(n.codexThreads??$t()).find(r.title,r.cwd):null);s&&i.set(`codex:${s}`,{agent:`codex`,kind:`id`,value:s,owner:`${o}:${s}`})}else if(s!==`agy`){let e=await Xo(a,n.claudeDir??(process.env.CLAUDE_CONFIG_DIR||L(F(),`.claude`)));e&&i.set(`claude:${e}`,{agent:`claude`,kind:`id`,value:e,owner:o})}else{let e=await Qo(a,n.antigravityDir??L(F(),`.gemini`,`antigravity-cli`),t,r,n);e&&i.set(`agy:${e}`,{agent:`agy`,kind:`id`,value:e,owner:o})}}return i.size===1?Object.freeze([...i.values()][0]):null}catch{return null}}function es(e){if(!e)return{};let t,n;if(e.fgColor.case===`fgStandard`?t=e.fgColor.value:e.fgColor.case===`fgRgb`&&(t=[e.fgColor.value.red??0,e.fgColor.value.green??0,e.fgColor.value.blue??0]),e.bgColor.case===`bgStandard`?n=e.bgColor.value:e.bgColor.case===`bgRgb`&&(n=[e.bgColor.value.red??0,e.bgColor.value.green??0,e.bgColor.value.blue??0]),e.inverse){let e=t??15;t=n??0,n=e}let r={};return t!==void 0&&(r.fg=t),n!==void 0&&(r.bg=n),e.bold&&(r.b=!0),e.italic&&(r.i=!0),e.underline&&(r.u=!0),e.strikethrough&&(r.s=!0),e.faint&&(r.f=!0),e.invisible&&(r.invisible=!0),r}function ts(e){return`${JSON.stringify(e.fg??null)}|${JSON.stringify(e.bg??null)}|${+!!e.b}${+!!e.i}${+!!e.u}${+!!e.s}${+!!e.f}${+!!e.invisible}`}function ns(e){let t=Array.from(e.text??``),n=[];for(let t of e.codePointsPerCell)for(let e=0;e<(t.repeats||1);e++)n.push(t.numCodePoints);if(n.length===0)for(let e=0;e<t.length;e++)n.push(1);let r=[];for(let t of e.style)for(let e=0;e<(t.repeats||1);e++)r.push(t);let i=[],a=null,o=0;for(let e=0;e<n.length;e++){let s=n[e],c;s===0?c=` `:(c=t.slice(o,o+s).join(``),o+=s);let l=es(r[e]);l.invisible&&(c=` `.repeat(Math.max(1,S(c))));let u=ts(l);a&&a.key===u?(a.text+=c,a.cells+=1):(a&&i.push(rs(a)),a={style:l,key:u,text:c,cells:1})}a&&i.push(rs(a));let s=e.continuation===2,c=b(i),l={r:s?c:bt(c)};return s&&(l.w=!0),l}function rs(e){let t={t:e.text};return e.style.fg!==void 0&&(t.fg=e.style.fg),e.style.bg!==void 0&&(t.bg=e.style.bg),e.style.b&&(t.b=!0),e.style.i&&(t.i=!0),e.style.u&&(t.u=!0),e.style.s&&(t.s=!0),e.style.f&&(t.f=!0),e.cells!==S(e.text)&&(t.n=e.cells),t}function is(e,t,n){let r=Number(e.windowedCoordRange?.coordRange?.start?.y??0n),i=e.contents.map(ns);for(;i.length<t;)i.push(we());i.length>t&&(i.length=t);let a=e.cursor?Number(e.cursor.y??0n)-r:-1;return{cols:n,rows:t,cursor:{x:e.cursor?.x??0,y:Math.max(-1,Math.min(t-1,a))},lines:i,scrollbackTotal:r}}function as(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function os(e){return typeof e==`bigint`&&e>=0n&&e<=BigInt(2**53-1)}function ss(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t||Array.isArray(t))return null;let{overflow:n,history:r,grid:i,first_visible:a}=t;if(!as(n)||!as(r)||!as(i)||!as(a)||i===0)return null;let o=n+r;return Number.isSafeInteger(o)?{overflow:n,history:r,grid:i,firstVisible:a,origin:o}:null}function cs(e,t,n){if(!as(t)||!as(n)||n<t||e.status!==0)return!1;let r=e.windowedCoordRange?.coordRange,i=r?.start,a=r?.end;if(!i||!a||i.x!==0||a.x!==0||!os(i.y)||!os(a.y)||i.y!==BigInt(t)||a.y!==BigInt(n))return!1;let o=e.windowedCoordRange?.columns;return o&&(o.location!==0n||o.length!==0n)?!1:e.contents.length===n-t}function ls(e,t){return e.overflow===t.overflow&&e.history===t.history&&e.grid===t.grid}function us(e,t){return t!==void 0&&(e.overflow<t.overflow||e.origin<t.origin)}function ds(e){if(!e)return null;let t=e.links.map(e=>e.child.case===`session`?e.child.value.gridSize?{cols:e.child.value.gridSize.width,rows:e.child.value.gridSize.height}:null:e.child.case===`node`?ds(e.child.value):null).filter(e=>e!==null);if(t.length===0)return null;let n=t.length-1,r=e=>t.reduce((t,n)=>t+n[e],n),i=e=>Math.max(...t.map(t=>t[e]));return e.vertical?{cols:r(`cols`),rows:i(`rows`)}:{cols:i(`cols`),rows:r(`rows`)}}const fs="iTerm2 → Settings → General → Magic → ✓ Enable Python API, then run `shellbell` again.";function ps(e){return N(e)}var ms=class{client;backoff;name=`iterm2`;capabilities={subscribe:!0,prompts:!0,createSession:!0,terminalInput:!0,focus:!0,history:!0,absoluteLines:!0};sessions=new Map;windowGrids=new Map;historyOwnership=new Map;historyCaptures=new WeakMap;order=[];focused=null;handlers=new Set;subscribed=new Set;log;attempt=0;retryTimer=null;closed=!1;connectionGeneration=0;layoutBusy=!1;layoutDirty=null;layoutRefresh=Promise.resolve();constructor(e,t,n={}){this.client=e,this.backoff=n,this.log=t.child({backend:`iterm2`}),this.client.on(`notification`,e=>this.onNotification(e)),this.client.on(`close`,()=>{this.invalidateConnection(),this.scheduleReconnect()})}get isConnected(){return!this.closed&&this.client.connected}invalidateConnection(){this.connectionGeneration++,this.layoutBusy=!1,this.layoutDirty=null;let e=[...this.sessions.keys()];this.sessions.clear(),this.historyOwnership.clear(),this.order=[],this.subscribed.clear(),this.focused=null;for(let t of e)this.emit({type:`session-removed`,sessionId:t});this.emit({type:`layout-changed`})}ownsConnection(e){return e===this.connectionGeneration&&this.isConnected}scheduleReconnect(){if(this.closed||this.retryTimer)return;let e=this.backoff.minMs??1e3,t=this.backoff.maxMs??3e4,n=Math.min(t,e*2**this.attempt);this.attempt=Math.min(this.attempt+1,10),this.log.info(`iTerm2 gone; retrying`,{delayMs:n,attempt:this.attempt}),this.retryTimer=setTimeout(()=>{this.retryTimer=null;let e=this.connectionGeneration;this.connect().catch(t=>{e!==this.connectionGeneration||this.closed||(this.log.warn(`iTerm2 reconnect failed`,{error:ps(t)}),this.scheduleReconnect())})},n)}async connect(){this.closed=!1;let e=this.connectionGeneration;if(this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=null,!this.client.connected)try{await this.client.connect()}catch(t){if(e!==this.connectionGeneration||this.closed)return;throw new w(String(t),fs)}if(!this.ownsConnection(e)){this.closed&&this.client.close();return}try{for(let t of[8,6,7,9])if(await this.client.request({case:`notificationRequest`,value:H(Vn,{subscribe:!0,notificationType:t})}),!this.ownsConnection(e))return;let t=await this.client.request({case:`listSessionsRequest`,value:H(pn,{})});if(!this.ownsConnection(e)||(t.submessage.case===`listSessionsResponse`&&await this.applyLayout(t.submessage.value,e),!this.ownsConnection(e)))return;let n=await this.client.request({case:`focusRequest`,value:H(Nn,{})});if(!this.ownsConnection(e))return;if(n.submessage.case===`focusResponse`)for(let e of n.submessage.value.notifications)e.event.case===`session`&&(this.focused=e.event.value)}catch(t){if(!this.ownsConnection(e))return;throw new w(String(t),fs)}this.attempt=0}async close(){this.closed=!0,this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=null,this.invalidateConnection(),this.client.close()}async notificationFacts(e){let t=this.sessions.get(e);if(t&&this.isConnected)return zn({sessionId:e,cwd:t.cwd,title:t.title,sessionLabel:`iTerm2`},t.job,`reported`)}async listSessions(){return this.order.map(e=>this.sessions.get(e)).filter(e=>e!==void 0).map(e=>this.toInfo(e))}tmuxWindowIds(){let e=new Set;for(let t of this.sessions.values())t.tmuxWindowId&&e.add(t.tmuxWindowId);return e}representedWindows(){return[...this.tmuxWindowIds()].map(e=>({backend:`tmux`,windowId:e}))}async conversationReference(e,t){if(t.aborted)return null;let n=await this.variable(e,`tty`);return!n||t.aborted?null:$o(n,t,{codexPane:{iterm:e},codexTitle:async()=>{let[t,n]=await Promise.all([this.variable(e,`terminalWindowName`),this.variable(e,`path`)]);return{title:t,cwd:n}}})}hostedProcess(e){return this.hostJob(e)}projectFolder(e){let t=this.sessions.get(e);return t?.cwd&&Yt(t.job)?t.cwd:void 0}hostJob(e){let t=this.sessions.get(e);if(t&&!t.tmuxWindowId)return t.job}async getScreen(e,t){let n=this.sessions.get(e);if(!n)throw new A(e);let r=this.historyOwnership.get(e),i=t?.history&&r?{sessionId:e,connectionGeneration:this.connectionGeneration,coordinateRevision:r.coordinateRevision,cols:n.cols,rows:n.rows}:void 0,a=r?.activityRevision,o=r?.observed,s=i?await this.fetchHistoryFacts(e):null;i&&s&&this.ownsHistory(i)&&(s.grid!==i.rows||us(s,o))&&this.revokeHistory(e);let c=await this.client.request({case:`getBufferRequest`,value:H(On,{session:e,lineRange:H(xn,{screenContentsOnly:!0}),includeStyles:!0})});if(c.submessage.case!==`getBufferResponse`||c.submessage.value.status!==0)throw new A(e);let l=c.submessage.value,u;if(i&&s&&s.grid===i.rows&&this.ownsHistory(i)&&this.historyOwnership.get(e)?.activityRevision===a&&cs(l,s.origin,s.origin+s.grid)){let t=await this.fetchHistoryFacts(e);t&&this.ownsHistory(i)&&(t.grid!==i.rows||us(t,s))&&this.revokeHistory(e),t&&ls(s,t)&&this.ownsHistory(i)&&this.historyOwnership.get(e)?.activityRevision===a&&(this.observeHistory(e,t),u=Object.freeze({}),this.historyCaptures.set(u,Object.freeze({...i,facts:Object.freeze(s)})))}let d=is(l,n.rows,n.cols);return u&&(d.historyCapture=u),d}ownsHistory(e){let t=this.sessions.get(e.sessionId);return this.ownsConnection(e.connectionGeneration)&&this.historyOwnership.get(e.sessionId)?.coordinateRevision===e.coordinateRevision&&t?.cols===e.cols&&t.rows===e.rows}revokeHistory(e){let t=this.historyOwnership.get(e);t&&(t.coordinateRevision={},t.observed=void 0)}observeHistory(e,t){let n=this.historyOwnership.get(e);n&&(n.observed={overflow:Math.max(t.overflow,n.observed?.overflow??0),origin:Math.max(t.origin,n.observed?.origin??0)})}async fetchHistoryFacts(e){try{let t=await this.client.request({case:`getPropertyRequest`,value:H(Sn,{identifier:{case:`sessionId`,value:e},name:`number_of_lines`})});return t.submessage.case===`getPropertyResponse`&&t.submessage.value.status===0?ss(t.submessage.value.jsonValue):null}catch{return null}}async getHistoryPage(e,t){if(Je(t),t.signal.aborted)return{status:`cancelled`};if(!this.sessions.has(e))throw new A(e);let n=this.historyCaptures.get(t.capture);if(!n||n.sessionId!==e)return{status:`unavailable`,reason:`unanchored`};let r=()=>{if(t.signal.aborted)return{status:`cancelled`};if(!this.ownsHistory(n))return{status:`reset`}},i=r();if(i)return i;if(t.reported!==n.facts.origin)return{status:`unavailable`,reason:`unanchored`};let a=this.historyOwnership.get(e)?.activityRevision,o=this.historyOwnership.get(e)?.observed??n.facts,s={status:`unavailable`,reason:`changed`},c=(t,r=o)=>{if(!t)return s;if(t.grid!==n.rows||us(t,r))return this.historyOwnership.get(e)?.coordinateRevision===n.coordinateRevision&&this.revokeHistory(e),{status:`reset`}},l=await this.fetchHistoryFacts(e),u=r()??c(l);if(u)return u;if(!l)return s;let d=l.overflow,f=Math.max(t.before-t.count,d),p;if(t.before>d)try{let n=await this.client.request({case:`getBufferRequest`,value:H(On,{session:e,lineRange:H(xn,{windowedCoordRange:H(on,{coordRange:H(Bn,{start:H(vn,{x:0,y:BigInt(f)}),end:H(vn,{x:0,y:BigInt(t.before)})})})}),includeStyles:!0})}),i=r();if(i)return i;if(n.submessage.case!==`getBufferResponse`||!cs(n.submessage.value,f,t.before))return s;p=n.submessage.value.contents.map(ns)}catch{return r()??s}let m=await this.fetchHistoryFacts(e);return(r()??c(m,l))||(!m||!ls(l,m)||this.historyOwnership.get(e)?.activityRevision!==a?s:(this.observeHistory(e,m),p?{status:`page`,from:f,to:t.before,oldestAvailable:d,lines:p}:{status:`boundary`,reason:t.before===d?`end`:`truncated`,oldestAvailable:d}))}async getHistory(e,t,n){if(!this.sessions.has(e))throw new A(e);let r=Math.max(0,t-n),i=await this.client.request({case:`getBufferRequest`,value:H(On,{session:e,lineRange:H(xn,{windowedCoordRange:H(on,{coordRange:H(Bn,{start:H(vn,{x:0,y:BigInt(r)}),end:H(vn,{x:0,y:BigInt(t)})})})}),includeStyles:!0})});if(i.submessage.case!==`getBufferResponse`||i.submessage.value.status!==0)throw new A(e);let a=i.submessage.value.contents.map(ns);return{lines:a,oldestAvailable:a.length<t-r?t-a.length:0}}async sendText(e,t){let n=await this.client.request({case:`sendTextRequest`,value:H(gn,{session:e,text:t,suppressBroadcast:!0})});if(n.submessage.case!==`sendTextResponse`)throw new A(e);let r=n.submessage.value.status;if(r===1)throw new A(e);if(r!==0)throw Error(`sendText failed: ${Un[r]}`)}async sendInput(e,t){await this.sendText(e,t)}async createSession(e){if(e.kind===`tab`){let t=e.windowId===void 0&&e.initialSize?Ct.parse(e.initialSize):void 0,n=await this.client.request({case:`createTabRequest`,value:H(bn,{windowId:e.windowId,selectTab:!1,...t?{customProfileProperties:[{key:`Columns`,jsonValue:JSON.stringify(t.cols)},{key:`Rows`,jsonValue:JSON.stringify(t.rows)}]}:{}})});if(n.submessage.case!==`createTabResponse`||!n.submessage.value.sessionId)throw Error(`create tab failed`);return n.submessage.value.sessionId}let t=await this.client.request({case:`splitPaneRequest`,value:H(an,{session:e.sessionId,splitDirection:e.direction===`vertical`?0:1})}),n=t.submessage.case===`splitPaneResponse`?t.submessage.value.sessionId[0]:void 0;if(!n)throw Error(`split failed`);return n}hostedWindowGrid(){let e=this.focused?this.sessions.get(this.focused):void 0,t=e?this.windowGrids.get(e.windowId):void 0;if(t)return t;let n;for(let e of this.windowGrids.values())(!n||e.cols*e.rows>n.cols*n.rows)&&(n=e);return n}async createCommandSession(e,t){if(e.length===0||e.length>8192||e.includes(`\0`))throw Error(`Invalid terminal launch command`);let n=t===void 0?this.hostedWindowGrid():Ct.parse(t),r=await this.client.request({case:`createTabRequest`,value:H(bn,{selectTab:!1,customProfileProperties:[{key:`Custom Command`,jsonValue:JSON.stringify(`Yes`)},{key:`Command`,jsonValue:JSON.stringify(e)},...n?[{key:`Columns`,jsonValue:JSON.stringify(n.cols)},{key:`Rows`,jsonValue:JSON.stringify(n.rows)}]:[]]})});if(r.submessage.case!==`createTabResponse`||r.submessage.value.status!==0||!r.submessage.value.sessionId)throw Error(`iTerm2 could not create the terminal window`);return r.submessage.value.sessionId}async focus(e){await this.client.request({case:`activateRequest`,value:H(_n,{identifier:{case:`sessionId`,value:e},orderWindowFront:!0,selectTab:!0,selectSession:!0,activateApp:H(Dn,{raiseAllWindows:!1,ignoringOtherApps:!1})})})}on(e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(e){for(let t of this.handlers)try{t(e)}catch(e){this.log.warn(`event handler failed`,{error:ps(e)})}}toInfo(e){return{id:e.id,backend:`iterm2`,title:e.title,cwd:e.cwd,...un({cwd:e.cwd,processName:e.job,title:e.title}),cols:e.cols,rows:e.rows,windowId:e.windowId,windowNumber:e.windowNumber,tabId:e.tabId,tabIndex:e.tabIndex,paneIndex:e.paneIndex,isFocusedOnMac:this.focused===e.id,state:`unknown`}}applyLayout(e,t){return this.ownsConnection(t)?(this.layoutDirty=e,this.layoutBusy?this.layoutRefresh:(this.layoutBusy=!0,this.layoutRefresh=this.drainLayout(t),this.layoutRefresh)):Promise.resolve()}async drainLayout(e){try{for(;this.ownsConnection(e)&&this.layoutDirty;){let t=this.layoutDirty;this.layoutDirty=null,await this.runApplyLayout(t,e)}}finally{e===this.connectionGeneration&&(this.layoutBusy=!1)}}async runApplyLayout(e,t){let n=new Map,r=[],i=[...e.windows].sort((e,t)=>(e.number??0)-(t.number??0)),a=new Map;for(let e of i){for(let t of e.tabs){let n=ds(t.root),r=a.get(e.windowId??``);n&&n.cols>0&&n.rows>0&&a.set(e.windowId??``,{cols:Math.max(n.cols,r?.cols??0),rows:Math.max(n.rows,r?.rows??0)})}e.tabs.forEach((t,i)=>{let a=0,o=s=>{if(s)for(let c of s.links)if(c.child.case===`session`){let o=c.child.value,s=o.uniqueIdentifier??``,l=this.sessions.get(s);n.set(s,{id:s,title:l?.title||o.title||`Session`,cwd:l?.cwd,job:l?.job,cols:o.gridSize?.width??80,rows:o.gridSize?.height??24,windowId:e.windowId??``,windowNumber:e.number??0,tabId:t.tabId??``,tabIndex:i,paneIndex:a++,tmuxWindowId:t.tmuxWindowId||void 0}),r.push(s)}else c.child.case===`node`&&o(c.child.value)};o(t.root)})}for(let e of this.sessions.keys())n.has(e)||(this.subscribed.delete(e),this.historyOwnership.delete(e));for(let[e,t]of n){let n=this.sessions.get(e);(!this.historyOwnership.has(e)||n?.cols!==t.cols||n.rows!==t.rows)&&this.historyOwnership.set(e,{coordinateRevision:{},activityRevision:{}})}this.sessions=n,this.windowGrids=a,this.order=r,await Promise.all(r.map(e=>this.ensureSession(e,t))),this.ownsConnection(t)&&this.emit({type:`layout-changed`})}async ensureSession(e,t){let n=this.sessions.get(e),r=()=>this.ownsConnection(t)&&this.sessions.get(e)===n;if(!n||!r()||this.subscribed.has(e))return;this.subscribed.add(e);let i=[H(Vn,{session:e,subscribe:!0,notificationType:2}),H(Vn,{session:e,subscribe:!0,notificationType:3,arguments:{case:`promptMonitorRequest`,value:H(Wn,{modes:[1,2,3]})}}),...[`session.name`,`session.path`,`jobName`].map(t=>H(Vn,{session:e,subscribe:!0,notificationType:12,arguments:{case:`variableMonitorRequest`,value:H(Ht,{name:t,scope:1,identifier:e})}}))];for(let t of i){try{await this.client.request({case:`notificationRequest`,value:t})}catch(t){if(!r())return;this.log.warn(`subscribe failed`,{session:e.slice(0,8),error:ps(t)})}if(!r())return}if(!r())return;let[a,o,s]=await Promise.all([this.variable(e,`session.name`),this.variable(e,`session.path`),this.variable(e,`jobName`)]);r()&&(a&&(n.title=a),o&&(n.cwd=o),s&&(n.job=s))}async variable(e,t){try{let n=await this.client.request({case:`variableRequest`,value:H(Hn,{scope:{case:`sessionId`,value:e},get:[t]})});if(n.submessage.case!==`variableResponse`||n.submessage.value.status!==0)return;let r=n.submessage.value.values[0];if(!r||r===`null`)return;let i=JSON.parse(r);return typeof i==`string`?i:void 0}catch{return}}onNotification(e){let t=this.connectionGeneration;if(!this.ownsConnection(t))return;let n=Date.now();if(e.screenUpdateNotification?.session){let t=this.historyOwnership.get(e.screenUpdateNotification.session);t&&(t.activityRevision={}),this.emit({type:`screen-changed`,sessionId:e.screenUpdateNotification.session});return}if(e.promptNotification?.session){let t=e.promptNotification,r=t.session;t.event.case===`commandStart`?this.emit({type:`command-start`,sessionId:r,command:t.event.value.command??``,at:n}):t.event.case===`commandEnd`?this.emit({type:`command-end`,sessionId:r,exitCode:t.event.value.status??0,at:n}):t.event.case===`prompt`&&this.emit({type:`prompt`,sessionId:r,at:n});return}if(e.layoutChangedNotification?.listSessionsResponse){for(let e of this.historyOwnership.keys())this.revokeHistory(e);this.applyLayout(e.layoutChangedNotification.listSessionsResponse,t).catch(e=>{this.ownsConnection(t)&&this.log.warn(`layout refresh failed`,{error:ps(e)})});return}if(e.newSessionNotification?.sessionId){this.client.request({case:`listSessionsRequest`,value:H(pn,{})}).then(e=>{if(this.ownsConnection(t)&&e.submessage.case===`listSessionsResponse`)return this.applyLayout(e.submessage.value,t)}).catch(e=>{this.ownsConnection(t)&&this.log.warn(`new-session layout refresh failed`,{error:ps(e)})}),this.emit({type:`session-added`,sessionId:e.newSessionNotification.sessionId});return}if(e.terminateSessionNotification?.sessionId){let t=e.terminateSessionNotification.sessionId;this.sessions.delete(t),this.historyOwnership.delete(t),this.subscribed.delete(t),this.order=this.order.filter(e=>e!==t),this.emit({type:`session-removed`,sessionId:t}),this.emit({type:`layout-changed`});return}if(e.focusChangedNotification){e.focusChangedNotification.event.case===`session`&&(this.focused=e.focusChangedNotification.event.value),this.emit({type:`focus-changed`});return}if(e.variableChangedNotification?.identifier){let t=e.variableChangedNotification,n=this.sessions.get(t.identifier);if(!n)return;try{let e=JSON.parse(t.jsonNewValue??`null`);t.name===`session.name`&&typeof e==`string`&&(n.title=e),t.name===`session.path`&&typeof e==`string`&&(n.cwd=e),t.name===`jobName`&&typeof e==`string`&&(n.job=e)}catch{return}this.emit({type:`title-changed`,sessionId:n.id})}}};const hs=R.object({apiVersion:R.literal(1),id:xt,label:pt,platforms:R.array(R.enum([`darwin`,`linux`])).min(1).max(2),hostCommands:R.array(R.string().regex(/^[a-zA-Z0-9._-]{1,64}$/)).max(16).optional()}),gs=R.string().min(1).max(128),_s=R.discriminatedUnion(`type`,[R.object({type:R.literal(`focus-changed`)}),...[`screen-changed`,`session-added`,`session-removed`,`title-changed`].map(e=>R.object({type:R.literal(e),sessionId:gs})),R.object({type:R.literal(`layout-changed`)}),R.object({type:R.literal(`command-start`),sessionId:gs,command:R.string().max(512),at:R.number().finite()}),R.object({type:R.literal(`command-end`),sessionId:gs,exitCode:R.number().int(),at:R.number().finite()}),R.object({type:R.literal(`prompt`),sessionId:gs,at:R.number().finite()}),R.object({type:R.literal(`agent-state`),sessionId:gs,state:R.enum([`working`,`blocked`,`idle`,`done`,`unknown`]),agent:R.string().max(128).optional(),at:R.number().finite()})]),vs=R.object({cols:R.number().int().min(1).max(M.cols),rows:R.number().int().min(1).max(M.rows),cursor:ht,lines:R.array(Ue).max(M.rows),scrollbackTotal:R.number().int().nonnegative().max(2**53-1),historyCapture:R.custom(e=>typeof e==`object`&&!!e&&!Array.isArray(e)).optional()}).refine(e=>e.lines.length===e.rows,`screen must contain every viewport row`),ys=R.number().int().nonnegative().max(2**53-1),bs=R.discriminatedUnion(`status`,[R.object({status:R.literal(`page`),from:ys,to:ys,oldestAvailable:ys,lines:R.array(Ue).max(M.historyLines)}),R.object({status:R.literal(`boundary`),reason:R.enum([`end`,`truncated`]),oldestAvailable:ys}),R.object({status:R.literal(`unavailable`),reason:R.enum([`unsupported`,`unanchored`,`busy`,`changed`,`fetch-window`])}),R.object({status:R.literal(`reset`)}),R.object({status:R.literal(`cancelled`)})]);var xs=class extends Error{};async function Ss(e,t){let n;try{return await Promise.race([e,new Promise((e,r)=>{n=setTimeout(()=>r(new xs(`Terminal adapter deadline exceeded`)),t),n.unref()})])}finally{n&&clearTimeout(n)}}var Cs=class{raw;abort;timeoutMs;name;capabilities;connected=!1;closed=!1;generation=0;pending=0;handlers=new Set;unsubscribe;constructor(e,t,n,r=5e3){if(this.raw=e,this.abort=n,this.timeoutMs=r,this.name=xt.parse(t),e.name!==t)throw Error(`Adapter identity does not match its manifest`);this.capabilities=Object.freeze(ze.parse(e.capabilities));for(let t of[`connect`,`close`,`listSessions`,`getScreen`,`getHistory`,`sendText`,`createSession`,`focus`,`on`])if(typeof e[t]!=`function`)throw Error(`Adapter is missing a required method`);if(this.capabilities.terminalInput&&!e.sendInput||this.capabilities.terminalPaste&&!e.paste||this.capabilities.mouseClick&&!e.clickMouse)throw Error(`Adapter capability has no implementation`);if(this.unsubscribe=e.on(e=>{if(this.closed)return;let t=_s.safeParse(e);if(!t.success||`sessionId`in t.data&&!this.validId(t.data.sessionId))return;let n=t.data;if(this.isConnected||n.type===`layout-changed`)for(let e of[...this.handlers])this.handlers.has(e)&&e(n)}),typeof this.unsubscribe!=`function`)throw Error(`Adapter subscription is invalid`)}get isConnected(){try{return!this.closed&&this.connected&&this.raw.isConnected!==!1}catch{return!1}}validId(e,t=!1){return(t||e.length>0)&&e.length+this.name.length+1<=128&&[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127)}async call(e){if(this.closed||this.pending>=4)throw new w(`Terminal adapter is busy`,`Try again after the adapter recovers.`);let t=this.generation;this.pending++;let n=Promise.resolve().then(()=>{if(this.closed||t!==this.generation)throw Error(`Terminal adapter generation retired`);return e()}).finally(()=>{this.pending--});try{let e=await Ss(n,this.timeoutMs);if(this.closed||t!==this.generation)throw Error(`Terminal adapter generation retired`);return e}catch(e){if(e instanceof xs){this.connected=!1,this.generation++;for(let e of[...this.handlers])this.handlers.has(e)&&e({type:`layout-changed`})}throw e}}async connect(){if(!this.isConnected){if(this.closed||this.pending>0)throw new w(`Terminal adapter is unavailable`,`Wait for its pending operation or restart the service.`);await this.call(()=>this.raw.connect()),this.connected=!0;for(let e of[...this.handlers])this.handlers.has(e)&&e({type:`layout-changed`})}}canLaunch(){try{return!this.closed&&this.capabilities.createSession&&!!this.raw.launch&&(this.raw.canLaunch?.()??!0)}catch{return!1}}async launch(){if(!this.canLaunch())throw new e(`terminal startup`);await this.call(()=>this.raw.launch())}async close(){if(!this.closed){this.closed=!0,this.connected=!1,this.generation++,this.abort.abort(),this.handlers.clear();try{this.unsubscribe()}finally{await Ss(Promise.resolve().then(()=>this.raw.close()),this.timeoutMs)}}}async listSessions(){if(!this.isConnected)return[];let e=R.array(ct).max(500).parse(await this.call(()=>this.raw.listSessions()));if(e.some(e=>e.backend!==this.name||!this.validId(e.id)||!this.validId(e.windowId,!0)||!this.validId(e.tabId,!0))||new Set(e.map(e=>e.id)).size!==e.length)throw Error(`Adapter returned invalid session identities`);return e}async getScreen(e,t){return vs.parse(await this.call(()=>this.raw.getScreen(e,t)))}async getHistory(e,t,n){return R.object({lines:R.array(Ue).max(1e3),oldestAvailable:R.number().int().nonnegative()}).parse(await this.call(()=>this.raw.getHistory(e,t,n)))}async getHistoryPage(e,t){if(!this.raw.getHistoryPage)return{status:`unavailable`,reason:`unsupported`};let n=bs.parse(await this.call(()=>this.raw.getHistoryPage(e,t)));if(n.status===`page`&&(n.to-n.from!==n.lines.length||n.from<n.oldestAvailable||n.to>t.before||n.lines.length>t.count))throw Error(`Adapter returned an invalid history range`);return n}async sendText(e,t){await this.call(()=>this.raw.sendText(e,t))}async sendInput(t,n){if(!this.raw.sendInput)throw new e(`terminal input`);await this.call(()=>this.raw.sendInput(t,n))}async paste(t,n,r){if(!this.raw.paste)throw new e(`terminal paste`);await this.call(()=>this.raw.paste(t,n,r))}async clickMouse(t,n){if(!this.raw.clickMouse)throw new e(`mouse input`);await this.call(()=>this.raw.clickMouse(t,n))}async createSession(e){let t=await this.call(()=>this.raw.createSession(e));if(!this.validId(t))throw Error(`Adapter returned an invalid session identity`);return t}async focus(e){await this.call(()=>this.raw.focus(e))}on(e){return this.handlers.add(e),()=>{this.handlers.delete(e)}}setWatched(e){this.raw.setWatched?.(e)}setReported(e,t){this.raw.setReported?.(e,t)}hostedProcess(e){let t=this.raw.hostedProcess?.(e);return t===void 0?void 0:R.string().max(128).refine(e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127)).parse(t)}representedWindows(){return R.array(R.object({backend:xt,windowId:R.string().min(1).max(128)})).max(500).parse(this.raw.representedWindows?.()??[])}nativeWindowIdOf(e){let t=this.raw.nativeWindowIdOf?.(e);return t===void 0?void 0:R.string().min(1).max(128).parse(t)}};function ws(e){let t=!1,n=[],r=new Set(et.options),i=e.timeoutMs??5e3;return{ready:(async()=>{for(let a of e.paths){if(t)break;let o=new AbortController;n.push(()=>o.abort());let s,c,l=!1,u=async e=>{l||(l=!0,await Ss(Promise.resolve().then(()=>e.close()),i).catch(()=>{}))};try{if(e.admitPath)e.admitPath(a);else{if($n(a).isSymbolicLink()||ar(a)!==a)throw Error(`Adapter path must be canonical`);m(a,262144,process.getuid())}let l=await Ss((e.importModule??Pr)(gr(a).href),i),d=hs.parse(l.default);if(r.has(d.id))throw Error(`Adapter identity is already registered`);if(!d.platforms.includes(e.platform??process.platform)){o.abort();continue}let f=l.default;if(typeof f.create!=`function`)throw Error(`Adapter factory is missing`);let p=Promise.resolve().then(()=>f.create({log:e.log.child({adapter:d.id}),signal:o.signal}));if(p.then(async e=>{o.signal.aborted&&await u(e)},()=>{}),c=await Ss(p,i),t){o.abort(),await u(c);break}s=new Cs(c,d.id,o,i),r.add(d.id),e.registry.add(s,d.label,d.hostCommands??[]);let h=c.launch?e.registry.registerSessionLauncher(d.id,{available:()=>s?.canLaunch()??!1,start:async()=>(await _.launch(),await _.connect(),{backend:_})}):void 0,g,_=s,v=async()=>{if(!t){if(e.registry.member(d.id)!==_){await _.close().catch(()=>{});return}try{await _.connect()}catch(t){e.log.debug(`terminal adapter unavailable`,{adapter:d.id,error:N(t)})}t||(g=setTimeout(()=>{v()},e.retryMs??1e4),g.unref())}};n.push(()=>{h?.(),g&&clearTimeout(g),e.registry.member(d.id)===_&&e.registry.remove(d.id),_.close().catch(t=>e.log.warn(`terminal adapter cleanup failed`,{adapter:d.id,error:N(t)}))}),v()}catch(t){o.abort(),s?await s.close().catch(()=>{}):c&&await u(c),e.log.warn(`terminal plugin could not be loaded`,{error:N(t)})}}})(),stop(){t=!0;for(let e of n.splice(0))e()}}}const Ts={iterm2:{bundle:`iTerm.app`,label:`iTerm2`}},Es=Nr(Kn);function Ds(e,t={}){if((t.platform??process.platform)!==`darwin`)return null;let n=t.roots??[`/Applications`,L(F(),`Applications`)],r=t.exists??Xn,i=Ts[e],a=()=>n.map(e=>L(e,i.bundle)).find(r);return{available:()=>a()!==void 0,start:async()=>{let e=a();if(!e)throw new w(`${i.label} is not installed`,`Install ${i.label} on your computer.`);try{await(t.execute??((e,t)=>Es(e,t,{timeout:5e3,maxBuffer:4096})))(`/usr/bin/open`,[`-g`,`-a`,e])}catch{throw new w(`Could not launch ${i.label}`,`Open ${i.label} on your computer and check its local API.`)}}}}function Os(e,t,n={}){let r=n.execute??((e,t)=>Es(e,t,{timeout:2e3,maxBuffer:65536,encoding:`utf8`})),i=n.exists??Xn,a=n.now??Date.now,o,s=-1/0,c=!1,l=async()=>{let t;try{let{stdout:n}=await r(`/usr/bin/osascript`,[`-l`,`JavaScript`,`-e`,`function run(argv) {
|
|
12
|
+
FROM steps WHERE idx = ?`),r=t.length>mo,i=0,a=new Map,o=[],s=[];for(let e of t.slice(0,mo)){let t=Number(e.idx),c=Number(e.size??0),l=c>ho;if(!l&&i+c>16777216){r=!0;break}let u=l?null:n.get(Math.min(ho,16777216-i),t);if(u&&u.payload===null&&Number(u.size??0)>0){r=!0;break}let d=u?.payload??null;i+=d?.byteLength??0;let f=d?R(`sha256`).update(d).digest(`base64url`):`large:${c}`,p=`${e.type}:${e.status}:${f}`,m=this.cache.get(t);m?.version!==p&&(m={version:p,parsed:fo({idx:t,type:Number(e.type),status:Number(e.status),payload:d})}),a.set(t,m),o.push(m.parsed),s.push(`${t}:${p}`)}return this.cache=a,{parsed:o.reverse(),truncated:r,fingerprint:`${r}|${s.join(`,`)}`}}async unchanged(){try{return!this.database||!this.latest||this.files===null?!1:this.database.prepare(`PRAGMA data_version`).get().data_version===this.version&&await this.fileStamp()===this.files}catch{return!1}}async fileStamp(){let e=async e=>{try{let t=await z(e,{bigint:!0});return`${t.dev}:${t.ino}:${t.size}:${t.mtimeNs}:${t.ctimeNs}`}catch(e){if(e?.code===`ENOENT`)return`none`;throw e}};return`${await e(this.identity.path)}|${await e(`${this.identity.path}-wal`)}`}async changed(e){try{return await this.proven(e)||!this.database?null:this.database.prepare(`PRAGMA data_version`).get().data_version!==this.version}catch{return null}}close(){try{this.database?.close()}catch{}this.database=null,this.latest=null,this.cache.clear()}};function bo(e){if(!e.resets)return[e];let t=[];for(let n of e.entries){let r=n.id.slice(0,n.id.lastIndexOf(`:`)),i=r.startsWith(`gemini:`)?r.slice(7):void 0,a=t.at(-1);a&&a.message===i&&(i||a.entries[0]?.id.startsWith(`${r}:`))?a.entries.push(n):t.push({...e,resets:!1,message:i,entries:[n]})}let[n,...r]=t.map(e=>Object.freeze({...e,entries:Object.freeze(e.entries)}));return n?[Object.freeze({...n,resets:!0}),...r]:[e]}function xo(e){return R(`sha256`).update(JSON.stringify(e)).digest(`base64url`)}function So(e){let t=e.node;return!!t&&!e.entries.length&&t.role===`other`&&!t.mainMessage&&!t.meta&&!t.compact&&!t.sourceAssistant&&!t.calls.length&&!t.results.length}function Co(e,t){return t.node.parent===e.node.id&&t.node.scope===e.node.scope&&t.node.session===e.node.session}function wo(e,t){let n=e.node.timestamp,r=t.node.timestamp;if(!!n!=!!r)return n?-1:1;if(n&&r){let e=e=>e.replace(/(?:\.(\d+))?Z$/,(e,t)=>`.${(t??``).padEnd(6,`0`)}Z`),t=e(n),i=e(r);if(t!==i)return t<i?-1:1}return e.start-t.start}function To(e,t){let n=``,r=0,i=!1;outer:for(let t of e)for(let e of t.entries){if(r>=8192){i=!0;break outer}let t=`${e.kind}: ${e.text}${e.detail?`\n${e.detail}`:``}`,a=Math.max(0,pa-r-!!n),o=G(t,a);if(n&&a&&(n+=`
|
|
13
|
+
`,r++),n+=o.text,r+=Buffer.byteLength(o.text),i||=o.truncated||e.truncated===!0,!a){i=!0;break outer}}return n?Object.freeze({id:t,kind:`group`,text:`Subagent conversation`,detail:n,collapsed:!0,...i&&{truncated:!0}}):null}var Eo=class{agent;onVersion;expected;header;records=[];queue=[];bytes=0;base=0;through=0;revision=0;evicted=!1;invalidated=!1;closed=!1;previous=null;entryFingerprints=new WeakMap;latest=null;latestUnanchored=!1;cutKnown=null;version=null;precedingEnd=new Map;folded=new Map;unplacedMain=-1;coveredThrough=0;lookups=null;constructor(e,t,n){this.agent=e,this.onVersion=n;let r=Sa(t);if(!r||e!==`claude`&&e!==`codex`&&e!==`gemini`)throw TypeError(`Invalid transcript document identity`);this.expected=r,this.header=e===`claude`?null:new Za(r)}get retainedBytes(){return this.bytes}get retainedRecords(){return this.records.length}get cursor(){return this.through}beginWindow(e){if(this.closed||!Number.isSafeInteger(e)||e<0)throw RangeError(`Invalid transcript window`);this.records=[],this.bytes=0,this.base=this.through=e,this.coveredThrough=e,this.unplacedMain=-1,this.evicted=!1,this.queue=[],this.previous=null,this.latest=null,this.entryFingerprints=new WeakMap,this.precedingEnd.clear(),this.folded.clear(),this.revision++}append(e){if(this.closed||e.length>64)throw RangeError(`Invalid transcript document batch`);let t=this.through;for(let n of e){if(!Number.isSafeInteger(n.start)||!Number.isSafeInteger(n.end)||n.start<t||n.end<=n.start)throw RangeError(`Invalid transcript document order`);t=n.end}for(let t of e.flatMap(bo)){if(this.header?.observe(t),t.version&&t.version!==this.version&&(this.version=t.version,this.onVersion?.(this.agent,t.version)),this.invalidated||=t.invalidates===!0,t.resets&&this.drop(0),t.rewind){let e=this.records.findIndex(({record:e})=>e.message===t.rewind);this.drop(e<0?0:e)}if(t.queue&&(this.queue.push(t.queue),this.queue.length>256&&this.queue.shift()),!t.node&&!t.entries.length)continue;let e=t,n=this.records.at(-1);if(n&&So(n.record)&&So(e)&&Co(n.record,e)){let t=this.parentOf(n.record.node);this.folded.set(n.record.node.id,t),this.folded.size>16384&&this.folded.delete(this.folded.keys().next().value),e=Object.freeze({...e,node:Object.freeze({...e.node,parent:t})}),this.records.pop(),this.bytes-=n.bytes}let r=Buffer.byteLength(JSON.stringify(e));if(r>262144){this.forgetUnseen(e),this.evicted=!0;continue}let i=e.message?this.records.findIndex(t=>t.record.message===e.message):-1;for(i>=0?(this.bytes+=r-this.records[i].bytes,this.records[i]={record:e,bytes:r}):(this.records.push({record:e,bytes:r}),this.bytes+=r);this.bytes>262144||this.records.length>2048;){let e=this.records.shift();this.forgetUnseen(e.record),this.bytes-=e.bytes,this.evicted=!0}}this.through=t,e.length&&(this.latest=null,this.revision++)}drop(e){for(let t of this.records.splice(e))this.bytes-=t.bytes}close(){this.closed=!0,this.header?.close(),this.records=[],this.queue=[],this.bytes=0,this.previous=null,this.latest=null,this.entryFingerprints=new WeakMap,this.precedingEnd.clear(),this.folded.clear(),this.lookups=null,this.cutKnown=null,this.revision++}hasCut(){let e=this.latest;if(e?.state!==`ready`)return!1;if(this.cutKnown?.revision===e.revision)return this.cutKnown.value;let t=e.entries.some(t=>!t.id.startsWith(`history:`)&&this.cut(t,e.branch)!==null);return this.cutKnown={revision:e.revision,value:t},t}windowGap(e,t){return e.kind===`skipped`&&t!==`complete`&&e.start===this.base&&e.entries[0]?.text===`Earlier content is not loaded`}anchor(e){let t=this.latest;if(t?.state!==`ready`)return null;let n=t.entries.find(t=>t.id===e);return n?this.cut(n,t.branch):null}cut(e,t){if(this.agent===`gemini`)return null;let n=e.id,r=this.index().records.get(n),i=r?.entries.find(e=>e.id===n);return!r||!i||i!==e&&xo(i)!==xo(e)||r.kind===`skipped`||!this.header&&(t?.kind!==`claude`||!r.node?.mainMessage||r.node.meta||!this.turnStart(r,n)||(this.precedingEnd.get(n)??1/0)>r.end||this.unplacedMain>=r.end||!t.nodes.some(e=>e.id===r.node.id&&e.start===r.start))?null:Object.freeze({agent:this.agent,start:r.start,end:r.end,recordHash:xo(r),entryId:n,entryHash:xo(e),nodeId:r.node?.id??null})}turnStart(e,t){let n=e.node;if(n.role===`user`)return n.results.length===0;if(n.role!==`assistant`||!n.response||e.entries[0]?.id!==t)return!1;let{main:r,replies:i,calls:a}=this.index();if(i.get(n.response)!==e.start)return!1;let o=this.parentRecord(n,r),s=e.start;for(;o&&o.start<s&&!o.entries.length&&!o.node.calls.length&&!o.node.results.length&&(o.node.role!==`assistant`||o.node.response===n.response);)s=o.start,o=this.parentRecord(o.node,r);return!o?.node.mainMessage||o.start>=s?!1:o.node.role===`assistant`?o.node.response!==n.response:o.node.role===`user`&&o.node.results.every(({id:e})=>{let t=o.node.sourceAssistant?r.get(o.node.sourceAssistant):a.get(e);return!!t?.node.response&&t.node.response!==n.response&&t.node.calls.some(t=>t.id===e)})}parentOf(e){let t=e.parent;return t&&this.folded.has(t)?this.folded.get(t):t}parentRecord(e,t){let n=this.parentOf(e);return n?t.get(n):void 0}index(){if(this.lookups?.revision===this.revision)return this.lookups;let e=new Map,t=new Map,n=new Map,r=new Map;for(let{record:i}of this.records){for(let t of i.entries)e.set(t.id,i);if(i.node?.scope!==`main`)continue;let a=i;if(t.set(a.node.id,a),a.node.role===`assistant`){a.node.response&&a.entries.length&&!n.has(a.node.response)&&n.set(a.node.response,a.start);for(let e of a.node.calls)r.set(e.id,r.has(e.id)?null:a)}}return this.lookups={revision:this.revision,records:e,main:t,replies:n,calls:r},this.lookups}permits(e){if(this.latest?.state!==`ready`||e.agent!==this.agent||e.agent===`claude`&&this.unplacedMain>=e.end||this.latest.branch?.kind===`claude`&&this.latest.branch.nodes.some(t=>t.id===e.nodeId&&t.start!==e.start))return!1;if(this.records.some(({record:t})=>t.start===e.start)){let t=this.anchor(e.entryId);return t!==null&&t.recordHash===e.recordHash&&t.entryHash===e.entryHash}return e.end<=(this.records[0]?.record.start??this.base)}snapshot(e){if(!e&&this.latest&&this.latestUnanchored)return this.latest.change!==`unchanged`&&(this.latest=Object.freeze({...this.latest,change:`unchanged`})),this.latest;this.latest=null,this.latestUnanchored=!e;let t=this.evicted?`truncated`:this.base>0?`unloaded`:`complete`;if(this.closed)return this.finish(`closed`,[],t);if(this.invalidated)return this.finish(`unsupported`,[],t);if(e){let n=this.records.find(({record:t})=>t.start===e.start)?.record;if(e.agent!==this.agent||this.through!==e.end||!n||n.end!==e.end||xo(n)!==e.recordHash||!n.entries.some(t=>t.id===e.entryId&&xo(t)===e.entryHash)||(n.node?.id??null)!==e.nodeId)return this.finish(`unbound`,[],t)}return this.header?this.header.status===`verified`?this.finish(`ready`,this.records.flatMap(({record:e})=>this.windowGap(e,t)?[]:e.entries),t,this.agent===`gemini`?{kind:`rows`}:{kind:`codex`}):this.finish(this.header.status===`unsupported`?`unsupported`:`unbound`,[],t):this.claudeSnapshot(t,e)}claudeSnapshot(e,t){let n=new Map;for(let{record:e}of this.records)e.node&&n.set(e.node.id,e);let r=new Map([...n].filter(([,e])=>e.node.scope===`main`)),i=new Set([...r.values()].flatMap(e=>{let t=this.parentOf(e.node);return t?[t]:[]})),a=new Map,o=null;for(let e of r.values()){if(i.has(e.node.id))continue;let t=e,n=[],s=new Set,c=null;for(;t&&!s.has(t.node.id);){let e=t.node.id;if(t.node.mainMessage){c=t;break}if(a.has(e)){c=a.get(e);break}s.add(e),n.push(e),t=this.parentRecord(t.node,r)}for(let e of n)a.set(e,c);c&&(!o||c.start>o.start)&&(o=c)}if(t&&(o=t.nodeId?r.get(t.nodeId)??null:null),!o)return this.finish(r.size&&[...r.values()].some(e=>e.node.mainMessage)?`unsupported`:`unbound`,[],e);if(!t&&o.node.session!==this.expected)return this.finish(`unbound`,[],e);let s=[],c=new Set,l=o,u=!0,d=!1;for(;l;){if(c.has(l.node.id))return this.finish(`unsupported`,[],`unlinked`);if(c.add(l.node.id),s.push(l),this.parentOf(l.node)===null){d=!0;break}let e=this.parentRecord(l.node,r);if(!e){u=!1;break}l=e}s.reverse();let{entries:f,after:p}=this.mainEntries(r,s,c),m=new Set(f.map(e=>e.id));for(let e of r.values())e.entries.some(e=>!m.has(e.id))&&(this.unplacedMain=Math.max(this.unplacedMain,e.start));let h=new Map,g=new Map,_=!1;for(let e of n.values()){if(e.node.scope===`main`||!e.entries.length)continue;let t=e,r=new Set,i=null,a=e;for(;t&&t.node.scope!==`main`&&!r.has(t.node.id);){if(g.has(t.node.id)){i=g.get(t.node.id);break}r.add(t.node.id),a=t,t=this.parentRecord(t.node,n)}t?.node.scope===`main`&&(i={main:t,root:a});for(let e of r)g.set(e,i);if(!i){_=!0;continue}if(!c.has(i.main.node.id))continue;let o=e.node.scope===`side:unknown`?`side:unknown:${i.root.node.id}`:e.node.scope,s=h.get(o)??{records:[],anchor:i.main.node.id};s.records.push(e),h.set(o,s)}let v=[],y=new Map;for(let{records:e,anchor:t}of h.values()){e.sort((e,t)=>e.start-t.start);let n=To(e,`side:${e[0].start}`);n&&(v.push({at:p.get(t)??0,start:e[0].start,entry:n}),y.set(n.id,Math.max(...e.map(e=>e.end))))}_&&v.push({at:0,start:0,entry:Object.freeze({id:`unlinked-side`,kind:`unsupported`,text:`Some subagent activity could not be linked to this conversation.`})});let b=new Map(this.records.flatMap(({record:e})=>e.entries.map(t=>[t.id,e.start])));for(let{record:t}of this.records){if(t.node||t.kind!==`unsupported`&&t.kind!==`skipped`||this.windowGap(t,e))continue;let n=f.findIndex(e=>(b.get(e.id)??1/0)>=t.start);for(let e of t.entries)v.push({at:n===-1?f.length:n,start:t.start,entry:e})}v.sort((e,t)=>t.at-e.at||t.start-e.start);for(let{at:e,entry:t}of v)f.splice(e,0,t);let x=new Set(s.map(e=>e.node.id));return this.finish(`ready`,f,!u&&e===`complete`?`unlinked`:d&&e===`unloaded`?`complete`:e,{kind:`claude`,nodes:Object.freeze(s.map(e=>Object.freeze({id:e.node.id,start:e.start}))),parallel:Object.freeze([...c].filter(e=>!x.has(e)).flatMap(e=>{let t=r.get(e);return t?[Object.freeze({id:e,start:t.start})]:[]}))},y)}mainEntries(e,t,n){let r=new Map;for(let e of t)e.node.role===`assistant`&&e.node.mainMessage&&e.node.response&&r.set(e.node.response,e);let i=new Map,a=new Map;for(let t of e.values())if(t.node.mainMessage&&t.node.role===`assistant`){for(let e of t.node.calls)a.set(e.id,a.has(e.id)?null:t);if(t.node.response&&r.has(t.node.response)){let e=i.get(t.node.response)??[];e.push(t),i.set(t.node.response,e)}}let o=new Map,s=new Map;for(let t of e.values())if(!(t.node.meta||t.node.role!==`user`||!n.has(t.node.id)&&!t.node.resultsOnly))for(let i of t.node.results){let c=t.node.sourceAssistant?e.get(t.node.sourceAssistant):void 0;if(t.node.sourceAssistant&&!c?.node.calls.some(e=>e.id===i.id))continue;if(!c){let n=this.parentRecord(t.node,e);c=n?.node.calls.some(e=>e.id===i.id)?n:a.get(i.id)??void 0}let l=c?.node.response;if(!c?.node.mainMessage||!l||!r.has(l))continue;let u=t.entries.find(e=>e.id===i.entry);if(!u)continue;s.set(u.id,`${l}/${i.id}`);let d=o.get(l)??new Map,f=d.get(i.id);(!f||n.has(t.node.id)&&!n.has(f.record.node.id)||n.has(t.node.id)===n.has(f.record.node.id)&&wo(t,f.record)<0)&&d.set(i.id,{record:t,entry:u,call:i.id}),o.set(l,d)}let c=new Set;for(let e of o.values())for(let t of e.values())c.add(t.entry.id);let l=[],u=new Set,d=e=>{(!s.has(e.id)||c.has(e.id))&&(u.has(e.id)||(u.add(e.id),l.push(e)))},f=new Set(n),p=new Map;for(let e of t){if(!e.node.meta)for(let t of e.entries)d(t);p.set(e.node.id,l.length);let t=e.node.response;if(t&&r.get(t)===e){for(let e of(i.get(t)??[]).sort(wo))if(!f.has(e.node.id)){n.add(e.node.id);for(let t of e.entries)d(t);p.set(e.node.id,l.length)}for(let e of[...o.get(t)?.values()??[]].sort((e,t)=>wo(e.record,t.record)))f.has(e.record.node.id)||(n.add(e.record.node.id),d(e.entry),p.set(e.record.node.id,l.length))}}return{entries:l,after:p}}finish(e,t,n,r=null,i){let a=this.mergeUnshown(t);t=a.entries;let o=[],s=2;if(e===`ready`){for(let e=t.length-1;e>=0;e--){let r=t[e],i=Buffer.byteLength(JSON.stringify(r))+1;if(o.length>=1999||s+i>261632){n=`truncated`;break}o.push(r),s+=i}o.reverse()}let c=new Map(this.records.flatMap(({record:e})=>e.node?.mainMessage&&!e.node.meta&&e.entries[0]&&this.turnStart(e,e.entries[0].id)?e.entries.map(t=>[t.id,e.end]):[])),l=new Map(this.records.flatMap(({record:e})=>e.entries.map(t=>[t.id,e.end])));for(let[e,t]of i??[])l.set(e,t);for(let[e,t]of a.members)l.set(e,Math.max(...t.map(e=>l.get(e)??1/0)));let u=new Set(o.map(e=>e.id));this.precedingEnd.clear();let d=0;for(let e of t){e.id!==`unlinked-side`&&!e.id.startsWith(`history:`)&&(d=Math.max(d,l.get(e.id)??1/0)),u.has(e.id)&&this.precedingEnd.set(e.id,d);let t=c.get(e.id);t!==void 0&&d>t&&(this.unplacedMain=Math.max(this.unplacedMain,t))}if(e===`ready`&&this.latestUnanchored&&(n===`unloaded`||n===`truncated`)){let e=o.findIndex(e=>e.id!==`unlinked-side`&&this.cut(e,r)!==null);e>0&&(o=o.filter((t,n)=>n>=e||t.id===`unlinked-side`))}if(e===`ready`){let e={unloaded:`Earlier conversation is not loaded.`,truncated:`Earlier conversation omitted to save memory.`,unlinked:`Some earlier conversation entries could not be linked.`};e[n]&&o.unshift(Object.freeze({id:`history:${n}`,kind:`status`,text:e[n]}))}let f=o.map(e=>{let t=this.entryFingerprints.get(e);return t===void 0&&(t=xo(e),this.entryFingerprints.set(e,t)),t}),p=this.previous!==null&&this.previous.length<=f.length&&this.previous.every((e,t)=>e===f[t])?this.previous.length===f.length?`unchanged`:`append`:`replace`;this.previous=f,this.coveredThrough=this.through;let m=e===`ready`&&this.agent===`claude`?this.queued():null;return this.latest=Object.freeze({state:e,entries:Object.freeze(o),history:n,change:p,revision:this.revision,branch:r&&e===`ready`?Object.freeze(r):null,...m&&{queued:m}}),this.latest}queued(){let e=[],t=(t,n)=>{let r=t.content?e.findIndex(e=>e.content===t.content):n?0:-1;r>=0&&r<e.length&&e.splice(r,1)};for(let n of this.queue)n.operation===`enqueue`?(n.text||n.attachment)&&e.push(n):n.operation===`dequeue`?t(n,!0):n.operation===`remove`?t(n,!1):e.length=0;return Object.freeze(e.slice(0,D.queuedItems).map(e=>Object.freeze({...e.text&&{text:e.text},...e.attachment&&{attachment:!0}})))}mergeUnshown(e){let t=new Map,n=new Set(this.records.flatMap(({record:e})=>e.kind===`skipped`?e.entries.filter(e=>e.text!==da).map(e=>e.id):[])),r=e=>e.id!==`unlinked-side`&&(e.kind===`unsupported`||n.has(e.id));if(!e.some(r))return{entries:e,members:t};let i=[];for(let n=0;n<e.length;){let a=e[n];if(!r(a)){i.push(a),n++;continue}let o=[];for(;n<e.length&&r(e[n]);)o.push(e[n++].id);t.set(a.id,o),i.push(Object.freeze({id:a.id,kind:`unsupported`,text:o.length===1?`1 step couldn't be shown here.`:`${o.length} steps couldn't be shown here.`}))}return{entries:i,members:t}}forgetUnseen(e){e.end>this.coveredThrough&&e.node?.scope===`main`&&(e.node.results.length||e.node.role===`assistant`)&&(this.unplacedMain=Math.max(this.unplacedMain,e.start))}};const Do=8388608,Oo=D.batchBytes-2048;var ko=class{session;header;document;decoder;anchor;raw=null;consumed=0;closed=!1;reach=262144;target=0;windowStart=0;decoded=[];decodedChars=0;carry=[];constructor(e,t,n){this.session=t,this.header=n,this.anchor=Object.freeze({...e}),this.target=this.anchor.end,this.begin()}begin(){this.document=new Eo(this.anchor.agent,this.session),this.anchor.agent===`codex`&&this.header&&this.document.append([this.header]);let e=Math.max(0,this.anchor.end-this.reach);this.windowStart=e,this.decoded=[],this.decodedChars=0,this.document.beginWindow(e),this.decoder=new ua(e,e>0,Ya(this.anchor.agent))}keep(e){if(this.decoded){for(let t of e)for(let e of t.entries)this.decodedChars+=e.text.length+(e.detail?.length??0);if(this.decoded.length+e.length>2048||this.decodedChars>4194304){this.decoded=null;return}this.decoded.push(...e)}}joinCarry(){if(this.raw||this.decoder.offset<this.target||!this.carry.length)return;let e=this.carry;this.carry=[];for(let t=0;t<e.length;t+=64)this.document.append(e.slice(t,t+64));this.keep(e),this.target=this.anchor.end,this.decoder.close(),this.decoder=new ua(this.target,!1,Ya(this.anchor.agent))}widen(){if(this.reach>=8388608||this.anchor.end<=this.reach)return null;this.reach=Math.min(Do,this.reach*2);let e=this.decoded?.filter(e=>!(e.start===this.windowStart&&this.windowStart>0));return e?.length?(this.carry=e,this.target=e[0].start):(this.carry=[],this.target=this.anchor.end),this.raw?.fill(0),this.raw=null,this.consumed=0,this.decoder.close(),this.document.close(),this.begin(),{status:`reading`}}close(){this.closed=!0,this.raw?.fill(0),this.raw=null,this.document.close(),this.decoder.close()}async next(e){if(this.closed)return{status:`unavailable`};if(!this.raw){this.joinCarry();let t=this.target-this.decoder.offset;if(t<=0)return this.finish();let n=await e(this.decoder.offset,Math.min(t,Yi));if(this.closed)return n.status===`data`&&n.bytes.fill(0),{status:`unavailable`};if(n.status!==`data`)return n;if(!n.bytes.byteLength||n.offset!==this.decoder.offset||n.bytes.byteLength>t)return n.bytes.fill(0),this.close(),{status:`unavailable`};this.raw=n.bytes,this.consumed=0}for(let e=0;e<4&&this.raw;e++){let e=this.raw.subarray(this.consumed),t=this.decoder.push(e);e.fill(0,0,t.consumed),this.consumed+=t.consumed;let n=t.lines.map(e=>Xa(this.anchor.agent,e));this.document.append(n),this.keep(n),this.consumed===this.raw.byteLength&&(this.raw.fill(0),this.raw=null,this.consumed=0)}return this.joinCarry(),this.raw||this.decoder.offset<this.target?{status:`reading`}:this.finish()}finish(){let e=this.document.snapshot(this.anchor),t=e.entries.findIndex(e=>e.id===this.anchor.entryId);if(e.state!==`ready`||t<0)return this.widen()||(this.close(),{status:`unavailable`});let n=e.entries.slice(0,t).filter(e=>!e.id.startsWith(`history:`)&&e.id!==`unlinked-side`),r=[],i=0;for(let e=n.length-1;e>=0;e--){let t=n[e],a=Buffer.byteLength(JSON.stringify(t));if(r.length>=D.entriesPerBatch||i+a>Oo)break;r.push(Object.freeze({entry:t,anchor:this.document.anchor(t.id)})),i+=a}r.reverse();let a=r.findIndex(e=>e.anchor);a>0&&r.splice(0,a);let o=e.history===`complete`&&r.length<n.length?`unloaded`:e.history;if(a<0&&o!==`complete`){let e=this.widen();if(e)return e}let s=e.entries.some(e=>e.id===`unlinked-side`)?`unlinked`:o;return this.close(),!r.length&&(n.length||s!==`complete`)?{status:`unavailable`}:Object.freeze({status:`page`,entries:Object.freeze(r),history:s,more:o!==`complete`,branch:e.branch})}};const Ao=262144;var jo=class{pool;sources=new Map;working=null;closed=!1;constructor(e={}){this.pool=e}get active(){return this.sources.size}get busy(){return this.working!==null}create(e){if(this.closed||this.sources.size>=10)return null;let t={};this.sources.set(t,null);try{let n=new Mo(e,this.pool.onVersion,{begin:()=>this.closed||this.working?!1:(this.working=n,!0),end:()=>{this.working===n&&(this.working=null)},release:()=>{this.sources.delete(t)}});return this.closed?(n.close(),null):(this.sources.set(t,n),n.activate(),n)}catch{return this.sources.delete(t),null}}close(){this.closed=!0;for(let e of[...this.sources.values()])e?.close()}},Mo=class{onVersion;admission;controller=new AbortController;options;onAbort=()=>this.close();reason=null;file=null;antigravity=null;document=null;decoder=null;header=null;canonicalHeader=null;anchors=new WeakSet;history=null;raw=null;consumed=0;pending=!1;fileClosed=!0;released=!1;discontinuity=0;windowStart=0;reach=Ao;currentRevision=null;target=null;timer;watcher=null;antigravityReference;changeListener=null;finishStopped;stopped=new Promise(e=>{this.finishStopped=e});finishDrained;drained=new Promise(e=>{this.finishDrained=e});constructor(e,t,n){this.onVersion=t,this.admission=n;let r=e=>{let t=e.length;if(!Array.isArray(e)||!Number.isSafeInteger(t)||t<0||t>8)throw TypeError(`Invalid transcript roots`);let n=[];for(let r=0;r<t;r++)n.push(e[r]);return n};this.options={enabled:e.enabled.bind(e),identity:e.identity.bind(e),signal:e.signal,roots:{claude:r(e.roots.claude),codex:r(e.roots.codex),...e.roots.agy&&{agy:r(e.roots.agy)},...e.roots.gemini&&{gemini:r(e.roots.gemini)}}}}activate(){this.options.signal?.addEventListener(`abort`,this.onAbort,{once:!0}),this.available()}close(){this.stop(`cancelled`)}poll(){return this.run(()=>this.advance())}confirm(e){return this.run(async()=>{if(this.antigravity){if(this.currentRevision!==e)return{status:`changed`};let t=await this.antigravity.changed(this.controller.signal);return this.available()?t===null?this.stop(`changed`):(t&&(this.currentRevision=null),t?{status:`changed`}:{status:`confirmed`,caughtUp:!0}):this.stopResult()}if(!Number.isSafeInteger(e)||e<0||this.currentRevision!==e||!this.file||!this.decoder)return{status:`changed`};let t=await this.file.verify();return this.available()?t.status===`stopped`?this.stop(t.reason):t.status===`busy`?t:this.raw||this.header||t.size<this.decoder.offset||this.currentRevision!==e?(this.currentRevision=null,{status:`changed`}):{status:`confirmed`,caughtUp:t.size===this.decoder.offset}:this.stopResult()})}anchor(e,t){if(!this.available()||e!==this.currentRevision)return null;let n=this.document?.anchor(t)??null;return n&&this.anchors.add(n),n}older(e){return this.run(async()=>{if(!this.file||!this.anchors.has(e))return{status:`unavailable`};this.history?.anchor!==e&&(this.history?.reader.close(),this.history={anchor:e,reader:new ko(e,this.file.identity.session,this.canonicalHeader)});let t=this.history,n=await this.file.verify();if(!this.available())return this.stopResult();if(n.status===`stopped`)return this.stop(n.reason);if(n.status===`busy`)return n;if(this.raw||this.header||n.size!==this.decoder?.offset)return{status:`refresh`};if(!this.document?.permits(e))return this.cancelOlder(),{status:`unavailable`};let r=await t.reader.next((e,t)=>this.file.read(e,t));if(!this.available())return this.stopResult();if(this.history!==t)return{status:`unavailable`};if(r.status===`stopped`)return this.stop(r.reason);if(this.file.size!==this.decoder?.offset)return this.cancelOlder(),{status:`refresh`};if(r.status===`page`)for(let e of r.entries)e.anchor&&this.anchors.add(e.anchor);return r.status!==`reading`&&r.status!==`busy`&&(t.reader.close(),this.history=null),r})}cancelOlder(){this.history?.reader.close(),this.history=null}async idle(){if(!this.available()||this.pending)return!1;if(this.antigravity)return this.currentRevision!==null&&await this.antigravity.unchanged()&&this.available();let e=this.file;return!e||!this.decoder||this.raw||this.header||this.currentRevision===null||this.target!==null||this.decoder.offset!==e.size?!1:await e.unchanged()&&this.available()&&this.file===e}get reference(){if(!this.reason)return this.antigravity?this.antigravityReference:this.file?.identity.reference}onChange(e){this.changeListener=e}watchFile(e){try{let t=gr(e,{persistent:!1},()=>this.changeListener?.());t.on(`error`,()=>{t.close(),this.watcher===t&&(this.watcher=null)}),this.watcher=t}catch{}}async run(e){if(!this.available())return this.stopResult();if(this.pending||!this.admission.begin())return{status:`busy`};this.pending=!0,this.timer=setTimeout(()=>this.stop(`timeout`),1e4);let t=Promise.resolve().then(async()=>{try{return this.available()?await e():this.stopResult()}catch{return this.stop(`unreadable`)}finally{clearTimeout(this.timer),this.timer=void 0,this.pending=!1,this.admission.end(),this.finish()}}),n=await Promise.race([t,this.stopped]);return this.available()?n:this.stopResult()}async advance(){if(this.antigravity)return this.readAntigravity();if(!this.file){let e=await this.options.identity(this.controller.signal).catch(()=>null);if(!this.available())return this.stopResult();if(e?.agent===`agy`)return this.antigravityReference=e.reference,this.antigravity=new yo(this.options,e),this.readAntigravity();let t=await na.open({...this.options,signal:this.controller.signal});if(t.status===`stopped`)return this.stop(t.reason);if(this.file=t.file,this.fileClosed=!1,t.file.closed.then(()=>{this.fileClosed=!0,this.finish()}),!this.available())return t.file.close(),this.stopResult();if(!Sa(t.file.identity.session))return this.stop(`unbound`);this.watchFile(t.file.watchPath),this.document=new Eo(t.file.identity.agent,t.file.identity.session,this.onVersion),t.file.identity.agent===`claude`?this.window(Math.max(0,t.file.size-Ao)):(this.header=new Za(t.file.identity.session),this.decoder=new ua(0,!1,Ya(t.file.identity.agent)))}let e=this.file;if(this.raw){let t=await e.verify();if(!this.available())return this.stopResult();if(t.status===`stopped`)return this.stop(t.reason);if(t.status===`busy`)return t}else{this.target===this.decoder.offset&&(this.target=null);let t=this.target===null?Yi:this.target-this.decoder.offset,n=await e.read(this.decoder.offset,Math.max(1,Math.min(Yi,t)));if(!this.available())return n.status===`data`&&n.bytes.fill(0),this.stopResult();if(n.status===`stopped`)return this.stop(n.reason);if(n.status===`busy`)return n;this.raw=n.bytes,this.consumed=0,this.target??=n.size}for(let t=0;t<4&&this.raw;t++){let t=this.raw.subarray(this.consumed),n=this.decoder.push(t);if(t.fill(0,0,n.consumed),this.consumed+=n.consumed,this.consumed===this.raw.byteLength&&this.clearRaw(),this.header&&n.lines.length){let t=Xa(e.identity.agent,n.lines[0]);if(this.header.observe(t),this.header.status!==`verified`)return this.stop(this.header.status===`mismatch`?`unbound`:`unsupported`);if(this.canonicalHeader=t,this.header=null,this.document.append([t]),e.size>262144)return this.window(e.size-Ao),this.catchingUp();this.document.append(n.lines.slice(1).map(t=>Xa(e.identity.agent,t)))}else!this.header&&n.lines.length&&this.document.append(n.lines.map(t=>Xa(e.identity.agent,t)));if(n.lines.length&&(this.currentRevision=null),this.header&&this.decoder.offset>131073)return this.stop(`unsupported`)}if(!this.available())return this.stopResult();if(!this.header&&this.lagged()||this.header||this.raw||this.decoder.offset!==this.target)return this.catchingUp();let t=this.document.snapshot();return t.state===`unsupported`?this.stop(`unsupported`):(t.state===`unbound`||this.unpageable(t))&&this.widen()?this.catchingUp():(this.currentRevision=t.state===`ready`?t.revision:null,this.target=null,{status:`snapshot`,snapshot:t,discontinuity:this.discontinuity,caughtUp:this.decoder.offset===e.size})}async readAntigravity(){let e=await this.antigravity.read(this.controller.signal);return this.available()?e.status===`stopped`?this.stop(e.reason):(this.currentRevision=e.snapshot.revision,{status:`snapshot`,snapshot:e.snapshot,discontinuity:0,caughtUp:!0}):this.stopResult()}lagged(){return this.file.size-this.decoder.offset<=Math.max(this.reach,4194304)?!1:this.discontinuity===2**53-1?(this.stop(`unsafe`),!0):(this.discontinuity++,this.reach=Ao,this.window(Math.max(0,this.file.size-Yi)),!0)}unpageable(e){return e.state===`ready`&&e.history===`unloaded`&&!this.document.hasCut()}widen(){return this.file.identity.agent!==`claude`||this.windowStart===0||this.reach>=8388608?!1:(this.reach=Math.min(Do,this.reach*2),this.window(Math.max(0,this.file.size-this.reach)),!0)}window(e){this.windowStart=e,this.anchors=new WeakSet,this.cancelOlder(),this.clearRaw(),this.decoder?.close(),this.decoder=new ua(e,e>0,Ya(this.file.identity.agent)),this.document.beginWindow(e),this.target=this.file.size,this.currentRevision=null}clearRaw(){this.raw?.fill(0),this.raw=null,this.consumed=0}catchingUp(){if(this.reason)return this.stopResult();let e=this.raw!==null||this.file!==null&&this.decoder!==null&&this.decoder.offset<this.file.size;return{status:`catching-up`,discontinuity:this.discontinuity,pending:e}}available(){if(this.reason)return!1;try{this.options.signal?.aborted?this.stop(`cancelled`):this.options.enabled()||this.stop(`disabled`)}catch{this.stop(`unreadable`)}return this.reason===null}stopResult(){return{status:`stopped`,reason:this.reason}}stop(e){return this.reason||(this.reason=e,clearTimeout(this.timer),this.watcher?.close(),this.watcher=null,this.changeListener=null,this.controller.abort(),this.options.signal?.removeEventListener(`abort`,this.onAbort),this.file?.close(),this.antigravity?.close(),this.antigravity=null,this.document?.close(),this.decoder?.close(),this.header?.close(),this.canonicalHeader=null,this.history?.reader.close(),this.history=null,this.clearRaw(),this.currentRevision=null,this.finishStopped(this.stopResult()),this.finish()),this.stopResult()}finish(){this.reason&&!this.pending&&this.fileClosed&&!this.released&&(this.released=!0,this.file=null,this.document=null,this.decoder=null,this.header=null,this.admission.release(),this.finishDrained())}};const No=2e3,Po=`[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`,Fo=RegExp(`^${Po}$`,`i`),Io=RegExp(`^(${Po})\\.jsonl$`,`i`),Lo=RegExp(`^(${Po})\\.db$`,`i`),Ro=RegExp(`^rollout-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-(${Po})(?:_(${Po}))?\\.jsonl$`,`i`),zo=/^session-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-([0-9a-f]{8})\.jsonl$/i,Bo=[/^\d{4}$/,/^(0[1-9]|1[0-2])$/,/^(0[1-9]|[12]\d|3[01])$/];var J=class extends Error{reason;constructor(e){super(e),this.reason=e}};function Vo(e){return F(e)&&e.length<=4096&&xr(e)===e&&!Array.from(e).some(e=>{let t=e.charCodeAt(0);return t<32||t>=127&&t<=159||e.length===1&&t>=55296&&t<=57343})}function Ho(e,t){return e.dev===t.dev&&e.ino===t.ino}function Uo(e,t){return Ho(e,t)&&e.mtimeNs===t.mtimeNs&&e.ctimeNs===t.ctimeNs}function Wo(e){return process.getuid===void 0||e.uid===BigInt(process.getuid())}function Go(e){return e?.code===`ENOENT`}function Ko(e,t){return e===`agy`?Lo.exec(t)?.[1]?.toLowerCase()??null:t.endsWith(`.jsonl`)?(e===`claude`?Io:Ro).exec(t)?.[1]?.toLowerCase()??null:null}function qo(e,t){return Bo[t]?.test(e)??!1}function Jo(e,t){let n=t.split(Cr);return F(t)||n.some(e=>e===``||e===`.`||e===`..`)||!Ko(e,n.at(-1))?!1:e===`claude`?n.length===2:e===`agy`?n.length===1:n.length===1||n.length===4&&n.slice(0,3).every(qo)}var Yo=class{options;busy=!1;constructor(e){this.options=e}async locate(e,t){let n=()=>{if(t?.aborted)return`cancelled`;try{return this.options.enabled()?null:`disabled`}catch{return`unreadable`}},r=n();if(r)return{status:`unavailable`,reason:r};if(this.busy)return{status:`busy`};this.busy=!0;let i=new AbortController,a=null,o,s=new Promise(e=>{o=t=>{a||(a=n()??t,i.abort(),e({status:`unavailable`,reason:a}))}}),c=()=>o(`cancelled`),l=setTimeout(()=>o(`limit`),No);t?.addEventListener(`abort`,c,{once:!0}),t?.aborted&&c();let u=(async()=>{try{let t=await new Xo(this.options,{...e},i.signal).run(),r=n()??a;return r?{status:`unavailable`,reason:r}:t}catch(e){return{status:`unavailable`,reason:n()??a??(e instanceof J?e.reason:`unreadable`)}}finally{this.busy=!1}})();try{let e=await Promise.race([u,s]),t=n()??a;return t?{status:`unavailable`,reason:t}:e}finally{clearTimeout(l),t?.removeEventListener(`abort`,c)}}},Xo=class{options;reference;signal;deadline=performance.now()+No;directories=new Map;candidates=new Map;missingRoots=new Set;entries=0;session=``;constructor(e,t,n){this.options=e,this.reference=t,this.signal=n}check(){if(this.signal?.aborted)throw new J(`cancelled`);if(!this.options.enabled())throw new J(`disabled`);if(performance.now()>=this.deadline)throw new J(`limit`)}async run(){this.check();let{agent:e,kind:t,value:n}=this.reference;if(e!==`claude`&&e!==`codex`&&e!==`agy`&&e!==`gemini`||t!==`id`&&t!==`path`||e===`gemini`&&t!==`id`||typeof n!=`string`)throw new J(`unsafe`);if(this.session=t===`id`?n.toLowerCase():Ko(e,br(n))??``,!Fo.test(this.session)||t===`path`&&!Vo(n))throw new J(`unbound`);let r=this.options.roots[e];if(!Array.isArray(r)||!r.length||r.length>8)throw new J(`unsafe`);let i=[...r],a=new Set;for(let e of i){if(this.check(),!Vo(e))throw new J(`unsafe`);let t=!1;try{let n=await B(e);if(t=!0,this.check(),await this.directory(n),[...a].some(e=>e!==n&&(n.startsWith(e.endsWith(Cr)?e:`${e}${Cr}`)||e.startsWith(n.endsWith(Cr)?n:`${n}${Cr}`))))throw new J(`unsafe`);a.add(n)}catch(n){if(!Go(n))throw n;if(t)throw new J(`changed`);try{throw await z(e),new J(`unsafe`)}catch(e){if(!Go(e))throw e}this.check(),this.missingRoots.add(e)}}if(t===`path`){let t=[...a].find(t=>Jo(e,Sr(t,n)));if(!t)throw new J(`unsafe`);let r=await z(n,{bigint:!0}).catch(e=>{throw Go(e)?new J(`unbound`):e});if(this.check(),!r.isFile()||!Wo(r))throw new J(`unsafe`);let i=await B(n);if(this.check(),i!==n)throw new J(`unsafe`);let o=P(i);for(;o!==t;)await this.directory(o),o=P(o);await this.candidate(i);let s=this.candidates.get(i);if(!s||!Ho(r,s))throw new J(`changed`)}else for(let t of a)e===`claude`?await this.claude(t):e===`agy`?await this.candidate(I(t,`${this.session}.db`)):e===`gemini`?await this.gemini(t):await this.codex(t,0);for(let[e,t]of this.directories){this.check();let n=await z(e,{bigint:!0});if(this.check(),!n.isDirectory()||!Uo(t,n)||await B(e)!==e)throw new J(`changed`)}for(let e of this.missingRoots){this.check();try{throw await z(e,{bigint:!0}),new J(`changed`)}catch(e){if(!Go(e))throw e}}if(!this.candidates.size)throw new J(`unbound`);let[o,s]=[...this.candidates][0],c=await z(o,{bigint:!0});if(this.check(),!c.isFile()||!Wo(c)||!Ho(s,c))throw new J(`changed`);return{status:`candidate`,candidate:Object.freeze({agent:e,path:o,session:this.session})}}async directory(e){if(this.check(),this.directories.has(e))return;if(this.directories.size>=512)throw new J(`limit`);if(!Vo(e))throw new J(`unsafe`);let t=await z(e,{bigint:!0});if(this.check(),!t.isDirectory()||!Wo(t)||await B(e)!==e)throw new J(`unsafe`);this.check(),this.directories.set(e,t)}async candidate(e){if(this.check(),!Vo(e))throw new J(`unsafe`);let t;try{t=await z(e,{bigint:!0})}catch(e){if(Go(e))return;throw e}if(this.check(),!t.isFile()||!Wo(t)||await B(e)!==e)throw new J(`unsafe`);if(this.check(),this.candidates.set(e,t),this.candidates.size>1)throw new J(`ambiguous`)}async visit(e,t){await this.directory(e),this.check();let n=await Rr(e,{bufferSize:32});try{for(;;){this.check();let e=await n.read();if(this.check(),!e)break;if(++this.entries>16384)throw new J(`limit`);await t(e.name)}}finally{await n.close()}}async claude(e){await this.visit(e,async t=>{let n=I(e,t),r=await z(n,{bigint:!0});if(this.check(),r.isSymbolicLink())throw new J(`unsafe`);r.isDirectory()&&(await this.directory(n),await this.candidate(I(n,`${this.session}.jsonl`)))})}async gemini(e){let t=this.session.slice(0,8);await this.visit(e,async n=>{let r=I(e,n),i=await z(r,{bigint:!0});if(this.check(),i.isSymbolicLink())throw new J(`unsafe`);if(!i.isDirectory())return;let a=I(r,`chats`),o=await z(a,{bigint:!0}).catch(e=>{if(Go(e))return null;throw e});if(this.check(),o){if(o.isSymbolicLink()||!o.isDirectory())throw new J(`unsafe`);await this.visit(a,async e=>{zo.exec(e)?.[1]?.toLowerCase()===t&&await this.candidate(I(a,e))})}})}async codex(e,t){await this.visit(e,async n=>{let r=I(e,n);if((t===0||t===3)&&Ko(`codex`,n)===this.session)await this.candidate(r);else if((t===0||t===3)&&n.toLowerCase().startsWith(`rollout-`)&&n.toLowerCase().includes(this.session))throw new J(`unbound`);else t<3&&qo(n,t)&&await this.codex(r,t+1)})}},Zo=class{options;roots;followers;locator;entries=new Set;off;timer=null;working=null;closed=!1;constructor(e){this.options={...e},this.roots=e.roots??{claude:[I(process.env.CLAUDE_CONFIG_DIR||I(N(),`.claude`),`projects`)],codex:[I(process.env.CODEX_HOME||I(N(),`.codex`),`sessions`)],agy:[I(N(),`.gemini`,`antigravity-cli`,`conversations`)],gemini:[I(process.env.GEMINI_CLI_HOME||N(),`.gemini`,`tmp`)]},this.followers=e.followers??new jo({onVersion:e.onAgentVersion}),this.locator=e.locator??new Yo({roots:this.roots,enabled:()=>!this.closed&&this.options.enabled()}),this.off=e.backend.on(e=>{if(e.type===`conversation-settled`){for(let e of this.entries)e.source?.retry();return}if(e.type===`conversation-changed`||e.type===`session-removed`){for(let t of this.entries)t.source?.sessionId===e.sessionId&&t.source.invalidate(e.type===`session-removed`?`ended`:`changed`);this.schedule()}})}get sharedLocator(){return this.locator}attach(e){if(this.closed||this.entries.size>=10)return{focus(){},receive(){},close(){}};let t={focused:null,source:null,current:e.current,send:e.send,lane:e.background(()=>this.current(t)?t.source?.offer()??!1:!1,()=>this.current(t)&&t.source!==null)};return this.entries.add(t),{focus:e=>{this.current(t)&&t.focused!==e&&(t.focused=e,t.source?.close(),t.source=null)},receive:(e,n)=>{if(!this.current(t))return;let r=v.safeParse(e);if(!(!r.success||!Number.isSafeInteger(n)||n<1||n>D.envelopeBytes)){if(e=r.data,e.type===`conversation.subscribe`){if(t.source?.subscriptionId===e.subscriptionId)return;t.source?.close(),t.source=null;let n=e.sessionId;t.focused=n;let r,i=null,a=()=>this.current(t)&&t.source===r&&t.focused===n&&this.options.enabled();r=new Ji({subscriptionId:e.subscriptionId,sessionId:n,now:()=>this.options.now?.()??performance.now(),newId:()=>this.options.newId?.()??O(Oe(16)),enabled:a,follow:()=>(i=this.followers.create({enabled:a,roots:this.roots,identity:Hi({enabled:a,locator:this.locator,reference:e=>this.options.backend.conversationReference(n,e)})}),i),chat:{adopt:()=>{let e=i?.reference;return e?this.options.chat?.idFor(n,e):void 0},known:()=>{let e=i?.reference;return e?this.options.chat?.knownId(n,e):void 0}},send:e=>this.current(t)&&t.source===r&&t.send(e),wake:()=>t.lane.wake(),due:()=>this.schedule(!0)}),t.source=r,this.options.enabled()||r.invalidate(`disabled`),t.lane.wake()}else t.source?.receive(e,n),e.type===`conversation.cancel`&&t.source?.subscriptionId===e.subscriptionId&&(t.source=null);this.schedule()}},close:()=>this.retire(t)}}sessionChanged(e){if(!this.closed){for(let t of this.entries)t.source?.sessionId===e&&t.source.invalidate(`changed`);this.schedule()}}consentChanged(){if(!this.closed){for(let e of this.entries)e.source&&e.source.invalidate(this.options.enabled()?`changed`:`disabled`);this.schedule()}}close(){if(!this.closed){this.closed=!0,this.off(),this.timer&&clearTimeout(this.timer),this.timer=null;for(let e of this.entries)this.retire(e);this.followers.close()}}current(e){return!this.closed&&this.entries.has(e)&&e.current()}retire(e){this.entries.delete(e)&&(e.source?.close(),e.source=null,e.lane.close())}schedule(e=!1){if(!this.closed&&[...this.entries].some(e=>e.source)){if(this.timer){if(!e)return;clearTimeout(this.timer)}this.timer=setTimeout(()=>{this.timer=null,this.pump()},e?0:200),this.timer.unref?.()}}pump(){if(!this.closed){for(let e of this.entries)e.current()?e.source?.tick():this.retire(e);if(!this.working){let e=[...this.entries].find(e=>e.source?.needsWork);if(e?.source){this.entries.delete(e),this.entries.add(e);let t={};this.working=t,e.source.work().finally(()=>{this.working===t&&(this.working=null),this.schedule([...this.entries].some(e=>e.source?.needsWork))})}}this.schedule()}}};const Qo=new Set([`bad-sig`,`fp-mismatch`]),$o=E.unacked*E.envelopeBytes;function es(e){if(e.t!==`ctrl`)return!1;let t=e.body;return typeof t==`object`&&!!t&&t.type===`auth`}function ts(e){if(e.t!==`ctrl`)return e.t;let t=e.body;return typeof t==`object`&&t&&typeof t.type==`string`?t.type:`ctrl`}function ns(e,t,n){let r=t*2**e,i=r*.2*(Math.random()*2-1);return Math.min(n,Math.max(0,r+i))}var rs=class extends Mr{opts;ws=null;stopped=!0;attempt=0;reconnectTimer=null;pingTimer=null;pongTimer=null;authTimer=null;authed=!1;relayWithholdsTurn=!1;ice=new gi;log;constructor(e){super(),this.opts=e,this.log=e.log.child({unit:`relay`})}get online(){return this.authed&&this.ws?.readyState===Ur.OPEN}start(){this.stopped&&(this.stopped=!1,this.attempt=0,this.connect())}stop(){this.stopped=!0,this.clearTimers();let e=this.ws,t=this.online;this.ws=null,this.authed=!1,e?.terminate(),t&&this.emit(`down`)}iceServers(){return this.refreshIceIfDue(),this.ice.servers(Date.now())}refreshIceIfDue(){let e=Date.now();this.authed&&this.ice.needsRefresh(e)&&this.ice.takeRefresh(e)&&this.sendCtrl({type:`ice-refresh`})}sendCtrl(e){return this.sendEnvelope({v:1,t:`ctrl`,from:this.opts.fp,seq:0,body:e})}sendEnvelope(e){return!this.authed&&!es(e)?(this.log.debug(`dropped send: not authenticated`,{type:ts(e)}),!1):this.ws?.readyState===Ur.OPEN?(this.ws.send(e.v===2?St(e):Ge(e),{binary:!0}),!0):(this.log.debug(`dropped send: socket not open`,{type:ts(e)}),!1)}sendBoundedEnvelope(e){let t=this.ws;if(!this.authed||t?.readyState!==Ur.OPEN)return!1;let n=e.v===2?St(e):Ge(e);if(n.byteLength>E.envelopeBytes)return!1;let r=t.bufferedAmount;return typeof r!=`number`||!Number.isFinite(r)||r<0||r>$o-n.byteLength?!1:(t.send(n,{binary:!0}),!0)}connect(){if(this.stopped)return;let e=Mt(this.opts.relayUrl,this.opts.fp);this.log.info(`connecting`,{attempt:this.attempt});let t=new Ur(e,{handshakeTimeout:1e4}),n=t;this.ws=t,t.on(`open`,()=>{this.ws===n&&(this.log.debug(`socket open`),this.authTimer=setTimeout(()=>{this.ws!==n||this.authed||(this.log.warn(`relay did not finish sign-in; reconnecting`),n.terminate())},this.opts.authTimeoutMs??2e4))}),t.on(`message`,(e,t)=>{if(this.ws!==n||!t)return;let r=new Uint8Array(e),i;try{i=ct(r)}catch(e){this.log.warn(`malformed frame from relay`,{code:e instanceof At?e.code:j(e)});return}if(i.t===`e2e`){this.authed&&this.emit(`e2e`,i,r.byteLength);return}let a;try{a=Ut(i.body)}catch(e){this.log.warn(`malformed ctrl from relay`,{code:e instanceof At?e.code:j(e)});return}this.onCtrl(a)}),t.on(`pong`,()=>{this.ws===n&&(this.pongTimer&&clearTimeout(this.pongTimer),this.pongTimer=null)}),t.on(`close`,e=>{this.ws===n&&this.onClose(e)}),t.on(`error`,e=>{this.ws===n&&this.log.warn(`socket error`,{name:j(e)})})}onCtrl(e){if(e.type===`challenge`){let t=be(this.opts.identity.ed25519.priv,d(e.connId,`agent`,this.opts.fp,e.nonce));this.sendCtrl({type:`auth`,role:`agent`,fp:this.opts.fp,ed25519Pub:this.opts.identity.ed25519.pub,sig:t,name:this.opts.name,appVersion:this.opts.appVersion,...this.opts.turn===!1&&{turn:!1}});return}if(e.type===`auth-ok`){this.authed=!0,this.authTimer&&clearTimeout(this.authTimer),this.authTimer=null,this.ice=new gi,e.iceServers&&this.ice.update(e.iceServers,e.iceExpiresInMs??0,Date.now()),this.attempt=0,this.startPing(),this.log.info(`authenticated`,{minFrameMs:e.minFrameMs}),this.relayWithholdsTurn=e.turnOff===!0,this.opts.turn===!1&&!this.relayWithholdsTurn&&this.log.warn(`relay does not withhold TURN from phones; update the relay to 0.3.0`),this.emit(`auth-ok`,e);return}if(e.type===`ice-servers`){this.ice.update(e.iceServers,e.iceExpiresInMs,Date.now());return}if(e.type===`auth-fail`){this.log.error(`auth failed`,{reason:e.reason}),Qo.has(e.reason)&&(this.stopped=!0),this.emit(`auth-fail`,e.reason);return}this.emit(`ctrl`,e)}onClose(e){let t=this.authed;if(this.authed=!1,this.clearTimers(),this.ws=null,e===4005){this.log.warn(`connection superseded by a newer agent`,{code:e}),this.stopped=!0,this.emit(`superseded`),this.emit(`down`);return}e===4413||e===4429?this.log.error(`relay closed connection`,{code:e}):this.log.info(`socket closed`,{code:e}),t&&this.emit(`down`),!this.stopped&&this.scheduleReconnect()}scheduleReconnect(){let e=this.opts.backoffMinMs??1e3,t=this.opts.backoffMaxMs??3e4,n=ns(this.attempt,e,t);this.attempt=Math.min(this.attempt+1,10),this.reconnectTimer=setTimeout(()=>this.connect(),n)}startPing(){if(this.pingTimer)return;let e=this.opts.pingIntervalMs??45e3,t=this.opts.pongTimeoutMs??1e4,n=this.ws;this.pingTimer=setInterval(()=>{this.ws===n&&n?.readyState===Ur.OPEN&&(this.refreshIceIfDue(),this.pongTimer&&clearTimeout(this.pongTimer),n.ping(),this.pongTimer=setTimeout(()=>{this.log.warn(`pong timeout; terminating socket`),n.terminate()},t))},e)}clearTimers(){this.reconnectTimer&&clearTimeout(this.reconnectTimer),this.pingTimer&&clearInterval(this.pingTimer),this.pongTimer&&clearTimeout(this.pongTimer),this.authTimer&&clearTimeout(this.authTimer),this.reconnectTimer=this.pingTimer=this.pongTimer=this.authTimer=null}},is=class{options;sender;startedAt;open=!0;admitted=!1;sending=!1;refusalAt=null;pending=null;nativeHistory=null;timedOutHistory=null;latestHistoryRequestId;historyRevoked=!1;anchor;anchorBound=!1;lastAcknowledgedGeneration;snapshotAccepted=!1;snapshotRequested=!1;refreshRequested=!1;constructor(e){if(!t.safeParse(e.subscriptionId).success||!Nt.safeParse(e.sessionId).success)throw Error(`Invalid screen stream identity`);let n=e.now();if(!Number.isFinite(n))throw Error(`Invalid screen stream clock`);this.options={...e,...e.history?{history:{...e.history}}:{}},this.startedAt=n,this.sender=new c({subscriptionId:e.subscriptionId,sessionId:e.sessionId,now:()=>this.readClock(),newTransferId:()=>this.options.newTransferId(),send:e=>this.admitChunk(e)})}offer(e,t){if(!this.canOfferScreen()||e.sessionId!==this.options.sessionId||e.gen!==t.generation||e.scrollbackTotal!==t.reported)return!1;if(e.type===`screen.diff`){if(!this.snapshotAccepted||this.lastAcknowledgedGeneration===void 0||e.gen!==this.lastAcknowledgedGeneration+1)return this.requestFreshSnapshot(),!1}else if(this.lastAcknowledgedGeneration!==void 0&&(e.gen<this.lastAcknowledgedGeneration||e.gen===this.lastAcknowledgedGeneration&&!this.refreshRequested))return!1;let n;try{if(e.type===`screen.snapshot`){let{type:t,sessionId:r,...i}=e,a=ee(i);if(!a.ok)return this.close(a.code),!1;n=a.bytes}else{let{type:t,sessionId:r,...i}=e;n=ke(i)}}catch{return e.type===`screen.diff`?this.requestFreshSnapshot():this.close(`invalid-transfer`),!1}if(!this.open)return!1;try{let t=this.sender.offer({kind:e.type===`screen.snapshot`?`snapshot`:`diff`,generation:e.gen},n);if(!this.reconcileSender())return!1;if(!t.accepted)return t.reason===`too-large`&&this.close(`screen-too-large`),!1}catch{return this.close(`invalid-transfer`),!1}return this.open?(this.pending={kind:e.type===`screen.snapshot`?`snapshot`:`diff`,generation:t.generation,reported:t.reported,...e.type===`screen.snapshot`&&t.capture!==void 0?{capture:t.capture}:{},finalSequence:null},e.type===`screen.snapshot`&&(this.snapshotAccepted=!0,this.snapshotRequested=!1,this.refreshRequested=!1),!0):!1}canOfferScreen(){if(this.tick(),!this.open||this.pending||this.sender.inFlight>=E.unacked)return!1;let e;try{e=this.sender.canOffer(`snapshot`)}catch{return this.close(`invalid-transfer`),!1}return!(!this.reconcileSender()||!e)}receive(e,t){if(!this.open||e.subscriptionId!==this.options.subscriptionId||(this.tick(),!this.open))return;if(!Number.isSafeInteger(t)||t<1||t>E.envelopeBytes||!tt.safeParse(e).success){this.close(`invalid-transfer`);return}if(e.type===`stream.cancel`){this.cancel();return}if(e.type===`stream.refresh`){this.refreshRequested=!0,this.requestFreshSnapshot();return}if(e.type===`stream.history.get`){this.requestHistory(e);return}if(e.type!==`stream.ack`){this.close(`invalid-transfer`);return}let n;try{n=this.sender.acknowledge(e.subscriptionId,e.through)}catch{this.close(`invalid-transfer`);return}if(!this.reconcileSender())return;if(n===`invalid`){this.close(`invalid-transfer`);return}if(n!==`advanced`)return;if(this.pending?.finalSequence!==null&&this.pending?.finalSequence!==void 0&&e.through>=this.pending.finalSequence){let e=this.pending;this.pending=null,this.lastAcknowledgedGeneration=e.generation,!this.anchorBound&&e.kind===`snapshot`&&(this.anchor=Object.freeze({generation:e.generation,reported:e.reported,...e.capture===void 0?{}:{capture:e.capture}}),this.anchorBound=!0)}let r=this.nativeHistory;r?.phase===`transfer`&&r.finalSequence!==null&&e.through>=r.finalSequence&&this.finishHistory(r)}requestHistory(e){let t=this.options.history;if(!t){this.close(`invalid-transfer`);return}if(e.requestId===this.nativeHistory?.requestId||e.requestId===this.latestHistoryRequestId)return;if(this.nativeHistory||this.timedOutHistory){this.sendHistoryError(e.requestId,`history-unavailable`);return}let n=this.anchor,r;try{r=this.sender.canOffer(`history`)}catch{this.close(`invalid-transfer`);return}if(!this.reconcileSender())return;if(this.historyRevoked||n&&!n.capture){this.latestHistoryRequestId=e.requestId,this.sendHistoryError(e.requestId,`history-reset`);return}if(!n?.capture||e.before>n.reported||this.sender.inFlight>=E.unacked||!r){this.latestHistoryRequestId=e.requestId,this.sendHistoryError(e.requestId,`history-unavailable`);return}let i;try{i=this.readClock()}catch{this.close(`invalid-transfer`);return}let a={requestId:e.requestId,before:e.before,count:e.count,anchor:n,controller:new AbortController,phase:`reading`,readDeadline:i+E.totalMs,readyDeadline:null,finalSequence:null};this.nativeHistory=a;let o;try{o=t.read(this.options.sessionId,{capture:n.capture,reported:n.reported,before:a.before,count:a.count,signal:a.controller.signal})}catch(e){this.failHistoryRead(a,e);return}Promise.resolve(o).then(e=>this.completeHistoryRead(a,e),e=>this.failHistoryRead(a,e)).catch(()=>{this.open&&this.nativeHistory===a&&this.close(`invalid-transfer`)})}completeHistoryRead(e,t){if(this.timedOutHistory===e){this.timedOutHistory=null;return}if(!this.open||this.nativeHistory!==e||e.phase!==`reading`)return;if(this.tick(),this.timedOutHistory===e){this.timedOutHistory=null;return}if(!this.open||this.nativeHistory!==e)return;if(typeof t!=`object`||!t){this.close(`invalid-transfer`);return}if(t.status===`reset`){this.historyRevoked=!0,this.finishHistory(e,`history-reset`);return}if(t.status===`unavailable`){if(![`unsupported`,`unanchored`,`busy`,`changed`,`fetch-window`].includes(t.reason)){this.close(`invalid-transfer`);return}this.finishHistory(e,`history-unavailable`,t.reason===`fetch-window`?`fetch-window`:void 0);return}if(t.status===`cancelled`){this.finishHistory(e,`history-unavailable`);return}if(t.status!==`page`&&t.status!==`boundary`){this.close(`invalid-transfer`);return}if(t.status===`page`&&(!Array.isArray(t.lines)||t.lines.length>e.count)){this.close(`invalid-transfer`);return}let n=Ee({...t,kind:`history`,generation:e.anchor.generation,requestId:e.requestId,before:e.before});if(!n.ok){n.code===`history-line-too-large`?this.finishHistory(e,`history-line-too-large`):this.close(`invalid-transfer`);return}try{let t=this.sender.offer({kind:`history`,generation:e.anchor.generation,requestId:e.requestId,before:e.before},n.bytes);if(!this.reconcileSender())return;if(!t.accepted){this.close(`invalid-transfer`);return}e.phase=`transfer`,e.readDeadline=null,e.readyDeadline=this.readClock()+E.progressMs}catch{this.close(`invalid-transfer`);return}if(this.open&&this.nativeHistory===e)try{as(this.options.history?.onReady(),()=>{this.open&&this.close(`invalid-transfer`)})}catch{this.open&&this.close(`invalid-transfer`)}}failHistoryRead(e,t){if(this.timedOutHistory===e){this.timedOutHistory=null;return}if(this.open&&this.nativeHistory===e&&e.phase===`reading`){if(this.tick(),this.timedOutHistory===e){this.timedOutHistory=null;return}this.open&&this.nativeHistory===e&&(t instanceof M?this.close(`session-gone`):this.finishHistory(e,`history-unavailable`))}}finishHistory(e,t,n){this.open&&this.nativeHistory===e&&(this.nativeHistory=null,this.latestHistoryRequestId=e.requestId,e.readDeadline=null,e.readyDeadline=null,t&&this.sendHistoryError(e.requestId,t,n))}sendHistoryError(e,t,n){if(!this.open)return;let r;try{r=this.options.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,requestId:e,code:t,...n?{historyReason:n}:{}})}catch{this.close(`invalid-transfer`);return}r!==!0&&r!==!1&&(as(r),this.close(`invalid-transfer`))}sendOne(){if(this.sending||(this.tick(),!this.open))return!1;this.sending=!0;try{return this.sender.pump(),this.reconcileSender(),this.chunkAdmitted}catch{throw this.close(`invalid-transfer`),Error(`Screen stream send failed`)}finally{this.chunkAdmitted=!1,this.sending=!1}}chunkAdmitted=!1;tick(){if(this.open)try{let e=this.readClock(),t=this.nativeHistory;if(t?.phase===`reading`&&t.readDeadline!==null&&e>=t.readDeadline&&(this.nativeHistory=null,this.timedOutHistory=t,this.latestHistoryRequestId=t.requestId,t.readDeadline=null,t.controller.abort(),this.sendHistoryError(t.requestId,`history-unavailable`)),!this.open)return;let n=this.nextDeadline();n!==null&&e>=n&&this.close(`stalled`)}catch{this.close(`invalid-transfer`)}}nextDeadline(){if(!this.open)return null;let e=[this.sender.nextDeadline()];this.admitted||e.push(this.startedAt+E.progressMs),this.refusalAt!==null&&e.push(this.refusalAt+E.progressMs),this.nativeHistory?.readDeadline!==null&&this.nativeHistory?.readDeadline!==void 0&&e.push(this.nativeHistory.readDeadline),this.nativeHistory?.readyDeadline!==null&&this.nativeHistory?.readyDeadline!==void 0&&e.push(this.nativeHistory.readyDeadline);let t=e.filter(e=>e!==null);return t.length===0?null:Math.min(...t)}historyAnchor(){return this.anchor}cancel(){this.close(`cancelled`)}hasAcceptedSnapshot(){return this.snapshotAccepted}terminate(e){if(e!==`session-gone`&&e!==`invalid-transfer`&&e!==`stalled`)throw TypeError(`Invalid screen stream termination reason`);this.close(e)}readClock(){let e=this.options.now();if(!Number.isFinite(e))throw Error(`Invalid screen stream clock`);return e}reconcileSender(){if(!this.open)return!1;try{let e=this.sender.tick();this.open&&e!==`open`&&this.close(e===`stalled`?`stalled`:`invalid-transfer`)}catch{this.close(`invalid-transfer`)}return this.open}admitChunk(e){if(!this.open||this.chunkAdmitted||(this.tick(),!this.open))return!1;let t;try{t=this.options.sendChunk(e)}catch{throw this.close(`invalid-transfer`),Error(`Screen stream send failed`)}if(t!==!0&&t!==!1)throw as(t),this.close(`invalid-transfer`),Error(`Screen stream send failed`);if(t)this.chunkAdmitted=!0,this.admitted=!0,this.refusalAt=null,e.meta.kind===`history`&&this.nativeHistory?.phase===`transfer`&&e.meta.requestId===this.nativeHistory.requestId?(this.nativeHistory.readyDeadline=null,e.index===e.count-1&&(this.nativeHistory.finalSequence=e.sequence)):e.meta.kind!==`history`&&this.pending&&e.meta.generation===this.pending.generation&&e.index===e.count-1&&(this.pending.finalSequence=e.sequence);else if(this.open&&this.refusalAt===null)try{this.refusalAt=this.readClock()}catch{this.close(`invalid-transfer`)}return t}requestFreshSnapshot(){if(this.open&&!this.snapshotRequested){this.snapshotRequested=!0;try{as(this.options.requestSnapshot(),()=>{this.open&&this.close(`invalid-transfer`)})}catch{this.close(`invalid-transfer`)}}}close(e){if(!this.open)return;this.open=!1;let t=this.nativeHistory;if(this.nativeHistory=null,this.timedOutHistory=null,this.sender.cancel(),this.pending=null,this.anchor=void 0,this.anchorBound=!1,this.refusalAt=null,this.snapshotRequested=!1,this.refreshRequested=!1,t?.controller.abort(),e!==`cancelled`)try{as(this.options.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,code:e}))}catch{}try{as(this.options.onClosed(e))}catch{}}};function as(e,t){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>t?.())}var os=class{options;anchor=null;request=null;reading=null;latestRequest=null;open=!0;constructor(e){this.options=e}bind(e,t,n){this.retire(),this.anchor=n?{capture:e,generation:t,native:n,before:n.from,applied:!1}:null}retire(){this.request?.controller.abort(),this.request?.phase===`reading`&&(this.request=null),this.latestRequest=null,this.anchor=null}applied(e,t){this.anchor?.capture===e&&this.anchor.generation===t&&(this.anchor.applied=!0)}receive(e){if(!this.open||this.request?.id===e.requestId||this.latestRequest===e.requestId)return;let t=this.anchor;if(!t||e.capture!==t.capture||e.generation!==t.generation){this.error(e.requestId,`history-reset`);return}if(!t.applied||this.request||this.reading||!this.options.sender.canOffer(`history`)){this.error(e.requestId,`history-unavailable`);return}if(e.before!==t.before){this.error(e.requestId,`history-reset`);return}let n={id:e.requestId,anchor:t,before:e.before,count:e.count,controller:new AbortController,deadline:this.options.now()+E.totalMs,finalSequence:null,nextBefore:null,phase:`reading`};this.request=this.reading=n;let r;try{r=this.options.source.read({capture:t.native.capture,reported:t.native.to,before:e.before,count:e.count,signal:n.controller.signal})}catch{this.complete(n,{status:`unavailable`,reason:`changed`});return}Promise.resolve(r).then(e=>this.complete(n,e),()=>this.complete(n,{status:`unavailable`,reason:`changed`})).catch(()=>{this.open&&this.options.invalid()})}admit(e){let t=this.request;t&&e.meta.kind===`history`&&e.meta.requestId===t.id&&(t.deadline=null,e.index===e.count-1&&(t.finalSequence=e.sequence))}acknowledge(e){let t=this.request;!t||t.finalSequence===null||e<t.finalSequence||(this.anchor===t.anchor&&(t.nextBefore===null?this.anchor=null:this.anchor.before=t.nextBefore),this.finish(t))}tick(){let e=this.request;if(!(!e||e.deadline===null||this.options.now()<e.deadline)){if(e.phase===`transfer`){this.options.stalled();return}e.controller.abort(),this.finish(e,`history-unavailable`)}}get deadline(){return this.request?.deadline??null}close(){this.open=!1,this.request?.controller.abort(),this.reading?.controller.abort(),this.request=null,this.anchor=null}complete(e,t){if(this.reading===e&&(this.reading=null),!this.open||this.request!==e||this.anchor!==e.anchor||(this.tick(),this.request!==e))return;if(t.status===`reset`){this.anchor=null,this.finish(e,`history-reset`);return}if(t.status===`unavailable`||t.status===`cancelled`){this.finish(e,`history-unavailable`,t.status===`unavailable`&&t.reason===`fetch-window`?`fetch-window`:void 0);return}if(t.status!==`page`&&t.status!==`boundary`){this.options.invalid();return}if(t.status===`page`&&(!Array.isArray(t.lines)||t.lines.length>e.count)){this.options.invalid();return}let n={kind:`history`,generation:e.anchor.generation,requestId:e.id,before:e.before},r=Ee({...t,...n});if(!r.ok){r.code===`history-line-too-large`?this.finish(e,r.code):this.options.invalid();return}if(!this.options.sender.offer({...n,capture:e.anchor.capture},r.bytes).accepted){this.options.invalid();return}e.phase=`transfer`,e.nextBefore=r.record.status===`page`?r.record.nextBefore:null,e.deadline=this.options.now()+E.progressMs,this.options.ready()}finish(e,t,n){this.request===e&&(this.request=null,this.latestRequest=e.id,e.deadline=null,t&&this.error(e.id,t,n))}error(e,t,n){this.options.error({type:`stream.error`,subscriptionId:this.options.subscriptionId,requestId:e,code:t,...n?{historyReason:n}:{}})}},ss=class{delivered=null;applied=null;admit(e){if(e.index!==e.count-1)return;let t=e.meta;if(t.kind===`vt-seed`)this.delivered={generation:t.generation,capture:t.capture,offset:0},this.applied=null;else if(t.kind===`vt`&&this.delivered?.generation===t.generation){if(t.offset!==this.delivered.offset)throw Error(`Noncontiguous delivery`);let n=t.offset+e.totalBytes;if(!Number.isSafeInteger(n))throw Error(`Stream offset exhausted`);this.delivered={...this.delivered,offset:n}}}receive(e){let t=this.delivered;return t?e.generation<t.generation?`ignored`:e.generation!==t.generation||e.capture!==t.capture||e.offset>t.offset||this.applied!==null&&e.offset<this.applied.offset?`invalid`:e.offset===this.applied?.offset?`ignored`:(this.applied={...t,offset:e.offset},`advanced`):`invalid`}get boundary(){return this.delivered?{...this.delivered}:null}matches(e,t,n){return this.applied?.generation===e&&this.applied.capture===t&&this.applied.offset===n}};const cs=new TextEncoder;var ls=class{options;sender;history;refreshHistory=!1;open=!0;sending=!1;chunkAdmitted=!1;generation=0;state=null;backlog=[];backlogBytes=0;offset=0;behind=!1;reseedRequested=!1;historyLines=2e3;extensions;negotiationPending;negotiationDeadline=null;progress=new ss;nextProbeAt=null;probeDeadline=null;probeToken=0;probePending=!1;probeExpired=!1;status=null;controlRetryAt=null;seeded=!1;constructor(e){this.options=e,this.extensions=Me(e.extensions,e.source.continuation?[...Pe,...e.source.history?[ze]:[]]:[]),this.negotiationPending=e.extensions!==void 0,this.sender=new c({subscriptionId:e.subscriptionId,sessionId:e.sessionId,now:()=>this.readClock(),newTransferId:()=>e.newTransferId(),send:e=>this.admitChunk(e)}),this.history=this.extensions.includes(`native-history-v1`)?new os({subscriptionId:e.subscriptionId,source:e.source.history,sender:this.sender,now:()=>this.readClock(),ready:()=>this.ready(),error:e=>this.sendControl(e),invalid:()=>this.close(`invalid-transfer`),stalled:()=>this.close(`stalled`)}):null,this.history&&e.source.history.enable();let{source:t}=e;t.on(`seed`,n=>{if(!this.open)return;let r=this.extensions.length>0;if(r&&!n.continuation){this.close(`invalid-transfer`);return}let i=this.refreshHistory,a=i||n.continuation?.reason===`herdr-idle`,o=this.seeded||e.retained===!0,s=this.history&&(!o||a)?n.nativeHistory:void 0,c=s?st(n.cols,s.lines.map(e=>e.r.map(e=>e.t).join(``))):null,l=cs.encode(r&&o&&!a?n.continuation.data:c?s.replay:n.data);if(l.length>E.screenBytes){this.history?.retire(),this.historyLines>1?(this.historyLines=Math.max(1,Math.floor(this.historyLines/2)),t.reseed(this.historyLines)):this.close(`invalid-transfer`);return}this.generation=n.generation;let u=r?e.newTransferId():void 0;u&&this.history?.bind(u,n.generation,c?s:void 0);let d={generation:n.generation,cols:n.cols,rows:n.rows};this.state={meta:r?{kind:`vt-seed`,...d,capture:u,disposition:o?a?`replace`:`discontinuity`:`initial`,reason:o?a?i?`refresh`:`herdr-idle`:this.seeded?this.behind?`overflow`:n.continuation.reason:`reconnect`:`start`,cursor:t.continuation.cursor,alternate:t.continuation.alternate,...c?{historyBefore:s.from,historyRows:s.lines.length,historyProof:c}:{}}:{kind:`vt-state`,...d},bytes:l},this.status=null,r&&!this.probePending&&(this.nextProbeAt=this.readClock()+2e3),this.backlog=[],this.backlogBytes=0,this.offset=0,this.behind=!1,this.reseedRequested=!1,this.ready()}),t.on(`bytes`,(e,t)=>{if(e.length!==0&&this.open&&!this.behind&&t===this.generation){if(this.backlogBytes+e.length>262144){this.behind=!0,this.backlog=[],this.backlogBytes=0,this.ready();return}this.backlog.push(new Uint8Array(e)),this.backlogBytes+=e.length,this.status=null,this.extensions.length&&!this.probePending&&(this.nextProbeAt=this.readClock()+2e3),this.ready()}}),t.on(`end`,e=>this.close(us(e)))}start(){return this.negotiationPending&&(this.negotiationDeadline=this.readClock()+E.progressMs),this.extensions.length&&(this.nextProbeAt=this.readClock()+2e3),this.options.source.start(this.historyLines)}receive(e,t){if(!this.open||e.subscriptionId!==this.options.subscriptionId||(this.tick(),!this.open))return;if(!Number.isSafeInteger(t)||t<1||t>E.envelopeBytes||!tt.safeParse(e).success){this.close(`invalid-transfer`);return}if(e.type===`stream.cancel`){this.cancel();return}if(e.type===`stream.refresh`){e.history&&this.history&&(this.refreshHistory=!0),this.requestReseed();return}if(e.type===`stream.history.get`){if(this.history){this.history.receive(e);return}this.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,requestId:e.requestId,code:`history-unavailable`});return}if(e.type===`stream.applied`){this.negotiationPending||this.extensions.length===0||this.progress.receive(e)===`invalid`?this.close(`invalid-transfer`):this.history?.applied(e.capture,e.generation);return}if(e.type!==`stream.ack`){this.close(`invalid-transfer`);return}let n;try{n=this.sender.acknowledge(e.subscriptionId,e.through)}catch{this.close(`invalid-transfer`);return}n===`invalid`?this.close(`invalid-transfer`):n===`advanced`&&(this.history?.acknowledge(e.through),this.ready())}sendOne(){if(this.sending||(this.tick(),!this.open))return!1;this.sending=!0;try{let e=this.flushControl();return e===`ready`?(this.sender.canOffer(`vt`)&&this.offerNext(),this.open?(this.sender.pump(),this.reconcileSender(),this.history?.tick(),this.chunkAdmitted):!1):e===`sent`}catch{return this.close(`invalid-transfer`),!1}finally{this.chunkAdmitted=!1,this.sending=!1}}tick(){if(this.open)try{this.reconcileSender(),this.open&&this.history?.tick(),this.negotiationDeadline!==null&&this.readClock()>=this.negotiationDeadline&&this.close(`stalled`),this.open&&this.probe()}catch{this.close(`invalid-transfer`)}}nextDeadline(){if(!this.open)return null;let e=[this.sender.nextDeadline(),this.nextProbeAt,this.probeDeadline,this.controlRetryAt,this.negotiationDeadline,this.history?.deadline??null].filter(e=>e!==null);return e.length?Math.min(...e):null}cancel(){this.close(`cancelled`)}terminate(e){this.close(e)}offerNext(){if(this.state){let{meta:e,bytes:t}=this.state;this.sender.offer(e,t).accepted&&(e.kind===`vt-seed`&&e.disposition===`replace`&&e.reason===`refresh`&&(this.refreshHistory=!1),this.state=null,this.seeded=!0);return}if(this.behind){this.requestReseed();return}if(this.backlogBytes===0)return;let e=new Uint8Array(this.backlogBytes),t=0;for(let n of this.backlog)e.set(n,t),t+=n.length;this.sender.offer({kind:`vt`,generation:this.generation,offset:this.offset},e).accepted&&(this.offset+=e.length,this.backlog=[],this.backlogBytes=0)}requestReseed(){this.reseedRequested||(this.reseedRequested=!0,this.options.source.reseed(this.historyLines))}ready(){try{this.options.onReady()}catch{}}readClock(){let e=this.options.now();if(!Number.isFinite(e))throw Error(`Invalid vt stream clock`);return e}reconcileSender(){let e=this.sender.tick();this.open&&e!==`open`&&this.close(e===`stalled`?`stalled`:`invalid-transfer`)}admitChunk(e){if(!this.open||this.chunkAdmitted)return!1;let t=this.options.sendChunk(e);return t&&(this.chunkAdmitted=!0,this.history?.admit(e),this.extensions.length&&this.progress.admit(e)),t}flushControl(){let e=this.negotiationPending?{type:`stream.accepted`,subscriptionId:this.options.subscriptionId,extensions:this.extensions}:this.status;if(!e)return this.controlRetryAt=null,`ready`;if(this.controlRetryAt!==null&&this.readClock()<this.controlRetryAt)return this.negotiationPending?`blocked`:`ready`;let t=!1;try{t=this.options.sendControl(e)===!0}catch{}return t?(this.controlRetryAt=null,this.negotiationPending?(this.negotiationPending=!1,this.negotiationDeadline=null):this.status===e&&(this.status=null),`sent`):(this.controlRetryAt=this.readClock()+100,this.negotiationPending?`blocked`:`ready`)}probe(){if(!this.extensions.length)return;let e=this.readClock();if(this.probeDeadline!==null&&e>=this.probeDeadline&&(this.probeDeadline=null,this.probeExpired=!0,this.publishStatus(`paused`)),this.probePending||this.nextProbeAt===null||e<this.nextProbeAt)return;this.nextProbeAt=null,this.probeDeadline=e+2e3,this.probePending=!0,this.probeExpired=!1;let t=++this.probeToken;Promise.resolve().then(()=>this.options.source.continuation.probe()).then(e=>{if(!this.open||t!==this.probeToken)return;if(this.probePending=!1,this.probeDeadline=null,this.nextProbeAt=this.readClock()+2e3,this.probeExpired){this.ready();return}let n=e.quiescent&&e.generation===this.generation&&!this.state&&!this.behind&&this.backlogBytes===0&&this.sender.canOffer(`vt`);this.publishStatus(n?`quiescent`:`catching-up`)},()=>{this.open&&t===this.probeToken&&(this.probePending=!1,this.probeDeadline=null,this.nextProbeAt=this.readClock()+2e3,this.publishStatus(`paused`))}).catch(()=>{this.open&&t===this.probeToken&&this.close(`invalid-transfer`)})}publishStatus(e){let t=this.progress.boundary;t&&(this.status={type:`stream.status`,subscriptionId:this.options.subscriptionId,...t,state:e}),this.ready()}sendControl(e){try{this.options.sendControl(e)}catch{}}close(e){if(this.open){this.open=!1,++this.probeToken,this.status=null,this.negotiationDeadline=null,this.probeDeadline=null,this.nextProbeAt=null,this.controlRetryAt=null,this.sender.cancel(),this.history?.close(),this.state=null,this.backlog=[],this.backlogBytes=0,this.options.source.close(),e!==`cancelled`&&this.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,code:e});try{this.options.onClosed(e)}catch{}}}};function us(e){return e===`pane-gone`?`session-gone`:e===`herdr-unreadable`?`stalled`:`unsupported`}const ds=.6;var fs=class{opts;offerPrepared(e,t){if(this.opts.delivery!==`scheduled`||this.stopped)return!1;let n=this.viewerSession.get(e);if(!n)return!1;let r=this.sessions.get(n),i=r?.viewers.get(e),a=r?.prepared;if(!r||!i||!a||i.offering)return!1;if(i.needsHistory&&!a.historyViewers.has(i))return r.dirty=!0,!1;if(i.lastSentGen===a.gen&&!i.forceSnapshot)return!1;let o=()=>!this.stopped&&this.sessions.get(n)===r&&r.prepared===a&&r.viewers.get(e)===i;i.offering=!0;try{let e=i.preparation===`bounded`,n=!e&&i.skipped>=3,r=i.lastSentGen===a.gen-1&&!i.forceSnapshot&&!a.forceSnapshotAll&&!n,s=t(r?a.diff:e?a.fullSnapshot():a.snapshotFor(n),r?a.diffContext:a.snapshotContext);if(s!==!0&&s!==!1)throw ps(s),TypeError(`scheduled screen offer requires a synchronous boolean`);return s===!0?(o()&&(i.lastSentGen=a.gen,i.forceSnapshot=!1,i.skipped=0,r||(i.needsHistory=!1)),!0):(o()&&(i.forceSnapshot=!0),!1)}catch{throw o()&&(i.forceSnapshot=!0),TypeError(`scheduled screen offer failed`)}finally{i.offering=!1}}sessions=new Map;sessionOffset=0;scheduledCycle=0;lastReadinessCycle=0;viewerSession=new Map;budget;unsubscribe=null;timer=null;intervalMs;stopped=!0;watchedKey=``;now;log;constructor(e){this.opts=e,this.intervalMs=Math.max(125,e.intervalMs??125),this.now=e.now??(()=>Date.now()),this.log=e.log.child({unit:`tracker`}),this.budget={tokens:0,last:this.now()}}start(){this.timer||=(this.stopped=!1,this.unsubscribe??=this.opts.backend.on(e=>{e.type===`screen-changed`||e.type===`input-accepted`?this.markDirty(e.sessionId):e.type===`session-removed`&&this.sessionRemoved(e.sessionId)}),setInterval(()=>void this.tick(),this.intervalMs))}stop(){this.stopped=!0;for(let e of this.sessions.values())e.prepared=null,e.inflightViewers?.clear(),e.inflightViewers=null,e.viewers.size>0&&(e.dirty=!0);this.timer&&clearInterval(this.timer),this.timer=null,this.unsubscribe?.(),this.unsubscribe=null,this.watchedKey=`stopped`;try{this.opts.backend.setWatched?.([])}catch(e){this.log.warn(`setWatched failed`,{err:j(e)})}}setIntervalMs(e){let t=Math.max(125,e);t!==this.intervalMs&&(this.intervalMs=t,this.timer&&=(clearInterval(this.timer),setInterval(()=>void this.tick(),this.intervalMs)))}setViewed(e,t,n){if(t){let e=n?.preparation===void 0?`legacy`:n.preparation;if(e!==`legacy`&&e!==`bounded`)throw TypeError(`invalid screen preparation`);if(e===`bounded`&&this.opts.delivery!==`scheduled`)throw TypeError(`bounded screen preparation requires scheduled delivery`)}let r=this.viewerSession.get(e);if(r){let t=this.sessions.get(r),n=t?.viewers.get(e);n&&(t?.prepared?.historyViewers.delete(n),t?.inflightViewers?.delete(n)),t?.viewers.delete(e),t?.viewers.size===0&&(t.prepared=null,t.inflightViewers=null,this.retireUnused(r,t)),this.viewerSession.delete(e)}if(t){let r=this.state(t);r.viewers.set(e,{lastSentGen:-1,forceSnapshot:!0,skipped:0,needsHistory:n?.history===!0,offering:!1,preparation:n?.preparation??`legacy`}),r.dirty=!0,this.viewerSession.set(e,t)}this.pushWatched()}dropViewer(e){this.setViewed(e,null)}viewedBy(e){return[...this.sessions.get(e)?.viewers.keys()??[]]}markDirty(e){let t=this.sessions.get(e);t&&t.viewers.size>0&&(t.dirty=!0)}forceSnapshot(e,t){let n=this.sessions.get(t)?.viewers.get(e);n&&(n.forceSnapshot=!0,this.sessions.get(t).dirty=!0)}sessionRemoved(e){let t=this.sessions.get(e);if(t&&(t.prepared=null,t.inflightViewers?.clear(),t.inflightViewers=null),!t)return;let n=[...t.viewers.keys()];for(let e of n)this.viewerSession.delete(e);this.sessions.delete(e),this.pushWatched();try{ps(this.opts.onSessionGone?.(e,n))}catch{}}pushWatched(){let e=[...this.sessions.entries()].filter(([,e])=>e.viewers.size>0).map(([e])=>e).sort(),t=e.join(` `);if(t!==this.watchedKey){this.watchedKey=t;try{this.opts.backend.setWatched?.(e)}catch(e){this.log.warn(`setWatched failed`,{err:j(e)})}}}retireUnused(e,t){t.viewers.size===0&&!t.inflight&&t.lastBackendScrollback===null&&this.sessions.get(e)===t&&this.sessions.delete(e)}state(e){let t=this.sessions.get(e);return t||(t={viewers:new Map,dirty:!1,inflight:!1,lastKeys:[],lastCols:0,lastRows:0,lastCursor:null,lastBackendScrollback:null,reported:0,gen:0,rrOffset:0,oversizeWarned:!1,prepared:null,inflightViewers:null},this.sessions.set(e,t)),t}async tick(){if(this.opts.delivery===`scheduled`){this.tickScheduled();return}let e=[...this.sessions.entries()];if(e.length===0)return;let t=this.sessionOffset%e.length,n=e.slice(t).concat(e.slice(0,t));for(let t of n){let[n,r]=t;if(this.stopped)return;if(r.viewers.size===0&&this.retireUnused(n,r),r.inflight||r.viewers.size===0)continue;if(r.dirty){r.inflight=!0,r.dirty=!1;let e=new Set([...r.viewers.values()].filter(e=>e.needsHistory)),t=e.size>0;r.inflightViewers=e;let i;try{i=t?await this.opts.backend.getScreen(n,{history:!0}):await this.opts.backend.getScreen(n)}catch(t){if(!this.stopped&&this.sessions.get(n)===r&&r.inflightViewers===e){if(t instanceof M)this.log.warn(`getScreen: session gone; dropping`,{session:n.slice(0,12)}),this.sessionRemoved(n);else{this.opts.onCaptureResult?.(n,t),this.log.warn(`getScreen failed; will retry`,{session:n.slice(0,12),err:j(t)});for(let e of r.viewers.values())e.forceSnapshot=!0;r.dirty=!0}}r.inflightViewers=null,r.inflight=!1;continue}if(this.stopped||this.sessions.get(n)!==r||r.inflightViewers!==e){r.inflight=!1;continue}this.opts.onCaptureResult?.(n);try{this.processScreen(n,r,i,e,t)}catch(e){this.log.error(`processScreen threw; will resync every viewer next tick`,{session:n.slice(0,12),err:j(e)});for(let e of r.viewers.values())e.forceSnapshot=!0;r.dirty=!0;continue}finally{r.inflightViewers=null,r.inflight=!1}}let i=!1;try{i=this.deliver(n,r)}catch(e){i=!0,this.log.error(`screen delivery threw; will retry prepared generation`,{session:n.slice(0,12),err:j(e)})}i&&(this.sessionOffset=(e.indexOf(t)+1)%e.length)}}tickScheduled(){let e=[...this.sessions.entries()];if(e.length===0)return;let t=this.sessionOffset%e.length,n=++this.scheduledCycle,r=(t+1)%e.length;for(let i of e.slice(t).concat(e.slice(0,t))){let[e,t]=i;if(this.stopped)return;t.viewers.size===0&&this.retireUnused(e,t),!(t.inflight||t.viewers.size===0)&&(t.dirty?this.captureScheduled(e,t,n,r):this.notifyScheduled(e,t,n,r))}}async captureScheduled(e,t,n,r){t.inflight=!0,t.dirty=!1;let i=new Set([...t.viewers.values()].filter(e=>e.needsHistory));t.inflightViewers=i;try{let n=i.size>0?await this.opts.backend.getScreen(e,{history:!0}):await this.opts.backend.getScreen(e);if(this.stopped||this.sessions.get(e)!==t||t.inflightViewers!==i)return;this.opts.onCaptureResult?.(e);try{this.processScreen(e,t,n,i,i.size>0)}catch{this.log.error(`processScreen failed; will resync prepared screen`);for(let e of t.viewers.values())e.forceSnapshot=!0;t.dirty=!0;return}}catch(n){if(this.stopped||this.sessions.get(e)!==t||t.inflightViewers!==i)return;if(n instanceof M)this.sessionRemoved(e);else{this.opts.onCaptureResult?.(e,n),this.log.warn(`getScreen failed; will retry`,{session:e.slice(0,12),err:j(n)});for(let e of t.viewers.values())e.forceSnapshot=!0;t.dirty=!0}return}finally{t.inflightViewers=null,t.inflight=!1}this.notifyScheduled(e,t,n,r)}notifyScheduled(e,t,n,r){if(this.opts.delivery!==`scheduled`||this.stopped)return;let i=t.prepared;if(!i||this.sessions.get(e)!==t)return;let a=[...t.viewers.entries()].filter(([,e])=>e.needsHistory&&!i.historyViewers.has(e)?(t.dirty=!0,!1):e.lastSentGen!==i.gen||e.forceSnapshot);if(a.length!==0){try{ps(this.opts.onReady(e))}catch{this.log.error(`scheduled screen readiness failed`)}for(let[n,r]of a)!this.stopped&&this.sessions.get(e)===t&&t.prepared===i&&t.viewers.get(n)===r&&(r.lastSentGen!==i.gen||r.forceSnapshot)&&(r.skipped+=1);n>this.lastReadinessCycle&&(this.lastReadinessCycle=n,this.sessionOffset=r)}}processScreen(e,t,n,r,i){if(t.viewers.size===0)return;let a=this.opts.backend.capabilitiesOf?.(e)?.absoluteLines??this.opts.backend.capabilities.absoluteLines,o=n.lines.map(Le),s=n.rows,c=0,l=!1,u=t.lastKeys.length===0||t.lastCols!==n.cols||t.lastRows!==n.rows;if(t.lastBackendScrollback===null)t.reported=n.scrollbackTotal;else{let e=n.scrollbackTotal-t.lastBackendScrollback;if(e<0)l=!0,u=!0,t.reported=n.scrollbackTotal;else if(e>=s)u=!0,t.reported+=e;else if(e>0)c=e,t.reported+=e;else if(!a&&!u&&ms(o,t.lastKeys,0)>ds*s){let e=hs(o,t.lastKeys,s);e>0&&(c=e,t.reported+=e)}}t.lastBackendScrollback=n.scrollbackTotal,this.opts.backend.setReported?.(e,t.reported);let d=[];if(!u){for(let e=0;e<s;e++){let r=e+c<t.lastKeys.length?t.lastKeys[e+c]:void 0;(r===void 0||r!==o[e])&&d.push({i:e,line:n.lines[e]})}d.length>ds*s&&(u=!0)}let f=!t.lastCursor||t.lastCursor.x!==n.cursor.x||t.lastCursor.y!==n.cursor.y,p=!u&&c===0&&d.length===0&&!f;p||(t.gen+=1);let m=p&&t.prepared?.gen===t.gen&&![...r].some(e=>e.needsHistory),h=this.opts.delivery===`scheduled`&&p&&t.prepared?.gen===t.gen?t.prepared:null;if(t.lastKeys=o,t.lastCols=n.cols,t.lastRows=n.rows,t.lastCursor=n.cursor,m)return;let g={sessionId:e,cursor:n.cursor,scrollbackTotal:t.reported,gen:t.gen},_=this.opts.maxEncodedBytes??262144,v,y,b,x=()=>(v??={type:`screen.snapshot`,...g,cols:n.cols,rows:n.rows,lines:n.lines,reset:l||void 0},v),ee=()=>{if(!b&&(b={...x(),lines:n.lines.map(Be),degraded:!0},!t.oversizeWarned)){let n=k(b).byteLength;n>_&&(this.log.warn(`screen.snapshot exceeds maxEncodedBytes even after stripStyles`,{session:e.slice(0,12),bytes:n,maxEncodedBytes:_}),t.oversizeWarned=!0)}return b},te=e=>e?ee():(y??=k(x()).byteLength,y>_?ee():x()),S={type:`screen.diff`,...g,scroll:c,changed:d},C=Object.freeze({generation:t.gen,reported:t.reported,historyRequested:i}),ne=Object.freeze({...C,...n.historyCapture?{capture:n.historyCapture}:{}});t.prepared={gen:t.gen,diff:h?.diff??S,forceSnapshotAll:h?.forceSnapshotAll??(u||p),snapshotFor:te,fullSnapshot:x,snapshotContext:ne,diffContext:h?.diffContext??C,historyViewers:r}}deliver(e,t){if(this.opts.delivery===`scheduled`)return!1;let n=t.prepared;if(!n||t.viewers.size===0)return!1;let r=()=>!this.stopped&&this.sessions.get(e)===t&&t.prepared===n,{gen:i,diff:a,forceSnapshotAll:o,snapshotFor:s}=n,c=!1,l=[...t.viewers.entries()],u=l.length,d=t.rrOffset%u,f=l.slice(d).concat(l.slice(0,d)).map((e,t)=>({entry:e,idx:t})).sort((e,t)=>t.entry[1].skipped-e.entry[1].skipped||e.idx-t.idx).map(e=>e.entry);t.rrOffset=(t.rrOffset+1)%u;for(let[e,l]of f){if(!r())break;if(t.viewers.get(e)!==l)continue;if(l.needsHistory&&!n.historyViewers.has(l)){t.dirty=!0;continue}if(l.lastSentGen===i&&!l.forceSnapshot)continue;if(!this.spend()){l.skipped+=1;continue}c=!0;let u=l.skipped>=3,d=l.lastSentGen===i-1&&!l.forceSnapshot&&!o&&!u;try{let i=d?a:s(u),o=this.opts.sink(e,i,d?n.diffContext:n.snapshotContext);if(!r())break;if(t.viewers.get(e)!==l)continue;if(o===!1){l.skipped+=1,l.forceSnapshot=!0;continue}}catch(n){if(!r())break;if(t.viewers.get(e)!==l)continue;l.skipped+=1,l.forceSnapshot=!0,this.log.error(`screen sink threw; will retry prepared generation`,{conn:e.slice(0,12),err:j(n)});continue}l.lastSentGen=i,l.forceSnapshot=!1,l.skipped=0,d||(l.needsHistory=!1)}return c}spend(){let e=this.opts.maxFramesPerSecond??40,t=this.now(),n=Math.max(0,t-this.budget.last);return this.budget.tokens=Math.min(e,this.budget.tokens+n*e/1e3),this.budget.last=t,this.budget.tokens<1?!1:(--this.budget.tokens,!0)}};function ps(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}function ms(e,t,n){let r=0;for(let i=0;i<e.length;i++)t[i+n]!==e[i]&&r++;return r}function hs(e,t,n){for(let r=1;r<=Math.min(n-1,16);r++){let i=n-r;if(i<=0)break;let a=0;for(let n=0;n<i;n++)e[n]===t[n+r]&&a++;if(a>=.8*i)return r}return 0}var gs=class{now;rate;onError;registrations=new Map;ownership={};pumping=!1;tokens=0;last;constructor(e){if(this.now=e.now,this.rate=e.maxFramesPerSecond??40,this.onError=e.onError,!Number.isSafeInteger(this.rate)||this.rate<=0)throw RangeError(`wire scheduler rate must be a positive safe integer`);this.last=this.readClock()}register(e,t,n=`terminal`,r){if(e.length===0)throw RangeError(`wire scheduler key must not be empty`);if(n!==`terminal`&&n!==`background`)throw RangeError(`invalid wire scheduler priority`);if(r!==void 0&&typeof r!=`function`)throw TypeError(`invalid wire scheduler fairness`);let i=Symbol(),a={identity:i,sendOne:t,priority:n,...r&&{fair:r}};return this.registrations.set(e,a),()=>this.remove(e,i)}pump(){if(this.pumping)return 0;this.pumping=!0;try{this.refill();let e=this.ownership,t=[...this.registrations],n=new Set(t.flatMap(([,e])=>{if(e.priority!==`background`||!e.fair)return[];try{return e.fair()===!0?[e]:[]}catch{return[]}})),r=e=>e.priority===`terminal`||n.has(e),i=t.filter(([,e])=>r(e)),a=new Set(i.map(([,e])=>e)),o=t.filter(([,e])=>!r(e)),s=i,c=0;for(;this.tokens>=1&&this.ownership===e;){if(s.length===0){let e=o.shift();if(!e)break;let[t,n]=e;if(this.registrations.get(t)!==n)continue;this.offer(t,n)&&(c++,o.push(e)),s=[...this.registrations].filter(([,e])=>a.has(e));continue}let t=[];for(let[n,r]of s){if(this.tokens<1||this.ownership!==e)break;this.registrations.get(n)===r&&this.offer(n,r)&&(c++,t.push([n,r]))}s=t}return c}finally{this.pumping=!1}}nextBudgetAt(){return this.pumping||this.refill(),this.registrations.size===0||this.tokens>=1?null:this.last+(1-this.tokens)*1e3/this.rate}clear(){this.registrations.clear(),this.ownership={}}remove(e,t){this.registrations.get(e)?.identity===t&&this.registrations.delete(e)}offer(e,t){this.registrations.delete(e),this.registrations.set(e,t),--this.tokens;try{let e=t.sendOne();if(e===!0)return!0;if(e===!1)this.tokens+=1;else throw _s(e),TypeError(`wire producer must return a synchronous boolean`)}catch(n){this.remove(e,t.identity);try{_s(this.onError?.(n))}catch{}}return!1}readClock(){let e=this.now();if(!Number.isFinite(e))throw RangeError(`wire scheduler clock must be finite`);return e}refill(){let e=Math.max(this.last,this.readClock());this.tokens=Math.min(this.rate,this.tokens+(e-this.last)*this.rate/1e3),this.last=e}};function _s(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}var vs=class{options;tracker;scheduler;entries=new Map;viewerOwners=new Map;attachTokens=new Map;herdrCaptureFailures=new Map;started=!1;lifecycle=0;pumping=!1;timer=null;timerEpoch=0;nextViewer=0;constructor(e){if(!(e.backend instanceof Ne))throw TypeError(`Service view backend must be a BackendRegistry`);if(!Number.isFinite(e.now()))throw RangeError(`Service view clock must be finite`);this.options={...e},this.scheduler=new gs({now:()=>this.options.now(),onError:()=>this.notifyError()}),this.tracker=new fs({backend:this.options.backend,log:this.options.log,now:()=>this.options.now(),delivery:`scheduled`,onReady:()=>{this.pump()},onSessionGone:(e,t)=>this.sessionGone(e,t),onCaptureResult:(e,t)=>this.captureResult(e,t)})}start(){if(!this.started){if(!Number.isFinite(this.options.now()))throw RangeError(`Service view clock must be finite`);this.lifecycle++,this.started=!0,this.tracker.start()}}stop(){if(!this.started)return;this.lifecycle++,this.started=!1,this.clearTimer();for(let e of this.herdrCaptureFailures.values())clearTimeout(e);this.herdrCaptureFailures.clear();let e=[...this.entries.values()];this.entries.clear();for(let t of e)t.unregister(),this.dropBackground(t);this.tracker.stop();for(let t of e)this.dropView(t)}attach(e,t){if(!this.started)throw TypeError(`Service view coordinator is stopped`);if(typeof e!=`string`||e.length===0||e.length>256||!t)throw TypeError(`Invalid service view connection`);if(!this.entries.has(e)&&this.entries.size>=10)throw RangeError(`Too many service view connections`);let n=this.lifecycle,r={};this.attachTokens.set(e,r);try{let i=this.entries.get(e);i&&this.retire(i);let a={id:e,connection:{...t},view:null,closingView:null,unregister:()=>{},background:null,revision:0};if(this.started&&this.lifecycle===n&&this.attachTokens.get(e)===r&&!this.entries.has(e)){if(this.entries.size>=10)throw RangeError(`Too many service view connections`);this.entries.set(e,a),a.unregister=this.scheduler.register(`terminal:${e}`,()=>this.produce(a))}let o=this;return{get viewedSessionId(){return o.current(a)?a.view?.sessionId??null:null},receive:(e,t)=>this.receive(a,e,t),background:(e,t)=>this.background(a,e,t),close:()=>this.retire(a)}}finally{this.attachTokens.get(e)===r&&this.attachTokens.delete(e)}}setIntervalMs(e){if(!Number.isFinite(e))throw TypeError(`Invalid service view interval`);this.tracker.setIntervalMs(e)}pump(){if(!this.started||this.pumping)return 0;this.pumping=!0;let e=0;try{if(!Number.isFinite(this.options.now()))throw RangeError(`Service view clock must be finite`);for(let e of[...this.entries.values()])this.current(e)&&e.view&&e.view.stream.tick();return this.started&&(e=this.scheduler.pump()),e}catch{return this.stop(),this.notifyError(),0}finally{this.pumping=!1,this.arm()}}current(e){return this.started&&this.entries.get(e.id)===e}background(e,t,n){if(typeof t!=`function`)throw TypeError(`Invalid background producer`);if(n!==void 0&&typeof n!=`function`)throw TypeError(`Invalid background fairness`);if(!this.current(e))return{wake(){},close(){}};this.dropBackground(e);let r={producer:t,unregister:null,ready:!1,revision:{}};e.background=r;let i=()=>this.current(e)&&e.background===r,a=()=>{if(!i()||!r.ready||!r.producer)return!1;let e=r.revision;try{let t=r.producer();return t===!1&&e===r.revision&&this.suspendBackground(r),typeof t!=`boolean`&&(this.suspendBackground(r),r.producer=null),t}catch(e){throw this.suspendBackground(r),r.producer=null,e}};return this.arm(),{wake:()=>{i()&&r.producer&&(r.revision={},r.ready=!0,r.unregister??=this.scheduler.register(`background:${e.id}`,a,`background`,n&&(()=>i()&&n())),this.pump())},close:()=>{e.background===r&&(this.dropBackground(e),this.arm())}}}dropBackground(e){let t=e.background;t&&(e.background=null,this.suspendBackground(t),t.producer=null)}suspendBackground(e){e.ready=!1;let t=e.unregister;e.unregister=null,t?.()}receive(e,t,n){if(!this.current(e))return;let r=e.revision,i=e.view,a=null;try{if(Number.isSafeInteger(n)&&n>=1&&n<=E.envelopeBytes){let e=tt.safeParse(t);e.success&&(a=e.data)}}catch{}if(this.current(e)&&e.revision===r&&e.view===i){if(!a){i?.stream.terminate(`invalid-transfer`);return}if(a.type===`stream.subscribe`){let t=e.view;if(t&&t.subscriptionId===a.subscriptionId){t.sessionId!==a.sessionId&&t.stream.terminate(`invalid-transfer`);return}let n=++e.revision;if(this.dropView(e),!this.current(e)||e.revision!==n)return;let r={sessionId:a.sessionId,subscriptionId:a.subscriptionId,trackerKey:this.viewerKey(),stream:null};if(a.mode===`vt`&&this.openVtView(e,r,n,a.extensions,a.retained))return;if(r.stream=new is({subscriptionId:r.subscriptionId,sessionId:r.sessionId,now:()=>this.options.now(),newTransferId:()=>this.options.newTransferId(),sendChunk:t=>this.current(e)&&e.view===r&&e.connection.sendChunk(t),sendControl:t=>this.current(e)&&(e.view===r||e.closingView===r)&&e.connection.sendControl(t),requestSnapshot:()=>{this.current(e)&&e.view===r&&this.tracker.forceSnapshot(r.trackerKey,r.sessionId)},onClosed:()=>{this.current(e)&&e.view===r&&this.dropView(e)},history:{read:(e,t)=>this.options.backend.getHistoryPage(e,t),onReady:()=>{this.current(e)&&e.view===r&&this.pump()}}}),!this.current(e)||e.revision!==n){r.stream.cancel();return}if(e.view=r,this.viewerOwners.set(r.trackerKey,{entry:e,view:r}),this.tracker.setViewed(r.trackerKey,r.sessionId,{history:!0,preparation:`bounded`}),!this.current(e)||e.revision!==n||e.view!==r)return;this.arm();return}if(i?.subscriptionId===a.subscriptionId){try{i.stream.receive(t,n)}catch{this.current(e)&&e.revision===r&&e.view===i&&i.stream.terminate(`invalid-transfer`)}this.pump()}}}openVtView(e,t,n,r,i){if(!this.options.backend.capabilitiesOf(t.sessionId)?.vtStream)return!1;let a;try{a=new ls({subscriptionId:t.subscriptionId,sessionId:t.sessionId,source:this.options.backend.openVtStream(t.sessionId),extensions:r,retained:i,now:()=>this.options.now(),newTransferId:()=>this.options.newTransferId(),sendChunk:n=>this.current(e)&&e.view===t&&e.connection.sendChunk(n),sendControl:n=>this.current(e)&&(e.view===t||e.closingView===t)&&e.connection.sendControl(n),onReady:()=>{this.current(e)&&e.view===t&&this.pump()},onClosed:()=>{this.current(e)&&e.view===t&&this.dropView(e)}})}catch{return!1}return!this.current(e)||e.revision!==n?(a.cancel(),!0):(t.stream=a,e.view=t,this.viewerOwners.set(t.trackerKey,{entry:e,view:t}),a.start().catch(()=>a.terminate(`invalid-transfer`)),this.arm(),!0)}produce(e){if(!this.current(e))return!1;try{let t=e.view;return!t||(t.stream instanceof is&&t.stream.canOfferScreen()&&this.tracker.offerPrepared(t.trackerKey,(e,n)=>e.type!==`screen.snapshot`&&e.type!==`screen.diff`?!1:t.stream instanceof is&&t.stream.offer(e,n)),!this.current(e)||e.view!==t)?!1:t.stream.sendOne()}catch{throw this.retire(e),Error(`Service view producer failed`)}}viewerKey(){return`service-view-${++this.nextViewer}`}dropView(e){let t=e.view;t&&(e.view=null,this.viewerOwners.get(t.trackerKey)?.view===t&&this.viewerOwners.delete(t.trackerKey),this.tracker.dropViewer(t.trackerKey),t.stream.cancel())}retire(e){this.entries.get(e.id)===e&&(this.entries.delete(e.id),e.unregister(),this.dropBackground(e),this.dropView(e),this.arm())}captureResult(e,t){if(Re(e)?.name!==`herdr`)return;let n=this.herdrCaptureFailures.get(e);if(t===void 0){n&&clearTimeout(n),this.herdrCaptureFailures.delete(e);return}if(n||!this.started)return;let r=[...this.entries.values()].flatMap(t=>{let n=t.view;return n&&n.sessionId===e&&this.current(t)&&n.stream instanceof is&&n.stream.hasAcceptedSnapshot()?[{entry:t,view:n,stream:n.stream}]:[]});if(r.length===0)return;let i=setTimeout(()=>{if(this.herdrCaptureFailures.get(e)===i){this.herdrCaptureFailures.delete(e);for(let{entry:e,view:t,stream:n}of r)this.current(e)&&e.view===t&&n.terminate(`stalled`)}},3e3);i.unref?.(),this.herdrCaptureFailures.set(e,i)}sessionGone(e,t){let n=this.herdrCaptureFailures.get(e);n&&clearTimeout(n),this.herdrCaptureFailures.delete(e);let r=[];for(let n of t){let t=this.viewerOwners.get(n);t&&t.view.sessionId===e&&this.current(t.entry)&&t.entry.view===t.view&&(this.viewerOwners.delete(n),t.entry.view=null,r.push(t))}for(let{entry:e,view:t}of r)e.closingView=t,t.stream.terminate(`session-gone`),e.closingView===t&&(e.closingView=null);if(r.length>0)try{ys(this.options.onSessionGone?.(e))}catch{}this.arm()}notifyError(){try{ys(this.options.onError?.())}catch{}}clearTimer(){this.timerEpoch++,this.timer&&clearTimeout(this.timer),this.timer=null}arm(){if(this.clearTimer(),this.started)try{let e=[...this.entries.values()].flatMap(e=>e.view?[e.view]:[]);if(e.length===0&&![...this.entries.values()].some(e=>e.background?.ready))return;let t=this.options.now();if(!Number.isFinite(t))throw RangeError(`Service view clock must be finite`);let n=[this.scheduler.nextBudgetAt(),...e.map(e=>e.stream.nextDeadline())],r=25;for(let e of n)e!==null&&e>t&&(r=Math.min(r,e-t));let i=this.timerEpoch;this.timer=setTimeout(()=>{this.started&&i===this.timerEpoch&&(this.timer=null,this.pump())},Math.max(1,r))}catch{this.stop(),this.notifyError()}}};function ys(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}function bs(e){return`no conn.hello within ${e/1e3}s; ignoring this link until one arrives`}var xs=class{o;relay;views;conversations;chat;chatDebounce=null;chatSentAt=0;viewLeases=new Map;events;notifier;notificationState;notificationRelayCapable=!1;relayWithheldTurn=!1;pairing;links=new Map;connByFp=new Map;pairings;pairRequests=new Map;sessions=[];activityPublished=0;aliveSent=0;stateSeen=new Map;tick=null;sessionsDebounce=null;sessionsDueAt=0;sessionsRefreshedAt=0;sessionsRefreshes=0;sessionsPublished=0;lastSeenSavedAt=new Map;log;localProcess;projects;stopped=!1;conversationsEnabled;get agentConversationsEnabled(){return!this.stopped&&this.conversationsEnabled}get configurationRevision(){return _({...this.o.config,showAgentConversations:this.conversationsEnabled})}applyConversationSetting(e){if(this.stopped)throw Error(`Agent stopped`);try{return it(this.o.paths,t=>(t.showAgentConversations===!1&&this.setConversationConsent(!1),_(t)===e?(this.setConversationConsent(t.showAgentConversations!==!1),this.configurationRevision):null))}catch(e){throw this.setConversationConsent(!1),e}}setConversationConsent(e){let t=this.conversationsEnabled!==e;this.conversationsEnabled=e,(!e||t)&&(this.conversations.consentChanged(),this.chat.wake(),this.broadcast(this.helloMessage()),t&&this.scheduleChat())}backendsKey=null;constructor(e){this.o=e,e={...e,config:Object.freeze(Bt.parse(e.config))},this.o=e,this.conversationsEnabled=e.config.showAgentConversations!==!1,this.log=e.log.child({unit:`agent`}),this.pairings=_t(e.paths);let t=Jn();this.projects=new Un(t,()=>{this.stopped||this.scheduleSessions()}),e.registry.onSetupChanged(()=>{this.stopped||this.scheduleSessions()}),this.localProcess={pid:process.pid,agentVersion:e.appVersion,computerFp:e.fp,stateDir:mr(e.paths.dir),serviceInstance:e.serviceInstance??null};let n=e.relayUrlOverride??e.config.relayUrl;this.relay=e.relay??new rs({relayUrl:n,fp:e.fp,identity:e.identity,name:e.config.computerName,appVersion:e.appVersion,log:e.log,...e.config.turn===!1&&{turn:!1}}),this.views=new vs({backend:e.registry,log:e.log,now:()=>Date.now(),newTransferId:()=>O(Oe(16)),onSessionGone:()=>this.scheduleSessions(),onError:()=>this.log.warn(`terminal-view-delivery-failed`)}),this.conversations=new Zo({backend:e.registry,...e.conversationRoots&&{roots:e.conversationRoots},enabled:()=>this.agentConversationsEnabled,onAgentVersion:(e,t)=>b(e,t,(e,t)=>this.log.info(e,t)),chat:{idFor:(e,t)=>this.chat.idFor(e,t),knownId:(e,t)=>this.chat.knownId(e,t)}}),this.chat=new Gi({enabled:()=>this.agentConversationsEnabled,active:()=>this.viewLeases.size>0,viewed:e=>[...this.viewLeases.values()].some(t=>t.lease.viewedSessionId===e),supported:t=>e.registry.conversationSupported(t),reference:(t,n)=>e.registry.conversationReference(t,n),locator:this.conversations.sharedLocator,changed:()=>this.scheduleChat(),replaced:e=>this.conversations.sessionChanged(e)}),this.events=new _i({notifyMinCommandMs:e.config.notifyMinCommandMs,idleQuietMs:e.config.idleQuietMs,idleMinActiveMs:e.config.idleMinActiveMs}),this.notificationState=new Ti(e.paths),this.notificationState.retain(new Set(this.pairings.map(e=>e.phoneFp)));let r=new xi({state:this.notificationState,computerFp:e.fp,computerName:()=>e.config.computerName,capable:()=>this.notificationRelayCapable,pairings:()=>this.pairings,facts:t=>e.registry.notificationFacts(t),git:t});this.notifier=new Di(e=>this.relay.sendCtrl(e),e.log,Date.now,e=>r.prepare(e)),this.pairing=new Pi({identity:e.identity,fp:e.fp,computerName:e.config.computerName,accent:e.config.accent,relayUrl:e.config.relayUrl,sendCtrl:e=>this.relay.sendCtrl(e),savePairing:e=>this.addPairing(e),relayOnline:()=>this.relay.online,confirm:e.confirm,pairingCount:()=>this.pairings.length,log:e.log,onClose:e=>this.o.onPairingClosed?.(e)}),this.relay.on(`auth-ok`,e=>{this.notificationRelayCapable=e.features?.includes(`notify-context-v1`)??!1,this.safe(`auth-ok`,()=>{this.views.setIntervalMs(Math.max(125,e.minFrameMs));let t=e.turnOff===!0;if(t&&!this.relayWithheldTurn)for(let e of[...this.links.values()])this.dropLinkFor(e.phoneFp);this.relayWithheldTurn=t,this.pairing.readvertise()})}),this.relay.on(`ctrl`,e=>this.safe(`ctrl`,()=>this.onCtrl(e))),this.relay.on(`e2e`,e=>this.safe(`e2e`,()=>this.onE2E(e))),this.relay.on(`down`,()=>{this.notificationRelayCapable=!1,this.safe(`down`,()=>{for(let e of[...this.links.values()])e.relayLost(),e.activeRoute!==`direct`&&this.dropLinkFor(e.phoneFp)})}),this.relay.on(`superseded`,()=>{this.safe(`superseded`,()=>{this.log.warn(`relay connection superseded by a newer agent instance; stopping`),this.stop(),this.o.onSuperseded?.()})}),e.registry.on(e=>this.safe(`backend-event`,()=>this.onBackendEvent(e))),this.events.on(`event`,e=>this.safe(`events-event`,()=>this.broadcast(e))),this.events.on(`ring`,e=>this.safe(`events-ring`,()=>{this.notifier.ring(e)}))}safe(e,t){try{let n=t();n&&typeof n.then==`function`&&n.catch(t=>this.logHandlerFailure(e,t))}catch(t){this.logHandlerFailure(e,t)}}logHandlerFailure(e,t){this.log.error(`handler failed`,{where:e,error:j(t)})}start(){this.stopped=!1,this.views.start(),this.relay.start(),this.tick=setInterval(()=>{this.safe(`tick`,()=>{this.events.tick(),this.pairing.tick(),this.sweepHandshakes(),this.sendAlive()})},1e3),this.safe(`refresh-sessions`,()=>this.refreshSessions())}stop(){this.stopped=!0,this.conversations.close(),this.chat.close(),this.chatDebounce&&clearTimeout(this.chatDebounce),this.chatDebounce=null,this.tick&&clearInterval(this.tick),this.tick=null,this.sessionsDebounce&&clearTimeout(this.sessionsDebounce),this.sessionsDebounce=null,this.pairing.closeWindow();for(let e of this.links.values())this.closeLease(e),e.close();this.links.clear(),this.connByFp.clear(),this.views.stop(),this.pairRequests.clear(),this.relay.stop()}sweepHandshakes(){let e=Date.now();for(let t of this.links.values())t.helloOverdue(e)&&(t.dormant=!0,this.log.warn(bs(t.helloTimeoutMs),{phone:t.phoneFp.slice(0,8),conn:t.connId.slice(0,6)}))}get relayOnline(){return this.relay.online}get localStatus(){let e=this.o.registry.status(),t=De();return{controlVersion:1,process:this.localProcess,backends:e,terminalReady:e.some(e=>e.connected),...t.length&&{newerAgents:t}}}terminalSetup(){return this.o.registry.terminalSetup()}connectTerminal(e){let t=this.o.registry.connectTerminal(e);return t&&this.o.registry.notifySetupChanged(),t}get pairingList(){return this.pairings}get sessionList(){return this.sessions}get connectedPhones(){return[...this.links.values()].map(e=>({phoneFp:e.phoneFp,name:e.name,viewed:this.viewLeases.get(e)?.lease.viewedSessionId??null,transport:e.transportDiagnostics}))}linkForPhone(e){let t=this.connByFp.get(e);return t?this.links.get(t):void 0}openPairing(){return this.pairing.openWindow()}closePairing(){this.pairing.closeWindow()}get pairingOpen(){return this.pairing.tick(),this.pairing.isOpen}unpair(e){if(!e)return!1;let t=this.pairings.filter(t=>t.phoneFp.startsWith(e)||t.name===e);if(t.length>1)throw Error(`Ambiguous phone target; use a longer or complete fingerprint`);let n=t[0];return n?this.removePairing(n):!1}unpairExact(e){let t=this.pairings.find(t=>t.phoneFp===e);return t?this.removePairing(t):!1}raisePairProtocolFloor(e,t,n){let r=this.pairings.find(t=>t.phoneFp===e),i=_t(this.o.paths).find(t=>t.phoneFp===e);if(!r||!i||t.length!==32)throw Error(`shellbell: pairing changed before protocol upgrade`);let a=A(i.kPair);if(a.length!==32||r.kPair!==i.kPair||r.ed25519Pub!==i.ed25519Pub||r.x25519Pub!==i.x25519Pub||!jr(Buffer.from(a),Buffer.from(t)))throw Error(`shellbell: pairing changed before protocol upgrade`);let o=this.pairings.map(t=>t.phoneFp===e?{...t,minProtocolVersion:2}:t);this.pairings=He(this.o.paths,o),n!==this.linkForPhone(e)&&this.dropLinkFor(e)}removePairing(e){let t=this.pairings.filter(t=>t!==e);return this.pairings=He(this.o.paths,t),this.relay.sendCtrl({type:`unpair`,phoneFp:e.phoneFp}),this.retirePhone(e.phoneFp),!0}retirePhone(e){this.notificationState.forget(e),this.pairRequests.delete(e),this.dropLinkFor(e),this.lastSeenSavedAt.delete(e)}dropLinkFor(e){let t=this.connByFp.get(e);if(t===void 0)return;let n=this.links.get(t);n&&(this.closeLease(n),n.close()),this.links.delete(t),this.connByFp.delete(e)}addPairing(e){let t=this.pairings.find(t=>t.phoneFp===e.phoneFp),n=we(t,e),r=[...this.pairings.filter(t=>t.phoneFp!==e.phoneFp),n];this.pairings=He(this.o.paths,r),t?.kPair!==e.kPair||t?.ed25519Pub!==e.ed25519Pub||t?.x25519Pub!==e.x25519Pub?this.retirePhone(e.phoneFp):this.notificationState.forget(e.phoneFp)}acceptsRelayUnpair(e,t){if(e.minProtocolVersion!==2)return!0;if(!t)return!1;try{return Vt(t,{computerFp:this.o.fp,phoneFp:e.phoneFp,kPair:A(e.kPair),phoneEd25519Pub:A(e.ed25519Pub)})}catch{return!1}}forgetPairing(e,t){let n=this.pairings.find(t=>t.phoneFp===e);if(n&&!this.acceptsRelayUnpair(n,t))return this.log.warn(`ignored unsigned or invalid relay unpair for upgraded pairing`,{phone:e.slice(0,8)}),!1;let r=this.pairings.length,i=this.pairings.filter(t=>t.phoneFp!==e);return i.length!==r&&(this.pairings=He(this.o.paths,i)),this.retirePhone(e),!0}async onCtrl(e){switch(e.type){case`unpaired`:if(e.phoneFps.length){let t=new Map(e.proofs?.map(e=>[e.phoneFp,e])),n=(e.proofs??[]).filter(t=>{if(!e.phoneFps.includes(t.phoneFp))return!1;let n=this.pairings.find(e=>e.phoneFp===t.phoneFp);return!n||this.acceptsRelayUnpair(n,t)}),r=e.phoneFps.filter(e=>this.pairings.some(n=>n.phoneFp===e&&this.acceptsRelayUnpair(n,t.get(e))));if(r.length){let e=this.pairings.filter(e=>!r.includes(e.phoneFp));this.pairings=He(this.o.paths,e);for(let e of r)this.retirePhone(e);this.log.info(`applied verified or legacy unpair tombstones`,{count:r.length})}for(let e of n)this.relay.sendCtrl({type:`revocation-ack`,phoneFp:e.phoneFp,pairId:e.pairId})}this.relay.sendCtrl({type:`pairings-sync`,phones:this.pairings.slice(0,10).map(e=>({phoneFp:e.phoneFp,ed25519Pub:A(e.ed25519Pub),name:e.name,pairId:qe(A(e.kPair))}))});return;case`phones`:for(let t of e.connected)this.attach(t.phoneFp,t.connId,t.name);return;case`phone-connected`:this.attach(e.phoneFp,e.connId,e.name);return;case`phone-disconnected`:{let t=[...this.links.values()].find(t=>t.relayConnId===e.connId);if(!t||(t.relayLost(),t.activeRoute===`direct`))return;t.close(),this.closeLease(t),this.links.delete(t.connId),this.connByFp.get(t.phoneFp)===t.connId&&this.connByFp.delete(t.phoneFp);return}case`pairing-request`:await this.pairing.handleRequest(e);return;case`unpair`:this.forgetPairing(e.phoneFp,e.proof)&&e.proof&&this.relay.sendCtrl({type:`revocation-ack`,phoneFp:e.phoneFp,pairId:e.proof.pairId});return;case`error`:this.log.warn(`relay error`,{code:e.code===`too-many-pairings`?e.code:`unknown`});return;default:return}}attach(e,t,n){let r=this.pairings.find(t=>t.phoneFp===e);if(!r){this.log.warn(`relay announced an unknown phone; ignoring`,{phone:e.slice(0,8)});return}let i=this.linkForPhone(e);if(i&&!i.broken){i.relayConnId=t;return}this.dropLinkFor(e);let a=this.newV2Link(r,t,n);this.links.set(t,a),this.connByFp.set(e,t),r.lastSeenAt=new Date().toISOString();let o=Date.now();o-(this.lastSeenSavedAt.get(e)??0)>=6e4&&(this.lastSeenSavedAt.set(e,o),this.pairings=He(this.o.paths,this.pairings))}newV2Link(e,t,n){let r=A(e.kPair),i;return i=new Vi({phoneFp:e.phoneFp,connId:t,name:n,computerFp:this.o.fp,identity:this.o.identity,native:this.o.directFactory,iceServers:()=>this.relay.iceServers(),turn:this.o.config.turn!==!1,kPair:r,remoteStatic:A(e.x25519Pub),send:e=>this.relay.sendBoundedEnvelope(e),commitFloor:async()=>this.raisePairProtocolFloor(e.phoneFp,r,i),prepareReady:()=>this.pairRequests.get(e.phoneFp)?.idle!==!1,terminal:(e,t,n)=>this.safe(`v2-terminal`,()=>this.onInner(e,t,n)),ready:e=>this.onLinkReady(e),log:this.o.log}),i}onLinkReady(e){this.closeLease(e),this.ownsHandshake(e,e.handshakeGeneration)&&(this.installLease(e,e.handshakeGeneration),this.ownsHandshake(e,e.handshakeGeneration)&&(e.send(this.helloMessage()),this.ownsHandshake(e,e.handshakeGeneration)&&e.send(this.phoneSessionList())))}helloMessage(e=this.o.registry.connected()){return{type:`hello`,features:[Se,x,We],conversationEnabled:this.agentConversationsEnabled,agentVersion:this.o.appVersion,hostPlatform:vi(process.platform),backends:e.filter(e=>Ie.includes(e.name)),launchableBackends:this.o.registry.launchable().filter(e=>Ie.includes(e)),backendCatalog:this.o.registry.catalog(),sessionLaunchTargets:this.o.registry.launchTargets(),sessionLaunchIssues:this.o.registry.launchIssues(),terminalSetup:this.o.registry.terminalSetup(),computerName:this.o.config.computerName,accent:this.o.config.accent}}onE2E(e){let t=this.connByFp.get(e.from);return(t===void 0?void 0:this.links.get(t))?.handleEnvelope(e)}closeLease(e){let t=this.viewLeases.get(e);t&&(this.viewLeases.delete(e),t.conversation?.close(),t.lease.close())}installLease(e,t){let n=null,r=()=>this.ownsHandshake(e,t)&&this.viewLeases.get(e)?.lease===n;if(n=this.views.attach(e.connId,{sendChunk:t=>r()&&e.send(t),sendControl:t=>r()&&e.send(t)}),!this.ownsHandshake(e,t)){n.close();return}this.viewLeases.set(e,{generation:t,lease:n});let i=this.conversations.attach({current:r,send:t=>r()&&e.send(t),background:(e,t)=>n.background(e,t)}),a=this.viewLeases.get(e);a?.lease===n&&r()?a.conversation=i:i.close(),this.chat.wake()}ownsHandshake(e,t){return this.links.get(e.connId)===e&&e.handshaken&&!e.broken&&e.handshakeGeneration===t}async onInner(e,t,n){let r=e.handshakeGeneration;if(this.ownsHandshake(e,r)){if(t.type.startsWith(`conversation.`)){let i=this.viewLeases.get(e);i?.generation===r&&i.conversation?.receive(t,n);return}if(t.type===`notification.enroll`){this.notificationState.enroll(e.phoneFp,t.generation,t.features)&&this.ownsHandshake(e,r)&&e.send({type:`notification.enrolled`,generation:t.generation});return}if(t.type===`stream.subscribe`||t.type===`stream.ack`||t.type===`stream.applied`||t.type===`stream.accepted`||t.type===`stream.status`||t.type===`stream.history.get`||t.type===`stream.cancel`||t.type===`stream.refresh`||t.type===`stream.chunk`||t.type===`stream.error`){let i=this.viewLeases.get(e);i?.generation===r&&(t.type===`stream.subscribe`&&i.conversation?.focus(t.sessionId),i.lease.receive(t,n));return}if(!(`reqId`in t)){await this.execute(e,t,r);return}if(Oi(t)){let n=this.pairRequests.get(e.phoneFp);n||(n=new ki,this.pairRequests.set(e.phoneFp,n));let i=await n.run(t.reqId,async()=>{let n=await this.execute(e,t,r);if(!n)throw Error(`paired request produced no outcome`);return n});this.ownsHandshake(e,r)&&e.send(i)}}}async execute(t,n,r){let i=this.o.registry,a=()=>this.ownsHandshake(t,r),o=(e,t)=>t&&(()=>this.checkChatInput(e,t.chat)),s=(e,t={})=>({type:`ack`,reqId:e,ok:!0,...t}),c=(e,t)=>({type:`ack`,reqId:e,ok:!1,error:t});try{switch(n.type){case`input.line`:return this.log.info(`input`,{kind:`line`,len:n.text.length}),await i.sendText(n.sessionId,`${n.text}\r`,a,o(n.sessionId,n.expect)),s(n.reqId);case`input.text`:return this.log.info(`input`,{kind:`text`,len:n.text.length}),await i.sendText(n.sessionId,n.text,a),s(n.reqId);case`input.key`:return await i.sendText(n.sessionId,Lt(n.key),a),s(n.reqId);case`input.terminal`:return await i.sendInput(n.sessionId,n.data,a,o(n.sessionId,n.expect)),s(n.reqId);case`input.paste`:return await i.paste(n.sessionId,n.text,n.submit,a,o(n.sessionId,n.expect)),s(n.reqId);case`input.mouse`:return await i.clickMouse(n.sessionId,n,a),s(n.reqId);case`session.create`:{let e=await i.createSession(n.in);return this.scheduleSessions(),s(n.reqId,e)}case`session.focus`:{let e=i.capabilitiesOf(n.sessionId);if(e===null)throw new M(n.sessionId);return e.focus?(await i.focus(n.sessionId),s(n.reqId)):c(n.reqId,`unsupported`)}default:return null}}catch(t){let r=t instanceof nt?t.message:t instanceof M?`session-gone`:t instanceof Ot?`unsupported`:t instanceof e?`bad-window`:t instanceof xt?t.code:`failed`;return this.log.warn(`inner message failed`,{type:n.type,error:r,err:j(t)}),`reqId`in n?c(n.reqId,r):null}}sendAlive(e=Date.now()){if(!(e-this.aliveSent<5e3)){this.aliveSent=e;for(let e of this.links.values())e.activeRoute===`direct`&&e.send({type:`alive`})}}broadcast(e){for(let t of this.links.values())t.send(e)}onBackendEvent(e){switch(this.events.onBackendEvent(e),e.type){case`screen-changed`:Date.now()-this.activityPublished>=6e4&&(this.activityPublished=Date.now(),this.scheduleSessions());return;case`conversation-changed`:this.chat.recheck(e.sessionId);return;case`conversation-settled`:this.chat.settled();return;case`session-removed`:this.chat.remove(e.sessionId),this.notifier.forget(e.sessionId),this.events.forget(e.sessionId),this.scheduleSessions();return;case`title-changed`:this.scheduleSessions(1e3);return;case`layout-changed`:case`session-added`:case`focus-changed`:case`command-start`:case`command-end`:case`prompt`:case`agent-state`:this.scheduleSessions();return;default:return}}scheduleSessions(e=0){let t=Date.now(),n=Math.max(t+100,this.sessionsRefreshedAt+e);this.sessionsDebounce&&this.sessionsDueAt<=n||(this.sessionsDebounce&&clearTimeout(this.sessionsDebounce),this.sessionsDueAt=n,this.sessionsDebounce=setTimeout(()=>{this.sessionsDebounce=null,this.sessionsRefreshedAt=Date.now(),this.refreshSessions()},n-t))}async checkChatInput(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(),5e3),i;try{i=await this.chat.check(e,t,n.signal)}finally{clearTimeout(r)}if(i.result!==`ok`)throw new xt(i.result);let a=()=>{let t=this.events.stateOf(e);return(t===`unknown`?this.sessions.find(t=>t.id===e)?.state:t)===`blocked`};if(i.waiting===!0||a())throw new xt(`waiting-for-you`);if(i.waiting===void 0){let n=await this.screenWithin(e,300);if(n!==null&&fi(li(n))||a())throw new xt(`waiting-for-you`);if(n===null)throw this.log.warn(`chat-input-screen-unread`),new xt(`unchecked`);if(!this.chat.holds(e,t))throw new xt(`conversation-changed`)}}async screenWithin(e,t){let n;try{return await Promise.race([this.o.registry.getScreen(e),new Promise(e=>{n=setTimeout(()=>e(null),t)})])}catch{return null}finally{clearTimeout(n)}}phoneSessionList(){return rn(this.sessions.map(e=>{let t=this.chat.status(e.id);return t?{...e,chat:t}:e}))}broadcastSessions(){this.chatDebounce&&clearTimeout(this.chatDebounce),this.chatDebounce=null,this.chatSentAt=Date.now(),this.broadcast(this.phoneSessionList())}scheduleChat(){if(this.stopped||this.chatDebounce)return;let e=Math.max(0,this.chatSentAt+1e3-Date.now());this.chatDebounce=setTimeout(()=>{this.chatDebounce=null,this.stopped||this.broadcastSessions()},e)}broadcastHelloIfBackendProfilesChanged(){let e=this.o.registry.connected(),t=JSON.stringify([this.o.registry.catalog().map(({capabilities:e,...t})=>({...t,capabilities:Object.entries(e).sort(([e],[t])=>e.localeCompare(t))})),this.o.registry.launchTargets(),this.o.registry.launchIssues(),this.o.registry.terminalSetup()]);if(t===this.backendsKey)return;let n=this.backendsKey===null;this.backendsKey=t,!n&&this.broadcast(this.helloMessage(e))}async refreshSessions(){let e=++this.sessionsRefreshes;try{let t=await this.o.registry.listSessions();if(e<this.sessionsPublished)return;this.sessionsPublished=e;let n=Date.now(),r=new Map;this.sessions=t.map(e=>{let t=this.o.registry.projectFolder(e.id),i=t?this.projects.lookup(t):void 0,a=i?{...e,project:i}:e,o=this.events.stateOf(a.id),s=o===`unknown`?a.state:o,{activeAt:c,stateSince:l,reportsAgentState:u}=this.events.activityOf(a.id),d=this.stateSeen.get(a.id),f=d===void 0?void 0:d.state===s?d.since:n,p=l??f;return r.set(a.id,{state:s,...p===void 0?{}:{since:p}}),{...a,state:s,...a.agent&&u?{agent:{...a.agent,reportsState:!0}}:{},...p===void 0?{}:{stateSince:p},...c===void 0?{}:{activeAt:c}}}),this.stateSeen=r,this.chat.update(this.sessions),this.broadcastSessions()}catch(e){this.log.warn(`listSessions failed`,{err:j(e)})}finally{this.broadcastHelloIfBackendProfilesChanged()}}};const Ss=Wr(tr);var Cs=class{opts;granted;paused;explicit=!1;allowance=!1;current=`not-running`;listeners=new Set;constructor(e){this.opts=e;let t=this.readRecord();this.granted=t?.approved??!!e.assumeApproved,this.paused=e.interactive?void 0:t?.paused,this.paused&&(this.current=this.paused),(!t||t.paused!==this.paused)&&this.persist()}get issue(){return this.current}get connecting(){return this.explicit}onChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}async connect(e){if(!this.explicit){this.explicit=!0,this.allowance=!0;try{await e()}finally{this.explicit=!1,this.allowance=!1,this.emit()}}}cookieProvider=async e=>{if(!await(this.opts.isRunning??Ts)())throw this.set(`not-running`),new ln(`iTerm2 is not running`,`not-running`);if(!await(this.opts.apiListening??Es)(this.opts.socketPath))throw this.set(`api-off`),Error(`iTerm2 Python API is off`);let t=this.allowance;if(!(t||!this.paused&&(this.granted||this.opts.interactive)))throw this.set(this.paused??`needs-consent`),new ln(`waiting for Connect iTerm2`,`unknown`);this.allowance=!1,t&&this.set(`connecting`);try{let t=await(this.opts.requestCookie??Fn)(this.opts.appName??`Shellbell`,e);return this.granted=!0,this.paused=void 0,this.persist(),this.set(void 0),t}catch(e){let t=ws(e);throw(t===`iterm2-denied`||t===`timed-out`)&&(this.paused=t,this.persist()),this.set(t),e}};set(e){e!==this.current&&(this.current=e,this.emit())}emit(){for(let e of this.listeners)try{e()}catch{}}readRecord(){if(this.opts.recordPath)try{let e=JSON.parse(fr(this.opts.recordPath,`utf8`));if(typeof e?.approved!=`boolean`)return;let t=e.paused===`iterm2-denied`||e.paused===`timed-out`?e.paused:void 0;return{approved:e.approved,paused:t}}catch{return}}persist(){if(this.opts.recordPath)try{Rt(this.opts.recordPath,`${JSON.stringify({v:1,approved:this.granted,...this.paused?{paused:this.paused}:{},at:new Date(this.opts.now?.()??Date.now()).toISOString()})}\n`)}catch{}}};function ws(e){return e instanceof ln?e.kind===`too-old`?`too-old`:e.kind===`not-running`?`not-running`:/-1743\b|Not authori[sz]ed to send Apple events/i.test(e.message)?`automation-denied`:/timed out/i.test(e.message)?`timed-out`:e.kind===`denied`?`iterm2-denied`:`failed`:`failed`}async function Ts(){try{let e=process.getuid?.();return await Ss(`/usr/bin/pgrep`,[...e===void 0?[]:[`-U`,String(e)],`-x`,`iTerm2`],{timeout:2e3}),!0}catch{return!1}}async function Es(e){try{if(!hr(e).isSocket())return!1}catch{return!1}return new Promise(t=>{let n=Nr({path:e}),r=e=>{n.destroy(),t(e)};n.setTimeout(1e3,()=>r(!1)),n.once(`connect`,()=>r(!0)),n.once(`error`,()=>r(!1))})}const Ds=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,Os=/^\/dev\/(ttys\d{1,5}|pts\/\d{1,6})$/;function ks(e,t,n){return new Promise((r,i)=>{tr(e,[...t],{signal:n,timeout:2e3,maxBuffer:1048576,env:{PATH:`/usr/bin:/bin:/usr/sbin:/sbin`,TZ:`UTC`,LC_ALL:`C`}},(e,t)=>e?i(e):r(t))})}async function As(e,t,n){let r=await n(`ps`,[`-t`,e.slice(5),`-o`,`pid=,stat=,lstart=,comm=`],t),i=[];for(let e of r.split(`
|
|
14
|
+
`)){let t=/^\s*(\d+)\s+(\S+)\s+(\S+ \S+\s+\d+ \d\d:\d\d:\d\d \d{4})\s+(.+?)\s*$/.exec(e);if(!t||!t[2].includes(`+`))continue;if(i.length>=256)break;let n=t[4].split(`/`).pop();i.push({pid:Number(t[1]),start:t[3].replace(/\s+/g,` `),command:n})}return i}async function js(e,t){let n=I(t,`sessions`,`${e.pid}.json`),r=await z(n).catch(()=>null);if(!r?.isFile()||r.size>65536||process.getuid&&r.uid!==process.getuid())return null;let i=JSON.parse(await zr(n,`utf8`));if(typeof i!=`object`||!i)return null;let a=i;return a.pid!==e.pid||typeof a.procStart!=`string`||a.procStart.replace(/\s+/g,` `)!==e.start||typeof a.sessionId!=`string`||!Ds.test(a.sessionId)?null:a.sessionId.toLowerCase()}async function Ms(e,t,n,r){if(r===`linux`){let t=`/proc/${e}/fd`,n=await Br(t),r=[];for(let e of n.slice(0,4096)){let n=await Vr(I(t,e)).catch(()=>null);n&&r.push(n)}return r}return(await n(`lsof`,[`-n`,`-P`,`-a`,`-p`,String(e),`-Fn`],t)).split(`
|
|
15
|
+
`).filter(e=>e.startsWith(`n`)).map(e=>e.slice(1))}async function Ns(e,t,n,r,i){let a=I(t,`presence`),o=await Ms(e.pid,n,r,i.platform??process.platform),s=new Set(o.flatMap(e=>{if(!e.startsWith(`${a}/`))return[];let t=e.slice(a.length+1),n=t.endsWith(`.lock`)?t.slice(0,-5):``;return Ds.test(n)?[n.toLowerCase()]:[]}));return s.size===1?[...s][0]:null}async function Ps(e,t,n={}){if(!Os.test(e)||t.aborted)return null;let r=n.run??ks;try{let i=new Map;for(let a of await As(e,t,r)){if(t.aborted)return null;let o=`process:${e}:${a.pid}:${a.start}`,s=qt(a.command),c=n.codexPane?(n.geminiSessions??en(`gemini`)).find({...n.codexPane,tty:e.slice(5)},{pid:a.pid,start:a.start}):null;if(c)i.set(`gemini:${c.session}`,{agent:`gemini`,kind:`id`,value:c.session,owner:`${o}:${c.session}`});else if(s===`codex`){let t=n.codexPane?(n.codexSessions??en(`codex`)).find({...n.codexPane,tty:e.slice(5)},{pid:a.pid,start:a.start}):null,r=!t&&n.codexTitle?await n.codexTitle():void 0,s=t?.session??(r?(n.codexThreads??un()).find(r.title,r.cwd):null);s&&i.set(`codex:${s}`,{agent:`codex`,kind:`id`,value:s,owner:`${o}:${s}`})}else if(s!==`agy`){let e=await js(a,n.claudeDir??(process.env.CLAUDE_CONFIG_DIR||I(N(),`.claude`)));e&&i.set(`claude:${e}`,{agent:`claude`,kind:`id`,value:e,owner:o})}else{let e=await Ns(a,n.antigravityDir??I(N(),`.gemini`,`antigravity-cli`),t,r,n);e&&i.set(`agy:${e}`,{agent:`agy`,kind:`id`,value:e,owner:o})}}return i.size===1?Object.freeze([...i.values()][0]):null}catch{return null}}function Fs(e){if(!e)return{};let t,n;if(e.fgColor.case===`fgStandard`?t=e.fgColor.value:e.fgColor.case===`fgRgb`&&(t=[e.fgColor.value.red??0,e.fgColor.value.green??0,e.fgColor.value.blue??0]),e.bgColor.case===`bgStandard`?n=e.bgColor.value:e.bgColor.case===`bgRgb`&&(n=[e.bgColor.value.red??0,e.bgColor.value.green??0,e.bgColor.value.blue??0]),e.inverse){let e=t??15;t=n??0,n=e}let r={};return t!==void 0&&(r.fg=t),n!==void 0&&(r.bg=n),e.bold&&(r.b=!0),e.italic&&(r.i=!0),e.underline&&(r.u=!0),e.strikethrough&&(r.s=!0),e.faint&&(r.f=!0),e.invisible&&(r.invisible=!0),r}function Is(e){return`${JSON.stringify(e.fg??null)}|${JSON.stringify(e.bg??null)}|${+!!e.b}${+!!e.i}${+!!e.u}${+!!e.s}${+!!e.f}${+!!e.invisible}`}function Ls(e){let t=Array.from(e.text??``),n=[];for(let t of e.codePointsPerCell)for(let e=0;e<(t.repeats||1);e++)n.push(t.numCodePoints);if(n.length===0)for(let e=0;e<t.length;e++)n.push(1);let r=[];for(let t of e.style)for(let e=0;e<(t.repeats||1);e++)r.push(t);let i=[],a=null,o=0;for(let e=0;e<n.length;e++){let s=n[e],c;s===0?c=` `:(c=t.slice(o,o+s).join(``),o+=s);let l=Fs(r[e]);l.invisible&&(c=` `.repeat(Math.max(1,Et(c))));let u=Is(l);a&&a.key===u?(a.text+=c,a.cells+=1):(a&&i.push(Rs(a)),a={style:l,key:u,text:c,cells:1})}a&&i.push(Rs(a));let s=e.continuation===2,c=Fe(i),l={r:s?c:ye(c)};return s&&(l.w=!0),l}function Rs(e){let t={t:e.text};return e.style.fg!==void 0&&(t.fg=e.style.fg),e.style.bg!==void 0&&(t.bg=e.style.bg),e.style.b&&(t.b=!0),e.style.i&&(t.i=!0),e.style.u&&(t.u=!0),e.style.s&&(t.s=!0),e.style.f&&(t.f=!0),e.cells!==Et(e.text)&&(t.n=e.cells),t}function zs(e,t,n){let r=Number(e.windowedCoordRange?.coordRange?.start?.y??0n),i=e.contents.map(Ls);for(;i.length<t;)i.push(ie());i.length>t&&(i.length=t);let a=e.cursor?Number(e.cursor.y??0n)-r:-1;return{cols:n,rows:t,cursor:{x:e.cursor?.x??0,y:Math.max(-1,Math.min(t-1,a))},lines:i,scrollbackTotal:r}}function Bs(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function Vs(e){return typeof e==`bigint`&&e>=0n&&e<=BigInt(2**53-1)}function Hs(e){let t;try{t=JSON.parse(e)}catch{return null}if(typeof t!=`object`||!t||Array.isArray(t))return null;let{overflow:n,history:r,grid:i,first_visible:a}=t;if(!Bs(n)||!Bs(r)||!Bs(i)||!Bs(a)||i===0)return null;let o=n+r;return Number.isSafeInteger(o)?{overflow:n,history:r,grid:i,firstVisible:a,origin:o}:null}function Us(e,t,n){if(!Bs(t)||!Bs(n)||n<t||e.status!==0)return!1;let r=e.windowedCoordRange?.coordRange,i=r?.start,a=r?.end;if(!i||!a||i.x!==0||a.x!==0||!Vs(i.y)||!Vs(a.y)||i.y!==BigInt(t)||a.y!==BigInt(n))return!1;let o=e.windowedCoordRange?.columns;return o&&(o.location!==0n||o.length!==0n)?!1:e.contents.length===n-t}function Ws(e,t){return e.overflow===t.overflow&&e.history===t.history&&e.grid===t.grid}function Gs(e,t){return t!==void 0&&(e.overflow<t.overflow||e.origin<t.origin)}function Ks(e){if(!e)return null;let t=e.links.map(e=>e.child.case===`session`?e.child.value.gridSize?{cols:e.child.value.gridSize.width,rows:e.child.value.gridSize.height}:null:e.child.case===`node`?Ks(e.child.value):null).filter(e=>e!==null);if(t.length===0)return null;let n=t.length-1,r=e=>t.reduce((t,n)=>t+n[e],n),i=e=>Math.max(...t.map(t=>t[e]));return e.vertical?{cols:r(`cols`),rows:i(`rows`)}:{cols:i(`cols`),rows:r(`rows`)}}const qs="iTerm2 → Settings → General → Magic → ✓ Enable Python API, then run `shellbell` again.";function Js(e){return j(e)}var Ys=class{client;backoff;name=`iterm2`;capabilities={subscribe:!0,prompts:!0,createSession:!0,terminalInput:!0,focus:!0,history:!0,absoluteLines:!0};sessions=new Map;windowGrids=new Map;historyOwnership=new Map;historyCaptures=new WeakMap;order=[];focused=null;handlers=new Set;subscribed=new Set;log;attempt=0;retryTimer=null;closed=!1;connectionGeneration=0;layoutBusy=!1;layoutDirty=null;layoutRefresh=Promise.resolve();constructor(e,t,n={}){this.client=e,this.backoff=n,this.log=t.child({backend:`iterm2`}),this.client.on(`notification`,e=>this.onNotification(e)),this.client.on(`close`,()=>{this.invalidateConnection(),this.scheduleReconnect()})}get isConnected(){return!this.closed&&this.client.connected}invalidateConnection(){this.connectionGeneration++,this.layoutBusy=!1,this.layoutDirty=null;let e=[...this.sessions.keys()];this.sessions.clear(),this.historyOwnership.clear(),this.order=[],this.subscribed.clear(),this.focused=null;for(let t of e)this.emit({type:`session-removed`,sessionId:t});this.emit({type:`layout-changed`})}ownsConnection(e){return e===this.connectionGeneration&&this.isConnected}scheduleReconnect(){if(this.closed||this.retryTimer)return;let e=this.backoff.minMs??1e3,t=this.backoff.maxMs??3e4,n=Math.min(t,e*2**this.attempt);this.attempt=Math.min(this.attempt+1,10),this.log.info(`iTerm2 gone; retrying`,{delayMs:n,attempt:this.attempt}),this.retryTimer=setTimeout(()=>{this.retryTimer=null;let e=this.connectionGeneration;this.connect().catch(t=>{e!==this.connectionGeneration||this.closed||(this.log.warn(`iTerm2 reconnect failed`,{error:Js(t)}),this.scheduleReconnect())})},n)}async connect(){this.closed=!1;let e=this.connectionGeneration;if(this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=null,!this.client.connected)try{await this.client.connect()}catch(t){if(e!==this.connectionGeneration||this.closed)return;throw new T(String(t),qs)}if(!this.ownsConnection(e)){this.closed&&this.client.close();return}try{for(let t of[8,6,7,9])if(await this.client.request({case:`notificationRequest`,value:V($n,{subscribe:!0,notificationType:t})}),!this.ownsConnection(e))return;let t=await this.client.request({case:`listSessionsRequest`,value:V(Xn,{})});if(!this.ownsConnection(e)||(t.submessage.case===`listSessionsResponse`&&await this.applyLayout(t.submessage.value,e),!this.ownsConnection(e)))return;let n=await this.client.request({case:`focusRequest`,value:V(Ln,{})});if(!this.ownsConnection(e))return;if(n.submessage.case===`focusResponse`)for(let e of n.submessage.value.notifications)e.event.case===`session`&&(this.focused=e.event.value)}catch(t){if(!this.ownsConnection(e))return;throw new T(String(t),qs)}this.attempt=0}async close(){this.closed=!0,this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=null,this.invalidateConnection(),this.client.close()}async notificationFacts(e){let t=this.sessions.get(e);if(t&&this.isConnected)return zn({sessionId:e,cwd:t.cwd,title:t.title,sessionLabel:`iTerm2`},t.job,`reported`)}async listSessions(){return this.order.map(e=>this.sessions.get(e)).filter(e=>e!==void 0).map(e=>this.toInfo(e))}tmuxWindowIds(){let e=new Set;for(let t of this.sessions.values())t.tmuxWindowId&&e.add(t.tmuxWindowId);return e}representedWindows(){return[...this.tmuxWindowIds()].map(e=>({backend:`tmux`,windowId:e}))}async conversationReference(e,t){if(t.aborted)return null;let n=await this.variable(e,`tty`);return!n||t.aborted?null:Ps(n,t,{codexPane:{iterm:e},codexTitle:async()=>{let[t,n]=await Promise.all([this.variable(e,`terminalWindowName`),this.variable(e,`path`)]);return{title:t,cwd:n}}})}hostedProcess(e){return this.hostJob(e)}projectFolder(e){let t=this.sessions.get(e);return t?.cwd&&yn(t.job)?t.cwd:void 0}hostJob(e){let t=this.sessions.get(e);if(t&&!t.tmuxWindowId)return t.job}async getScreen(e,t){let n=this.sessions.get(e);if(!n)throw new M(e);let r=this.historyOwnership.get(e),i=t?.history&&r?{sessionId:e,connectionGeneration:this.connectionGeneration,coordinateRevision:r.coordinateRevision,cols:n.cols,rows:n.rows}:void 0,a=r?.activityRevision,o=r?.observed,s=i?await this.fetchHistoryFacts(e):null;i&&s&&this.ownsHistory(i)&&(s.grid!==i.rows||Gs(s,o))&&this.revokeHistory(e);let c=await this.client.request({case:`getBufferRequest`,value:V(jn,{session:e,lineRange:V(xn,{screenContentsOnly:!0}),includeStyles:!0})});if(c.submessage.case!==`getBufferResponse`||c.submessage.value.status!==0)throw new M(e);let l=c.submessage.value,u;if(i&&s&&s.grid===i.rows&&this.ownsHistory(i)&&this.historyOwnership.get(e)?.activityRevision===a&&Us(l,s.origin,s.origin+s.grid)){let t=await this.fetchHistoryFacts(e);t&&this.ownsHistory(i)&&(t.grid!==i.rows||Gs(t,s))&&this.revokeHistory(e),t&&Ws(s,t)&&this.ownsHistory(i)&&this.historyOwnership.get(e)?.activityRevision===a&&(this.observeHistory(e,t),u=Object.freeze({}),this.historyCaptures.set(u,Object.freeze({...i,facts:Object.freeze(s)})))}let d=zs(l,n.rows,n.cols);return u&&(d.historyCapture=u),d}ownsHistory(e){let t=this.sessions.get(e.sessionId);return this.ownsConnection(e.connectionGeneration)&&this.historyOwnership.get(e.sessionId)?.coordinateRevision===e.coordinateRevision&&t?.cols===e.cols&&t.rows===e.rows}revokeHistory(e){let t=this.historyOwnership.get(e);t&&(t.coordinateRevision={},t.observed=void 0)}observeHistory(e,t){let n=this.historyOwnership.get(e);n&&(n.observed={overflow:Math.max(t.overflow,n.observed?.overflow??0),origin:Math.max(t.origin,n.observed?.origin??0)})}async fetchHistoryFacts(e){try{let t=await this.client.request({case:`getPropertyRequest`,value:V(An,{identifier:{case:`sessionId`,value:e},name:`number_of_lines`})});return t.submessage.case===`getPropertyResponse`&&t.submessage.value.status===0?Hs(t.submessage.value.jsonValue):null}catch{return null}}async getHistoryPage(e,t){if(lt(t),t.signal.aborted)return{status:`cancelled`};if(!this.sessions.has(e))throw new M(e);let n=this.historyCaptures.get(t.capture);if(!n||n.sessionId!==e)return{status:`unavailable`,reason:`unanchored`};let r=()=>{if(t.signal.aborted)return{status:`cancelled`};if(!this.ownsHistory(n))return{status:`reset`}},i=r();if(i)return i;if(t.reported!==n.facts.origin)return{status:`unavailable`,reason:`unanchored`};let a=this.historyOwnership.get(e)?.activityRevision,o=this.historyOwnership.get(e)?.observed??n.facts,s={status:`unavailable`,reason:`changed`},c=(t,r=o)=>{if(!t)return s;if(t.grid!==n.rows||Gs(t,r))return this.historyOwnership.get(e)?.coordinateRevision===n.coordinateRevision&&this.revokeHistory(e),{status:`reset`}},l=await this.fetchHistoryFacts(e),u=r()??c(l);if(u)return u;if(!l)return s;let d=l.overflow,f=Math.max(t.before-t.count,d),p;if(t.before>d)try{let n=await this.client.request({case:`getBufferRequest`,value:V(jn,{session:e,lineRange:V(xn,{windowedCoordRange:V(Qt,{coordRange:V(Dn,{start:V(kn,{x:0,y:BigInt(f)}),end:V(kn,{x:0,y:BigInt(t.before)})})})}),includeStyles:!0})}),i=r();if(i)return i;if(n.submessage.case!==`getBufferResponse`||!Us(n.submessage.value,f,t.before))return s;p=n.submessage.value.contents.map(Ls)}catch{return r()??s}let m=await this.fetchHistoryFacts(e);return(r()??c(m,l))||(!m||!Ws(l,m)||this.historyOwnership.get(e)?.activityRevision!==a?s:(this.observeHistory(e,m),p?{status:`page`,from:f,to:t.before,oldestAvailable:d,lines:p}:{status:`boundary`,reason:t.before===d?`end`:`truncated`,oldestAvailable:d}))}async getHistory(e,t,n){if(!this.sessions.has(e))throw new M(e);let r=Math.max(0,t-n),i=await this.client.request({case:`getBufferRequest`,value:V(jn,{session:e,lineRange:V(xn,{windowedCoordRange:V(Qt,{coordRange:V(Dn,{start:V(kn,{x:0,y:BigInt(r)}),end:V(kn,{x:0,y:BigInt(t)})})})}),includeStyles:!0})});if(i.submessage.case!==`getBufferResponse`||i.submessage.value.status!==0)throw new M(e);let a=i.submessage.value.contents.map(Ls);return{lines:a,oldestAvailable:a.length<t-r?t-a.length:0}}async sendText(e,t){let n=await this.client.request({case:`sendTextRequest`,value:V(Qn,{session:e,text:t,suppressBroadcast:!0})});if(n.submessage.case!==`sendTextResponse`)throw new M(e);let r=n.submessage.value.status;if(r===1)throw new M(e);if(r!==0)throw Error(`sendText failed: ${pn[r]}`)}async sendInput(e,t){await this.sendText(e,t)}async createSession(e){if(e.kind===`tab`){let t=e.windowId===void 0&&e.initialSize?rt.parse(e.initialSize):void 0,n=await this.client.request({case:`createTabRequest`,value:V(Hn,{windowId:e.windowId,selectTab:!1,...t?{customProfileProperties:[{key:`Columns`,jsonValue:JSON.stringify(t.cols)},{key:`Rows`,jsonValue:JSON.stringify(t.rows)}]}:{}})});if(n.submessage.case!==`createTabResponse`||!n.submessage.value.sessionId)throw Error(`create tab failed`);return n.submessage.value.sessionId}let t=await this.client.request({case:`splitPaneRequest`,value:V(Xt,{session:e.sessionId,splitDirection:e.direction===`vertical`?0:1})}),n=t.submessage.case===`splitPaneResponse`?t.submessage.value.sessionId[0]:void 0;if(!n)throw Error(`split failed`);return n}hostedWindowGrid(){let e=this.focused?this.sessions.get(this.focused):void 0,t=e?this.windowGrids.get(e.windowId):void 0;if(t)return t;let n;for(let e of this.windowGrids.values())(!n||e.cols*e.rows>n.cols*n.rows)&&(n=e);return n}async focusedWindow(){let e=this.focused?this.sessions.get(this.focused):void 0;if(e?.windowId)return e.windowId;for(let e of this.sessions.values())if(e.windowId)return e.windowId}async createCommandSession(e,t,n){if(e.length===0||e.length>8192||e.includes(`\0`))throw Error(`Invalid terminal launch command`);let r=n===void 0?t===void 0?this.hostedWindowGrid():rt.parse(t):void 0,i=await this.client.request({case:`createTabRequest`,value:V(Hn,{...n!==void 0&&{windowId:n},selectTab:!1,customProfileProperties:[{key:`Custom Command`,jsonValue:JSON.stringify(`Yes`)},{key:`Command`,jsonValue:JSON.stringify(e)},...r?[{key:`Columns`,jsonValue:JSON.stringify(r.cols)},{key:`Rows`,jsonValue:JSON.stringify(r.rows)}]:[]]})});if(i.submessage.case!==`createTabResponse`||i.submessage.value.status!==0||!i.submessage.value.sessionId)throw Error(`iTerm2 could not create the terminal window`);return i.submessage.value.sessionId}async focus(e){await this.client.request({case:`activateRequest`,value:V(In,{identifier:{case:`sessionId`,value:e},orderWindowFront:!0,selectTab:!0,selectSession:!0,activateApp:V(Yn,{raiseAllWindows:!1,ignoringOtherApps:!1})})})}on(e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(e){for(let t of this.handlers)try{t(e)}catch(e){this.log.warn(`event handler failed`,{error:Js(e)})}}toInfo(e){return{id:e.id,backend:`iterm2`,title:e.title,cwd:e.cwd,...bn({cwd:e.cwd,processName:e.job,title:e.title}),cols:e.cols,rows:e.rows,windowId:e.windowId,windowNumber:e.windowNumber,tabId:e.tabId,tabIndex:e.tabIndex,paneIndex:e.paneIndex,isFocusedOnMac:this.focused===e.id,state:`unknown`}}applyLayout(e,t){return this.ownsConnection(t)?(this.layoutDirty=e,this.layoutBusy?this.layoutRefresh:(this.layoutBusy=!0,this.layoutRefresh=this.drainLayout(t),this.layoutRefresh)):Promise.resolve()}async drainLayout(e){try{for(;this.ownsConnection(e)&&this.layoutDirty;){let t=this.layoutDirty;this.layoutDirty=null,await this.runApplyLayout(t,e)}}finally{e===this.connectionGeneration&&(this.layoutBusy=!1)}}async runApplyLayout(e,t){let n=new Map,r=[],i=[...e.windows].sort((e,t)=>(e.number??0)-(t.number??0)),a=new Map;for(let e of i){for(let t of e.tabs){let n=Ks(t.root),r=a.get(e.windowId??``);n&&n.cols>0&&n.rows>0&&a.set(e.windowId??``,{cols:Math.max(n.cols,r?.cols??0),rows:Math.max(n.rows,r?.rows??0)})}e.tabs.forEach((t,i)=>{let a=0,o=s=>{if(s)for(let c of s.links)if(c.child.case===`session`){let o=c.child.value,s=o.uniqueIdentifier??``,l=this.sessions.get(s);n.set(s,{id:s,title:l?.title||o.title||`Session`,cwd:l?.cwd,job:l?.job,cols:o.gridSize?.width??80,rows:o.gridSize?.height??24,windowId:e.windowId??``,windowNumber:e.number??0,tabId:t.tabId??``,tabIndex:i,paneIndex:a++,tmuxWindowId:t.tmuxWindowId||void 0}),r.push(s)}else c.child.case===`node`&&o(c.child.value)};o(t.root)})}for(let e of this.sessions.keys())n.has(e)||(this.subscribed.delete(e),this.historyOwnership.delete(e));for(let[e,t]of n){let n=this.sessions.get(e);(!this.historyOwnership.has(e)||n?.cols!==t.cols||n.rows!==t.rows)&&this.historyOwnership.set(e,{coordinateRevision:{},activityRevision:{}})}this.sessions=n,this.windowGrids=a,this.order=r,await Promise.all(r.map(e=>this.ensureSession(e,t))),this.ownsConnection(t)&&this.emit({type:`layout-changed`})}async ensureSession(e,t){let n=this.sessions.get(e),r=()=>this.ownsConnection(t)&&this.sessions.get(e)===n;if(!n||!r()||this.subscribed.has(e))return;this.subscribed.add(e);let i=[V($n,{session:e,subscribe:!0,notificationType:2}),V($n,{session:e,subscribe:!0,notificationType:3,arguments:{case:`promptMonitorRequest`,value:V(wn,{modes:[1,2,3]})}}),...[`session.name`,`session.path`,`jobName`].map(t=>V($n,{session:e,subscribe:!0,notificationType:12,arguments:{case:`variableMonitorRequest`,value:V(Zn,{name:t,scope:1,identifier:e})}}))];for(let t of i){try{await this.client.request({case:`notificationRequest`,value:t})}catch(t){if(!r())return;this.log.warn(`subscribe failed`,{session:e.slice(0,8),error:Js(t)})}if(!r())return}if(!r())return;let[a,o,s]=await Promise.all([this.variable(e,`session.name`),this.variable(e,`session.path`),this.variable(e,`jobName`)]);r()&&(a&&(n.title=a),o&&(n.cwd=o),s&&(n.job=s))}async variable(e,t){try{let n=await this.client.request({case:`variableRequest`,value:V(mn,{scope:{case:`sessionId`,value:e},get:[t]})});if(n.submessage.case!==`variableResponse`||n.submessage.value.status!==0)return;let r=n.submessage.value.values[0];if(!r||r===`null`)return;let i=JSON.parse(r);return typeof i==`string`?i:void 0}catch{return}}onNotification(e){let t=this.connectionGeneration;if(!this.ownsConnection(t))return;let n=Date.now();if(e.screenUpdateNotification?.session){let t=this.historyOwnership.get(e.screenUpdateNotification.session);t&&(t.activityRevision={}),this.emit({type:`screen-changed`,sessionId:e.screenUpdateNotification.session});return}if(e.promptNotification?.session){let t=e.promptNotification,r=t.session;t.event.case===`commandStart`?this.emit({type:`command-start`,sessionId:r,command:t.event.value.command??``,at:n}):t.event.case===`commandEnd`?this.emit({type:`command-end`,sessionId:r,exitCode:t.event.value.status??0,at:n}):t.event.case===`prompt`&&this.emit({type:`prompt`,sessionId:r,at:n});return}if(e.layoutChangedNotification?.listSessionsResponse){for(let e of this.historyOwnership.keys())this.revokeHistory(e);this.applyLayout(e.layoutChangedNotification.listSessionsResponse,t).catch(e=>{this.ownsConnection(t)&&this.log.warn(`layout refresh failed`,{error:Js(e)})});return}if(e.newSessionNotification?.sessionId){this.client.request({case:`listSessionsRequest`,value:V(Xn,{})}).then(e=>{if(this.ownsConnection(t)&&e.submessage.case===`listSessionsResponse`)return this.applyLayout(e.submessage.value,t)}).catch(e=>{this.ownsConnection(t)&&this.log.warn(`new-session layout refresh failed`,{error:Js(e)})}),this.emit({type:`session-added`,sessionId:e.newSessionNotification.sessionId});return}if(e.terminateSessionNotification?.sessionId){let t=e.terminateSessionNotification.sessionId;this.sessions.delete(t),this.historyOwnership.delete(t),this.subscribed.delete(t),this.order=this.order.filter(e=>e!==t),this.emit({type:`session-removed`,sessionId:t}),this.emit({type:`layout-changed`});return}if(e.focusChangedNotification){e.focusChangedNotification.event.case===`session`&&(this.focused=e.focusChangedNotification.event.value),this.emit({type:`focus-changed`});return}if(e.variableChangedNotification?.identifier){let t=e.variableChangedNotification,n=this.sessions.get(t.identifier);if(!n)return;try{let e=JSON.parse(t.jsonNewValue??`null`);t.name===`session.name`&&typeof e==`string`&&(n.title=e),t.name===`session.path`&&typeof e==`string`&&(n.cwd=e),t.name===`jobName`&&typeof e==`string`&&(n.job=e)}catch{return}this.emit({type:`title-changed`,sessionId:n.id})}}};const Xs=L.object({apiVersion:L.literal(1),id:Ye,label:kt,platforms:L.array(L.enum([`darwin`,`linux`])).min(1).max(2),hostCommands:L.array(L.string().regex(/^[a-zA-Z0-9._-]{1,64}$/)).max(16).optional()}),Zs=L.string().min(1).max(128),Qs=L.discriminatedUnion(`type`,[L.object({type:L.literal(`focus-changed`)}),...[`screen-changed`,`session-added`,`session-removed`,`title-changed`].map(e=>L.object({type:L.literal(e),sessionId:Zs})),L.object({type:L.literal(`layout-changed`)}),L.object({type:L.literal(`command-start`),sessionId:Zs,command:L.string().max(512),at:L.number().finite()}),L.object({type:L.literal(`command-end`),sessionId:Zs,exitCode:L.number().int(),at:L.number().finite()}),L.object({type:L.literal(`prompt`),sessionId:Zs,at:L.number().finite()}),L.object({type:L.literal(`agent-state`),sessionId:Zs,state:L.enum([`working`,`blocked`,`idle`,`done`,`unknown`]),agent:L.string().max(128).optional(),at:L.number().finite()})]),$s=L.object({cols:L.number().int().min(1).max(E.cols),rows:L.number().int().min(1).max(E.rows),cursor:Qe,lines:L.array(Ct).max(E.rows),scrollbackTotal:L.number().int().nonnegative().max(2**53-1),historyCapture:L.custom(e=>typeof e==`object`&&!!e&&!Array.isArray(e)).optional()}).refine(e=>e.lines.length===e.rows,`screen must contain every viewport row`),ec=L.number().int().nonnegative().max(2**53-1),tc=L.discriminatedUnion(`status`,[L.object({status:L.literal(`page`),from:ec,to:ec,oldestAvailable:ec,lines:L.array(Ct).max(E.historyLines)}),L.object({status:L.literal(`boundary`),reason:L.enum([`end`,`truncated`]),oldestAvailable:ec}),L.object({status:L.literal(`unavailable`),reason:L.enum([`unsupported`,`unanchored`,`busy`,`changed`,`fetch-window`])}),L.object({status:L.literal(`reset`)}),L.object({status:L.literal(`cancelled`)})]);var nc=class extends Error{};async function rc(e,t){let n;try{return await Promise.race([e,new Promise((e,r)=>{n=setTimeout(()=>r(new nc(`Terminal adapter deadline exceeded`)),t),n.unref()})])}finally{n&&clearTimeout(n)}}var ic=class{raw;abort;timeoutMs;name;capabilities;connected=!1;closed=!1;generation=0;pending=0;handlers=new Set;unsubscribe;constructor(e,t,n,r=5e3){if(this.raw=e,this.abort=n,this.timeoutMs=r,this.name=Ye.parse(t),e.name!==t)throw Error(`Adapter identity does not match its manifest`);this.capabilities=Object.freeze(Ft.parse(e.capabilities));for(let t of[`connect`,`close`,`listSessions`,`getScreen`,`getHistory`,`sendText`,`createSession`,`focus`,`on`])if(typeof e[t]!=`function`)throw Error(`Adapter is missing a required method`);if(this.capabilities.terminalInput&&!e.sendInput||this.capabilities.terminalPaste&&!e.paste||this.capabilities.mouseClick&&!e.clickMouse)throw Error(`Adapter capability has no implementation`);if(this.unsubscribe=e.on(e=>{if(this.closed)return;let t=Qs.safeParse(e);if(!t.success||`sessionId`in t.data&&!this.validId(t.data.sessionId))return;let n=t.data;if(this.isConnected||n.type===`layout-changed`)for(let e of[...this.handlers])this.handlers.has(e)&&e(n)}),typeof this.unsubscribe!=`function`)throw Error(`Adapter subscription is invalid`)}get isConnected(){try{return!this.closed&&this.connected&&this.raw.isConnected!==!1}catch{return!1}}validId(e,t=!1){return(t||e.length>0)&&e.length+this.name.length+1<=128&&[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127)}async call(e){if(this.closed||this.pending>=4)throw new T(`Terminal adapter is busy`,`Try again after the adapter recovers.`);let t=this.generation;this.pending++;let n=Promise.resolve().then(()=>{if(this.closed||t!==this.generation)throw Error(`Terminal adapter generation retired`);return e()}).finally(()=>{this.pending--});try{let e=await rc(n,this.timeoutMs);if(this.closed||t!==this.generation)throw Error(`Terminal adapter generation retired`);return e}catch(e){if(e instanceof nc){this.connected=!1,this.generation++;for(let e of[...this.handlers])this.handlers.has(e)&&e({type:`layout-changed`})}throw e}}async connect(){if(!this.isConnected){if(this.closed||this.pending>0)throw new T(`Terminal adapter is unavailable`,`Wait for its pending operation or restart the service.`);await this.call(()=>this.raw.connect()),this.connected=!0;for(let e of[...this.handlers])this.handlers.has(e)&&e({type:`layout-changed`})}}canLaunch(){try{return!this.closed&&this.capabilities.createSession&&!!this.raw.launch&&(this.raw.canLaunch?.()??!0)}catch{return!1}}async launch(){if(!this.canLaunch())throw new Ot(`terminal startup`);await this.call(()=>this.raw.launch())}async close(){if(!this.closed){this.closed=!0,this.connected=!1,this.generation++,this.abort.abort(),this.handlers.clear();try{this.unsubscribe()}finally{await rc(Promise.resolve().then(()=>this.raw.close()),this.timeoutMs)}}}async listSessions(){if(!this.isConnected)return[];let e=L.array(gt).max(500).parse(await this.call(()=>this.raw.listSessions()));if(e.some(e=>e.backend!==this.name||!this.validId(e.id)||!this.validId(e.windowId,!0)||!this.validId(e.tabId,!0))||new Set(e.map(e=>e.id)).size!==e.length)throw Error(`Adapter returned invalid session identities`);return e}async getScreen(e,t){return $s.parse(await this.call(()=>this.raw.getScreen(e,t)))}async getHistory(e,t,n){return L.object({lines:L.array(Ct).max(1e3),oldestAvailable:L.number().int().nonnegative()}).parse(await this.call(()=>this.raw.getHistory(e,t,n)))}async getHistoryPage(e,t){if(!this.raw.getHistoryPage)return{status:`unavailable`,reason:`unsupported`};let n=tc.parse(await this.call(()=>this.raw.getHistoryPage(e,t)));if(n.status===`page`&&(n.to-n.from!==n.lines.length||n.from<n.oldestAvailable||n.to>t.before||n.lines.length>t.count))throw Error(`Adapter returned an invalid history range`);return n}async sendText(e,t){await this.call(()=>this.raw.sendText(e,t))}async sendInput(e,t){if(!this.raw.sendInput)throw new Ot(`terminal input`);await this.call(()=>this.raw.sendInput(e,t))}async paste(e,t,n){if(!this.raw.paste)throw new Ot(`terminal paste`);await this.call(()=>this.raw.paste(e,t,n))}async clickMouse(e,t){if(!this.raw.clickMouse)throw new Ot(`mouse input`);await this.call(()=>this.raw.clickMouse(e,t))}async createSession(e){let t=await this.call(()=>this.raw.createSession(e));if(!this.validId(t))throw Error(`Adapter returned an invalid session identity`);return t}async focus(e){await this.call(()=>this.raw.focus(e))}on(e){return this.handlers.add(e),()=>{this.handlers.delete(e)}}setWatched(e){this.raw.setWatched?.(e)}setReported(e,t){this.raw.setReported?.(e,t)}hostedProcess(e){let t=this.raw.hostedProcess?.(e);return t===void 0?void 0:L.string().max(128).refine(e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127)).parse(t)}representedWindows(){return L.array(L.object({backend:Ye,windowId:L.string().min(1).max(128)})).max(500).parse(this.raw.representedWindows?.()??[])}nativeWindowIdOf(e){let t=this.raw.nativeWindowIdOf?.(e);return t===void 0?void 0:L.string().min(1).max(128).parse(t)}};function ac(e){let t=!1,n=[],r=new Set(mt.options),i=e.timeoutMs??5e3;return{ready:(async()=>{for(let a of e.paths){if(t)break;let o=new AbortController;n.push(()=>o.abort());let s,c,l=!1,u=async e=>{l||(l=!0,await rc(Promise.resolve().then(()=>e.close()),i).catch(()=>{}))};try{if(e.admitPath)e.admitPath(a);else{if(cr(a).isSymbolicLink()||mr(a)!==a)throw Error(`Adapter path must be canonical`);dt(a,262144,process.getuid())}let l=await rc((e.importModule??Gr)(Er(a).href),i),d=Xs.parse(l.default);if(r.has(d.id))throw Error(`Adapter identity is already registered`);if(!d.platforms.includes(e.platform??process.platform)){o.abort();continue}let f=l.default;if(typeof f.create!=`function`)throw Error(`Adapter factory is missing`);let p=Promise.resolve().then(()=>f.create({log:e.log.child({adapter:d.id}),signal:o.signal}));if(p.then(async e=>{o.signal.aborted&&await u(e)},()=>{}),c=await rc(p,i),t){o.abort(),await u(c);break}s=new ic(c,d.id,o,i),r.add(d.id),e.registry.add(s,d.label,d.hostCommands??[]);let m=c.launch?e.registry.registerSessionLauncher(d.id,{available:()=>s?.canLaunch()??!1,start:async()=>(await g.launch(),await g.connect(),{backend:g})}):void 0,h,g=s,_=async()=>{if(!t){if(e.registry.member(d.id)!==g){await g.close().catch(()=>{});return}try{await g.connect()}catch(t){e.log.debug(`terminal adapter unavailable`,{adapter:d.id,error:j(t)})}t||(h=setTimeout(()=>{_()},e.retryMs??1e4),h.unref())}};n.push(()=>{m?.(),h&&clearTimeout(h),e.registry.member(d.id)===g&&e.registry.remove(d.id),g.close().catch(t=>e.log.warn(`terminal adapter cleanup failed`,{adapter:d.id,error:j(t)}))}),_()}catch(t){o.abort(),s?await s.close().catch(()=>{}):c&&await u(c),e.log.warn(`terminal plugin could not be loaded`,{error:j(t)})}}})(),stop(){t=!0;for(let e of n.splice(0))e()}}}const oc={iterm2:{bundle:`iTerm.app`,label:`iTerm2`}},sc=Wr(tr);function cc(e,t={}){if((t.platform??process.platform)!==`darwin`)return null;let n=t.roots??[`/Applications`,I(N(),`Applications`)],r=t.exists??ar,i=oc[e],a=()=>n.map(e=>I(e,i.bundle)).find(r);return{available:()=>a()!==void 0,start:async()=>{let e=a();if(!e)throw new T(`${i.label} is not installed`,`Install ${i.label} on your computer.`);try{await(t.execute??((e,t)=>sc(e,t,{timeout:5e3,maxBuffer:4096})))(`/usr/bin/open`,[`-g`,`-a`,e])}catch{throw new T(`Could not launch ${i.label}`,`Open ${i.label} on your computer and check its local API.`)}}}}function lc(e,t,n={}){let r=n.execute??((e,t)=>sc(e,t,{timeout:2e3,maxBuffer:65536,encoding:`utf8`})),i=n.exists??ar,a=n.now??Date.now,o,s=-1/0,c=!1,l=async()=>{let t;try{let{stdout:n}=await r(`/usr/bin/osascript`,[`-l`,`JavaScript`,`-e`,`function run(argv) {
|
|
16
16
|
ObjC.import(argv[1]);
|
|
17
17
|
const find = (id) => $.NSWorkspace.sharedWorkspace.URLForApplicationWithBundleIdentifier(id);
|
|
18
18
|
if (find("com.apple.finder").isNil()) return "?";
|
|
19
19
|
const url = find(argv[0]);
|
|
20
20
|
return url.isNil() ? "" : ObjC.unwrap(url.path);
|
|
21
|
-
}`,e,`AppKit`]),a=n.replace(/\n$/,``);t=a===`?`?void 0:a===``?!1:i(a)?!0:void 0}catch{t=void 0}s=a(),c=!1,t!==o&&(o=t,n.onChange?.())};return()=>t()?!0:(!c&&a()-s>=6e4&&(c=!0,l()),o)}function
|
|
22
|
-
`)}catch{}this.child.kill()}this.onExit()}onExit(){if(this.alive){this.alive=!1,this.settleReady?.();for(let e of[this.currentPending,...this.queue])e&&(clearTimeout(e.timer),e.reject(Error(`tmux control exited`)));this.queue=[],this.currentPending=null,this.emit(`exit`)}}};const
|
|
23
|
-
`,`Enter`],[` `,`Tab`]]);for(let[t,n]of Object.entries(
|
|
24
|
-
`),n+=e;for(let[,n=``]of e.matchAll(/\x1b\[([\d;:]*)m/g))t=
|
|
25
|
-
`)}}var
|
|
26
|
-
`).filter(Boolean)}catch(e){this.log.debug(`tmux list-sessions failed; keeping the existing clients`,{error:Ac(e)});return}this.sessionIndex=new Map(e.map((e,t)=>[e,t]));for(let[t,n]of this.controls)(!e.includes(t)||!n.alive)&&(n.stop(),this.controls.delete(t),this.invalidateAllHistory());for(let t of e){if(this.closed||this.controls.has(t))continue;let e=(this.opts.controlFactory??(e=>new Ks({sessionId:e,socketName:this.opts.socketName,executable:this.program(),log:this.opts.log})))(t);e.on(`output`,e=>{this.panes.has(e)?(this.invalidatePane(e),this.emit({type:`screen-changed`,sessionId:e})):this.scheduleRefresh()}),e.on(`layout`,()=>{this.invalidateAllHistory(),this.scheduleRefresh()}),e.on(`exit`,()=>{this.controls.delete(t),this.invalidateAllHistory(),this.scheduleRefresh()}),this.controls.set(t,e),this.invalidateAllHistory(),await e.start()}}finally{this.syncBusy=!1}}}scheduleRefresh(){if(!this.closed){if(this.refreshBusy){this.refreshDirty=!0;return}this.refreshTimer||(this.refreshTimer=setTimeout(()=>{this.refreshTimer=null,this.refreshPanes().catch(e=>this.log.warn(`tmux refresh failed`,{error:Ac(e)}))},this.opts.refreshDebounceMs??100),this.refreshTimer.unref?.())}}async refreshPanes(){if(!this.closed){if(this.refreshBusy){this.refreshDirty=!0;return}this.refreshBusy=!0;try{do this.refreshDirty=!1,await this.runRefresh();while(this.refreshDirty&&!this.closed)}finally{this.refreshBusy=!1}}}async runRefresh(){if(this.controls.size===0){let e=[...this.panes.keys()];this.panes.clear(),this.serverInstance=void 0,this.alternate.clear(),this.invalidateAllHistory();for(let t of e)this.emit({type:`session-removed`,sessionId:t});e.length>0&&this.emit({type:`layout-changed`});return}let e;try{e=lc(await this.channel().command(`list-panes -a -F ${ec}`))}catch(e){this.log.warn(`list-panes failed`,{error:Ac(e)});return}let t=this.panes,n=new Map(e.filter(e=>!e.dead).map(e=>[e.paneId,e])),r=[...t.keys()].filter(e=>!n.has(e)),i=[...n.keys()].filter(e=>!t.has(e)),a=this.opts.hostname??sr(),o=[...n.keys()].filter(e=>{let r=t.get(e);if(!r)return!1;let i=n.get(e);return mc(r,a)!==mc(i,a)||r.cwd!==i.cwd||!fn(kc(r,a),kc(i,a))});this.panes=n;for(let e of r)this.reported.delete(e),this.alternate.delete(e),this.invalidatePane(e),this.emit({type:`session-removed`,sessionId:e});for(let e of i)this.revisionFor(e),this.emit({type:`session-added`,sessionId:e});for(let e of o)this.emit({type:`title-changed`,sessionId:e});(r.length>0||i.length>0)&&this.emit({type:`layout-changed`})}pane(e){let t=this.panes.get(e);if(!t)throw new A(e);return t}revisionFor(e){let t=this.paneRevisions.get(e);return t||(t={},this.paneRevisions.set(e,t)),t}invalidatePane(e){this.paneRevisions.delete(e)}invalidateAllHistory(){this.paneRevisions.clear()}ownsEvidence(e){return this.panes.has(e.paneId)&&this.paneRevisions.get(e.paneId)===e.revision&&e.channel.alive&&this.channel(e.paneId)===e.channel}sameFacts(e,t){return e.cursorX===t.cursorX&&e.cursorY===t.cursorY&&e.historySize===t.historySize&&e.width===t.width&&e.height===t.height&&e.historyLimit===t.historyLimit&&e.alternate===t.alternate}async checkedFacts(e,t){if(t.aborted)return{status:`cancelled`};if(!this.ownsEvidence(e))return{status:`reset`};let n;try{n=(await e.channel.command(`display-message -p -t ${e.paneId} ${rc}`))[0]}catch{return t.aborted?{status:`cancelled`}:this.ownsEvidence(e)?{status:`unavailable`,reason:`changed`}:{status:`reset`}}if(t.aborted)return{status:`cancelled`};if(!this.ownsEvidence(e))return{status:`reset`};let r=Z(n??``);return r?this.sameFacts(r,e.facts)?r:(this.invalidatePane(e.paneId),{status:`reset`}):{status:`unavailable`,reason:`changed`}}readOutcome(e,t){if(t.aborted)return{status:`cancelled`};if(!this.ownsEvidence(e))return{status:`reset`}}async notificationFacts(e){let t=this.panes.get(e);if(!t||!this.isConnected)return;let n=zn({sessionId:e,cwd:t.cwd,title:mc(t,this.opts.hostname??sr()),sessionLabel:`tmux`},t.currentCommand,`local-process`),r=this.serverInstance;return r?{...n,instance:r,revision:JSON.stringify([n.revision,r])}:n}async listSessions(){let e=new Set,t=new Map,n;try{let r=(await this.channel().command(`list-clients -F ${tc}`)).map(uc),i=r.filter(e=>!e.controlMode),a=r.find(e=>e.serverPid)?.serverPid;a&&(n=`tmux-server-${a}`),e=new Set(i.map(e=>e.sessionId)),t=await this.hostApps(i)}catch(e){this.log.debug(`list-clients failed; no pane reported focused`,{error:Ac(e)})}this.serverInstance=n;let r=this.opts.hostname??sr(),i=e=>this.sessionIndex.get(e)??2**53-1;return[...this.panes.values()].sort((e,t)=>i(e.sessionId)-i(t.sessionId)||e.windowIndex-t.windowIndex||e.paneIndex-t.paneIndex).map(i=>({id:i.paneId,backend:`tmux`,title:mc(i,r),cwd:i.cwd||void 0,...kc(i,r),cols:Math.max(1,i.width),rows:Math.max(1,i.height),windowId:i.sessionId,windowNumber:this.sessionIndex.get(i.sessionId)??0,tabId:i.windowId,tabIndex:i.windowIndex,paneIndex:i.paneIndex,isFocusedOnMac:i.paneActive&&i.windowActive&&e.has(i.sessionId),state:`unknown`,...this.alternate.has(i.paneId)&&{alternateScreen:this.alternate.get(i.paneId)},...t.has(i.sessionId)&&{shownIn:t.get(i.sessionId)},...n&&{instance:n}}))}async hostApps(e){let t=new Map;if(!e.some(e=>e.pid))return t;let n=Date.now();(!this.processes||n-this.processes.at>1e4)&&(this.processes={at:n,table:await(this.opts.processTable??Gt)().catch(()=>void 0)});let r=this.processes.table;if(!r)return t;for(let{sessionId:n,pid:i}of e){let e=i?tn(i,r):void 0;if(!e)continue;let a=t.get(n)??[];!a.includes(e)&&a.length<4&&a.push(e),t.set(n,a.sort((e,t)=>e.localeCompare(t)))}return t}openVtStream(e){return new wc({tmuxSessionId:this.pane(e).sessionId,paneId:e,socketName:this.opts.socketName,executable:this.program(),log:this.opts.log})}projectFolder(e){let t=this.panes.get(e);if(t?.cwd&&!dn(t.windowName,t.currentCommand))return Yt(t.currentCommand)?t.cwd:void 0}tmuxWindowIdOf(e){return this.panes.get(e)?.windowId}nativeWindowIdOf(e){return this.tmuxWindowIdOf(e)}hostedProcess(e){return this.panes.get(e)?.currentCommand}async conversationReference(e,t){if(t.aborted||!this.panes.has(e))return null;let[n=``,r=``]=await this.exec([`display-message`,`-p`,`-t`,e,`#{pane_tty} #{socket_path}`]).then(e=>e.trim().split(` `),()=>[]);return t.aborted||!this.panes.has(e)?null:$o(n,t,{codexPane:{tmux:{socket:r,pane:e}},codexTitle:async()=>{let t=this.panes.get(e);return{title:t?.paneTitle,cwd:t?.cwd||void 0}}})}observeAlternate(e,t){if(t===void 0||!this.panes.has(e))return;let n=this.alternate.get(e);n!==t&&(this.alternate.set(e,t),(n!==void 0||t)&&this.emit({type:`title-changed`,sessionId:e}))}setReported(e,t){this.reported.set(e,t)}async getScreen(e,t){this.pane(e);let n=this.channel(e),r=t?.history===!0,i=r?this.revisionFor(e):void 0,a=r?rc:nc,o=await n.command(`display-message -p -t ${e} ${a}`),s=await n.command(`capture-pane -p -e -N -t ${e}`),c=dc(o[0]??``);this.observeAlternate(e,r?Z(o[0]??``)?.alternate:fc(o[0]??``));let l=Math.max(1,c.height),u=s.map(Mn);for(;u.length<l;)u.push({r:[]});u.length>l&&(u.length=l);let d={cols:Math.max(1,c.width),rows:l,cursor:{x:c.cursorX,y:c.cursorY},lines:u,scrollbackTotal:c.historySize};if(!r)return d;let f=Z(o[0]??``);if(!f||f.alternate||!this.panes.has(e)||this.channel(e)!==n||!n.alive)return d;let p;try{p=Z((await n.command(`display-message -p -t ${e} ${rc}`))[0]??``)}catch{return d}if(!p||!this.sameFacts(f,p)||p.alternate||this.paneRevisions.get(e)!==i||this.channel(e)!==n||!n.alive)return d;let m=Object.freeze({});return this.historyEvidence.set(m,{paneId:e,revision:i,channel:n,facts:Object.freeze(f)}),{...d,historyCapture:m}}async getHistory(e,t,n){this.pane(e);let r=this.reported.get(e);if(r===void 0)return{lines:[],oldestAvailable:0};let i=this.channel(e),a=dc((await i.command(`display-message -p -t ${e} ${nc}`))[0]??``),o=Math.max(0,r-a.historySize),s=t-1-r,c=Math.max(t-n-r,-a.historySize);return s<c||s>-1?{lines:[],oldestAvailable:o}:{lines:(await i.command(`capture-pane -p -e -N -t ${e} -S ${c} -E ${s}`)).map(Mn),oldestAvailable:o}}async getHistoryPage(e,t){if(Je(t),t.signal.aborted)return{status:`cancelled`};this.pane(e);let n=this.historyEvidence.get(t.capture);if(!n||n.paneId!==e)return{status:`unavailable`,reason:`unanchored`};let r=this.readOutcome(n,t.signal);if(r)return r;if(t.reported<n.facts.historySize)return{status:`unavailable`,reason:`unanchored`};let i=await this.checkedFacts(n,t.signal),a=this.readOutcome(n,t.signal);if(a)return a;if(!jc(i))return i;let o=Math.max(0,t.reported-n.facts.historySize);if(t.before<o){let e=await this.checkedFacts(n,t.signal);return this.readOutcome(n,t.signal)||(jc(e)?{status:`boundary`,reason:`truncated`,oldestAvailable:o}:e)}if(t.before===o){let e=await this.checkedFacts(n,t.signal);return this.readOutcome(n,t.signal)||(jc(e)?{status:`boundary`,reason:`end`,oldestAvailable:o}:e)}let s=Math.max(t.before-t.count,o),c=s-t.reported,l=t.before-1-t.reported;if(c<-2147483648||l<-2147483648||c>-1||l>-1)return{status:`unavailable`,reason:`fetch-window`};if(t.signal.aborted)return{status:`cancelled`};if(!this.ownsEvidence(n))return{status:`reset`};let u;try{u=await n.channel.command(`capture-pane -p -e -N -t ${e} -S ${c} -E ${l}`)}catch{return t.signal.aborted?{status:`cancelled`}:this.ownsEvidence(n)?{status:`unavailable`,reason:`changed`}:{status:`reset`}}if(t.signal.aborted)return{status:`cancelled`};if(!this.ownsEvidence(n))return{status:`reset`};let d=await this.checkedFacts(n,t.signal);return this.readOutcome(n,t.signal)||(jc(d)?u.length===t.before-s?{status:`page`,from:s,to:t.before,oldestAvailable:o,lines:u.map(Mn)}:{status:`unavailable`,reason:`changed`}:d)}async sendText(e,t){this.pane(e);let n=this.channel(e),r=Zs(t);if(r){this.log.debug(`tmux key`),await n.command(`send-keys -t ${e} ${r}`);return}this.log.debug(`tmux text`,{len:t.length});let i=t.split(/\r\n|\r|\n/);for(let t=0;t<i.length;t++){let r=i[t];r&&await n.command(`send-keys -t ${e} -l -- ${Hs(r)}`),t<i.length-1&&await n.command(`send-keys -t ${e} Enter`)}}async sendInput(e,t){this.pane(e);let n=[...Buffer.from(t,`utf8`)].map(e=>e.toString(16).padStart(2,`0`)).join(` `);await this.channel(e).command(`send-keys -t ${e} -H -- ${n}`)}async paste(t,n,r){if(this.pane(t),n.includes(`\0`))throw new e(`paste containing NUL`);let i=`shellbell-${yr()}`,a=`"${[...Buffer.from(n,`utf8`)].map(e=>`\\${e.toString(8).padStart(3,`0`)}`).join(``)}"`,o=this.channel(t);try{await o.command(`set-buffer -b ${i} -- ${a}`),await o.command(`paste-buffer -p -d -b ${i} -t ${t}`),r&&await o.command(`send-keys -t ${t} Enter`)}finally{await o.command(`delete-buffer -b ${i}`).catch(()=>{})}}async createFirstSession(e){let n=this.closes,r=e===void 0?void 0:Ct.parse(e),i=await t.detect(this.exec,{requireServer:!1});if(!i.ok)throw new w(i.reason??`tmux unavailable`,Ec);let a=(await this.exec([`new-session`,`-d`,`-P`,`-F`,`#{pane_id}`,...r?[`-x`,String(r.cols),`-y`,String(r.rows)]:[]])).trim();if(!/^%\d+$/.test(a))throw Error(`tmux new-session returned an invalid pane id`);try{if(r&&await this.exec([`if-shell`,`-F`,`-t`,a,`#{==:#{default-size},${r.cols}x${r.rows}}`,`set-option -u -t ${a} default-size`]),n!==this.closes||(await this.connect(),n!==this.closes))throw new w(`tmux backend stopped`,Ec)}catch(e){throw await this.exec([`kill-pane`,`-t`,a]).catch(()=>void 0),e}return a}async hostedSessionTarget(e){if(!/^%\d+$/.test(e))throw new A(e);let t=(await this.exec([`display-message`,`-p`,`-t`,e,`#{session_id}`])).trim();if(!/^\$\d+$/.test(t))throw new A(e);return{sessionId:t,socketName:this.opts.socketName}}async discardHostedSession(e){if(/^\$\d+$/.test(e))await this.exec([`kill-session`,`-t`,e]);else if(/^%\d+$/.test(e))await this.exec([`kill-pane`,`-t`,e]);else throw new A(e);this.scheduleRefresh()}async waitForVisibleClient(e,{timeoutMs:t=15e3,intervalMs:n=250}={}){if(!/^\$\d+$/.test(e))throw new A(e);let r=Date.now()+t;for(;;){if(await this.hasDesktopClient(e).catch(()=>!1))return!0;if(Date.now()>=r)return!1;await new Promise(e=>setTimeout(e,n))}}async shownOnComputer(e){let t;if(e.kind===`split`)t=this.pane(e.sessionId).sessionId;else if(e.windowId!==void 0){if(!this.sessionIndex.has(e.windowId))throw new A(e.windowId);t=e.windowId}else return!1;return this.hasDesktopClient(t)}async hasDesktopClient(e){let t=Qs.replace(/\\t/g,` `),n=(await this.exec([`list-clients`,`-t`,e,`-F`,t])).split(`
|
|
27
|
-
`).filter(Boolean).map(
|
|
28
|
-
`)};for(let t of[`identity`,`config`,`pairings`]){r.checkpoint?.(`before-${t}`),
|
|
29
|
-
`).filter(e=>e.startsWith(`Shellbell staging directory: `));return[e.stdout.trim(),...t].filter(Boolean).join(`
|
|
30
|
-
`)}function il(e,t){let n=/^\d{1,3}\.\d{1,3}(?:\.\d{1,3})?$/;if(!n.test(e.trim())||!n.test(t))throw Error(`Could not verify the release's macOS requirement`);let r=e.trim().split(`.`).map(Number),i=t.split(`.`).map(Number);if(([0,1,2].map(e=>(r[e]??0)-(i[e]??0)).find(e=>e!==0)??0)<0)throw Error(`This release requires macOS ${t} or later`)}function al(e,t){let n=/^glibc ([0-9]{1,6})\.([0-9]{1,6})\s*$/.exec(e),r=/^([0-9]{1,6})\.([0-9]{1,6})$/.exec(t);if(!n||!r)throw Error(`Could not verify this release's glibc requirement; use the official manual installation guide`);let i=BigInt(n[1]),a=BigInt(n[2]),o=BigInt(r[1]),s=BigInt(r[2]);if(i<o||i===o&&a<s)throw Error(`This release requires glibc ${t} or later; the installed system has ${n[1]}.${n[2]}`)}async function ol(e){let t=await V(e.cli);if(e.platform===`darwin`&&e.arch===`arm64`){let n=L(await V(e.home),`.local/share/shellbell/installs/darwin-arm64`,e.version);if(t===L(n,`Shellbell.app/Contents/Resources/agent/dist/cli.js`)&&await V(e.node)===L(n,`Shellbell.app/Contents/Helpers/node`)){let t=L(n,`installation.json`),r=await B(t);if(!r.isFile()||r.isSymbolicLink()||r.nlink!==1||r.uid!==process.getuid()||r.mode&3602||r.size>4096)throw Error(`Unsafe managed CLI installation receipt`);let i=JSON.parse(await Or(t,`utf8`));if(i.schema!==1||i.platform!==`darwin-arm64`||i.version!==e.version||!/^[a-f0-9]{64}$/.test(i.dmgSha256))throw Error(`Invalid managed CLI installation receipt`);return`mac-cli`}}if(e.platform===`darwin`&&t.includes(`/Shellbell.app/Contents/Resources/agent/dist/`))return`mac-app`;if(e.platform!==`linux`||![`arm64`,`x64`].includes(e.arch))return`other`;let n=L(await V(e.home),`.local/share/shellbell/installs`,`linux-${e.arch}`,e.version);return t!==L(n,`agent/dist/cli.js`)||await V(e.node)!==L(n,`runtime/bin/node`)?`other`:`linux-archive`}async function sl(e,t,n){let r=await e.response(t.browser_download_url,AbortSignal.timeout(18e4));if(!r.body)throw Error(`Empty update download`);let i=r.body.getReader(),a,o=0,s=z(`sha256`);try{for(a=await Er(n,`wx`,384);;){let{done:e,value:n}=await i.read();if(e)break;if(o+=n.byteLength,o>t.size)throw Error(`Update download exceeds the published size`);s.update(n);let r=0;for(;r<n.byteLength;){let{bytesWritten:e}=await a.write(n,r,n.byteLength-r);if(!e)throw Error(`Could not write update download`);r+=e}}if(o!==t.size||`sha256:${s.digest(`hex`)}`!==t.digest)throw Error(`Update download does not match the published digest`)}finally{try{await i.cancel()}finally{await a?.close()}}}async function cl(e){if(!process.stdin.isTTY)throw Error(`Use --yes to install an update without an interactive terminal, or --check to check only`);let t=Fr({input:process.stdin,output:process.stdout});try{return/^y(es)?$/i.test((await t.question(`Download and install Shellbell ${e}? The running service will stay on its current version. [y/N] `)).trim())}finally{t.close()}}function ll(e,t){e.command(`update [version]`).description(`check computer updates; manually update managed macOS/Linux CLI installs`).option(`--check`,`check only; do not download or install an app/archive`).option(`--yes`,`confirm installation without prompting`).action(async(n,r)=>{let i=!!e.opts().json;if(i&&!r.check)throw Error(`Use --check with --json; installation requires human-readable output`);let a=new tl,{check:o,assets:s}=await a.check(t,n);if(i){console.log(JSON.stringify(o));return}if(console.log(`Installed: ${t}. Latest stable computer release: ${o.release.version}.`),console.log(`Release notes: ${o.releaseUrl}`),!o.available){console.log(`No newer computer version is available.`);return}if(r.check)return;let c=await V(F()),l=await ol({home:c,platform:process.platform,arch:process.arch,version:t,cli:process.argv[1],node:process.execPath});if(l===`mac-app`){console.log(`Open Shellbell → Settings → General → Check for Updates to download the official Mac installer.`);return}if(l!==`linux-archive`&&l!==`mac-cli`){console.log(`This installation is managed outside the CLI installer. Use its original installation method.`),process.platform===`darwin`&&console.log(`For a global npm installation, stop Shellbell first, then run: npm install -g shellbell@${o.release.version}`),console.log(`No files or services were changed.`),console.log(`Installation guide: https://github.com/bilal-/shellbell/blob/main/docs/install-agent.md`);return}let u=l===`mac-cli`?s.macosArm64:process.arch===`arm64`?s.linuxArm64:s.linuxX64;if(!u)throw Error(`This release has no archive for this computer's architecture`);let d=L(c,`.local/share/shellbell/installs`,`${process.platform}-${process.arch}`);if(l===`mac-cli`){let e=o.release.platforms.macosArm64;if(!e)throw Error(`Missing platform compatibility information`);il((await nl(`/usr/bin/sw_vers`,[`-productVersion`],{env:{PATH:`/usr/bin:/bin`,LC_ALL:`C`},timeout:5e3,maxBuffer:1024})).stdout,e.minimumOS)}else{let e=process.arch===`arm64`?o.release.platforms.linuxArm64:o.release.platforms.linuxX64;if(!e)throw Error(`Missing platform compatibility information`);al((await nl(`/usr/bin/getconf`,[`GNU_LIBC_VERSION`],{env:{PATH:`/usr/bin:/bin`,LC_ALL:`C`},timeout:5e3,maxBuffer:1024})).stdout,e.minimumGlibc)}if(await Ar(L(d,`current`))!==t)throw Error(`A different version is already selected; run ~/.local/bin/shellbell update instead`);let f=L(d,t,`install.sh`),p=await B(f);if(!p.isFile()||p.isSymbolicLink()||p.uid!==process.getuid()||p.mode&3602)throw Error(`The installed CLI's update bootstrap is unsafe; use the official manual installer`);if(!r.yes&&!await cl(o.release.version)){console.log(`Update cancelled.`);return}let m=await Tr(L(cr(),`shellbell-update-`));try{let e=L(m,u.name);console.log(`Downloading Shellbell ${o.release.version}…`),await sl(a,u,e);let n=await nl(`/bin/sh`,[f,`--archive`,e,`--sha256`,u.digest.slice(7),`--update-from`,t,`--target-version`,o.release.version],{env:{HOME:c,PATH:`/usr/bin:/bin`,LANG:`C`},timeout:6e5,maxBuffer:65536});console.log(rl(n)),console.log(`The new version is installed. Running sessions still use the previous runtime.`),console.log(`When ready to interrupt remote access, run: shellbell service stop; shellbell service install; shellbell service start`),console.log(`For a foreground process, stop it and run shellbell start again. Pairings are preserved.`)}finally{await jr(m,{recursive:!0,force:!0})}})}const ul=he,Q=new _r().name(`shellbell`).version(ul).option(`--relay <url>`,`override relay url`).option(`--json`,`machine output`).option(`--verbose`,`debug logging`).option(`--insecure`,`allow a ws:// relay url (LAN dev only)`);ll(Q,ul);function $(){let e=Q.opts(),t=Bc();return{opts:e,p:t,cfg:lt(t),log:Dt({file:t.log,verbose:e.verbose,stdout:process.stdout.isTTY&&!e.json})}}const dl=e=>`${e.slice(0,4)}-${e.slice(4,8)}`;function fl(e,t){return pl(`\n Pair "${ti(t)}"?\n Phone fingerprint ${p(e)}\n Check that your phone shows the same fingerprint. [y/N] (60 s) `,6e4)}function pl(e,t,n=!1){return new Promise(r=>{let i=mr({input:process.stdin,output:process.stdout}),a=setTimeout(()=>{i.close(),console.log(`
|
|
31
|
-
(timed out — declined)`),r(!1)},t);i.question(e,e=>{clearTimeout(a),i.close();let t=e.trim();r(t===``?n:/^y(es)?$/i.test(t))})})}function ml(e){if(!e.length){console.log(` No coding agents found on this computer.`);return}for(let t of e)console.log(` ${t.name.padEnd(12)} ${Jt(t)}`)}async function hl(e){let t=Zt(e),n=rn(Gn(t));if(!n.length)return;let r=n.map(e=>e.name).join(`, `);console.log(`\n Get the most out of ${r} on your phone (highly recommended)\n Scroll back through a whole session, not just what's on screen, in text sized for your
|
|
32
|
-
phone. Shellbell adds a small helper to each agent. It only notes which window each
|
|
33
|
-
session runs in, and doesn't change how the agent works. Remove it with
|
|
34
|
-
\`shellbell agents remove <name>\`.`),n.some(e=>e.kind===`codex`)&&console.log(` Codex asks you to trust the helper the next time it starts. Choose Trust.`);let i=n.map(e=>e.kind);if(await pl(` Set up now? [Y/n] `,12e4,!0))try{ml(qt(t,i).filter(e=>i.includes(e.kind)))}catch(e){console.error(` ${e instanceof Error?e.message:String(e)}`)}else sn(t,i),console.log(" Skipped. Set up later with `shellbell agents setup`.")}function gl(e,t){console.log(`\n Computer ${e.computerName} (${dl(t)})\n Relay ${e.relayUrl}\n\n Scan this with the Shellbell app:\n`)}function _l(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function vl(e,t){console.log(` Valid until ${_l(t)}\n`),vr.generate(e,{small:!0},e=>{console.log(e.split(`
|
|
35
|
-
`).map(e=>` ${e}`).join(`
|
|
36
|
-
`)),console.log(``)})}function yl(e,t,n){let r=tr(e,`r`);try{let e=Zn(r).size,i=Math.max(0,e-t),a=e-i,o=Buffer.alloc(a);a>0&&ir(r,o,0,a,i);let s=o.toString(`utf8`).replace(/\n$/,``);return s.length===0?``:s.split(`
|
|
37
|
-
`).slice(-n).join(`
|
|
38
|
-
`)}finally{Jn(r)}}async function bl(e){try{return await T(e,`status`),!0}catch(e){let t=e.code;return t!==`ECONNREFUSED`&&t!==`ENOENT`}}function xl(e,t,n,r=!0){return async(i,a)=>e.server?.hasNativePairOwner?e.server.nativePairingConfirm(i,a):r?t?!0:e.server?.hasPairClients?e.server.pairingConfirm(i,a):n(i,a):!1}async function Sl(e,t,n=process.exit,r){r?.();let i=!1,a=e=>{i||(i=!0,n(e))},o=setTimeout(()=>a(1),5e3);typeof o.unref==`function`&&o.unref();try{e.stop(),await t.stop(),a(0)}finally{clearTimeout(o)}}function Cl(e,t){if(t===void 0)return{cfg:e};let n=Oe(t,!0);if(n)return{error:n};let r=new URL(t).protocol===`ws:`;return{cfg:{...e,relayUrl:t},warning:r?`insecure relay URL; for local testing only`:void 0}}async function wl(e,t,n=!1,r={}){let i=r.paths??Bc(),a=r.nativeService?void 0:()=>st({stateDir:i.dir,uid:i.linuxHost?.uid??process.getuid(),serviceInstance:r.serviceInstance});a?.(),i.linuxHost&&(jt(i),Pt(i)),Kt(i.dir),Vt(Zt(i.dir));let o=lt(i);if(t!==void 0){let e=Cl(o,t);`error`in e&&(console.error(` --relay ${t}: ${e.error}`),process.exit(1)),e.warning&&console.error(` warning: ${e.warning}`),o=e.cfg}let{identity:s,fp:c}=it(i),l=new re(e),u=ws({paths:o.terminalPlugins??[],registry:l,log:e}),d=i.linuxHost?null:new Ho({recordPath:L(i.dir,`iterm2-access.json`),assumeApproved:(()=>{try{return At(i).length>0}catch{return!1}})(),interactive:!r.nativeService&&!r.managedService&&process.stdin.isTTY===!0,socketPath:jn}),f=i.linuxHost?null:r.itermBackend===void 0?new ms(new Ln({log:e,cookieProvider:()=>d.cookieProvider(Wt)}),e):r.itermBackend,p={ready:!1,queue:[]},m=e=>{r.nativeService||(p.ready?console.log(e):p.queue.push(e))},h=()=>{p.ready=!0;for(let e of p.queue)console.log(e);p.queue=[]},g=null,_=null,v=!1,y,b=async()=>{if(f&&!v)try{if(await f.connect(),v)return;l.add(f),y=void 0;let t=await f.listSessions().catch(()=>[]);if(v)return;m(` iTerm2 connected · ${t.length} session${t.length===1?``:`s`}`),e.info(`iTerm2 connected`)}catch(t){if(v)return;let n=d?.issue??`failed`;if(n!==y){y=n;let r=hn({name:`iterm2`,connected:!1,issue:n},`command-line`);m(` iTerm2 ${r.status}${r.fix?`\n ${r.fix}`:``}`),e.info(`iTerm2 not connected`,{issue:n,err:N(t)})}g=setTimeout(()=>void x(),1e4)}},x=()=>v?Promise.resolve():_||(g&&clearTimeout(g),g=null,_=b().finally(()=>{_=null}),_);f?.isConnected===!1&&l.add(f),f&&x();let S=!i.linuxHost&&r.itermBackend===void 0?Ds(`iterm2`):null,C=S?Os(`com.googlecode.iterm2`,S.available,{onChange:()=>l.notifySetupChanged()}):()=>void 0,ee=f&&d?(()=>{let e=d.onChange(()=>l.notifySetupChanged()),t=Object.assign(e=>El(e,d,C),{connect:()=>d.connect(async()=>{await _,l.connected().some(e=>e.name===`iterm2`)||await x()})}),n=l.registerSetupReporter(`iterm2`,t);return()=>{e(),n()}})():()=>{},te=!i.linuxHost&&r.tmuxBackendOptions===void 0?Ps():null,ne=async()=>{await S?.start(),await x();let e=d?.issue;if(e&&!l.connected().some(e=>e.name===`iterm2`)&&wn({name:`iterm2`,connected:!1,issue:e})){let{status:t,fix:n}=hn({name:`iterm2`,connected:!1,issue:e},`phone`);throw new Ae(`${t} ${n??``}`.trim())}await As(l,`iterm2`)},ie=r.terminalWindows??[...te?[te]:[],...f&&S?[{id:`iterm2`,label:`iTerm2`,available:S.available,async launch(e){if(l.connected().some(e=>e.name===`iterm2`)||await ne(),l.member(`iterm2`)!==f)throw new w(`iTerm2 was replaced`,`Reconnect your computer.`);e.initialSize?await f.createCommandSession(Ms(e),e.initialSize):await f.createCommandSession(Ms(e))}}]:[]],ae=Pc({registry:l,log:e,onConnected:e=>m(` tmux connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>m(` tmux not running`),backendOptions:r.tmuxBackendOptions,terminalWindows:ie}),oe=i.linuxHost?null:(r.startHerdr??En)({registry:l,log:e,onConnected:e=>m(` herdr connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>m(` herdr not running (optional)`),...r.herdrBackendOptions?{backendOptions:r.herdrBackendOptions}:{}}),se=()=>{ee(),u.stop(),v=!0,g&&clearTimeout(g),g=null},ce=[];f&&S&&ce.push(l.registerSessionLauncher(`iterm2`,{available:S.available,start:async()=>(await ne(),{backend:f})}));let le=!i.linuxHost&&r.startHerdr===void 0?ks():null;if(le){ce.push(l.registerSessionLauncher(`herdr`,{available:le.available,start:async()=>{await le.start(),await As(l,`herdr`);let e=l.member(`herdr`);if(!e)throw new w(`Herdr unavailable`,`Check Herdr's local API.`);return{backend:e}}}));for(let e of ie)ce.push(l.registerHostedLauncher({backend:`herdr`,host:e.id,label:e.label},{available:()=>{let t=l.member(`herdr`);return e.available()&&(t instanceof Bt&&t.isConnected?t.terminalAttachExecutable!==void 0:Tn()!==void 0)},unavailableReason:()=>{let t=l.member(`herdr`);return e.available()&&t instanceof Bt?t.terminalAttachIssue:void 0},create:async(t,n,r)=>{let i=t instanceof Bt?t.terminalAttachExecutable:void 0;if(!i||!(t instanceof Bt))throw new w(`Herdr terminal attach is unavailable`,`Use matching Herdr CLI/server versions, 0.9.3 or newer.`);let{terminalId:a,workspaceId:o}=await t.createWorkspace();return await Ns(async()=>{if(l.member(`herdr`)!==t||t.terminalAttachExecutable!==i)throw new w(`Herdr was disconnected before the terminal could open`,`Reconnect Herdr and try again.`);if(await e.launch({executable:i,...r?{initialSize:r}:{},args:[`terminal`,`attach`,a],environment:{HERDR_SOCKET_PATH:t.terminalSocketPath}}),!await t.waitForVisibleAttach(a))throw new w(`terminal window did not attach`,`Unlock your computer and try again.`)},async()=>{if(!o)throw Error(`Herdr workspace id unknown`);await t.closeWorkspace(o)}),a}}))}let ue=()=>{for(let e of ce)e();se(),ae.stop(),oe?.stop()},T={server:null},de;return de=new Bo({paths:i,config:o,identity:s,fp:c,registry:l,log:e,appVersion:ul,serviceInstance:r.serviceInstance??null,confirm:xl(T,n,(e,t)=>fl(e,t),!r.nativeService),onPairingClosed:e=>T.server?.notifyClosed(e),onSuperseded:()=>{r.nativeService||console.log(` another shellbell agent took over; exiting`),T.server?Sl(de,T.server,()=>process.exit(0),ue).catch(()=>process.exit(1)):process.exit(0)}}),T.server=new tt(i.sock,de,e,i.pid,a,!r.nativeService&&!r.managedService?e=>Ot({stateDir:i.dir,uid:i.linuxHost?.uid??process.getuid()},e):void 0,r.nativeService?`native`:`terminal`),{agent:de,control:T.server,p:i,cfg:o,fp:c,releaseOutput:h,stopFirstConnect:se,stopBackendDetectors:ue,herdr:oe}}Q.command(`start`,{isDefault:!0}).description(`run the agent in the foreground`).option(`--service`,`running under launchd or a systemd user service`).action(async e=>{let t;try{t=It(e.service===!0)}catch(e){console.error(` ${e.message}`),process.exit(1)}let{opts:n,p:r,log:i}=$(),{agent:a,control:o,cfg:s,fp:c,releaseOutput:l,stopBackendDetectors:u}=await wl(i,n.relay,!1,{serviceInstance:t,managedService:e.service===!0,paths:r});try{await o.start()}catch(e){console.error(` ${e.message}`),process.exit(1)}if(a.start(),console.log(`\n Shellbell agent v${ul}\n Computer ${s.computerName} (${dl(c)})`),console.log(` Relay ${s.relayUrl} ${a.relayOnline?`connected`:`connecting…`}`),a.relay.on(`auth-ok`,()=>console.log(` Relay ${s.relayUrl} connected`)),a.relay.on(`down`,()=>console.log(` Relay ${s.relayUrl} connecting…`)),console.log(` tmux detecting…`),r.linuxHost||console.log(` herdr detecting…`),l(),!e.service&&process.stdin.isTTY&&!n.json&&await hl(r.dir),a.pairingList.length===0&&!e.service&&process.stdin.isTTY){console.log(`
|
|
39
|
-
No phones paired yet. Scan this with the Shellbell app:
|
|
40
|
-
`);let{qrText:e,expiresAt:t}=a.openPairing();vl(e,t)}let d=!1,f=()=>{if(d){console.error(` forcing exit`),process.exit(130);return}d=!0,Sl(a,o,process.exit,u).catch(()=>process.exit(1))};process.on(`SIGINT`,f),process.on(`SIGTERM`,f)}),Q.command(`pair`).description(`open a 5-minute pairing window and show the QR`).option(`--yes`,`auto-accept requests (unsafe on shared screens)`).action(async e=>{let{opts:t,p:n,cfg:r,log:i}=$(),{fp:a}=it(n),o=async()=>{let{agent:r,control:a,cfg:o,fp:s,releaseOutput:c,stopBackendDetectors:l}=await wl(i,t.relay,e.yes,{paths:n});try{await a.start()}catch(e){console.error(` ${e.message}`),process.exit(1)}r.start();let{qrText:u,expiresAt:d}=r.openPairing();gl(o,s),vl(u,d),c(),setTimeout(()=>void Sl(r,a,()=>process.exit(0),l).catch(()=>process.exit(1)),301e3)};if(!await bl(n.sock)){await o();return}let s=ce(n.sock,{onOpen:(e,t)=>{gl(r,a),vl(e,t)},onRequest:(t,n)=>e.yes?Promise.resolve(!0):fl(t,n),onClose:e=>{console.log(e===`replaced`?` This code has been replaced by a newer one. Scan the new code instead.`:` pairing window closed`),process.exit(0)},onError:e=>{console.error(` ${e.message}`),process.exit(1)}});setTimeout(()=>{s.close(),process.exit(0)},301e3)}),Q.command(`status`).description(`show agent status`).action(async()=>{let{opts:e,p:t}=$();try{let n=await T(t.sock,`status`);console.log(e.json?JSON.stringify(n):JSON.stringify(n,null,2))}catch{console.log(e.json?JSON.stringify({running:!1}):` agent not running`)}});function Tl(e){let t=e?.code;console.error(t===`ENOENT`||t===`ECONNREFUSED`?` agent not running`:`shellbell: ${e instanceof Error?e.message:`control request failed`}`),process.exitCode=2}Q.command(`devices`).description(`list paired phones`).action(async()=>{let{opts:e,p:t}=$();try{let n=await T(t.sock,`devices`);console.log(e.json?JSON.stringify(n):JSON.stringify(n,null,2))}catch(e){Tl(e)}});function El(e,t,n){if(e)return{};if(t.connecting)return{issue:`connecting`};let r=t.issue??`not-running`;return r===`not-running`&&n()===!1?{issue:`not-installed`}:{issue:r}}async function Dl(e,t,n={}){let r=n.log??console.log,i=await e.connectTerminal(t);if(!i)return r(` Update Shellbell on this computer to connect terminals from the command line.`),2;if(!i.started)return r(` ${t} has no connection step. Run shellbell doctor to see its status.`),2;r(` macOS may ask to let Shellbell control iTerm2, and iTerm2 may ask to allow Shellbell.`);let a=Date.now()+(n.timeoutMs??13e4),o=i.terminals;for(;o.find(e=>e.name===t)?.issue===`connecting`&&Date.now()<a;)await new Promise(e=>setTimeout(e,n.pollMs??500)),o=await e.terminals()??o;let s=o.find(e=>e.name===t);if(!s)return 2;let{status:c,fix:l}=hn(s,`command-line`);return r(` ${c}`),l&&r(` ${l}`),s.connected&&!s.issue?0:2}Q.command(`connect <terminal>`).description(`connect a terminal that needs your approval, such as iterm2`).action(async e=>{let{p:t}=$(),n;try{n=await h(t.sock),process.exitCode=await Dl(n,e)}catch(e){Tl(e)}finally{n?.close()}}),Q.command(`agents [action] [name]`).description(`list coding agents, or set them up for full history: agents [setup [name] | remove <name>]`).action((e,t)=>{let{opts:n,p:r}=$(),i=Zt(r.dir);if(!(e===void 0||e===`setup`||e===`remove`&&t!==void 0)){process.exitCode=2,console.error(` usage: shellbell agents [setup [name] | remove <name>]`);return}try{let r=Gn(i),a=t&&r.find(e=>[e.kind,e.name.toLowerCase()].includes(t.toLowerCase()))?.kind;if(t&&!a){process.exitCode=2,console.error(` Shellbell didn't find ${t} on this computer.`);return}let o=e===`setup`?qt(i,a?[a]:void 0):e===`remove`?cn(i,a):r;n.json?console.log(JSON.stringify({agents:o})):ml(o),e===void 0&&!n.json&&rn(o).length&&console.log("\n Run `shellbell agents setup` for full history on your phone.")}catch(e){process.exitCode=2,console.error(` ${e instanceof Error?e.message:String(e)}`)}}),Q.command(`integration <action> <agent>`,{hidden:!0}).action((e,t)=>{if(t!==`codex`||![`install`,`uninstall`,`status`].includes(e)){process.exitCode=2,console.error(` usage: shellbell agents [setup [name] | remove <name>]`);return}let n=Zt($().p.dir);try{ml((e===`install`?qt(n,[`codex`]):e===`uninstall`?cn(n,`codex`):Gn(n)).filter(e=>e.kind===`codex`))}catch(e){process.exitCode=2,console.error(` ${e instanceof Error?e.message:String(e)}`)}}),Q.command(`unpair <target>`).description(`remove a paired phone (fp prefix or name)`).action(async e=>{let{p:t}=$();try{let n=await T(t.sock,`unpair`,{target:e});console.log(n.removed?` removed`:` no such phone`)}catch(e){Tl(e)}});function Ol(e,t,n={}){let r=e.command(`service`).description(`manage the per-user service`);for(let[i,a]of Object.entries({status:`inspect the installed service and local readiness without starting it`,install:`install or update the service (Linux: does not start or enable)`,start:`start the installed definition and verify local readiness`,stop:`stop now; retain the configured future autostart choice`,restart:`restart the installed definition and verify the new process`,uninstall:`remove future autostart; identity and pairings remain`,enable:`enable future per-user startup; do not start now`,disable:`disable owned future startup; do not stop now`}))r.command(i).description(a).action(async()=>{let r=e.opts().json,a=n.platform??process.platform,o=a===`linux`;if(!o&&a!==`darwin`){let e=`Service management supports macOS launchd and Linux systemd user managers only`;r?console.log(JSON.stringify({error:e})):console.error(` ${e}`),process.exitCode=2;return}(i===`install`||i===`start`)&&!r&&process.stdin.isTTY&&await hl(Bc().dir);try{if(o){let e=await(n.createLinuxLifecycle??(()=>new mn({env:process.env})))()[i](),t=[`start`,`restart`,`status`].includes(i)?e.ready:i===`enable`?e.enabled&&e.autostartConfigured:i===`disable`?!e.enabled&&!e.autostartConfigured:i===`uninstall`?!e.installed&&!e.enabled&&!e.autostartConfigured:i!==`install`||e.installed;console.log(r?JSON.stringify(e):`${JSON.stringify(e,null,2)}\n Future autostart: ${e.enabled?`enabled`:`disabled`}; linger: ${e.linger}. Stop retains autostart; disable does not stop a running job.\n Linger is an operator policy; Shellbell never enables it automatically.`),process.exitCode=t?0:2;return}let e=await t()[i]();console.log(r?JSON.stringify(e):JSON.stringify(e,null,2)),i===`install`&&!r&&console.log(kl),process.exitCode=i===`status`&&!e.ready?2:0}catch(e){if(o){let t=e instanceof Error&&e.message.startsWith(`shellbell:`)?e.message:`Linux systemd service operation failed; inspect service status, host state, and the durable installed runtime before retrying`;r?console.log(JSON.stringify({error:t})):console.error(` ${t}`),process.exitCode=2;return}let t=e instanceof ft?e:new ft(e instanceof Error?e.message:`Service operation failed`),n={error:t.message,rollback:t.rollback,rollbackDiagnostic:t.rollbackDiagnostic,recoveryPath:t.recoveryPath};r?console.log(JSON.stringify(n)):console.error(` ${t.message}\n rollback: ${t.rollback}${t.rollbackDiagnostic?` — ${t.rollbackDiagnostic}`:``}${t.recoveryPath?`\n recovery definition: ${t.recoveryPath}`:``}`),process.exitCode=2}})}const kl=`
|
|
21
|
+
}`,e,`AppKit`]),a=n.replace(/\n$/,``);t=a===`?`?void 0:a===``?!1:i(a)?!0:void 0}catch{t=void 0}s=a(),c=!1,t!==o&&(o=t,n.onChange?.())};return()=>t()?!0:(!c&&a()-s>=6e4&&(c=!0,l()),o)}function uc(e={}){let t=()=>sn(e.env,e.executable);return{available:()=>t()!==void 0,start:async()=>{let n=t();if(!n)throw new T(`Herdr is not installed`,`Install Herdr on your computer.`);await new Promise((t,r)=>{let i=(e.spawnImpl??nr)(n,[`server`],{detached:!0,stdio:`ignore`,env:e.env??process.env});i.once(`error`,()=>r(new T(`Could not start Herdr`,`Check your Herdr installation.`))),i.once(`spawn`,()=>{i.unref(),t()})})}}}function dc(e,t,n=2e4){return new Promise((r,i)=>{let a=setTimeout(()=>{s(),i(new T(`${t} did not become ready`,`Check the terminal application's local API on your computer.`))},n);a.unref();let o=()=>{e.connected().some(e=>e.name===t)&&(clearTimeout(a),s(),r())},s=e.on(o);o()})}const fc=Wr(tr);function pc(e){let t=[e.executable,...e.args],n=e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127);if(!F(e.executable)||t.some(e=>!n(e))||t.reduce((e,t)=>e+t.length,0)>4096)throw Error(`Invalid terminal command`);let r=Object.entries(e.environment??{}).map(([e,t])=>{if(!/^[A-Z_][A-Z0-9_]*$/.test(e)||!n(t))throw Error(`Invalid terminal environment`);return`${e}=${t}`}),i=e=>`'${e.replace(/'/g,`'\\''`)}'`,a=[...r.length?[`/usr/bin/env`,...r]:[],...t].map(i).join(` `);if(a.length>8192)throw Error(`Terminal command is too large`);return a}async function mc(e,t){try{await e()}catch{try{await t()}catch{throw new nt(`The terminal window could not open on your computer, and the new session could not be closed. Check the session list.`)}throw new nt(`The terminal window didn't open on your computer, so the new session was closed. If your computer is locked, unlock it and try again.`)}}function hc(e={}){if((e.platform??process.platform)!==`darwin`)return null;let t=()=>(e.roots??[`/Applications`,I(N(),`Applications`)]).map(e=>I(e,`Ghostty.app`)).find(e.exists??ar);return{id:`ghostty`,label:`Ghostty`,available:()=>t()!==void 0,async launch(n){let r=t();if(!r)throw new T(`Ghostty is not installed`,`Install Ghostty on your computer.`);let i=pc(n),a=n.initialSize===void 0?void 0:rt.parse(n.initialSize);try{await(e.execute??((e,t)=>fc(e,t,{timeout:5e3,maxBuffer:4096})))(`/usr/bin/open`,[`-n`,`-a`,r,`--args`,`--initial-window=true`,`--window-save-state=never`,`--quit-after-last-window-closed=true`,...a?[`--window-width=${a.cols}`,`--window-height=${a.rows}`]:[],`--initial-command=${i}`])}catch{throw new T(`Ghostty could not be launched`,`Check that Ghostty opens on your computer, then try again.`)}return`window`}}}function gc(e){let{iterm:t}=e;return{id:`iterm2`,label:`iTerm2`,available:e.available,async launch(n){await e.ready();let r=pc(n);if(n.initialSize)return await t.createCommandSession(r,n.initialSize),`window`;let i=n.tab?await t.focusedWindow():void 0;if(i!==void 0)try{return await t.createCommandSession(r,void 0,i),`tab`}catch(n){let r=await t.listSessions().catch(()=>null);if(!r||r.some(e=>e.windowId===i))throw n;e.log.warn(`focused window closed before its tab`,{backend:`iterm2`,err:j(n)})}return await t.createCommandSession(r),`window`}}}var _c=class{parts=[];length=0;push(e){let t=[],n=0;for(let r=e.indexOf(10);r!==-1;r=e.indexOf(10,n)){this.parts.push(e.subarray(n,r)),this.length+=r-n,this.check();let i=this.parts.length===1?this.parts[0]:Buffer.concat(this.parts,this.length);i.length>0&&i[i.length-1]===13&&(i=i.subarray(0,-1)),t.push(i),this.parts=[],this.length=0,n=r+1}return n<e.length&&(this.parts.push(e.subarray(n)),this.length+=e.length-n,this.check()),t}check(){if(this.length>4194304)throw this.parts=[],this.length=0,Error(`tmux control line too long`)}};function vc(e){let t=new Uint8Array(e.length),n=0;for(let r=0;r<e.length;r++){let i=e[r];i===92&&e[r+1]===92?(t[n++]=92,r++):i===92&&r+3<e.length&&yc(e[r+1])&&yc(e[r+2])&&yc(e[r+3])?(t[n++]=e[r+1]-48<<6|e[r+2]-48<<3|e[r+3]-48,r+=3):t[n++]=i}return t.subarray(0,n)}function yc(e){return e!==void 0&&e>=48&&e<=55}const bc=Buffer.from(`%output `),xc=Buffer.from(`%extended-output `),Sc=Buffer.from(` : `);function Cc(e){let t;if(e.subarray(0,bc.length).equals(bc))t=e.subarray(bc.length);else if(e.subarray(0,xc.length).equals(xc))t=e.subarray(xc.length);else return;let n=t.indexOf(32),r=(n===-1?t:t.subarray(0,n)).toString(`latin1`);if(!/^%\d+$/.test(r))return;if(n===-1)return{pane:r,data:Buffer.alloc(0)};if(e[1]===bc[1])return{pane:r,data:t.subarray(n+1)};let i=t.indexOf(Sc,n);if(i!==-1)return{pane:r,data:t.subarray(i+Sc.length)}}function wc(e){return`'${e.replace(/'/g,`'\\''`)}'`}function Tc(e){return e.trim().split(/\s+/,1)[0]||`?`}const Ec=/^%(?:end|error) (\S+) (\S+) \S+$/;function Dc(e,t){let n=Ec.exec(e);return n!==null&&n[1]===t.time&&n[2]===t.num}var Oc=class extends Mr{opts;child=null;queue=[];current=null;currentPending=null;started=!1;outputSeq=0;readyTimer=null;settleReady=null;alive=!1;log;constructor(e){super(),this.opts=e,this.log=e.log.child({backend:`tmux`,session:e.sessionId})}start(){let e=[...this.opts.socketName?[`-L`,this.opts.socketName]:[],`-u`,`-C`,`attach-session`,`-t`,this.opts.sessionId,`-f`,`ignore-size`],t=(this.opts.spawnImpl??nr)(this.opts.executable??`tmux`,e,{stdio:[`pipe`,`pipe`,`pipe`]});this.child=t,this.alive=!0;let n=new _c,r=null,i=new Promise(e=>{r=e,this.readyTimer=setTimeout(e,this.opts.readyTimeoutMs??2e3),this.readyTimer.unref?.()}),a=()=>{this.readyTimer&&clearTimeout(this.readyTimer),this.readyTimer=null,this.settleReady=null,r?.()};this.settleReady=a;let o=(e,t)=>{if(this.current&&!Dc(e,this.current)){this.current.lines.push(e);return}if(e.startsWith(`%begin`)){let[,t=``,n=``]=e.split(` `);this.current={lines:[],time:t,num:n},this.currentPending=this.started?this.queue.shift()??null:null;return}if(e.startsWith(`%end`)||e.startsWith(`%error`)){let t=this.current,n=this.currentPending;if(this.current=null,this.currentPending=null,!this.started){this.started=!0,a();return}n&&(clearTimeout(n.timer),e.startsWith(`%error`)?(n.reject(Error(`tmux error: ${n.verb}`)),n.retireOnError&&this.stop()):n.resolve((t?.lines??[]).map(e=>e),this.outputSeq));return}this.dispatchNotification(e,t)};return t.stdout?.on(`data`,e=>{if(!this.alive)return;let t;try{t=n.push(e)}catch{this.log.warn(`tmux control line too long`),this.stop();return}for(let e of t){if(!this.alive)return;o(e.toString(`utf8`),e)}}),t.stdout?.on(`end`,()=>this.onExit()),t.stdout?.on(`close`,()=>this.onExit()),t.on(`exit`,()=>this.onExit()),t.on(`error`,e=>{this.log.warn(`tmux control spawn failed`,{error:j(e)}),a(),this.onExit()}),t.stdin?.on(`error`,()=>void 0),t.stderr?.on(`data`,()=>{this.log.debug(`tmux stderr`)}),i}dispatchNotification(e,t){if(e.startsWith(`%output `)||e.startsWith(`%extended-output `)){let e=Cc(t);if(!e)return!1;let n=++this.outputSeq;return this.emit(`output`,e.pane),this.listenerCount(`bytes`)>0&&this.emit(`bytes`,e.pane,vc(e.data),n),!0}let n=/^%(pause|continue) (%\d+)$/.exec(e);return n?(n[1]===`pause`?this.emit(`pause`,n[2]):this.emit(`output`,n[2]),!0):/^%(layout-change|window-add|window-close|window-renamed|unlinked-window-|session-changed|session-renamed|sessions-changed)/.test(e)?(this.emit(`layout`),!0):e.startsWith(`%exit`)?(this.onExit(),!0):!1}command(e){return this.send([e]).then(([e])=>e.lines)}async checkpoint(e){let t=this.outputSeq,n=await this.send(e);return{replies:n.map(e=>e.lines),sentSeq:t,outputSeq:n[0].outputSeq}}send(e){if(e.length===0||!this.alive||!this.child?.stdin)return Promise.reject(Error(`tmux control exited`));let t=[],n=e.map(n=>new Promise((r,i)=>{let a=setTimeout(()=>{i(Error(`tmux command timeout: ${Tc(n)}`)),this.stop()},this.opts.commandTimeoutMs??5e3);a.unref?.(),t.push({resolve:(e,t)=>r({lines:e,outputSeq:t}),reject:i,timer:a,verb:Tc(n),retireOnError:e.length>1})}));this.queue.push(...t);try{this.child.stdin.write(`${e.join(` ; `)}\n`)}catch{for(let e of t)clearTimeout(e.timer),e.reject(Error(`tmux control exited`));this.queue=this.queue.filter(e=>!t.includes(e))}return Promise.all(n)}stop(){if(this.child){try{this.child.stdin?.write(`detach-client
|
|
22
|
+
`)}catch{}this.child.kill()}this.onExit()}onExit(){if(this.alive){this.alive=!1,this.settleReady?.();for(let e of[this.currentPending,...this.queue])e&&(clearTimeout(e.timer),e.reject(Error(`tmux control exited`)));this.queue=[],this.currentPending=null,this.emit(`exit`)}}};const kc={enter:`Enter`,tab:`Tab`,"shift-tab":`BTab`,esc:`Escape`,backspace:`BSpace`,delete:`DC`,up:`Up`,down:`Down`,right:`Right`,left:`Left`,home:`Home`,end:`End`,"page-up":`PPage`,"page-down":`NPage`,"ctrl-space":`C-Space`};function Ac(e){let t=kc[e];if(t)return t;if(e.startsWith(`ctrl-`))return`C-${e.slice(5)}`;if(/^f([1-9]|1[0-2])$/.test(e))return e.toUpperCase();throw Error(`no tmux key for ${e}`)}const jc=Mc();function Mc(){let e=new Map([[`\r`,`Enter`],[`
|
|
23
|
+
`,`Enter`],[` `,`Tab`]]);for(let[t,n]of Object.entries(Ve))e.has(n)||e.set(n,Ac(t));return e}function Nc(e){return e?jc.get(e):void 0}const Pc=`#{session_id}\\t#{client_control_mode}\\t#{client_pid}\\t#{pid}\\t#{client_activity}`,Fc=e=>wc(e.replace(/\\t/g,` `)),Ic=Fc(`#{pane_id}\\t#{session_id}\\t#{session_name}\\t#{window_id}\\t#{window_index}\\t#{window_name}\\t#{pane_index}\\t#{pane_title}\\t#{pane_current_path}\\t#{pane_width}\\t#{pane_height}\\t#{pane_active}\\t#{window_active}\\t#{history_size}\\t#{cursor_x}\\t#{cursor_y}\\t#{pane_dead}\\t#{pane_current_command}`),Lc=Fc(Pc),Rc=Fc(`#{cursor_x}\\t#{cursor_y}\\t#{history_size}\\t#{pane_width}\\t#{pane_height}\\t#{alternate_on}`),zc=Fc(`#{cursor_x}\\t#{cursor_y}\\t#{history_size}\\t#{pane_width}\\t#{pane_height}\\t#{history_limit}\\t#{alternate_on}`),Y=e=>Number.parseInt(e??`0`,10)||0,Bc=/^%\d+$/,Vc=/^\$\d+$/,Hc=/^@\d+$/;function Uc(e){let t=e.split(` `);return t.length!==18||!Bc.test(t[0]??``)||!Vc.test(t[1]??``)||!Hc.test(t[3]??``)?null:{paneId:t[0]??``,sessionId:t[1]??``,sessionName:t[2]??``,windowId:t[3]??``,windowIndex:Y(t[4]),windowName:t[5]??``,paneIndex:Y(t[6]),paneTitle:t[7]??``,cwd:t[8]??``,width:Y(t[9]),height:Y(t[10]),paneActive:t[11]===`1`,windowActive:t[12]===`1`,historySize:Y(t[13]),cursorX:Y(t[14]),cursorY:Y(t[15]),dead:t[16]===`1`,currentCommand:t[17]??``}}const Wc=({sessionId:e,sessionName:t,windowIndex:n,windowActive:r,...i})=>JSON.stringify(i);function Gc(e){let t=e.map(Uc).filter(e=>e!==null),n=new Map;for(let e of t){let t=n.get(e.paneId);n.set(e.paneId,t===void 0||t===Wc(e)?Wc(e):null)}let r=new Map;for(let e of t)n.get(e.paneId)!==null&&r.set(e.paneId,e);return[...r.values()]}function Kc(e){let t=e.split(` `),n=e=>/^\d{1,10}$/.test(e??``)?Number(e):void 0,r=n(t[2]),i=n(t[3]),a=n(t[4]);return{sessionId:t[0]??``,controlMode:t[1]===`1`,...r?{pid:r}:{},...i?{serverPid:i}:{},...a?{activity:a}:{}}}function qc(e){let t=e.split(` `);return{cursorX:Y(t[0]),cursorY:Y(t[1]),historySize:Y(t[2]),width:Y(t[3]),height:Y(t[4])}}function Jc(e){let t=e.split(` `);if(!(t.length!==6||t[5]!==`0`&&t[5]!==`1`))return t[5]===`1`}function Yc(e){let t=e.split(` `);if(t.length!==7||t[6]!==`0`&&t[6]!==`1`)return null;let n=t.slice(0,6).map(Xc);if(n.some(e=>e===null))return null;let[r,i,a,o,s,c]=n;return o<1||s<1?null:{cursorX:r,cursorY:i,historySize:a,width:o,height:s,historyLimit:c,alternate:t[6]===`1`}}function Xc(e){if(!/^(?:0|[1-9]\d*)$/.test(e))return null;let t=Number(e);return Number.isSafeInteger(t)?t:null}function Zc(e,t){return e.windowName&&e.windowName!==e.currentCommand?e.windowName:e.paneTitle&&e.paneTitle!==t?e.paneTitle:`${e.sessionName}:${e.windowIndex}.${e.paneIndex}`}var Qc=class{state=`ground`;write(e){let t=new Uint8Array(e.length+1),n=0;for(let r of e){if(this.state===`name-esc`&&r===92){this.state=`ground`;continue}if(this.state===`esc`||this.state===`name-esc`){if(r===107){this.state=`name`;continue}t[n++]=27,this.state=`ground`}r===27?this.state=this.state===`name`?`name-esc`:`esc`:this.state===`name`?(r===24||r===26)&&(t[n++]=r,this.state=`ground`):t[n++]=r}return t.subarray(0,n)}},$c=class{control;pane;enabled=!1;epoch=0;outputSeq=0;evidence=null;busy=!1;closed=!1;seedRevision=0;get revision(){return this.seedRevision}constructor(e,t){if(this.control=e,this.pane=t,!/^%\d+$/.test(t))throw Error(`invalid tmux pane id`)}enable(){this.enabled=!0}output(e){this.outputSeq=Math.max(this.outputSeq,e),this.retire()}invalidate(){this.seedRevision++,this.retire()}retire(){this.epoch++,this.evidence=null}close(){this.closed=!0,this.invalidate()}commands(e){if(!this.enabled||this.closed)return[];let t=`-${Math.min(e??2e3,2e3)}`;return[`display -p -t ${this.pane} ${zc}`,`capture-pane -p -e -N -S ${t} -E -1 -t ${this.pane}`]}capture(e,t,n,r,i,a){if(this.evidence=null,!this.enabled||this.closed||!this.control.alive||a!==this.seedRevision||this.outputSeq>r)return;let o=Yc(e[5]?.[0]??``);if(!o||o.width!==t.cols||o.height!==t.rows)return;let s=Math.min(o.historySize,n??o.historySize);if(s>2e3||s>0&&e[6]?.length!==s||Buffer.byteLength(i)>E.screenBytes||(e[6]?.reduce((e,t)=>e+Buffer.byteLength(t),0)??0)>E.screenBytes)return;let c=s===0?[]:En(e[6]);if(e[6]?.some(e=>e.includes(` `)))return;let l=Object.freeze({});return this.evidence={capture:l,epoch:this.epoch,facts:o},{capture:l,from:o.historySize-s,to:o.historySize,lines:c,replay:i}}async read(e){if(lt(e),e.signal.aborted)return{status:`cancelled`};let t=this.evidence;if(!t||e.capture!==t.capture||e.reported!==t.facts.historySize)return{status:`unavailable`,reason:`unanchored`};if(this.busy)return{status:`unavailable`,reason:`busy`};this.busy=!0;try{let n=Math.max(0,e.before-e.count);if(n-e.reported<-2147483648)return{status:`unavailable`,reason:`fetch-window`};let r=`display -p -t ${this.pane} ${zc}`,i=[r];e.before>0&&i.push(`capture-pane -p -e -N -S ${n-e.reported} -E ${e.before-1-e.reported} -t ${this.pane}`),i.push(r);let{replies:a}=await this.control.checkpoint(i);if(e.signal.aborted)return{status:`cancelled`};if(!this.owns(t))return{status:`reset`};let o=Yc(a[0]?.[0]??``),s=Yc(a.at(-1)?.[0]??``);if(!el(o,t.facts)||!el(s,t.facts))return this.invalidate(),{status:`reset`};if(e.before===0)return{status:`boundary`,reason:`end`,oldestAvailable:0};let c=a[1];return c.length!==e.before-n||c.some(e=>e.includes(` `))?{status:`unavailable`,reason:`unanchored`}:{status:`page`,from:n,to:e.before,oldestAvailable:0,lines:En(c)}}catch{return e.signal.aborted?{status:`cancelled`}:(this.evidence===t&&this.invalidate(),{status:`reset`})}finally{this.busy=!1}}owns(e){return!this.closed&&this.control.alive&&this.evidence===e&&e.epoch===this.epoch}};function el(e,t){return e!==null&&e.cursorX===t.cursorX&&e.cursorY===t.cursorY&&e.historySize===t.historySize&&e.width===t.width&&e.height===t.height&&e.historyLimit===t.historyLimit&&e.alternate===t.alternate}const tl=[`history_size`,`pane_width`,`pane_height`,`cursor_x`,`cursor_y`,`scroll_region_upper`,`scroll_region_lower`,`origin_flag`,`wrap_flag`,`insert_flag`,`cursor_flag`,`keypad_cursor_flag`,`keypad_flag`,`alternate_on`,`alternate_saved_x`,`alternate_saved_y`,`pane_tabs`,`cursor_shape`,`cursor_blinking`];function nl(e,t){if(!/^%\d+$/.test(e))throw Error(`invalid tmux pane id`);if(t!==void 0&&!(Number.isSafeInteger(t)&&t>=1))throw Error(`invalid history line count`);let n=t===void 0?`-`:`-${t}`;return[`display -p -t ${e} '${tl.map(e=>`#{${e}}`).join(` `)}'`,`capture-pane -p -e -J -S ${n} -E -1 -t ${e}`,`capture-pane -p -e -J -t ${e}`,`capture-pane -p -e -J -a -q -t ${e}`,`capture-pane -p -P -t ${e}`]}const rl={block:2,underline:4,bar:6};function il(e){let t=``,n=``;return e.forEach((e,r)=>{r>0&&(n+=t?`\x1b[49m\r\n${t}`:`\r
|
|
24
|
+
`),n+=e;for(let[,n=``]of e.matchAll(/\x1b\[([\d;:]*)m/g))t=al(t,n)}),n}function al(e,t){let n=t.split(`;`);for(let t=0;t<n.length;t++){let r=n[t].split(`:`)[0],i=r===``?0:Number(r);i===0||i===49?e=``:i>=40&&i<=47||i>=100&&i<=107?e=`\x1b[${i}m`:i===48&&n[t].includes(`:`)?e=`\x1b[${n[t]}m`:i===48&&n[t+1]===`5`?(e=`\x1b[${n.slice(t,t+3).join(`;`)}m`,t+=2):i===48&&n[t+1]===`2`?(e=`\x1b[${n.slice(t,t+5).join(`;`)}m`,t+=4):(i===38||i===58)&&n[t+1]===`5`?t+=2:(i===38||i===58)&&n[t+1]===`2`&&(t+=4)}return e}function ol(e,t=!1){let[n=[],r=[],i=[],a=[],o=[]]=e,s=(n[0]??``).split(` `);if(s.length!==tl.length)throw Error(`unexpected tmux pane state`);let c=Object.fromEntries(tl.map((e,t)=>[e,s[t]])),l=e=>{if(!/^\d{1,6}$/.test(c[e]))throw Error(`unexpected tmux ${e}`);return Number(c[e])},u=c.alternate_on===`1`,d=l(`pane_height`),f=t?`${Nn}\x1b[3g`:`\x1Bc\x1B[3g`,p=c.pane_tabs.split(`,`).filter(Boolean);if(!p.every(e=>/^\d{1,6}$/.test(e)))throw Error(`unexpected tmux pane_tabs`);for(let e of p)f+=`\x1b[1;${Number(e)+1}H\x1bH`;f+=`\x1B[H`;let m=[...t!==!0&&l(`history_size`)>0?r:[],...u?a:i];f+=il(m),u&&(f+=`\x1b[0m\x1b[${l(`alternate_saved_y`)+1};${l(`alternate_saved_x`)+1}H`,f+=`\x1b[?1049h${il(i.slice(0,d))}`),f+=`\x1B[0m`;let h=l(`scroll_region_upper`);f+=`\x1b[${h+1};${l(`scroll_region_lower`)+1}r`,c.wrap_flag===`0`&&(f+=`\x1B[?7l`),c.insert_flag===`1`&&(f+=`\x1B[4h`),c.keypad_cursor_flag===`1`&&(f+=`\x1B[?1h`),c.keypad_flag===`1`&&(f+=`\x1B=`),c.cursor_flag===`0`&&(f+=`\x1B[?25l`);let g=rl[c.cursor_shape];g!==void 0&&(f+=`\x1b[${g-+(c.cursor_blinking===`1`)} q`);let _=c.origin_flag===`1`;_&&(f+=`\x1B[?6h`);let v=l(`cursor_y`)-(_?h:0);return f+=`\x1b[${v+1};${l(`cursor_x`)+1}H`,{cols:l(`pane_width`),rows:d,data:f+o.join(`
|
|
25
|
+
`)}}var sl=class extends Mr{opts;control;history;log;generation=0;held=[];size;seeding=!1;reseedWanted=!1;resizeTimer=null;muting=null;ended=!1;historyLines;names=new Qc;reason=`refresh`;probing=null;continuation={cursor:`real`,alternate:`real`,probe:()=>(this.probing??=this.probe().finally(()=>{this.probing=null}),this.probing)};constructor(e){if(super(),this.opts=e,!/^\$\d+$/.test(e.tmuxSessionId)||!/^%\d+$/.test(e.paneId))throw Error(`invalid tmux pane identity`);this.log=e.log.child({backend:`tmux`,stream:`vt`}),this.control=(e.controlFactory??(t=>new Oc({sessionId:t,socketName:e.socketName,executable:e.executable,log:e.log})))(e.tmuxSessionId),this.history=new $c(this.control,e.paneId),this.control.on(`bytes`,(t,n,r)=>{this.history.output(r),this.held?this.held.push({pane:t,seq:r,data:n}):t===e.paneId?this.emitBytes(this.names.write(n)):this.mutePanes()}),this.control.on(`layout`,()=>{this.history.invalidate(),this.mutePanes().then(e=>{e&&this.scheduleResizeCheck()})}),this.control.on(`exit`,()=>this.end(`exited`))}async start(e){if(this.historyLines=e??this.opts.historyLines,await this.control.start(),!this.control.alive)return this.end(`exited`);await this.mutePanes()&&await this.reseed()}async reseed(e){if(!this.ended){if(this.history.invalidate(),e!==void 0&&(this.historyLines=e),this.seeding){this.reseedWanted=!0;return}this.seeding=!0;try{for(let e=0;e<5&&!this.ended;){this.reseedWanted=!1,this.held=[];let t=this.history.revision,n=this.history.commands(this.historyLines),{replies:r,sentSeq:i,outputSeq:a}=await this.control.checkpoint([...nl(this.opts.paneId,this.historyLines),...n]),o=this.held;if(o.some(e=>e.pane!==this.opts.paneId&&e.seq>i&&e.seq<=a)){e++,await this.mutePanes();continue}let s=ol(r);this.size={cols:s.cols,rows:s.rows},this.held=void 0,this.generation++,this.names=new Qc;let c=Buffer.from(this.names.write(Buffer.from(s.data))).toString(),l=ol(r,!0),u={data:Buffer.from(new Qc().write(Buffer.from(l.data))).toString(),reason:this.reason},d=n.length>0?this.history.capture(r,s,this.historyLines,a,Buffer.from(new Qc().write(Buffer.from(ol(r,`prependable`).data))).toString(),t):void 0;this.reason=`refresh`,this.emit(`seed`,{...s,data:c,generation:this.generation,continuation:u,...d?{nativeHistory:d}:{}});for(let e of o)e.pane===this.opts.paneId&&e.seq>a&&this.emitBytes(this.names.write(e.data));if(!this.reseedWanted)return}this.ended||this.end(`unsettled`)}catch(e){this.ended||(this.log.debug(`tmux vt seed failed`,{error:e instanceof Error?e.name:`unknown`}),this.end(this.control.alive?`failed`:`exited`))}finally{this.seeding=!1}}}close(){this.end(void 0)}emitBytes(e){e.length>0&&this.emit(`bytes`,e,this.generation)}mutePanes(){return this.muting??=this.listAndMute().finally(()=>{this.muting=null}),this.muting}async listAndMute(){if(this.ended)return!1;let e;try{e=await this.control.command(`list-panes -s -t ${this.opts.tmuxSessionId} -F '#{pane_id}'`)}catch{return this.ended||this.end(this.control.alive?`pane-gone`:`exited`),!1}if(!e.includes(this.opts.paneId))return this.end(`pane-gone`),!1;let t=e.filter(e=>/^%\d+$/.test(e)&&e!==this.opts.paneId);try{for(let e of t)await this.control.command(`refresh-client -A '${e}:off'`)}catch{}return!this.ended}scheduleResizeCheck(){this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=setTimeout(()=>{this.resizeTimer=null,this.checkSize()},this.opts.resizeDebounceMs??300),this.resizeTimer.unref?.()}async checkSize(){if(this.ended||!this.size)return;let e;try{[e]=await this.control.command(`display -p -t ${this.opts.paneId} '#{pane_width} #{pane_height}'`)}catch{return}e!==`${this.size.cols} ${this.size.rows}`&&(this.reason=`resize`,await this.reseed())}async probe(){let e=this.generation,[t]=await this.control.command(`display -p -t ${this.opts.paneId} '#{pane_id} #{pane_width} #{pane_height}'`);return{generation:e,quiescent:!this.ended&&!this.seeding&&!this.held&&e===this.generation&&t===`${this.opts.paneId} ${this.size?.cols} ${this.size?.rows}`}}end(e){this.ended||(this.ended=!0,this.history.close(),this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=null,this.held=void 0,this.control.stop(),e&&this.emit(`end`,e))}};const cl=Wr(tr),ll=`brew install tmux (3.2+), then start a tmux session`,ul=5e3,dl=10485760;function fl(e,t){return bn({cwd:e.cwd||void 0,project:vn(e.windowName,e.currentCommand),processName:e.currentCommand,title:e.paneTitle,ignore:[t]})}function pl(e){return j(e)}function ml(e){return`historySize`in e}function hl(e,t){return new Promise((n,r)=>{let i=setTimeout(()=>r(Error(`tmux exec timeout: ${t}`)),ul);i.unref?.(),e.then(e=>{clearTimeout(i),n(e)},e=>{clearTimeout(i),r(e instanceof Error?e:Error(String(e)))})})}var gl=class e{opts;name=`tmux`;processes;capabilities={subscribe:!0,prompts:!1,createSession:!0,terminalInput:!0,terminalPaste:!0,focus:!1,history:!0,absoluteLines:!1,vtStream:!0};setupIssue=`no-session`;controls=new Map;panes=new Map;serverInstance;paneRevisions=new Map;historyEvidence=new WeakMap;reported=new Map;alternate=new Map;sessionIndex=new Map;handlers=new Set;watcher=null;refreshTimer=null;refreshBusy=!1;refreshDirty=!1;syncBusy=!1;closed=!0;closes=0;log;exec;constructor(e){this.opts=e,this.log=e.log.child({backend:`tmux`});let t=e.execImpl??(async t=>(await cl(this.program(),[`-u`,...e.socketName?[`-L`,e.socketName]:[],...t],{timeout:ul,maxBuffer:dl})).stdout);this.exec=e=>hl(t(e),e[0]??`tmux`)}program(){let e=this.opts.executable;return(typeof e==`function`?e():e)??`tmux`}get isConnected(){return!this.closed&&[...this.controls.values()].some(e=>e.alive)}static async detect(e,{requireServer:t=!0,executable:n=`tmux`}={}){let r=e??(async e=>(await cl(n,[`-u`,...e],{timeout:ul,maxBuffer:dl})).stdout),i=e=>hl(r(e),e[0]??`tmux`),a;try{a=await i([`-V`])}catch{return{ok:!1,version:``,reason:`tmux not found`}}let o=/(\d+\.\d+)/.exec(a)?.[1]??``,s=Wn(a);if(s===null||s<3.02)return{ok:!1,version:o,reason:`tmux 3.2+ required for Shellbell (found ${o||a.trim()})`};if(!t)return{ok:!0,version:o};try{await i([`list-sessions`,`-F`,`#{session_id}`])}catch{return{ok:!1,version:o,reason:`no tmux server running`}}return{ok:!0,version:o}}async connect(){let t=this.closes,n=await e.detect(this.exec);if(t===this.closes){if(this.setupIssue=n.ok?void 0:n.reason===`tmux not found`?`not-installed`:n.reason===`no tmux server running`?`no-session`:`too-old`,!n.ok)throw new T(n.reason??`tmux unavailable`,ll);this.watcher&&clearInterval(this.watcher),this.closed=!1,await this.syncControls(),await this.refreshPanes(),!(this.closed||t!==this.closes)&&(this.watcher&&clearInterval(this.watcher),this.watcher=setInterval(()=>{this.syncControls().then(()=>this.refreshPanes()).catch(e=>this.log.warn(`tmux watcher failed`,{error:pl(e)}))},this.opts.watchIntervalMs??5e3),this.watcher.unref?.())}}async close(){this.closed=!0,this.closes++,this.watcher&&clearInterval(this.watcher),this.watcher=null,this.refreshTimer&&clearTimeout(this.refreshTimer),this.refreshTimer=null,this.refreshDirty=!1,this.syncBusy=!1,this.refreshBusy=!1;for(let e of this.controls.values())e.stop();this.controls.clear(),this.panes.clear(),this.serverInstance=void 0,this.invalidateAllHistory(),this.reported.clear(),this.alternate.clear(),this.sessionIndex.clear(),this.handlers.clear()}on(e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(e){for(let t of this.handlers)try{t(e)}catch(e){this.log.warn(`event handler failed`,{error:pl(e)})}}channelForSession(e){if(e){let t=this.controls.get(e);if(t?.alive)return t}let t=[...this.controls.values()].find(e=>e.alive);if(!t)throw Error(`tmux command channel unavailable`);return t}channel(e){return this.channelForSession(e?this.panes.get(e)?.sessionId:void 0)}async syncControls(){if(!(this.syncBusy||this.closed)){this.syncBusy=!0;try{let e;try{e=(await this.exec([`list-sessions`,`-F`,`#{session_id}`])).split(`
|
|
26
|
+
`).filter(Boolean)}catch(e){this.log.debug(`tmux list-sessions failed; keeping the existing clients`,{error:pl(e)});return}this.sessionIndex=new Map(e.map((e,t)=>[e,t]));for(let[t,n]of this.controls)(!e.includes(t)||!n.alive)&&(n.stop(),this.controls.delete(t),this.invalidateAllHistory());for(let t of e){if(this.closed||this.controls.has(t))continue;let e=(this.opts.controlFactory??(e=>new Oc({sessionId:e,socketName:this.opts.socketName,executable:this.program(),log:this.opts.log})))(t);e.on(`output`,e=>{this.panes.has(e)?(this.invalidatePane(e),this.emit({type:`screen-changed`,sessionId:e})):this.scheduleRefresh()}),e.on(`layout`,()=>{this.invalidateAllHistory(),this.scheduleRefresh()}),e.on(`exit`,()=>{this.controls.delete(t),this.invalidateAllHistory(),this.scheduleRefresh()}),this.controls.set(t,e),this.invalidateAllHistory(),await e.start()}}finally{this.syncBusy=!1}}}scheduleRefresh(){if(!this.closed){if(this.refreshBusy){this.refreshDirty=!0;return}this.refreshTimer||(this.refreshTimer=setTimeout(()=>{this.refreshTimer=null,this.refreshPanes().catch(e=>this.log.warn(`tmux refresh failed`,{error:pl(e)}))},this.opts.refreshDebounceMs??100),this.refreshTimer.unref?.())}}async refreshPanes(){if(!this.closed){if(this.refreshBusy){this.refreshDirty=!0;return}this.refreshBusy=!0;try{do this.refreshDirty=!1,await this.runRefresh();while(this.refreshDirty&&!this.closed)}finally{this.refreshBusy=!1}}}async runRefresh(){if(this.controls.size===0){let e=[...this.panes.keys()];this.panes.clear(),this.serverInstance=void 0,this.alternate.clear(),this.invalidateAllHistory();for(let t of e)this.emit({type:`session-removed`,sessionId:t});e.length>0&&this.emit({type:`layout-changed`});return}let e;try{e=Gc(await this.channel().command(`list-panes -a -F ${Ic}`))}catch(e){this.log.warn(`list-panes failed`,{error:pl(e)});return}let t=this.panes,n=new Map(e.filter(e=>!e.dead).map(e=>[e.paneId,e])),r=[...t.keys()].filter(e=>!n.has(e)),i=[...n.keys()].filter(e=>!t.has(e)),a=this.opts.hostname??_r(),o=[...n.keys()].filter(e=>{let r=t.get(e);if(!r)return!1;let i=n.get(e);return Zc(r,a)!==Zc(i,a)||r.cwd!==i.cwd||!dn(fl(r,a),fl(i,a))});this.panes=n;for(let e of r)this.reported.delete(e),this.alternate.delete(e),this.invalidatePane(e),this.emit({type:`session-removed`,sessionId:e});for(let e of i)this.revisionFor(e),this.emit({type:`session-added`,sessionId:e});for(let e of o)this.emit({type:`title-changed`,sessionId:e});(r.length>0||i.length>0)&&this.emit({type:`layout-changed`})}pane(e){let t=this.panes.get(e);if(!t)throw new M(e);return t}revisionFor(e){let t=this.paneRevisions.get(e);return t||(t={},this.paneRevisions.set(e,t)),t}invalidatePane(e){this.paneRevisions.delete(e)}invalidateAllHistory(){this.paneRevisions.clear()}ownsEvidence(e){return this.panes.has(e.paneId)&&this.paneRevisions.get(e.paneId)===e.revision&&e.channel.alive&&this.channel(e.paneId)===e.channel}sameFacts(e,t){return e.cursorX===t.cursorX&&e.cursorY===t.cursorY&&e.historySize===t.historySize&&e.width===t.width&&e.height===t.height&&e.historyLimit===t.historyLimit&&e.alternate===t.alternate}async checkedFacts(e,t){if(t.aborted)return{status:`cancelled`};if(!this.ownsEvidence(e))return{status:`reset`};let n;try{n=(await e.channel.command(`display-message -p -t ${e.paneId} ${zc}`))[0]}catch{return t.aborted?{status:`cancelled`}:this.ownsEvidence(e)?{status:`unavailable`,reason:`changed`}:{status:`reset`}}if(t.aborted)return{status:`cancelled`};if(!this.ownsEvidence(e))return{status:`reset`};let r=Yc(n??``);return r?this.sameFacts(r,e.facts)?r:(this.invalidatePane(e.paneId),{status:`reset`}):{status:`unavailable`,reason:`changed`}}readOutcome(e,t){if(t.aborted)return{status:`cancelled`};if(!this.ownsEvidence(e))return{status:`reset`}}async notificationFacts(e){let t=this.panes.get(e);if(!t||!this.isConnected)return;let n=zn({sessionId:e,cwd:t.cwd,title:Zc(t,this.opts.hostname??_r()),sessionLabel:`tmux`},t.currentCommand,`local-process`),r=this.serverInstance;return r?{...n,instance:r,revision:JSON.stringify([n.revision,r])}:n}async listSessions(){let e=new Set,t=new Map,n;try{let r=(await this.channel().command(`list-clients -F ${Lc}`)).map(Kc),i=r.filter(e=>!e.controlMode),a=r.find(e=>e.serverPid)?.serverPid;a&&(n=`tmux-server-${a}`),e=new Set(i.map(e=>e.sessionId)),t=await this.hostApps(i)}catch(e){this.log.debug(`list-clients failed; no pane reported focused`,{error:pl(e)})}this.serverInstance=n;let r=this.opts.hostname??_r(),i=e=>this.sessionIndex.get(e)??2**53-1;return[...this.panes.values()].sort((e,t)=>i(e.sessionId)-i(t.sessionId)||e.windowIndex-t.windowIndex||e.paneIndex-t.paneIndex).map(i=>({id:i.paneId,backend:`tmux`,title:Zc(i,r),cwd:i.cwd||void 0,...fl(i,r),cols:Math.max(1,i.width),rows:Math.max(1,i.height),windowId:i.sessionId,windowNumber:this.sessionIndex.get(i.sessionId)??0,tabId:i.windowId,tabIndex:i.windowIndex,paneIndex:i.paneIndex,isFocusedOnMac:i.paneActive&&i.windowActive&&e.has(i.sessionId),state:`unknown`,...this.alternate.has(i.paneId)&&{alternateScreen:this.alternate.get(i.paneId)},...t.has(i.sessionId)&&{shownIn:t.get(i.sessionId)},...n&&{instance:n}}))}async hostApps(e){let t=new Map;if(!e.some(e=>e.pid))return t;let n=Date.now();(!this.processes||n-this.processes.at>1e4)&&(this.processes={at:n,table:await(this.opts.processTable??nn)().catch(()=>void 0)});let r=this.processes.table;if(!r)return t;for(let{sessionId:n,pid:i}of e){let e=i?$t(i,r):void 0;if(!e)continue;let a=t.get(n)??[];!a.includes(e)&&a.length<4&&a.push(e),t.set(n,a.sort((e,t)=>e.localeCompare(t)))}return t}openVtStream(e){return new sl({tmuxSessionId:this.pane(e).sessionId,paneId:e,socketName:this.opts.socketName,executable:this.program(),log:this.opts.log})}projectFolder(e){let t=this.panes.get(e);if(t?.cwd&&!vn(t.windowName,t.currentCommand))return yn(t.currentCommand)?t.cwd:void 0}tmuxWindowIdOf(e){return this.panes.get(e)?.windowId}nativeWindowIdOf(e){return this.tmuxWindowIdOf(e)}hostedProcess(e){return this.panes.get(e)?.currentCommand}async conversationReference(e,t){if(t.aborted||!this.panes.has(e))return null;let[n=``,r=``]=await this.exec([`display-message`,`-p`,`-t`,e,`#{pane_tty} #{socket_path}`]).then(e=>e.trim().split(` `),()=>[]);return t.aborted||!this.panes.has(e)?null:Ps(n,t,{codexPane:{tmux:{socket:r,pane:e}},codexTitle:async()=>{let t=this.panes.get(e);return{title:t?.paneTitle,cwd:t?.cwd||void 0}}})}observeAlternate(e,t){if(t===void 0||!this.panes.has(e))return;let n=this.alternate.get(e);n!==t&&(this.alternate.set(e,t),(n!==void 0||t)&&this.emit({type:`title-changed`,sessionId:e}))}setReported(e,t){this.reported.set(e,t)}async getScreen(e,t){this.pane(e);let n=this.channel(e),r=t?.history===!0,i=r?this.revisionFor(e):void 0,a=r?zc:Rc,o=await n.command(`display-message -p -t ${e} ${a}`),s=await n.command(`capture-pane -p -e -N -t ${e}`),c=qc(o[0]??``);this.observeAlternate(e,r?Yc(o[0]??``)?.alternate:Jc(o[0]??``));let l=Math.max(1,c.height),u=s.map(qn);for(;u.length<l;)u.push({r:[]});u.length>l&&(u.length=l);let d={cols:Math.max(1,c.width),rows:l,cursor:{x:c.cursorX,y:c.cursorY},lines:u,scrollbackTotal:c.historySize};if(!r)return d;let f=Yc(o[0]??``);if(!f||f.alternate||!this.panes.has(e)||this.channel(e)!==n||!n.alive)return d;let p;try{p=Yc((await n.command(`display-message -p -t ${e} ${zc}`))[0]??``)}catch{return d}if(!p||!this.sameFacts(f,p)||p.alternate||this.paneRevisions.get(e)!==i||this.channel(e)!==n||!n.alive)return d;let m=Object.freeze({});return this.historyEvidence.set(m,{paneId:e,revision:i,channel:n,facts:Object.freeze(f)}),{...d,historyCapture:m}}async getHistory(e,t,n){this.pane(e);let r=this.reported.get(e);if(r===void 0)return{lines:[],oldestAvailable:0};let i=this.channel(e),a=qc((await i.command(`display-message -p -t ${e} ${Rc}`))[0]??``),o=Math.max(0,r-a.historySize),s=t-1-r,c=Math.max(t-n-r,-a.historySize);return s<c||s>-1?{lines:[],oldestAvailable:o}:{lines:(await i.command(`capture-pane -p -e -N -t ${e} -S ${c} -E ${s}`)).map(qn),oldestAvailable:o}}async getHistoryPage(e,t){if(lt(t),t.signal.aborted)return{status:`cancelled`};this.pane(e);let n=this.historyEvidence.get(t.capture);if(!n||n.paneId!==e)return{status:`unavailable`,reason:`unanchored`};let r=this.readOutcome(n,t.signal);if(r)return r;if(t.reported<n.facts.historySize)return{status:`unavailable`,reason:`unanchored`};let i=await this.checkedFacts(n,t.signal),a=this.readOutcome(n,t.signal);if(a)return a;if(!ml(i))return i;let o=Math.max(0,t.reported-n.facts.historySize);if(t.before<o){let e=await this.checkedFacts(n,t.signal);return this.readOutcome(n,t.signal)||(ml(e)?{status:`boundary`,reason:`truncated`,oldestAvailable:o}:e)}if(t.before===o){let e=await this.checkedFacts(n,t.signal);return this.readOutcome(n,t.signal)||(ml(e)?{status:`boundary`,reason:`end`,oldestAvailable:o}:e)}let s=Math.max(t.before-t.count,o),c=s-t.reported,l=t.before-1-t.reported;if(c<-2147483648||l<-2147483648||c>-1||l>-1)return{status:`unavailable`,reason:`fetch-window`};if(t.signal.aborted)return{status:`cancelled`};if(!this.ownsEvidence(n))return{status:`reset`};let u;try{u=await n.channel.command(`capture-pane -p -e -N -t ${e} -S ${c} -E ${l}`)}catch{return t.signal.aborted?{status:`cancelled`}:this.ownsEvidence(n)?{status:`unavailable`,reason:`changed`}:{status:`reset`}}if(t.signal.aborted)return{status:`cancelled`};if(!this.ownsEvidence(n))return{status:`reset`};let d=await this.checkedFacts(n,t.signal);return this.readOutcome(n,t.signal)||(ml(d)?u.length===t.before-s?{status:`page`,from:s,to:t.before,oldestAvailable:o,lines:u.map(qn)}:{status:`unavailable`,reason:`changed`}:d)}async sendText(e,t){this.pane(e);let n=this.channel(e),r=Nc(t);if(r){this.log.debug(`tmux key`),await n.command(`send-keys -t ${e} ${r}`);return}this.log.debug(`tmux text`,{len:t.length});let i=t.split(/\r\n|\r|\n/);for(let t=0;t<i.length;t++){let r=i[t];r&&await n.command(`send-keys -t ${e} -l -- ${wc(r)}`),t<i.length-1&&await n.command(`send-keys -t ${e} Enter`)}}async sendInput(e,t){this.pane(e);let n=[...Buffer.from(t,`utf8`)].map(e=>e.toString(16).padStart(2,`0`)).join(` `);await this.channel(e).command(`send-keys -t ${e} -H -- ${n}`)}async paste(e,t,n){if(this.pane(e),t.includes(`\0`))throw new Ot(`paste containing NUL`);let r=`shellbell-${Ar()}`,i=`"${[...Buffer.from(t,`utf8`)].map(e=>`\\${e.toString(8).padStart(3,`0`)}`).join(``)}"`,a=this.channel(e);try{await a.command(`set-buffer -b ${r} -- ${i}`),await a.command(`paste-buffer -p -d -b ${r} -t ${e}`),n&&await a.command(`send-keys -t ${e} Enter`)}finally{await a.command(`delete-buffer -b ${r}`).catch(()=>{})}}async createFirstSession(t){let n=this.closes,r=t===void 0?void 0:rt.parse(t),i=await e.detect(this.exec,{requireServer:!1});if(!i.ok)throw new T(i.reason??`tmux unavailable`,ll);let a=(await this.exec([`new-session`,`-d`,`-P`,`-F`,`#{pane_id}`,...r?[`-x`,String(r.cols),`-y`,String(r.rows)]:[]])).trim();if(!/^%\d+$/.test(a))throw Error(`tmux new-session returned an invalid pane id`);try{if(r&&await this.exec([`if-shell`,`-F`,`-t`,a,`#{==:#{default-size},${r.cols}x${r.rows}}`,`set-option -u -t ${a} default-size`]),n!==this.closes||(await this.connect(),n!==this.closes))throw new T(`tmux backend stopped`,ll)}catch(e){throw await this.exec([`kill-pane`,`-t`,a]).catch(()=>void 0),e}return a}async hostedSessionTarget(e){if(!/^%\d+$/.test(e))throw new M(e);let t=(await this.exec([`display-message`,`-p`,`-t`,e,`#{session_id}`])).trim();if(!/^\$\d+$/.test(t))throw new M(e);return{sessionId:t,socketName:this.opts.socketName}}async discardHostedSession(e){if(/^\$\d+$/.test(e))await this.exec([`kill-session`,`-t`,e]);else if(/^%\d+$/.test(e))await this.exec([`kill-pane`,`-t`,e]);else throw new M(e);this.scheduleRefresh()}async waitForVisibleClient(e,{timeoutMs:t=15e3,intervalMs:n=250}={}){if(!/^\$\d+$/.test(e))throw new M(e);let r=Date.now()+t;for(;;){if(await this.hasDesktopClient(e).catch(()=>!1))return!0;if(Date.now()>=r)return!1;await new Promise(e=>setTimeout(e,n))}}async shownOnComputer(e){let t;if(e.kind===`split`)t=this.pane(e.sessionId).sessionId;else if(e.windowId!==void 0){if(!this.sessionIndex.has(e.windowId))throw new M(e.windowId);t=e.windowId}else return!1;return this.hasDesktopClient(t)}async focusedWindow(){return(await this.desktopClients()).filter(e=>this.sessionIndex.has(e.sessionId)).sort((e,t)=>(t.activity??0)-(e.activity??0))[0]?.sessionId}async discardSession(e){if(!/^%\d+$/.test(e))throw new M(e);await this.exec([`kill-pane`,`-t`,e]),this.scheduleRefresh()}async hasDesktopClient(e){return(await this.desktopClients(e)).length>0}async desktopClients(e){let t=Pc.replace(/\\t/g,` `),n=e===void 0?[]:[`-t`,e],r=(await this.exec([`list-clients`,...n,`-F`,t])).split(`
|
|
27
|
+
`).filter(Boolean).map(Kc).filter(e=>!e.controlMode);if(r.length===0)return[];let i=await(this.opts.processTable??nn)().catch(()=>void 0);return i?r.filter(e=>e.pid!==void 0&&$t(e.pid,i)!==void 0):(this.opts.platform??process.platform)===`darwin`?[]:r}async createSession(e){let t,n;if(e.kind===`split`)this.pane(e.sessionId),t=this.channel(e.sessionId),n=`split-window -P -F '#{pane_id}' -t ${e.sessionId} ${e.direction===`vertical`?`-h`:`-v`}`;else if(e.windowId){if(!this.sessionIndex.has(e.windowId))throw new M(e.windowId);t=this.channelForSession(e.windowId),n=`new-window -d -P -F '#{pane_id}' -t ${e.windowId}`}else t=this.channel(),n=`new-session -d -P -F '#{pane_id}'`;let r=(await t.command(n))[0]?.trim();if(!r)throw Error(`tmux ${n.split(` `)[0]} returned no pane id`);return this.scheduleRefresh(),r}async focus(e){throw new Ot(`focus`)}};function _l(e){let t=e.log.child({unit:`tmux-start`}),n=e.terminalExecutable??(()=>cn(`tmux`)),r=()=>n()??`tmux`,i=new gl({log:e.log,executable:r,...e.backendOptions}),a,o=[],s=null,c=!1,l=!1,u=!1;e.registry.add(i);let d=e.registry.registerSetupReporter(`tmux`,e=>e?{}:{issue:i.setupIssue??`no-session`}),f=`none`,p=()=>{f!==`none`||c||(f=`checking`,gl.detect(e.backendOptions?.execImpl,{requireServer:!1,executable:r()}).then(t=>{if(c||!t.ok){f=`none`;return}f=`registered`,a=e.registry.registerSessionLauncher(`tmux`,{available:()=>!c,start:async e=>({backend:i,sessionId:await i.createFirstSession(e)})});for(let t of e.terminalWindows??[])o.push(e.registry.registerHostedLauncher({backend:`tmux`,host:t.id,label:t.label},{available:()=>!c&&t.available()&&n()!==void 0,create:async(r,a,o,s)=>{if(c||r!==i)throw new T(`tmux was replaced`,`Try again after the service reconnects.`);let l=n();if(!l)throw new T(`tmux is not installed`,`Install tmux 3.2 or newer.`);let u=a??await i.createFirstSession(o),d=u,f=`window`;return await mc(async()=>{let n=await i.hostedSessionTarget(u);if(d=n.sessionId,c)throw new T(`tmux stopped`,`Reconnect your computer.`);if(f=await t.launch({executable:l,...o?{initialSize:o}:{},...s?.tab&&{tab:!0},args:[...n.socketName?[`-L`,n.socketName]:[],`attach-session`,`-t`,n.sessionId]}),!await i.waitForVisibleClient(n.sessionId,{timeoutMs:e.attachTimeoutMs}))throw new T(`terminal window did not attach`,`Unlock your computer and try again.`)},()=>i.discardHostedSession(d)),{sessionId:u,opened:f}}}))}).catch(e=>{f=`none`,t.debug(`tmux startup discovery failed`,{error:j(e)})}))};p();let m=()=>{c||s||(s=setTimeout(()=>{s=null,h()},e.retryMs??1e4),s.unref?.())},h=async()=>{if(!c){if(i.isConnected){p(),m();return}try{await i.connect()}catch(n){p(),t.debug(`tmux not available`,{error:j(n)}),e.onUnavailable&&!u&&n instanceof T&&(u=!0,e.onUnavailable()),m();return}try{if(c)return;if(p(),t.info(`tmux connected`),e.onConnected&&!l){l=!0;let t=await i.listSessions().catch(()=>[]);e.onConnected(t.length)}}catch(e){t.debug(`tmux post-connect setup failed`,{error:j(e)})}m()}};return h(),{stop(){d(),a?.();for(let e of o)e();c=!0,s&&clearTimeout(s),s=null,i.close(),e.registry.remove(`tmux`)}}}function vl(e){return new Promise(t=>{let n=Pr(e),r=e=>{n.destroy(),t(e)};n.setTimeout(250,()=>r(`ambiguous`)),n.once(`connect`,()=>r(`active`)),n.once(`error`,e=>r([`ENOENT`,`ECONNREFUSED`].includes(e.code??``)?`absent`:`ambiguous`))})}async function yl(e,t,n){let r=I(P(t.runtimeDir),R(`sha256`).update(e).digest(`hex`).slice(0,32));for(let i of[e,r]){if(!w(i))continue;ve(i,t.linuxHost.uid),i===r&&he(t,i);let e=I(i,`agent.pid`);if(w(e)){let r=xe(dt(e,64,t.linuxHost.uid).toString(`utf8`).trim());if(!r||(n.processAlive??ce)(r))throw new a(`unsafe`)}let o=[`agent.sock.lock`,`init.sock.lock`,`service.lock`],s=dr(i);try{for(let e=s.readSync();e;e=s.readSync())if(o.some(t=>e.name===t||e.name.startsWith(`${t}-candidate-`)))throw new a(`unsafe`)}finally{s.closeSync()}let c=I(i,`agent.sock`);if(Buffer.byteLength(c)>107)throw new a(`unsafe`);let l=w(c);if(l&&(!l.isSocket()||l.uid!==t.linuxHost.uid||(l.mode&4095)!=384)||await(n.probeSocket??vl)(c)!==`absent`)throw new a(`unsafe`)}}function bl(e,t){let n=t===void 0?w(e):ve(e,t),r=ur(e,ir.O_RDONLY|ir.O_DIRECTORY|ir.O_NOFOLLOW);try{if(!n||!g(n,or(r)))throw new a(`unsafe`);sr(r)}finally{rr(r)}}function xl(e,t){let n=w(e);if(n){if(!n.isDirectory()||n.isSymbolicLink())throw new a(`unsafe`);return}xl(P(e),t);try{lr(e,{mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}ve(e,t),bl(P(e))}async function Sl(e,t,n,r={}){let i;try{if(de(e.dir)!==e.dir)throw new a(`unsafe`);let o=Wt(e);if(o.status===`ready`)return{status:`already-initialized`,stateDir:e.dir};if(o.status!==`absent`)throw new a(`unsafe`);let s,c,l;if(t.kind===`adopt`){if(t.confirmSourceInactive!==!0||!F(t.source)||(c=de(t.source),c===e.dir))throw new a(`unsafe`);s=Ht(c,e.linuxHost.uid),await yl(c,e,r)}else if(t.kind===`new`){if(l=Bt.parse(n),Buffer.byteLength(`${JSON.stringify(l,null,2)}\n`)>65536)throw new a(`invalid`)}else throw new a(`invalid`);m(e),i=C(I(e.runtimeDir,`init.sock`));let u=Wt(e);if(u.status===`ready`)return{status:`already-initialized`,stateDir:e.dir};if(u.status!==`absent`)throw new a(`unsafe`);if(c){await yl(c,e,r);let t=Ht(c,e.linuxHost.uid);if(!s||!t.identity.equals(s.identity)||!t.config.equals(s.config)||!t.pairings.equals(s.pairings))throw new a(`unsafe`)}if(xl(P(e.dir),e.linuxHost.uid),de(e.dir)!==e.dir)throw new a(`unsafe`);lr(e.dir,{mode:448});let d=ve(e.dir,e.linuxHost.uid);bl(P(e.dir));let f=()=>{if(!g(d,ve(e.dir,e.linuxHost.uid)))throw new a(`unsafe`)},p=s??{identity:Buffer.from(`${JSON.stringify(pe(ue()),null,2)}\n`),config:Buffer.from(`${JSON.stringify(l,null,2)}\n`),pairings:Buffer.from(`{"v":1,"phones":[]}
|
|
28
|
+
`)};for(let t of[`identity`,`config`,`pairings`]){r.checkpoint?.(`before-${t}`),f();let n=I(e.dir,`${t}.json`);if(w(n))throw new a(`unsafe`);Rt(n,p[t],()=>{if(f(),w(n))throw new a(`unsafe`)}),r.checkpoint?.(`after-${t}`)}Ht(e.dir,e.linuxHost.uid),bl(e.dir,e.linuxHost.uid),r.checkpoint?.(`before-marker`),f();let h=I(e.dir,`host.json`);return Rt(h,`${JSON.stringify({v:1,hostDigest:e.linuxHost.hostDigest,installationId:Ar()})}\n`,()=>{if(f(),w(h))throw new a(`unsafe`)}),r.checkpoint?.(`after-marker`),r.checkpoint?.(`before-directory-fsync`),bl(e.dir,e.linuxHost.uid),r.checkpoint?.(`after-directory-fsync`),{status:`initialized`,stateDir:e.dir}}catch{throw Error(`shellbell: host initialization failed; inspect ${e.dir} before retrying. Preserve existing credentials; move partial state aside only after explicit recovery. Adoption requires the source to be inactive on every host.`)}finally{i?.()}}async function Cl(e,t,n,r){if(!t.running||t.version!==n)return!1;let i=await e.installedRuntime(),a=r();return i?.nodePath===a.nodePath&&i.cliPath===a.cliPath}function wl(e,t=Ue){let n=e=>({installed:e.installed,running:e.ready,startsAtLogin:e.installed&&e.startupEnabled!==!1,available:!0,version:e.ready?e.local?.process.agentVersion??null:null,service:e});return{system:`macos`,checkRuntime:()=>void t(),status:async()=>n(await e.status()),async install(r){let i=n(await e.status());return await Cl(e,i,r,t)||(i=n(await e.install())),i.startsAtLogin||(i=n(await e.enable())),i},async start(){let t=n(await e.status());return t.running?t:n(await e.start())},stop:async()=>n(await e.stop()),restart:async()=>n(await e.restart()),uninstall:async()=>n(await e.uninstall())}}function Tl(e,t,n=Ue){let r=e=>({installed:e.installed,running:e.ready,startsAtLogin:e.enabled,available:e.installed||e.activeState!==`unknown`,keepsRunningAfterLogout:e.linger===`yes`,version:e.ready?e.local?.process.agentVersion??null:null,service:e});return{system:`linux`,checkRuntime:()=>void n(),status:async()=>r(await e.status()),async install(i){let a=r(await e.status());return a.available?(await t((await e.installedRuntime())?.stateDir??null),await Cl(e,a,i,n)||(a.installed&&await e.stop(),await e.install(),(await e.status()).enabled||await e.enable(),a=r(await e.start())),a.startsAtLogin?a:r(await e.enable())):a},async start(){let t=r(await e.status());return t.running?t:r(await e.start())},stop:async()=>r(await e.stop()),restart:async()=>r(await e.restart()),uninstall:async()=>r(await e.uninstall())}}async function El(e=f(),t={}){let n=Wt(e);if(n.status===`ready`&&(t.installedStateDir??e.dir)===e.dir)return;if(n.status!==`absent`&&n.status!==`ready`)throw Error(Je(e.dir,n.status));let r=I(t.home??N(),`.shellbell`),i=t.installedStateDir??(ar(I(r,`identity.json`))?r:null);if(i)throw Error(i===e.dir?`Shellbell's background service keeps its identity in ${e.dir}, but the identity is missing. To keep your paired phones, Shellbell won't make a new one. Restore the folder from a backup, or run \`shellbell uninstall\` to start over and pair your phones again.`:`Shellbell already has an identity on this computer, in ${i}, but is looking in ${e.dir}. To keep your paired phones, Shellbell won't make a new one. Run Shellbell with the same SHELLBELL_DIR as before, or see the Linux guide to move it.`);await Sl(e,{kind:`new`},{...ht(),computerName:_r().replace(/\.local$/,``)||`Linux`})}function Dl(e=process.platform){if(e===`linux`)return Tl(new Sn({env:process.env}),e=>El(void 0,{installedStateDir:e}));if(e!==`darwin`)throw Error(`Shellbell runs in the background on macOS and Linux only.`);return wl(new jt({manager:u(),requestedStateDir:process.env.SHELLBELL_DIR||void 0,defaultStateDir:I(N(),`.shellbell`),env:process.env}))}const Ol="This computer can't run Shellbell in the background: it has no systemd user session, as is common in containers. Run `shellbell run` to keep Shellbell running in this window.";function kl(e){return e instanceof Bn?Ol:(e instanceof Error?e.message:String(e)).replace(/^shellbell: /,``)}function Al(e,t,n=yr().username){if(!e.running)return e.available?e.installed?[e.startsAtLogin?"Shellbell is stopped. It starts again the next time you log in, or run `shellbell start`.":"Shellbell is stopped. Run `shellbell start` to start it."]:["Shellbell doesn't run in the background on this computer yet. Run `shellbell install`."]:[Ol];let r=[`Shellbell ${e.version??``} is running in the background${e.startsAtLogin?` and starts again whenever you log in`:``}.`.replace(` `,` `)];return t===`macos`&&e.startsAtLogin&&r.push(`After this Mac restarts, log in once so your phone can reach it.`),t===`linux`&&!e.keepsRunningAfterLogout&&r.push(`It stops when you log out. To keep it running after you log out, an administrator can run: sudo loginctl enable-linger ${n}`),r}const jl={log:e=>console.log(e),error:e=>console.error(e)};async function Ml(e,t,n=jl){try{let r=e.background();if(r.checkRuntime(),e.appOwned?.())return 2;let i=await r.status();if(!i.running&&await e.otherCopyRunning?.())return Nl(Error(`Shellbell is running in a terminal window. Press Ctrl-C in that window, then try again.`),t,n),2;!t&&!i.installed&&i.available&&await e.offerAgents?.();let a=await r.install(e.version);if(t)n.log(JSON.stringify(a));else{for(let e of Al(a,r.system))n.log(` ${e}`);a.running&&!i.installed&&r.system===`macos`&&n.log(`
|
|
41
29
|
macOS may now ask a few questions. Each one is optional:
|
|
42
|
-
- "Background Items Added: node" is
|
|
30
|
+
- "Background Items Added: node" is Shellbell. node is the runtime Shellbell runs on.
|
|
43
31
|
- "node" or "osascript" wants to control "iTerm2" appears when you run
|
|
44
32
|
shellbell connect iterm2, so your phone can show iTerm2 tabs and type into them.
|
|
45
33
|
Shellbell controls no other app.
|
|
46
34
|
- "Find devices on your local network" lets your phone connect straight to this Mac on the
|
|
47
35
|
same Wi-Fi. Without it, your phone may not connect while it is on the same Wi-Fi.
|
|
48
|
-
Change any answer later in System Settings → Privacy & Security.`;Ol(Q,()=>new Tt({manager:f(),requestedStateDir:process.env.SHELLBELL_DIR||void 0,defaultStateDir:L(F(),`.shellbell`),env:process.env})),Q.command(`logs`).option(`-f, --follow`).description(`show the agent log`).action(e=>{let{p:t}=$();e.follow?qn(`tail`,[`-f`,t.log],{stdio:`inherit`}):Xn(t.log)&&process.stdout.write(yl(t.log,65536,200))});function Al(e,t){process.exitCode=2,t?console.log(JSON.stringify({error:e})):console.error(` ${e}`)}Q.command(`config`).description(`config set <${a.join(`|`)}> <value>`).argument(`<op>`).argument(`<key>`).argument(`<value>`).action(async(e,t,n)=>{let r=Q.opts();if(e!==`set`){Al(`unknown config operation ${e} (expected set)`,r.json);return}let i=!!r.insecure||process.env.SHELLBELL_ALLOW_INSECURE_RELAY===`1`,a=Se(Be(),t,n,i);if(`error`in a){Al(a.error,r.json);return}let o=!1,s=!0;try{let e=Bc(),r=gt(e,e=>{let r=Se(e,t,n,i);if(`error`in r)throw Error(r.error);return r.next});if(t===`conversations`){let t;try{if(t=await h(e.sock),t.runtime.stateDir===ar(e.dir)){let e=await t.applyConversationSetting(Te(r));o=e!==null,s=e!==Te(r)}}catch{}finally{t?.close()}}}catch(e){Al(e instanceof Error?e.message:String(e),r.json);return}r.json?console.log(JSON.stringify({saved:!0,restartRequired:s,...t===`conversations`?{conversationApplied:o}:{}})):console.log(t===`conversations`&&!o?` configuration saved; live conversation consent could not be confirmed. Restart the agent if it is running.`:s?o?` conversation consent applied; other saved settings still need an agent restart`:` configuration saved; the running agent must be restarted`:` conversation consent saved and applied to the running agent`)});function jl(e,t,n=console.log,r=e=>{process.exitCode=e}){let i=kn(e);if(t)n(JSON.stringify(e));else for(let t of e)n(` ${t.severity===`pass`?`✓`:t.severity===`warning`?`!`:`✗`} ${t.name.padEnd(18)} ${t.detail}${t.fix?`\n fix: ${t.fix}`:``}`);r(i)}function Ml(e,t={}){e.command(`doctor`).description(`inspect local agent, relay and terminal backend health without changing state`).option(`--require-backend [name]`,`treat a disconnected backend as an error (repeatable)`,(e,t)=>[...t,typeof e==`string`?e:``],[]).action(async n=>{let r=!!e.opts().json,i=new Set(Array.isArray(n.requireBackend)?n.requireBackend:[``]);if([...i].some(e=>!v.some(t=>t===e))){let e={name:`doctor arguments`,ok:!1,severity:`error`,detail:`invalid required backend name`,fix:`use iterm2, tmux, or herdr`};console.log(r?JSON.stringify([e]):` ✗ ${e.name} ${e.detail}\n fix: ${e.fix}`),process.exitCode=2;return}let a=v.filter(e=>i.has(e)),o=t.env??process.env,s;try{s=await(t.runDoctor??Cn)({requestedStateDir:o.SHELLBELL_DIR,defaultStateDir:t.defaultStateDir??L(F(),`.shellbell`),requiredBackends:a,env:o})}catch{s=[{name:`doctor`,ok:!1,severity:`error`,detail:`diagnostic inspection failed`}]}jl(s,r)})}Ml(Q),Vc(Q);function Nl(e,t,n=ar){if(!e)return!1;let r;try{r=n(e)}catch{r=e}let i=hr(t),a;try{a=n(i)}catch{a=i}return a===r}Nl(process.argv[1],import.meta.url)&&Q.parseAsync().catch(e=>{console.error(e),process.exit(1)});export{a as CONFIG_KEYS,kl as MACOS_SERVICE_PROMPTS,Ml as addDoctorCommand,Ol as addServiceCommands,wl as buildAgent,xl as chooseConfirm,Dl as connectTerminalCommand,El as iTermSetupReport,Nl as isEntryPoint,_l as pairValidUntil,jl as printDoctorResult,Q as program,Se as resolveConfigSet,Cl as resolveRelayOverride,Sl as shutdown,bl as socketAlive,yl as tailFile,Oe as validateRelayUrl};
|
|
36
|
+
Change any answer later in System Settings → Privacy & Security.`)}return a.running?(t||await e.afterInstall?.(),0):2}catch(e){return Nl(e,t,n),2}}function Nl(e,t,n){let r=kl(e),i=e instanceof vt?{rollback:e.rollback,rollbackDiagnostic:e.rollbackDiagnostic,recoveryPath:e.recoveryPath}:{};t?n.log(JSON.stringify({error:r,...i})):(n.error(` ${r}`),i.rollback===`failed`&&n.error(` Shellbell couldn't put the previous setup back${i.rollbackDiagnostic?` (${i.rollbackDiagnostic})`:``}.${i.recoveryPath?` A copy of it is saved at ${i.recoveryPath}.`:``}`))}async function Pl(e,t,n,r){try{if(e.appOwned?.())return 2;let i=e.background(),a=await i.status();if(!a.installed){if(t)n.log(JSON.stringify(a));else if(r!==`start`&&await e.otherCopyRunning?.())n.log(` Shellbell is running in a terminal window, not in the background. Press Ctrl-C in that window to stop it.`);else if(r===`uninstall`||r===`stop`)n.log(` Shellbell doesn't run in the background on this computer.`);else for(let e of Al(a,i.system))n.log(` ${e}`);return r===`uninstall`||r===`stop`?0:2}let o=await i[r](),s=r===`uninstall`?!o.installed&&!o.startsAtLogin:r===`stop`!==o.running;if(t)n.log(JSON.stringify(o));else if(r===`uninstall`)n.log(s?" Shellbell no longer runs in the background. Your phones stay paired; run `shellbell install` to turn it back on.":` Shellbell's background setup is removed, but something else still starts it when you log in. ${o.service.diagnostic??``}`.trimEnd());else for(let e of Al(o,i.system))n.log(` ${e}`);return s?0:2}catch(e){return Nl(e,t,n),2}}const Fl=(e,t,n=jl)=>Pl(e,t,n,`start`);function Il(e,t){let n=()=>!!e.opts().json;e.command(`install`).description(`run Shellbell in the background, starting again whenever you log in`).action(async()=>{process.exitCode=await Ml(t,n())}),e.command(`uninstall`).description(`stop running Shellbell in the background; your phones stay paired`).action(async()=>{process.exitCode=await Pl(t,n(),jl,`uninstall`)}),e.command(`stop`).description(`stop Shellbell until you next log in or run start`).action(async()=>{process.exitCode=await Pl(t,n(),jl,`stop`)}),e.command(`restart`).description(`restart the background Shellbell, for example after config set`).action(async()=>{process.exitCode=await Pl(t,n(),jl,`restart`)})}function X(e=process.platform,t){if(e!==`linux`)return ot();let n=f(t);return l(n),n}function Ll(e,t={}){e.command(`host`,{hidden:!0}).description(`recover or move Linux host identity state`).command(`init`).description(`initialize Linux host state without starting an agent or enabling autostart`).option(`--new`,`create a new independent host identity`).option(`--adopt <absolute-source>`,`copy validated inactive legacy identity and pairings`).option(`--confirm-source-inactive`,`confirm no agent uses the source, including on other hosts`).action(async n=>{let r=!!e.opts().json,i;if((t.platform??process.platform)===`linux`?!!n.new==(n.adopt!==void 0)?i=`choose exactly one of --new or --adopt <absolute-source>`:n.adopt!==void 0&&(!F(n.adopt)||!n.confirmSourceInactive)?i=`adoption requires an absolute source and --confirm-source-inactive`:n.new&&n.confirmSourceInactive&&(i=`--confirm-source-inactive requires --adopt`):i=`host init is available only on Linux`,!i)try{let e=await Sl((t.selectPaths??f)(),n.new?{kind:`new`}:{kind:`adopt`,source:n.adopt,confirmSourceInactive:!0},{...ht(),computerName:(t.hostname??_r)().replace(/\.local$/,``)||`Linux`}),i={status:e.status,next:`shellbell install`};console.log(r?JSON.stringify(i):` host state ${e.status}; run shellbell install to run Shellbell in the background`);return}catch{i=`Linux host initialization failed; inspect host state and runtime permissions. Existing or partial state is preserved; do not delete paired keys to retry. Use shellbell doctor for admission diagnostics.`}process.exitCode=2,r?console.log(JSON.stringify({error:i})):console.error(` ${i}`)})}function Rl(e){let t;try{t=ur(e,`r`);let n=Buffer.alloc(65536),r=pr(t,n,0,n.length,0),i=JSON.parse(n.subarray(0,r).toString(`utf8`)).version;return typeof i==`string`&&/^\d+\.\d+\.\d+/.test(i)?i:null}catch{return null}finally{t!==void 0&&rr(t)}}function zl(e=process.argv[1]??``){return I(P(P(e)),`package.json`)}function Bl(e){let t=e.now??Date.now,n=Rl(e.packageJson)??e.running,r=null,i=null,a=!1,o=setInterval(()=>{if(a)return;let o=Rl(e.packageJson),s=I(P(e.packageJson),`dist`,`cli.js`);if(!o||o===n||!ar(s)){r=null,i=null;return}if(o!==r){r=o,i=null;return}i??=t();let c=t()-i;e.busy()&&c<(e.graceMs??6e5)||(a=!0,e.log.info(`installed version changed; restarting`,{from:e.running,to:o}),e.restart(o))},e.intervalMs??6e4);return o.unref?.(),()=>{a=!0,clearInterval(o)}}const Vl=`https://github.com/bilal-/shellbell`,Hl=`https://api.github.com/repos/bilal-/shellbell`,Ul=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/,Wl=L.string().max(32).regex(Ul),Gl=L.string().regex(/^[a-f0-9]{64}$/),Kl=L.string().regex(/^[a-f0-9]{40}$/),ql=L.object({asset:L.string().max(160),sha256:Gl}).strict(),Jl=ql.extend({buildNumber:L.number().int().positive().max(2147483647),minimumOS:L.string().regex(/^\d{1,3}\.\d{1,3}(?:\.\d{1,3})?$/),signed:L.literal(!0),notarized:L.literal(!0)}).strict(),Yl=ql.extend({minimumGlibc:L.string().regex(/^[0-9]{1,6}\.[0-9]{1,6}$/)}).strict(),Xl=L.object({schemaVersion:L.literal(1),component:L.literal(`computer`),channel:L.literal(`stable`),version:Wl,tag:L.string().max(64),sourceCommit:Kl,platforms:L.object({macosArm64:Jl.optional(),macosHeadless:ql.optional(),linuxArm64:Yl.optional(),linuxX64:Yl.optional()}).strict()}).strict(),Zl=L.object({tag_name:L.string(),draft:L.boolean(),prerelease:L.boolean(),assets:L.array(L.object({name:L.string(),digest:L.string().nullable(),size:L.number().int().nonnegative(),browser_download_url:L.string()})).max(100)});function Ql(e,t){Wl.parse(e),Wl.parse(t);let n=e.split(`.`).map(BigInt),r=t.split(`.`).map(BigInt);for(let e=0;e<3;e++){if(n[e]<r[e])return-1;if(n[e]>r[e])return 1}return 0}function $l(e,t){if(!e.startsWith(`shellbell@`)||!Ul.test(e.slice(10)))throw Error(`Invalid computer release tag`);if(!/^[A-Za-z0-9._-]+$/.test(t))throw Error(`Invalid release asset name`);return`${Vl}/releases/download/${encodeURIComponent(e)}/${t}`}var eu=class{request;constructor(e=fetch){this.request=e}async bytes(e,t,n){let r=await this.response(e,n),i=[],a=0;if(!r.body)throw Error(`Empty release response`);let o=r.body.getReader();try{for(;;){let{done:e,value:n}=await o.read();if(e)break;if(a+=n.length,a>t)throw Error(`Release response exceeds its size limit`);i.push(n)}}finally{await o.cancel()}return Buffer.concat(i,a)}async response(e,t){let n=new URL(e);if(!(n.origin===`https://api.github.com`&&n.pathname.startsWith(`/repos/bilal-/shellbell/`))&&!(n.origin===`https://github.com`&&n.pathname.startsWith(`/bilal-/shellbell/releases/download/`)))throw Error(`Untrusted release URL`);for(let e=0;e<=3;e++){if(n.protocol!==`https:`||n.port!==``||n.username||n.password||![`api.github.com`,`github.com`,`release-assets.githubusercontent.com`,`objects.githubusercontent.com`].includes(n.hostname))throw Error(`Untrusted release redirect`);let r=await this.request(n.href,{redirect:`manual`,signal:t,headers:{Accept:`application/vnd.github+json`,"User-Agent":`Shellbell-update-check`}});if([301,302,303,307,308].includes(r.status)){let t=r.headers.get(`location`);if(await r.body?.cancel(),!t||e===3)throw Error(`Invalid release redirect`);n=new URL(t,n);continue}if(!r.ok)throw await r.body?.cancel(),Error(r.status===403||r.status===429?`GitHub is limiting update checks. Try again later.`:`Update lookup failed (HTTP ${r.status})`);return r}throw Error(`Too many release redirects`)}async json(e,t){return JSON.parse(Buffer.from(await this.bytes(e,2097152,t)).toString(`utf8`))}async check(e,t){Wl.parse(e);let n=AbortSignal.timeout(3e4),r;if(t){if(Wl.parse(t),r=Zl.parse(await this.json(`${Hl}/releases/tags/${encodeURIComponent(`shellbell@${t}`)}`,n)),r.tag_name!==`shellbell@${t}`)throw Error(`Release tag mismatch`)}else{let e=[],t=!1;for(let r=1;r<=5;r++){let i=L.array(Zl).max(100).parse(await this.json(`${Hl}/releases?per_page=100&page=${r}`,n));if(e.push(...i.filter(e=>!e.draft&&!e.prerelease&&e.tag_name.startsWith(`shellbell@`)&&Ul.test(e.tag_name.slice(10)))),i.length<100){t=!0;break}}if(!t)throw Error(`Release history is too large; specify the computer version to check`);if(e.sort((e,t)=>Ql(t.tag_name.slice(10),e.tag_name.slice(10))),!e[0])throw Error(`No stable computer release is available`);r=e[0]}if(r.draft||r.prerelease)throw Error(`Only published stable computer releases can be installed`);let i=this.asset(r,`computer-release.json`,1048576),a=await this.bytes(i.browser_download_url,i.size,n);this.verify(a,i);let o=Xl.parse(JSON.parse(Buffer.from(a).toString(`utf8`)));if(o.tag!==r.tag_name||o.tag!==`shellbell@${o.version}`)throw Error(`Computer release metadata does not match its tag`);if(L.object({object:L.object({type:L.literal(`commit`),sha:Kl})}).parse(await this.json(`${Hl}/git/ref/tags/${encodeURIComponent(o.tag)}`,n)).object.sha!==o.sourceCommit)throw Error(`Computer release source does not match its tag`);let s={macosArm64:`Shellbell-${o.version}-arm64.dmg`,macosHeadless:`shellbell-${o.version}.tgz`,linuxArm64:`shellbell-${o.version}-linux-arm64.tar.gz`,linuxX64:`shellbell-${o.version}-linux-x64.tar.gz`},c={};for(let e of Object.keys(s)){let t=o.platforms[e];if(!t)continue;if(t.asset!==s[e])throw Error(`Unexpected computer release asset`);let n=this.asset(r,s[e],268435456);if(n.digest!==`sha256:${t.sha256}`)throw Error(`Computer artifact digest mismatch`);c[e]=n}if(!Object.keys(c).length)throw Error(`Computer release has no installable artifacts`);return{check:{schemaVersion:1,currentVersion:e,available:Ql(o.version,e)>0,releaseUrl:`${Vl}/releases/tag/${encodeURIComponent(o.tag)}`,release:o},assets:c}}asset(e,t,n){let r=e.assets.filter(e=>e.name===t),i=r[0];if(r.length!==1||!i||!i.digest||!/^sha256:[a-f0-9]{64}$/.test(i.digest)||i.size<1||i.size>n||i.browser_download_url!==$l(e.tag_name,t))throw Error(`Missing or invalid release asset: ${t}`);return{...i,digest:i.digest}}verify(e,t){if(e.byteLength!==t.size||`sha256:${R(`sha256`).update(e).digest(`hex`)}`!==t.digest)throw Error(`Downloaded artifact does not match the published digest`)}};const tu=Wr(tr);function nu(e){let t=e.stderr.split(`
|
|
37
|
+
`).filter(e=>e.startsWith(`Shellbell staging directory: `));return[e.stdout.trim(),...t].filter(Boolean).join(`
|
|
38
|
+
`)}function ru(e,t){let n=/^\d{1,3}\.\d{1,3}(?:\.\d{1,3})?$/;if(!n.test(e.trim())||!n.test(t))throw Error(`Could not verify the release's macOS requirement`);let r=e.trim().split(`.`).map(Number),i=t.split(`.`).map(Number);if(([0,1,2].map(e=>(r[e]??0)-(i[e]??0)).find(e=>e!==0)??0)<0)throw Error(`This release requires macOS ${t} or later`)}function iu(e,t){let n=/^glibc ([0-9]{1,6})\.([0-9]{1,6})\s*$/.exec(e),r=/^([0-9]{1,6})\.([0-9]{1,6})$/.exec(t);if(!n||!r)throw Error(`Could not verify this release's glibc requirement; use the official manual installation guide`);let i=BigInt(n[1]),a=BigInt(n[2]),o=BigInt(r[1]),s=BigInt(r[2]);if(i<o||i===o&&a<s)throw Error(`This release requires glibc ${t} or later; the installed system has ${n[1]}.${n[2]}`)}async function au(e){let t=await B(e.cli);if(e.platform===`darwin`&&e.arch===`arm64`){let n=I(await B(e.home),`.local/share/shellbell/installs/darwin-arm64`,e.version);if(t===I(n,`Shellbell.app/Contents/Resources/agent/dist/cli.js`)&&await B(e.node)===I(n,`Shellbell.app/Contents/Helpers/node`)){let t=I(n,`installation.json`),r=await z(t);if(!r.isFile()||r.isSymbolicLink()||r.nlink!==1||r.uid!==process.getuid()||r.mode&3602||r.size>4096)throw Error(`Unsafe managed CLI installation receipt`);let i=JSON.parse(await zr(t,`utf8`));if(i.schema!==1||i.platform!==`darwin-arm64`||i.version!==e.version||!/^[a-f0-9]{64}$/.test(i.dmgSha256))throw Error(`Invalid managed CLI installation receipt`);return`mac-cli`}}if(e.platform===`darwin`&&t.includes(`/Shellbell.app/Contents/Resources/agent/dist/`))return`mac-app`;if(e.platform!==`linux`||![`arm64`,`x64`].includes(e.arch))return`other`;let n=I(await B(e.home),`.local/share/shellbell/installs`,`linux-${e.arch}`,e.version);return t!==I(n,`agent/dist/cli.js`)||await B(e.node)!==I(n,`runtime/bin/node`)?`other`:`linux-archive`}async function ou(e,t,n){let r=await e.response(t.browser_download_url,AbortSignal.timeout(18e4));if(!r.body)throw Error(`Empty update download`);let i=r.body.getReader(),a,o=0,s=R(`sha256`);try{for(a=await Lr(n,`wx`,384);;){let{done:e,value:n}=await i.read();if(e)break;if(o+=n.byteLength,o>t.size)throw Error(`Update download exceeds the published size`);s.update(n);let r=0;for(;r<n.byteLength;){let{bytesWritten:e}=await a.write(n,r,n.byteLength-r);if(!e)throw Error(`Could not write update download`);r+=e}}if(o!==t.size||`sha256:${s.digest(`hex`)}`!==t.digest)throw Error(`Update download does not match the published digest`)}finally{try{await i.cancel()}finally{await a?.close()}}}async function su(e){if(!process.stdin.isTTY)throw Error(`Use --yes to install an update without an interactive terminal, or --check to check only`);let t=Kr({input:process.stdin,output:process.stdout});try{return/^y(es)?$/i.test((await t.question(`Download and install Shellbell ${e}? Shellbell running in the background then restarts on it. [y/N] `)).trim())}finally{t.close()}}async function cu(e,t={}){let n=t.log??console.log,r=!1;try{r=(await(t.status??(async()=>Dl().status()))()).installed}catch{r=!1}if(!r)return n(`Run shellbell install to run it in the background. Shellbell running in a terminal window keeps the previous version until you start it again.`),!1;n(`Switching the background Shellbell to it. Your phone reconnects in a few seconds.`);let i=await(t.run??((e,t)=>new Promise(n=>{let r=nr(e,t,{stdio:[`ignore`,`inherit`,`inherit`]});r.once(`error`,()=>n(1)),r.once(`exit`,e=>n(e??1))})))(e,[`install`]);return i!==0&&n(`The background Shellbell couldn't switch. Run shellbell install to try again.`),i===0}function lu(e,t){e.command(`update [version]`).description(`check for a newer Shellbell, and install it when installed from shellbell.dev`).option(`--check`,`check only; do not download or install an app/archive`).option(`--yes`,`confirm installation without prompting`).action(async(n,r)=>{let i=!!e.opts().json;if(i&&!r.check)throw Error(`Use --check with --json; installation requires human-readable output`);let a=new eu,{check:o,assets:s}=await a.check(t,n);if(i){console.log(JSON.stringify(o));return}if(console.log(`Installed: ${t}. Latest stable computer release: ${o.release.version}.`),console.log(`Release notes: ${o.releaseUrl}`),!o.available){console.log(`No newer computer version is available.`);return}if(r.check)return;let c=await B(N()),l=await au({home:c,platform:process.platform,arch:process.arch,version:t,cli:process.argv[1],node:process.execPath});if(l===`mac-app`){console.log(`Open Shellbell → Settings → General → Check for Updates to download the official Mac installer.`);return}if(l!==`linux-archive`&&l!==`mac-cli`){console.log(`This installation is managed outside the CLI installer. Use its original installation method.`),process.platform===`darwin`&&console.log(`For a global npm installation, run: npm install -g shellbell@${o.release.version}. Shellbell running in the background switches to it by itself within a few minutes.`),console.log(`No files or services were changed.`),console.log(`Installation guide: https://github.com/bilal-/shellbell/blob/main/docs/install-agent.md`);return}let u=l===`mac-cli`?s.macosArm64:process.arch===`arm64`?s.linuxArm64:s.linuxX64;if(!u)throw Error(`This release has no archive for this computer's architecture`);let d=I(c,`.local/share/shellbell/installs`,`${process.platform}-${process.arch}`);if(l===`mac-cli`){let e=o.release.platforms.macosArm64;if(!e)throw Error(`Missing platform compatibility information`);ru((await tu(`/usr/bin/sw_vers`,[`-productVersion`],{env:{PATH:`/usr/bin:/bin`,LC_ALL:`C`},timeout:5e3,maxBuffer:1024})).stdout,e.minimumOS)}else{let e=process.arch===`arm64`?o.release.platforms.linuxArm64:o.release.platforms.linuxX64;if(!e)throw Error(`Missing platform compatibility information`);iu((await tu(`/usr/bin/getconf`,[`GNU_LIBC_VERSION`],{env:{PATH:`/usr/bin:/bin`,LC_ALL:`C`},timeout:5e3,maxBuffer:1024})).stdout,e.minimumGlibc)}if(await Vr(I(d,`current`))!==t)throw Error(`A different version is already selected; run ~/.local/bin/shellbell update instead`);let f=I(d,t,`install.sh`),p=await z(f);if(!p.isFile()||p.isSymbolicLink()||p.uid!==process.getuid()||p.mode&3602)throw Error(`The installed CLI's update bootstrap is unsafe; use the official manual installer`);if(!r.yes&&!await su(o.release.version)){console.log(`Update cancelled.`);return}let m=await Ir(I(vr(),`shellbell-update-`));try{let e=I(m,u.name);console.log(`Downloading Shellbell ${o.release.version}…`),await ou(a,u,e);let n=await tu(`/bin/sh`,[f,`--archive`,e,`--sha256`,u.digest.slice(7),`--update-from`,t,`--target-version`,o.release.version],{env:{HOME:c,PATH:`/usr/bin:/bin`,LANG:`C`},timeout:6e5,maxBuffer:65536});console.log(nu(n)),console.log(`Shellbell ${o.release.version} is installed.`),await cu(I(c,`.local/bin/shellbell`))}finally{await Hr(m,{recursive:!0,force:!0})}})}const Z=Kt,Q=new Dr().name(`shellbell`).version(Z).option(`--relay <url>`,`override relay url`).option(`--json`,`machine output`).option(`--verbose`,`debug logging`).option(`--insecure`,`allow a ws:// relay url (LAN dev only)`);lu(Q,Z);function $(e){let t=Q.opts(),n=e??X();return{opts:t,p:n,cfg:wt(n),log:Ke({file:n.log,verbose:t.verbose,stdout:process.stdout.isTTY&&!t.json})}}const uu=e=>`${e.slice(0,4)}-${e.slice(4,8)}`;function du(e,t){return fu(`\n Pair "${Mi(t)}"?\n Phone fingerprint ${ut(e)}\n Check that your phone shows the same fingerprint. [y/N] (60 s) `,6e4)}function fu(e,t,n=!1){return new Promise(r=>{let i=wr({input:process.stdin,output:process.stdout}),a=setTimeout(()=>{i.close(),console.log(`
|
|
39
|
+
(timed out — declined)`),r(!1)},t);i.question(e,e=>{clearTimeout(a),i.close();let t=e.trim();r(t===``?n:/^y(es)?$/i.test(t))})})}function pu(e){if(!e.length){console.log(` No coding agents found on this computer.`);return}for(let t of e)console.log(` ${t.name.padEnd(12)} ${on(t)}`)}async function mu(e){let t=fn(e),n=er(Yt(t));if(!n.length)return;let r=n.map(e=>e.name).join(`, `);console.log(`\n Get the most out of ${r} on your phone (highly recommended)\n Scroll back through a whole session, not just what's on screen, in text sized for your
|
|
40
|
+
phone. Shellbell adds a small helper to each agent. It only notes which window each
|
|
41
|
+
session runs in, and doesn't change how the agent works. Remove it with
|
|
42
|
+
\`shellbell agents remove <name>\`.`),n.some(e=>e.kind===`codex`)&&console.log(` Codex asks you to trust the helper the next time it starts. Choose Trust.`);let i=n.map(e=>e.kind);if(await fu(` Set up now? [Y/n] `,12e4,!0))try{pu(hn(t,i).filter(e=>i.includes(e.kind)))}catch(e){console.error(` ${e instanceof Error?e.message:String(e)}`)}else _n(t,i),console.log(" Skipped. Set up later with `shellbell agents setup`.")}function hu(e,t){console.log(`\n Computer ${e.computerName} (${uu(t)})\n Relay ${e.relayUrl}\n\n Scan this with the Shellbell app:\n`)}function gu(e){return new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`})}function _u(e,t){console.log(` Valid until ${gu(t)}\n`),kr.generate(e,{small:!0},e=>{console.log(e.split(`
|
|
43
|
+
`).map(e=>` ${e}`).join(`
|
|
44
|
+
`)),console.log(``)})}function vu(e,t,n){let r=ur(e,`r`);try{let e=or(r).size,i=Math.max(0,e-t),a=e-i,o=Buffer.alloc(a);a>0&&pr(r,o,0,a,i);let s=o.toString(`utf8`).replace(/\n$/,``);return s.length===0?``:s.split(`
|
|
45
|
+
`).slice(-n).join(`
|
|
46
|
+
`)}finally{rr(r)}}async function yu(e){try{return await ge(e,`status`),!0}catch(e){let t=e.code;return t!==`ECONNREFUSED`&&t!==`ENOENT`}}function bu(e,t,n,r=!0){return async(i,a)=>e.server?.hasNativePairOwner?e.server.nativePairingConfirm(i,a):r?t?!0:e.server?.hasPairClients?e.server.pairingConfirm(i,a):n(i,a):!1}async function xu(e,t,n=process.exit,r){r?.();let i=!1,a=e=>{i||(i=!0,n(e))},o=setTimeout(()=>a(1),5e3);typeof o.unref==`function`&&o.unref();try{e.stop(),await t.stop(),a(0)}finally{clearTimeout(o)}}function Su(e,t){if(t===void 0)return{cfg:e};let n=ne(t,!0);if(n)return{error:n};let r=new URL(t).protocol===`ws:`;return{cfg:{...e,relayUrl:t},warning:r?`insecure relay URL; for local testing only`:void 0}}async function Cu(e,t,n=!1,i={}){let a=i.paths??X(),o=i.nativeService?void 0:()=>Pt({stateDir:a.dir,uid:a.linuxHost?.uid??process.getuid(),serviceInstance:i.serviceInstance});o?.(),a.linuxHost&&(l(a),m(a)),an(a.dir),gn(fn(a.dir));let s=wt(a);if(t!==void 0){let e=Su(s,t);`error`in e&&(console.error(` --relay ${t}: ${e.error}`),process.exit(1)),e.warning&&console.error(` warning: ${e.warning}`),s=e.cfg}let{identity:c,fp:u}=r(a),d=new Ne(e),f=ac({paths:s.terminalPlugins??[],registry:d,log:e}),p=a.linuxHost?null:new Cs({recordPath:I(a.dir,`iterm2-access.json`),assumeApproved:(()=>{try{return _t(a).length>0}catch{return!1}})(),interactive:!i.nativeService&&!i.managedService&&process.stdin.isTTY===!0,socketPath:Kn}),h=a.linuxHost?null:i.itermBackend===void 0?new Ys(new Tn({log:e,cookieProvider:()=>p.cookieProvider(Zt)}),e):i.itermBackend,g={ready:!1,queue:[]},_=e=>{i.nativeService||(g.ready?console.log(e):g.queue.push(e))},v=()=>{g.ready=!0;for(let e of g.queue)console.log(e);g.queue=[]},y=null,b=null,x=!1,ee,te=async()=>{if(h&&!x)try{if(await h.connect(),x)return;d.add(h),ee=void 0;let t=await h.listSessions().catch(()=>[]);if(x)return;_(` iTerm2 connected · ${t.length} session${t.length===1?``:`s`}`),e.info(`iTerm2 connected`)}catch(t){if(x)return;let n=p?.issue??`failed`;if(n!==ee){ee=n;let r=Vn({name:`iterm2`,connected:!1,issue:n},`command-line`);_(` iTerm2 ${r.status}${r.fix?`\n ${r.fix}`:``}`),e.info(`iTerm2 not connected`,{issue:n,err:j(t)})}y=setTimeout(()=>void S(),1e4)}},S=()=>x?Promise.resolve():b||(y&&clearTimeout(y),y=null,b=te().finally(()=>{b=null}),b);h?.isConnected===!1&&d.add(h),h&&S();let C=!a.linuxHost&&i.itermBackend===void 0?cc(`iterm2`):null,ne=C?lc(`com.googlecode.iterm2`,C.available,{onChange:()=>d.notifySetupChanged()}):()=>void 0,re=h&&p?(()=>{let e=p.onChange(()=>d.notifySetupChanged()),t=Object.assign(e=>Ru(e,p,ne),{connect:()=>p.connect(async()=>{await b,d.connected().some(e=>e.name===`iterm2`)||await S()})}),n=d.registerSetupReporter(`iterm2`,t);return()=>{e(),n()}})():()=>{},ie=!a.linuxHost&&i.tmuxBackendOptions===void 0?hc():null,ae=async()=>{await C?.start(),await S();let e=p?.issue;if(e&&!d.connected().some(e=>e.name===`iterm2`)&&Cn({name:`iterm2`,connected:!1,issue:e})){let{status:t,fix:n}=Vn({name:`iterm2`,connected:!1,issue:e},`phone`);throw new nt(`${t} ${n??``}`.trim())}await dc(d,`iterm2`)},oe=i.terminalWindows??[...ie?[ie]:[],...h&&C?[gc({iterm:h,available:C.available,log:e,ready:async()=>{if(d.connected().some(e=>e.name===`iterm2`)||await ae(),d.member(`iterm2`)!==h)throw new T(`iTerm2 was replaced`,`Reconnect your computer.`)}})]:[]],se=_l({registry:d,log:e,onConnected:e=>_(` tmux connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>_(` tmux not running`),backendOptions:i.tmuxBackendOptions,terminalWindows:oe}),ce=a.linuxHost?null:(i.startHerdr??Jt)({registry:d,log:e,onConnected:e=>_(` herdr connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>_(` herdr not running (optional)`),...i.herdrBackendOptions?{backendOptions:i.herdrBackendOptions}:{}}),ue=()=>{re(),f.stop(),x=!0,y&&clearTimeout(y),y=null},de=[];h&&C&&de.push(d.registerSessionLauncher(`iterm2`,{available:C.available,start:async()=>(await ae(),{backend:h})}));let fe=!a.linuxHost&&i.startHerdr===void 0?uc():null;if(fe){de.push(d.registerSessionLauncher(`herdr`,{available:fe.available,start:async()=>{await fe.start(),await dc(d,`herdr`);let e=d.member(`herdr`);if(!e)throw new T(`Herdr unavailable`,`Check Herdr's local API.`);return{backend:e}}}));for(let e of oe)de.push(d.registerHostedLauncher({backend:`herdr`,host:e.id,label:e.label},{available:()=>{let t=d.member(`herdr`);return e.available()&&(t instanceof Pn&&t.isConnected?t.terminalAttachExecutable!==void 0:sn()!==void 0)},unavailableReason:()=>{let t=d.member(`herdr`);return e.available()&&t instanceof Pn?t.terminalAttachIssue:void 0},create:async(t,n,r,i)=>{let a=t instanceof Pn?t.terminalAttachExecutable:void 0;if(!a||!(t instanceof Pn))throw new T(`Herdr terminal attach is unavailable`,`Use matching Herdr CLI/server versions, 0.9.3 or newer.`);let{terminalId:o,workspaceId:s}=await t.createWorkspace(),c=`window`;return await mc(async()=>{if(d.member(`herdr`)!==t||t.terminalAttachExecutable!==a)throw new T(`Herdr was disconnected before the terminal could open`,`Reconnect Herdr and try again.`);if(c=await e.launch({executable:a,...r?{initialSize:r}:{},...i?.tab&&{tab:!0},args:[`terminal`,`attach`,o],environment:{HERDR_SOCKET_PATH:t.terminalSocketPath}}),!await t.waitForVisibleAttach(o))throw new T(`terminal window did not attach`,`Unlock your computer and try again.`)},async()=>{if(!s)throw Error(`Herdr workspace id unknown`);await t.closeWorkspace(s)}),{sessionId:o,opened:c}}}))}let pe=()=>{for(let e of de)e();ue(),se.stop(),ce?.stop()},w={server:null},me;return me=new xs({paths:a,config:s,identity:c,fp:u,registry:d,log:e,appVersion:Z,serviceInstance:i.serviceInstance??null,confirm:bu(w,n,(e,t)=>du(e,t),!i.nativeService),onPairingClosed:e=>{w.server?.notifyClosed(e),i.onPairingClosed?.(e)},onSuperseded:()=>{i.nativeService||console.log(` another shellbell agent took over; exiting`),w.server?xu(me,w.server,()=>process.exit(0),pe).catch(()=>process.exit(1)):process.exit(0)}}),w.server=new le(a.sock,me,e,a.pid,o,!i.nativeService&&!i.managedService?e=>Ze({stateDir:a.dir,uid:a.linuxHost?.uid??process.getuid()},e):void 0,i.nativeService?`native`:`terminal`),{agent:me,control:w.server,p:a,cfg:s,fp:u,releaseOutput:v,stopFirstConnect:ue,stopBackendDetectors:pe,herdr:ce}}async function wu(e){let t;try{t=o(e.service===!0)}catch(e){console.error(` ${e.message}`),process.exit(1)}let{opts:n,p:r,log:i}=$(e.paths),{agent:a,control:s,cfg:c,fp:l,releaseOutput:u,stopBackendDetectors:d}=await Cu(i,n.relay,!1,{serviceInstance:t,managedService:e.service===!0,paths:r});try{await s.start()}catch(e){console.error(` ${e.message}`),process.exit(1)}if(a.start(),console.log(`\n Shellbell ${Z}\n Computer ${c.computerName} (${uu(l)})`),console.log(` Relay ${c.relayUrl} ${a.relayOnline?`connected`:`connecting…`}`),a.relay.on(`auth-ok`,()=>console.log(` Relay ${c.relayUrl} connected`)),a.relay.on(`down`,()=>console.log(` Relay ${c.relayUrl} connecting…`)),console.log(` tmux detecting…`),r.linuxHost||console.log(` herdr detecting…`),u(),!e.service&&process.stdin.isTTY&&!n.json&&await mu(r.dir),a.pairingList.length===0&&!e.service&&process.stdin.isTTY){console.log(`
|
|
47
|
+
No phones paired yet. Scan this with the Shellbell app:
|
|
48
|
+
`);let{qrText:e,expiresAt:t}=a.openPairing();_u(e,t)}let f=!1,p=()=>{if(f){console.error(` forcing exit`),process.exit(130);return}f=!0,xu(a,s,process.exit,d).catch(()=>process.exit(1))};process.on(`SIGINT`,p),process.on(`SIGTERM`,p),e.service&&Bl({running:Z,packageJson:zl(),busy:()=>a.connectedPhones.some(e=>e.viewed!==null),log:i,restart:()=>{f||(f=!0,xu(a,s,()=>process.exit(75),d).catch(()=>process.exit(75)))}}),!e.service&&process.stdin.isTTY&&!n.json&&console.log(`\n ${Tu}`)}const Tu="Shellbell is running in this window, so your phone can reach this computer until you close it or press Ctrl-C. Run `shellbell install` to keep Shellbell running in the background instead.",Eu=`
|
|
49
|
+
Run Shellbell in the background? (highly recommended)
|
|
50
|
+
Your phone can then reach this computer whenever it's on and you're logged in, without a
|
|
51
|
+
terminal window open. [Y/n] `;function Du(){if(process.platform!==`darwin`)return!1;let e=pt({stateDir:X().dir,uid:process.getuid()});return e&&console.log(` ${e}`),e!==null}function Ou(){return process.platform===`linux`?f():ot()}async function ku(e){if(!e.linuxHost)return;let t=null;try{t=(await new Sn({env:process.env}).installedRuntime())?.stateDir??null}catch{}await El(e,{installedStateDir:t})}async function Au(e){try{return await yu((e??X()).sock)}catch{return!1}}async function ju(){try{return(await ge(X().sock,`status`)).process?.serviceInstance===null}catch{return!1}}async function Mu(){if(process.platform===`darwin`||process.platform===`linux`)try{return await Dl().status()}catch{return}}function Nu(){return{background:()=>Dl(),version:Z,offerAgents:async()=>{process.stdin.isTTY&&await mu(X().dir)},afterInstall:async()=>{if(!process.stdin.isTTY)return;let{p:e}=$();_t(e).length===0&&await Pu(!1)},otherCopyRunning:ju,appOwned:Du}}async function Pu(e){let{p:t,cfg:n}=$(),{fp:i}=r(t),a;try{a=await ge(t.sock,`status`)}catch{a=void 0}return new Promise(r=>{let o=``,s=fe(t.sock,{onOpen:(e,t)=>{hu(n,i),_u(e,t)},onRequest:async(t,n)=>{let r=e||await du(t,n);return r&&(o=Mi(n)),r},onClose:e=>{clearTimeout(c),e===`replaced`?console.log(` This code has been replaced by a newer one. Scan the new code instead.`):e===`paired`?a?.process?.serviceInstance===null?console.log(` Paired with ${o||`your phone`}. Shellbell is running in a terminal window, so your phone can reach this computer only while that window stays open. Run \`shellbell install\` to keep it running in the background.`):console.log(` Paired with ${o||`your phone`}. You're all set.`):console.log(` pairing window closed`),s.close(),r(e===`paired`?0:1)},onError:e=>{clearTimeout(c),console.error(` ${e.message}`),r(1)}}),c=setTimeout(()=>{s.close(),r(1)},301e3)})}async function Fu(e,t,n){let{p:r,log:i}=$(n),a=!1,o,s,c=e=>s?void xu(s.agent,s.control,()=>process.exit(e),s.stopBackendDetectors).catch(()=>process.exit(1)):process.exit(e);s=await Cu(i,t.relay,e,{paths:r,onPairingClosed:e=>{if(e!==`paired`){a||(console.log(` pairing window closed`),c(0));return}a=!0,clearTimeout(o);let t=s?.agent.pairingList.at(-1)?.name;console.log(` Paired with ${t?Mi(t):`your phone`}.\n\n ${Tu}`)}});let{agent:l,control:u,cfg:d,fp:f,releaseOutput:p}=s;try{await u.start()}catch(e){console.error(` ${e.message}`),process.exit(1)}l.start();let{qrText:m,expiresAt:h}=l.openPairing();hu(d,f),_u(m,h),p(),o=setTimeout(()=>c(0),301e3);let g=!1,_=()=>{g&&process.exit(130),g=!0,c(0)};process.on(`SIGINT`,_),process.on(`SIGTERM`,_)}Q.command(`start`,{isDefault:!0}).description(`start Shellbell, offering to run it in the background`).addOption(new Or(`--service`,`the background service's own entry`).hideHelp()).action(async e=>{if(e.service)return wu(e);let t=!!Q.opts().json;if(Du())return;let n=Nu(),r=await Mu();if(r?.installed){process.exitCode=await Fl(n,t);return}let i=Ou();if(await Au(i)){console.log(` Shellbell is already running in a terminal window.`);return}if(r?.available&&process.stdin.isTTY&&!t){if(console.log(`
|
|
52
|
+
Shellbell isn't set up to run in the background on this computer yet.`),await fu(Eu,12e4,!0)){process.exitCode=await Ml(n,t);return}}else r&&!r.available&&!t&&console.log(` ${Ol}`);return await ku(i),wu({paths:i})}),Q.command(`run`).description(`run Shellbell in this window only, for containers and testing`).action(async()=>{if(Du())return;let e=Ou();return await ku(e),wu({paths:e})}),Q.command(`pair`).description(`pair a phone: shows a QR code to scan with the Shellbell app`).option(`--yes`,`auto-accept requests (unsafe on shared screens)`).action(async e=>{let t=Q.opts(),n=!!e.yes;if(Du())return;let r=Ou();if(await Au(r)){process.exitCode=await Pu(n);return}let i=await Mu(),a=Nu();if(i?.installed){await Fl(a,!!t.json)===0?process.exitCode=await Pu(n):process.exitCode=2;return}if(i?.available&&process.stdin.isTTY&&!t.json){if(console.log(`
|
|
53
|
+
Shellbell isn't running in the background on this computer yet.`),await fu(Eu,12e4,!0)){let e=await Ml({...a,afterInstall:void 0},!1);process.exitCode=e===0?await Pu(n):e;return}}else process.stdin.isTTY||console.error(" Shellbell isn't running in the background, so this pairing lasts only while this command runs. Run `shellbell install` first.");await ku(r),await Fu(n,t,r)});const Iu={iterm2:`iTerm2`,tmux:`tmux`,herdr:`Herdr`};Q.command(`status`).description(`show whether Shellbell is running, and its phones and terminals`).action(async()=>{let e=!!Q.opts().json,t=null,n=null,r;try{if(process.platform===`darwin`||process.platform===`linux`){let e=Dl();n=e.system,t=await e.status()}}catch(e){r=kl(e)}let i=null;try{i=await ge(X().sock,`status`)}catch{i=null}if(process.exitCode=i?0:2,e){console.log(JSON.stringify({background:t,running:i,...r?{backgroundError:r}:{}}));return}if(Du())return;if(r&&console.log(` ${r}`),!i){for(let e of t&&n?Al(t,n):["Shellbell isn't running. Run `shellbell start`."])console.log(` ${e}`);return}if(t?.running&&n)for(let e of Al(t,n))console.log(` ${e}`);else console.log(` Shellbell ${i.process.agentVersion} is running in a terminal window, so it stops when that window closes. Run \`shellbell install\` to keep it running in the background.`);i.process.agentVersion!==Z&&console.log(i.process.serviceInstance?` Shellbell ${Z} is installed, but ${i.process.agentVersion} is still running. Run \`shellbell install\` to switch now.`:` Shellbell ${Z} is installed. Stop the copy in the terminal window and start it again to use it.`);let a=new Set(i.connected.map(e=>e.phoneFp)),o=i.phones.map(e=>`${Mi(e.name)}${a.has(e.phoneFp)?` (connected)`:``}`),s=i.backends.filter(e=>e.connected).map(e=>Iu[e.name]??e.name);console.log(` Phones ${o.join(`, `)||"none yet. Run `shellbell pair`."}`),console.log(` Terminals ${s.join(`, `)||"none ready. Run `shellbell doctor` to see why."}`),console.log(` Relay ${i.relayOnline?`connected`:`connecting…`}`)});function Lu(e){let t=e?.code;console.error(t===`ENOENT`||t===`ECONNREFUSED`?" Shellbell isn't running. Run `shellbell start`.":`shellbell: ${e instanceof Error?e.message:`control request failed`}`),process.exitCode=2}Q.command(`phones`).alias(`devices`).description(`list paired phones`).action(async()=>{let{opts:e,p:t}=$(),n=_t(t),r=new Set;try{let e=await ge(t.sock,`status`);r=new Set(e.connected.map(e=>e.phoneFp))}catch{}if(e.json){console.log(JSON.stringify(n.map(e=>({phoneFp:e.phoneFp,name:e.name,pairedAt:e.pairedAt,lastSeenAt:e.lastSeenAt,connected:r.has(e.phoneFp)}))));return}n.length||console.log(" No phones paired yet. Run `shellbell pair`.");for(let e of n)console.log(` ${Mi(e.name).padEnd(20)} ${r.has(e.phoneFp)?`connected`:e.lastSeenAt?`last seen ${new Date(e.lastSeenAt).toLocaleString()}`:`not seen yet`} ${uu(e.phoneFp)}`)});function Ru(e,t,n){if(e)return{};if(t.connecting)return{issue:`connecting`};let r=t.issue??`not-running`;return r===`not-running`&&n()===!1?{issue:`not-installed`}:{issue:r}}async function zu(e,t,n={}){let r=n.log??console.log,i=await e.connectTerminal(t);if(!i)return r(` Update Shellbell on this computer to connect terminals from the command line.`),2;if(!i.started)return r(` ${t} has no connection step. Run shellbell doctor to see its status.`),2;r(` macOS may ask to let Shellbell control iTerm2, and iTerm2 may ask to allow Shellbell.`);let a=Date.now()+(n.timeoutMs??13e4),o=i.terminals;for(;o.find(e=>e.name===t)?.issue===`connecting`&&Date.now()<a;)await new Promise(e=>setTimeout(e,n.pollMs??500)),o=await e.terminals()??o;let s=o.find(e=>e.name===t);if(!s)return 2;let{status:c,fix:l}=Vn(s,`command-line`);return r(` ${c}`),l&&r(` ${l}`),s.connected&&!s.issue?0:2}Q.command(`connect <terminal>`).description(`connect a terminal that needs your approval, such as iterm2`).action(async e=>{let{p:t}=$(),n;try{n=await te(t.sock),process.exitCode=await zu(n,e)}catch(e){Lu(e)}finally{n?.close()}}),Q.command(`agents [action] [name]`).description(`list coding agents, or set them up for full history: agents [setup [name] | remove <name>]`).action((e,t)=>{let{opts:n,p:r}=$(),i=fn(r.dir);if(!(e===void 0||e===`setup`||e===`remove`&&t!==void 0)){process.exitCode=2,console.error(` usage: shellbell agents [setup [name] | remove <name>]`);return}try{let r=Yt(i),a=t&&r.find(e=>[e.kind,e.name.toLowerCase()].includes(t.toLowerCase()))?.kind;if(t&&!a){process.exitCode=2,console.error(` Shellbell didn't find ${t} on this computer.`);return}let o=e===`setup`?hn(i,a?[a]:void 0):e===`remove`?tn(i,a):r;n.json?console.log(JSON.stringify({agents:o})):pu(o),e===void 0&&!n.json&&er(o).length&&console.log("\n Run `shellbell agents setup` for full history on your phone.")}catch(e){process.exitCode=2,console.error(` ${e instanceof Error?e.message:String(e)}`)}}),Q.command(`integration <action> <agent>`,{hidden:!0}).action((e,t)=>{if(t!==`codex`||![`install`,`uninstall`,`status`].includes(e)){process.exitCode=2,console.error(` usage: shellbell agents [setup [name] | remove <name>]`);return}let n=fn($().p.dir);try{pu((e===`install`?hn(n,[`codex`]):e===`uninstall`?tn(n,`codex`):Yt(n)).filter(e=>e.kind===`codex`))}catch(e){process.exitCode=2,console.error(` ${e instanceof Error?e.message:String(e)}`)}}),Q.command(`unpair <target>`).description(`remove a paired phone (fp prefix or name)`).action(async e=>{let{p:t}=$();try{let n=await ge(t.sock,`unpair`,{target:e});console.log(n.removed?` removed`:` no such phone`)}catch(e){Lu(e)}}),Il(Q,Nu()),Q.command(`logs`).option(`-f, --follow`).description(`show Shellbell's log`).action(e=>{let{p:t}=$();e.follow?nr(`tail`,[`-f`,t.log],{stdio:`inherit`}):ar(t.log)&&process.stdout.write(vu(t.log,65536,200))});function Bu(e,t){process.exitCode=2,t?console.log(JSON.stringify({error:e})):console.error(` ${e}`)}Q.command(`config`).description(`config set <${Ae.join(`|`)}> <value>`).argument(`<op>`).argument(`<key>`).argument(`<value>`).action(async(e,t,n)=>{let r=Q.opts();if(e!==`set`){Bu(`unknown config operation ${e} (expected set)`,r.json);return}let i=!!r.insecure||process.env.SHELLBELL_ALLOW_INSECURE_RELAY===`1`,a=Tt(ht(),t,n,i);if(`error`in a){Bu(a.error,r.json);return}let o=!1,s=!0;try{let e=X(),r=It(e,e=>{let r=Tt(e,t,n,i);if(`error`in r)throw Error(r.error);return r.next});if(t===`conversations`){let t;try{if(t=await te(e.sock),t.runtime.stateDir===mr(e.dir)){let e=await t.applyConversationSetting(_(r));o=e!==null,s=e!==_(r)}}catch{}finally{t?.close()}}}catch(e){Bu(e instanceof Error?e.message:String(e),r.json);return}r.json?console.log(JSON.stringify({saved:!0,restartRequired:s,...t===`conversations`?{conversationApplied:o}:{}})):console.log(t===`conversations`&&!o?` configuration saved; live conversation consent could not be confirmed. Restart the agent if it is running.`:s?o?` conversation consent applied; other saved settings still need an agent restart`:` configuration saved; the running agent must be restarted`:` conversation consent saved and applied to the running agent`)});function Vu(e,t,n=console.log,r=e=>{process.exitCode=e}){let i=Rn(e);if(t)n(JSON.stringify(e));else for(let t of e)n(` ${t.severity===`pass`?`✓`:t.severity===`warning`?`!`:`✗`} ${t.name.padEnd(18)} ${t.detail}${t.fix?`\n fix: ${t.fix}`:``}`);r(i)}function Hu(e,t={}){e.command(`doctor`).description(`check Shellbell, the relay and terminals without changing anything`).option(`--require-backend [name]`,`treat a disconnected backend as an error (repeatable)`,(e,t)=>[...t,typeof e==`string`?e:``],[]).action(async n=>{let r=!!e.opts().json,i=new Set(Array.isArray(n.requireBackend)?n.requireBackend:[``]);if([...i].some(e=>!Ie.some(t=>t===e))){let e={name:`doctor arguments`,ok:!1,severity:`error`,detail:`invalid required backend name`,fix:`use iterm2, tmux, or herdr`};console.log(r?JSON.stringify([e]):` ✗ ${e.name} ${e.detail}\n fix: ${e.fix}`),process.exitCode=2;return}let a=Ie.filter(e=>i.has(e)),o=t.env??process.env,s;try{s=await(t.runDoctor??Mn)({requestedStateDir:o.SHELLBELL_DIR,defaultStateDir:t.defaultStateDir??I(N(),`.shellbell`),requiredBackends:a,env:o,version:Z})}catch{s=[{name:`doctor`,ok:!1,severity:`error`,detail:`diagnostic inspection failed`}]}Vu(s,r)})}Hu(Q),Ll(Q);function Uu(e,t,n=mr){if(!e)return!1;let r;try{r=n(e)}catch{r=e}let i=Tr(t),a;try{a=n(i)}catch{a=i}return a===r}Uu(process.argv[1],import.meta.url)&&Q.parseAsync().catch(e=>{e instanceof Error&&!Q.opts().verbose?console.error(` ${e.message.replace(/^shellbell: /,``)}`):console.error(e),process.exit(1)});export{Ae as CONFIG_KEYS,Tu as IN_THIS_WINDOW,Hu as addDoctorCommand,Cu as buildAgent,bu as chooseConfirm,zu as connectTerminalCommand,Ru as iTermSetupReport,Uu as isEntryPoint,gu as pairValidUntil,Vu as printDoctorResult,Q as program,Tt as resolveConfigSet,Su as resolveRelayOverride,xu as shutdown,yu as socketAlive,vu as tailFile,ne as validateRelayUrl};
|