shellbell 0.7.0 → 0.9.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 CHANGED
@@ -1,44 +1,48 @@
1
1
  #!/usr/bin/env node
2
- import{$ as e,$t as t,A 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,Gt as y,Hn as b,Ht as x,It as S,J as C,Jt as w,K as ee,Kt as te,Ln as ne,Lt as re,M as ie,Mn as ae,Mt as oe,N as se,Nn as ce,Nt as le,On as T,Ot as ue,Pn as de,Pt as fe,Q as E,Qt as pe,R as me,Rn as he,Rt as ge,Sn as _e,St as D,Tn as ve,Tt as O,U as ye,Ut as be,V as xe,Vn as Se,Vt as Ce,W as we,Wt as Te,X as k,Xt as Ee,Y as De,Yt as Oe,Z as ke,Zt as Ae,_n as je,_t as Me,a as Ne,an as Pe,at as Fe,bn as Ie,bt as Le,cn as Re,ct as ze,d as Be,dn as Ve,dt as He,en as Ue,et as We,fn as Ge,ft as Ke,gn as qe,gt as Je,hn as Ye,ht as Xe,in as Ze,it as Qe,j as $e,jn as A,jt as et,k as tt,kn as nt,kt as rt,l as it,ln as at,lt as ot,mn as st,mt as ct,n as lt,nn as ut,o as dt,on as ft,ot as pt,pn as mt,pt as ht,q as j,qt as gt,r as _t,rn as vt,rt as yt,s as bt,sn as xt,st as St,t as Ct,tn as wt,tt as M,u as Tt,un as Et,ut as Dt,vn as Ot,vt as kt,wn as At,wt as jt,xn as Mt,xt as Nt,yn as Pt,yt as Ft,z as It,zn as Lt,zt as Rt}from"./service-lifecycle-CcyJ7m6L.js";import{execFile as zt,spawn as Bt}from"node:child_process";import{accessSync as Vt,closeSync as Ht,constants as N,existsSync as Ut,fstatSync as Wt,fsyncSync as Gt,linkSync as Kt,lstatSync as qt,mkdirSync as Jt,openSync as Yt,opendirSync as Xt,readFileSync as Zt,readSync as Qt,readdirSync as $t,readlinkSync as en,realpathSync as tn,renameSync as nn,statSync as rn,statfsSync as an,symlinkSync as on,unlinkSync as sn,writeFileSync as cn}from"node:fs";import{homedir as P,hostname as ln}from"node:os";import{basename as un,delimiter as dn,dirname as F,isAbsolute as I,join as L,relative as fn,resolve as pn,sep as mn}from"node:path";import{createInterface as hn}from"node:readline";import{fileURLToPath as gn,pathToFileURL as _n}from"node:url";import{z as R}from"zod";import{Command as vn}from"commander";import yn from"qrcode-terminal";import{createHash as bn,randomUUID as xn,timingSafeEqual as Sn}from"node:crypto";import{EventEmitter as Cn}from"node:events";import{connect as wn,createConnection as Tn,isIP as En}from"node:net";import Dn from"ws";import{StringDecoder as On}from"node:string_decoder";import{isDeepStrictEqual as kn,promisify as An}from"node:util";import{create as z,fromBinary as jn,toBinary as Mn}from"@bufbuild/protobuf";import{fileDesc as Nn,messageDesc as B}from"@bufbuild/protobuf/codegenv2";import{importTerminalPlugin as Pn}from"#terminal-plugin-loader";import{performance as Fn}from"node:perf_hooks";const In=e=>/^turns?:/.test(e),Ln=e=>!/:53(\?|$)/.test(e);function Rn(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=>In(e)&&Ln(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 zn=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 Rn(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)}};const Bn=[[768,879],[1155,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1552,1562],[1611,1631],[1648,1648],[1750,1756],[1759,1764],[1767,1768],[1770,1773],[1809,1809],[1840,1866],[1958,1968],[2070,2093],[2304,2306],[2362,2362],[2364,2364],[2369,2376],[2381,2381],[2385,2391],[2402,2403],[3633,3633],[3636,3642],[3655,3662],[6832,6911],[7616,7679],[8203,8207],[8232,8238],[8288,8292],[8400,8432],[65024,65039],[65056,65071],[65279,65279],[127995,127999],[917760,917999]],Vn=[[4352,4447],[8986,8987],[9001,9002],[9193,9196],[9200,9200],[9203,9203],[9725,9726],[9748,9749],[9800,9811],[9855,9855],[9875,9875],[9889,9889],[9898,9899],[9917,9918],[9924,9925],[9934,9934],[9940,9940],[9962,9962],[9970,9971],[9973,9973],[9978,9978],[9981,9981],[9989,9989],[9994,9995],[10024,10024],[10060,10060],[10062,10062],[10067,10069],[10071,10071],[10133,10135],[10160,10160],[10175,10175],[11035,11036],[11088,11088],[11093,11093],[11904,12350],[12353,13311],[13312,19903],[19968,40959],[40960,42191],[43360,43391],[44032,55203],[63744,64255],[65040,65049],[65072,65135],[65280,65376],[65504,65510],[94176,94180],[94208,101119],[110592,111359],[126980,126980],[127183,127183],[127374,127374],[127377,127386],[127488,127569],[127744,127776],[127789,127797],[127799,127868],[127870,127891],[127904,127946],[127951,127955],[127968,127984],[127988,127988],[127992,128062],[128064,128064],[128066,128252],[128255,128317],[128331,128334],[128336,128359],[128378,128378],[128405,128406],[128420,128420],[128507,128591],[128640,128709],[128716,128716],[128720,128722],[128725,128727],[128747,128748],[128756,128764],[128992,129003],[129292,129338],[129340,129349],[129351,129535],[129648,129791],[131072,196605],[196608,262141]];function Hn(e,t){let n=0,r=t.length-1;for(;n<=r;){let i=n+r>>1,a=t[i];if(e<a[0])r=i-1;else if(e>a[1])n=i+1;else return!0}return!1}function Un(e){return e===0||e<32||e>=127&&e<160||Hn(e,Bn)?0:Hn(e,Vn)?2:1}function Wn(e){let t=0,n=!1,r=0;for(let i of e){let e=i.codePointAt(0);if(e===8205){n=!0;continue}let a=Un(e);if(a!==0||n){if(n){r=Math.max(r,a),n=!1;continue}t+=r,r=a}}return t+r}function Gn(e,t){let n={t:e},r=t.fg,i=t.bg;if(t.inv){let e=r??15;r=i??0,i=e}r!==void 0&&(n.fg=r),i!==void 0&&(n.bg=i),t.b&&(n.b=!0),t.i&&(n.i=!0),t.u&&(n.u=!0),t.s&&(n.s=!0),t.f&&(n.f=!0);let a=Wn(e);return a!==re(e)&&(n.n=a),n}function Kn(e){return Math.max(0,Math.min(255,e|0))}function qn(e,t){let n=e[t];if(n.length>1){let e=n[1],t=n.slice(2);if(e===5&&t.length>=1)return{color:Kn(t[0]),consumed:0};if(e===2){let e=t.length>=4?t.slice(1,4):t.slice(0,3);if(e.length===3)return{color:[Kn(e[0]),Kn(e[1]),Kn(e[2])],consumed:0}}return{consumed:0}}let r=e[t+1]?.[0];return r===5&&e[t+2]?{color:Kn(e[t+2]?.[0]??0),consumed:2}:r===2&&e[t+4]?{color:[Kn(e[t+2]?.[0]??0),Kn(e[t+3]?.[0]??0),Kn(e[t+4]?.[0]??0)],consumed:4}:{consumed:0}}function Jn(e,t){let n={...e},r=(t===``?[`0`]:t.split(`;`)).map(e=>e.split(`:`).map(e=>e===``?0:Number(e)));for(let e=0;e<r.length;e++){let t=r[e]?.[0]??0;if(t===0)for(let e of Object.keys(n))delete n[e];else if(t===1)n.b=!0;else if(t===2)n.f=!0;else if(t===3)n.i=!0;else if(t===4)n.u=!0;else if(t===7)n.inv=!0;else if(t===9)n.s=!0;else if(t===22)delete n.b,delete n.f;else if(t===23)delete n.i;else if(t===24)delete n.u;else if(t===27)delete n.inv;else if(t===29)delete n.s;else if(t>=30&&t<=37)n.fg=t-30;else if(t===39)delete n.fg;else if(t>=40&&t<=47)n.bg=t-40;else if(t===49)delete n.bg;else if(t>=90&&t<=97)n.fg=t-90+8;else if(t>=100&&t<=107)n.bg=t-100+8;else if(t===38||t===48){let{color:i,consumed:a}=qn(r,e);i!==void 0&&(t===38?n.fg=i:n.bg=i),e+=a}}return n}function Yn(e){let t=[],n={},r=``,i=0,a=()=>{r&&t.push(Gn(r,n)),r=``},o=0;for(;o<e.length;){let t=e[o];if(t===`\x1B`){let i=e[o+1];if(i===`[`){let i=o+2,s=``;for(;i<e.length&&i-(o+2)<32;){let t=e.charCodeAt(i);if(t>=64&&t<=126)break;s+=e[i],i++}if(i>=e.length||i-(o+2)>=32){r+=t,o++;continue}e[i]===`m`&&(a(),n=Jn(n,s)),o=i+1;continue}if(i===`]`){let t=o+2;for(;t<e.length&&e[t]!==`\x07`&&(e[t]!==`\x1B`||e[t+1]!==`\\`);)t++;o=e[t]===`\x07`?t+1:t+2;continue}o+=i===void 0?1:2,(i===`(`||i===`)`)&&(o+=1);continue}let s=e.charCodeAt(o);if(t===` `){let e=8-i%8;r+=` `.repeat(e),i+=e,o++;continue}if(s<32||s===127){o++;continue}let c=e.codePointAt(o);r+=String.fromCodePoint(c),i+=Un(c),o+=c>65535?2:1}return a(),{r:x(s(t))}}function Xn(e){return e.issue!==void 0&&[`needs-consent`,`automation-denied`,`iterm2-denied`,`timed-out`,`too-old`,`failed`,`limited`].includes(e.issue)}const Zn={iterm2:`iTerm2`,tmux:`tmux`,herdr:`Herdr`};function Qn(e,t){let n=Zn[e.name]??e.name;if(e.connected&&!e.issue)return{status:`Connected. Ready for your paired phone.`};if(t===`phone`)return Xn(e)?{status:`${n} needs one more step on your Mac.`,fix:`Open Shellbell → Settings → Terminals on that Mac, or run shellbell doctor there.`}:{status:`${n} isn't connected right now.`};let r=t===`mac-app`?`Click Connect iTerm2.`:`Run shellbell connect iterm2.`;switch(e.issue){case`not-installed`:return{status:`Shellbell couldn't find ${n}. Optional.`,...e.name===`tmux`?{fix:`Install tmux 3.2 or newer, for example: brew install tmux`}:{}};case`not-running`:return e.name===`iterm2`?{status:`iTerm2 isn't open. Open it to see its tabs on your phone.`}:{status:`${n} isn't running.`,fix:`In any terminal, run: ${e.name}`};case`no-session`:return{status:`No tmux session is running.`,fix:`In any terminal, run: tmux`};case`api-off`:return{status:`Turn on iTerm2's Python API to connect.`,fix:`In iTerm2, open Settings → General → Magic and turn on Enable Python API.`};case`needs-consent`:return{status:`Ready to connect.`,fix:`${r} macOS will ask to let Shellbell control iTerm2, and iTerm2 may ask to allow Shellbell. Allow both. Your paired phone can then read and type in your iTerm2 tabs.`};case`connecting`:return{status:`Finish connecting in the macOS or iTerm2 dialog.`};case`automation-denied`:return{status:`macOS is blocking Shellbell from iTerm2.`,fix:`Open System Settings → Privacy & Security → Automation, find Shellbell (or node, for the background service) and turn on iTerm2.`};case`iterm2-denied`:return{status:`iTerm2 is blocking Shellbell.`,fix:`In iTerm2, open Settings → General → Magic and check who may use the Python API. Then ${r.charAt(0).toLowerCase()}${r.slice(1)}`};case`timed-out`:return{status:`Connecting wasn't finished.`,fix:`Check for an open macOS or iTerm2 dialog, then try again. ${r}`};case`too-old`:return e.name===`iterm2`?{status:`Update iTerm2 to connect.`,fix:`Shellbell needs iTerm2 3.3 or newer.`}:e.name===`tmux`?{status:`Shellbell needs tmux 3.2 or newer.`,fix:`Update tmux, for example: brew upgrade tmux`}:{status:`Update ${n} to connect.`};case`limited`:return{status:`Viewing and typing work. Opening new sessions from your phone doesn't.`,...e.detail?{fix:e.detail}:{}};default:return{status:`Shellbell couldn't connect to ${n}.`,fix:e.name===`iterm2`?`Try again. ${r}`:`Shellbell keeps trying.`}}}var $n=class extends Cn{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`}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},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);n.promptState=`running`,n.commandStartedAt=t,n.command=e.command;return}case`command-end`:{let n=this.get(e.sessionId);n.promptState=`finished`;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,n.promptState=`editing`,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,n.promptState=`running`,n.workingSince=t;return}if(e.state===`blocked`){n.promptState=`blocked`,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`){n.promptState=`finished`;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.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 er(e){return e===`darwin`||e===`linux`||e===`win32`?e:`unknown`}const tr=new Set([`sh`,`bash`,`zsh`,`fish`,`dash`,`ksh`,`pwsh`,`powershell`,`cmd`]),nr=new Set([`ssh`,`mosh`,`docker`,`podman`,`kubectl`,`wsl`]);function rr(e){return un(e??``).replace(/^-/,``).replace(/\.exe$/i,``)}function ir(e,t,n){let r=rr(t),i=tr.has(r)?r:void 0,a=r===`claude`?`Claude`:r===`codex`?`Codex`:void 0,o=nr.has(r);return{...e,shell:i,agentName:a,locality:o?`guest`:n===`local-process`&&(i||a)?`local`:`unknown`,revision:JSON.stringify([e.sessionId,e.cwd,e.title,e.sessionLabel,r,n])}}function V(e,t){if(e===void 0)return;let n=e.replace(/[\r\n\t\u2028\u2029]+/gu,` `).replace(/[\p{Cc}\p{Cs}\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/gu,``).replace(/\s+/gu,` `).trim();if(/(?:^|[\s("'=:])(?:\/|~[\\/]|[a-z]:[\\/])|\\\\|[a-z][a-z0-9+.-]*:\/\/|[^\s@]+@[^\s:]+:/iu.test(n))return;let r=``,i=0;for(let e of n){let n=Buffer.byteLength(e,`utf8`);if(i+n>t)break;i+=n,r+=e}return r||void 0}function ar(e,t){return[...[`Desktop`,`Documents`,`Downloads`].map(e=>L(t,e)),L(t,`Library`,`Mobile Documents`),L(t,`Library`,`CloudStorage`),`/Volumes`].some(t=>{let n=fn(t,e);return n===``||!n.startsWith(`..${mn}`)&&n!==`..`&&!I(n)})}function or(e={}){let t=e.now??Date.now,n=e.platform??process.platform,r=e.home??P(),i=new Map,a=0,o=new Set;async function s(e){if(e.aborted||o.size>=32)throw Error(`git context unavailable`);if(a>=2?await new Promise((t,n)=>{let r=()=>{o.delete(i),n(Error(`git context unavailable`))},i=()=>{o.delete(i),e.removeEventListener(`abort`,r),a+=1,t()};o.add(i),e.addEventListener(`abort`,r,{once:!0})}):a+=1,e.aborted)throw--a,o.values().next().value?.(),Error(`git context unavailable`);return()=>{--a,o.values().next().value?.()}}let c={NODE_ENV:`production`,PATH:process.env.PATH,SystemRoot:process.env.SystemRoot,GIT_CONFIG_NOSYSTEM:`1`,GIT_CONFIG_GLOBAL:process.platform===`win32`?`NUL`:`/dev/null`,GIT_CONFIG_COUNT:`0`,GIT_TERMINAL_PROMPT:`0`,GIT_OPTIONAL_LOCKS:`0`,GIT_NO_REPLACE_OBJECTS:`1`},l=(e,t,n)=>new Promise((r,i)=>{zt(`git`,[`-c`,`core.fsmonitor=false`,`-C`,e,...t],{env:c,encoding:`utf8`,signal:n,timeout:250,killSignal:`SIGKILL`,maxBuffer:8192,windowsHide:!0},(e,t)=>e?i(e):r(t.trim()))});return async(e,a)=>{if(!I(e)||e.length>1024||a.aborted||n===`darwin`&&ar(e,r))return;let o=t();for(let[e,t]of i)(o<t.observedAt||o-t.observedAt>=5e3)&&i.delete(e);let c=i.get(e);if(c)return c;let u=new AbortController,d=()=>u.abort();a.addEventListener(`abort`,d,{once:!0});let f=setTimeout(d,250),p;try{p=await s(u.signal);let t=await l(e,[`rev-parse`,`--show-toplevel`],u.signal),n;try{n=await l(e,[`symbolic-ref`,`--quiet`,`--short`,`HEAD`],u.signal)}catch(e){!u.signal.aborted&&e.code===1&&(n=`detached HEAD`)}if(u.signal.aborted)return;let r=V(un(t),256);if(!r)return;let a={repository:r,branch:V(n,256),observedAt:o};return i.size>=500&&i.delete(i.keys().next().value),i.set(e,a),a}catch{return}finally{clearTimeout(f),a.removeEventListener(`abort`,d),p?.()}}}async function sr(e,t){let n=t.now(),r=new AbortController,i,a=new Promise(e=>{i=setTimeout(()=>{r.abort(),e(void 0)},250)}),o=async()=>{if(!await Promise.race([Promise.resolve().then(()=>t.stillCurrent(e)),a]))throw Error(`stale notification context`)};try{await o();let i;e.locality===`local`&&e.cwd&&I(e.cwd)&&(i=await Promise.race([Promise.resolve().then(()=>t.git(e.cwd,r.signal)).catch(()=>void 0),a]));let s=t.stillCurrent(e);if(typeof s==`boolean`?!s:!await Promise.race([s,a]))throw Error(`stale notification context`);let c={computerName:V(t.computerName,128)??`Computer`,sessionLabel:V(e.sessionLabel,128)??`Session`,observedAt:Math.min(n,i?.observedAt??n)};for(let[t,n]of[[`customName`,256],[`title`,256],[`shell`,64],[`agentName`,64]]){let r=V(e[t],n);r&&(c[t]=r)}let l=V(i?.repository,256),u=V(i?.branch,256);return l&&(c.repository=l),l&&u&&(c.branch=u),c}finally{clearTimeout(i),r.abort()}}function cr(e){return{type:`notify`,sessionId:e.sessionId,kind:e.kind,exitCode:e.exitCode,durationMs:e.durationMs}}function lr(e){let t={...e,context:{...e.context}};for(let e of[`branch`,`title`,`agentName`,`shell`,`customName`,`repository`]){if(Ve.safeParse(t).success)return t;delete t.context[e]}return Ve.safeParse(t).success?t:void 0}var ur=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(cr(e))},250)}),c=Promise.race([this.build(e,()=>i||performance.now()-a>=250,r),s]).catch(()=>cr(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>=at.freshnessMs)return cr(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}:cr(e)});return this.cache.set(e,l),l()}async build(e,t,n){let i=this.options,a=i.now??Date.now,o=cr(e);if(!i.capable()||!e.reason)return o;let s=r(p(16)),c=i.pairings().slice(0,10),l=await i.facts(e.sessionId);if(!l||t())return o;let u=async()=>{let t=await i.facts(e.sessionId);return t?.revision===l.revision&&t.sessionId===l.sessionId},d=await sr(l,{computerName:i.computerName(),now:a,stillCurrent:u,git:i.git});if(t()||!i.capable()||!await u()||t())return o;let f=a();if(f-n>=at.freshnessMs||f<n||f<d.observedAt)return o;let m=[],h={type:`notify-context`,sessionId:e.sessionId,eventId:s,kind:e.kind,exitCode:e.exitCode,durationMs:e.durationMs,boxes:m};for(let r of c){if(t())break;if(!i.pairings().some(e=>e.phoneFp===r.phoneFp&&e.kPair===r.kPair))continue;let a=i.state.reserve(r.phoneFp);if(!a)continue;let o=lr({computerFp:i.computerFp,phoneFp:r.phoneFp,generation:a.generation,sessionId:e.sessionId,eventId:s,sequence:a.sequence,issuedAt:f,expiresAt:n+at.freshnessMs,reason:e.reason,context:d,exitCode:e.exitCode,durationMs:e.durationMs});if(!o)continue;let c,l;try{c=T(r.kPair),l=te(c,o),m.push(gt(l,o)),Buffer.byteLength(JSON.stringify(h),`utf8`)>16384&&m.pop()}catch{}finally{c?.fill(0),l?.fill(0)}}return m.length?h:o}};const dr=R.string().regex(/^(0|[1-9][0-9]{0,19})$/).refine(e=>BigInt(e)<=18446744073709551615n),fr=R.strictObject({generation:Et,used:R.number().int().min(0).max(at.encryptions)}),pr=R.strictObject({version:R.literal(1),phones:R.array(R.strictObject({phoneFp:g,sequence:dr,current:fr,previous:R.strictObject({generation:Et,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 mr=class{paths;now;data={version:1,phones:[]};healthy=!0;file;constructor(e,t=Date.now){this.paths=e,this.now=t,this.file=L(e.dir,`notifications.json`);try{Fe(e);let t=L(e.dir,`notifications.initialized`),n=O(t)!==void 0;if(n&&l(t,8,process.getuid?.()).toString(`utf8`)!==`v1
3
- `)throw Error(`invalid marker`);try{this.data=pr.parse(JSON.parse(l(this.file,16384,process.getuid?.()).toString(`utf8`)))}catch(e){if(n||!(e instanceof D&&e.kind===`missing`))throw e;if(!this.commit(this.data))return}n||(He(t,`v1
4
- `),this.syncDirectory())}catch{this.healthy=!1}}syncDirectory(){if(process.platform===`win32`)return;let e=Yt(this.paths.dir,`r`);try{Gt(e)}finally{Ht(e)}}commit(e){if(!this.healthy)return!1;try{return Fe(this.paths),He(this.file,JSON.stringify(e)),this.syncDirectory(),this.data=e,!0}catch{return this.healthy=!1,!1}}enroll(e,t){if(!this.healthy||!g.safeParse(e).success||!Et.safeParse(t).success)return!1;let n=this.data.phones.find(t=>t.phoneFp===e);if(n?.current.generation===t)return n.current.used<at.encryptions;if(n?.previous?.generation===t||!n&&this.data.phones.length>=10)return!1;let r=structuredClone(this.data);return r.phones=r.phones.filter(t=>t.phoneFp!==e),r.phones.push({phoneFp:e,sequence:n?.sequence??`0`,current:{generation:t,used:0},...n?{previous:{generation:n.current.generation,expiresAt:this.now()+at.previousGenerationMs}}:{}}),this.commit(r)}reserve(e){if(!this.healthy)return;let t=structuredClone(this.data),n=t.phones.find(t=>t.phoneFp===e);if(!(!n||n.current.used>=at.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}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){let t=structuredClone(this.data);t.phones=t.phones.filter(t=>t.phoneFp!==e),this.commit(t)}};const hr=6e4;var gr=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>=hr&&this.last.delete(n);return n!==void 0&&t-n<hr?!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(cr(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 _r(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 vr=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 yr=R.instanceof(Uint8Array).refine(e=>e.length===32,{message:`expected 32 bytes`}),br=R.instanceof(Uint8Array).refine(e=>e.length===64,{message:`expected 64 bytes`});function xr(e){return e.replace(/[\p{Cc}\p{Cs}\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/gu,` `).replace(/\s+/gu,` `).trim()||`Phone`}const Sr=R.object({ed25519Pub:yr,x25519Pub:yr,name:R.string().min(1).max(64).transform(xr),platform:R.enum([`ios`,`android`]),bind:br});var Cr=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();let e=p(16),t=p(16),n=this.now()+(this.opts.windowMs??3e5),i=be({v:1,r:this.opts.relayUrl,c:this.opts.fp,e:r(this.opts.identity.ed25519.pub),n:this.opts.computerName.slice(0,40),p:r(e),g:r(t),b:1});Te(i,{allowInsecure:!0}),this.window={code:e,gate:t,expiresAt:n,failures:0,requests:0};let a=this.opts.sendCtrl({type:`pairing-open`,gateHash:ve(t),expiresAt:n});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: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:ve(this.window.gate),expiresAt:this.window.expiresAt});this.log.debug(e?`pairing window re-advertised`:`pairing window re-advertise dropped`)}closeWindow(){if(!this.window)return;let e=this.window;e.code.fill(0),e.gate.fill(0),this.window=null,this.pending?.window===e&&(this.pending=null),this.opts.sendCtrl({type:`pairing-close`}),this.log.info(`pairing window closed`),this.opts.onClose?.()}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=st(n.code,this.opts.fp),a;try{if(a=Sr.parse(Se(Pt(i,e.box,Ie(`request`,this.opts.fp,e.phoneFp)))),Ye(a.ed25519Pub)!==e.phoneFp)throw Error(`fp mismatch`);let t=Mt(`phone`,this.opts.fp,e.phoneFp,a.x25519Pub);if(!At(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=mt(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}this.opts.savePairing({phoneFp:e.phoneFp,name:a.name,platform:a.platform,ed25519Pub:r(a.ed25519Pub),x25519Pub:r(a.x25519Pub),kPair:r(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:ft(l)});let u=_e(i,b({x25519Pub:this.opts.identity.x25519.pub,computerName:this.opts.computerName,accent:this.opts.accent,bind:c(this.opts.identity.ed25519.priv,Mt(`computer`,this.opts.fp,e.phoneFp,this.opts.identity.x25519.pub))}),Ie(`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 wr=e=>!/^turns:/.test(e)&&!/[?&]transport=tcp(?:&|$)/.test(e);function Tr(e){return e.flatMap(e=>e.urls.filter(wr).map(t=>e.username&&e.credential?t.replace(/^(turns?):/,`$1:${encodeURIComponent(e.username)}:${encodeURIComponent(e.credential)}@`):t))}function Er(e){let t=e.trim().replace(/%.*$/,``).toLowerCase();if(En(t)!==6)return t;try{return new URL(`http://[${t}]/`).hostname.slice(1,-1)}catch{return t}}function Dr(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:Er(t[4]),type:t[7]}}function Or(e,t={}){let n=t.turn!==!1;return t=>kr(t,Tr(n?e():Rn()),n)}Or(()=>Rn());const kr=async(e,t,n=!0)=>{let{default:r}=await import(`node-datachannel`),i=new r.PeerConnection(`shellbell-v2`,{iceServers:t}),a=null,o=!1,s=new Set,c=new Set,l=()=>{let e=i.getSelectedCandidatePair();if(!e||e.local.type===`relay`||e.remote.type===`relay`)return!1;let t=Er(e.remote.address);return s.has(t)&&!c.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(l()){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){if(!n){let t=Dr(e);if(!t)return;if(t.type===`relay`){c.add(t.address);return}(t.type===`host`||t.type===`srflx`)&&s.add(t.address)}i.addRemoteCandidate(e,t??`0`)},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=nt(t.value.replaceAll(`:`,``));if(!u(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 Ar=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;constructor(e){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??Or(e.iceServers??(()=>Rn()),{turn:e.turn}),allowDirect:!0,terminal:(t,n)=>{let r;try{r=wt(Se(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)}),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(b(e))}relayLost(){this.endpoint.relayLost()}close(){this.broken=!0,this.handshaken=!1,this.endpoint.close()}};const jr=new Set([`bad-sig`,`fp-mismatch`]),Mr=A.unacked*A.envelopeBytes;function Nr(e){if(e.t!==`ctrl`)return!1;let t=e.body;return typeof t==`object`&&!!t&&t.type===`auth`}function Pr(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 Fr(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 Ir=class extends Cn{opts;ws=null;stopped=!0;attempt=0;reconnectTimer=null;pingTimer=null;pongTimer=null;authed=!1;relayWithholdsTurn=!1;ice=new zn;log;constructor(e){super(),this.opts=e,this.log=e.log.child({unit:`relay`})}get online(){return this.authed&&this.ws?.readyState===Dn.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&&!Nr(e)?(this.log.debug(`dropped send: not authenticated`,{type:Pr(e)}),!1):this.ws?.readyState===Dn.OPEN?(this.ws.send(e.v===2?Lt(e):he(e),{binary:!0}),!0):(this.log.debug(`dropped send: socket not open`,{type:Pr(e)}),!1)}sendBoundedEnvelope(e){let t=this.ws;if(!this.authed||t?.readyState!==Dn.OPEN)return!1;let n=e.v===2?Lt(e):he(e);if(n.byteLength>A.envelopeBytes)return!1;let r=t.bufferedAmount;return typeof r!=`number`||!Number.isFinite(r)||r<0||r>Mr-n.byteLength?!1:(t.send(n,{binary:!0}),!0)}connect(){if(this.stopped)return;let e=y(this.opts.relayUrl,this.opts.fp);this.log.info(`connecting`,{attempt:this.attempt});let t=new Dn(e,{handshakeTimeout:1e4}),n=t;this.ws=t,t.on(`open`,()=>{this.ws===n&&this.log.debug(`socket open`)}),t.on(`message`,(e,t)=>{if(this.ws!==n||!t)return;let r=new Uint8Array(e),i;try{i=ne(r)}catch(e){this.log.warn(`malformed frame from relay`,{code:e instanceof o?e.code:M(e)});return}if(i.t===`e2e`){this.authed&&this.emit(`e2e`,i,r.byteLength);return}let a;try{a=Pe(i.body)}catch(e){this.log.warn(`malformed ctrl from relay`,{code:e instanceof o?e.code:M(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:M(e)})})}onCtrl(e){if(e.type===`challenge`){let t=c(this.opts.identity.ed25519.priv,Ge(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.ice=new zn,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}),jr.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=Fr(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===Dn.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.reconnectTimer=this.pingTimer=this.pongTimer=null}},Lr=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(!ae.safeParse(e.subscriptionId).success||!de.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 oe({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=fe(i);if(!a.ok)return this.close(a.code),!1;n=a.bytes}else{let{type:t,sessionId:r,...i}=e;n=le(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>=A.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>A.envelopeBytes||!ce.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>=A.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+A.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=_({...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()+A.progressMs}catch{this.close(`invalid-transfer`);return}if(this.open&&this.nativeHistory===e)try{Rr(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 k?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&&(Rr(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+A.progressMs),this.refusalAt!==null&&e.push(this.refusalAt+A.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`)}terminate(e){if(e!==`session-gone`&&e!==`invalid-transfer`)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 Rr(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{Rr(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{Rr(this.options.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,code:e}))}catch{}try{Rr(this.options.onClosed(e))}catch{}}};function Rr(e,t){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>t?.())}const zr=new TextEncoder;var Br=class{options;sender;open=!0;sending=!1;chunkAdmitted=!1;generation=0;state=null;backlog=[];backlogBytes=0;offset=0;behind=!1;reseedRequested=!1;historyLines=2e3;constructor(e){this.options=e,this.sender=new oe({subscriptionId:e.subscriptionId,sessionId:e.sessionId,now:()=>this.readClock(),newTransferId:()=>e.newTransferId(),send:e=>this.admitChunk(e)});let{source:t}=e;t.on(`seed`,e=>{if(!this.open)return;let n=zr.encode(e.data);if(n.length>A.screenBytes){this.historyLines>1?(this.historyLines=Math.max(1,Math.floor(this.historyLines/2)),t.reseed(this.historyLines)):this.close(`invalid-transfer`);return}this.generation=e.generation,this.state={cols:e.cols,rows:e.rows,bytes:n},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.ready()}}),t.on(`end`,e=>this.close(Vr(e)))}start(){return 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>A.envelopeBytes||!ce.safeParse(e).success){this.close(`invalid-transfer`);return}if(e.type===`stream.cancel`){this.cancel();return}if(e.type===`stream.refresh`){this.requestReseed();return}if(e.type===`stream.history.get`){this.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,requestId:e.requestId,code:`history-unavailable`});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.ready()}sendOne(){if(this.sending||(this.tick(),!this.open))return!1;this.sending=!0;try{return this.sender.canOffer(`vt`)&&this.offerNext(),this.open?(this.sender.pump(),this.reconcileSender(),this.chunkAdmitted):!1}catch{return this.close(`invalid-transfer`),!1}finally{this.chunkAdmitted=!1,this.sending=!1}}tick(){if(this.open)try{this.reconcileSender()}catch{this.close(`invalid-transfer`)}}nextDeadline(){return this.open?this.sender.nextDeadline():null}cancel(){this.close(`cancelled`)}terminate(e){this.close(e)}offerNext(){if(this.state){let{cols:e,rows:t,bytes:n}=this.state;this.sender.offer({kind:`vt-state`,generation:this.generation,cols:e,rows:t},n).accepted&&(this.state=null);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),t}sendControl(e){try{this.options.sendControl(e)}catch{}}close(e){if(this.open){this.open=!1,this.sender.cancel(),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 Vr(e){return e===`pane-gone`?`session-gone`:`unsupported`}const Hr=.6;var Ur=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 Wr(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:M(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{Wr(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:M(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 k)this.log.warn(`getScreen: session gone; dropping`,{session:n.slice(0,12)}),this.sessionRemoved(n);else{this.log.warn(`getScreen failed; will retry`,{session:n.slice(0,12),err:M(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}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:M(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:M(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;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 k)this.sessionRemoved(e);else{this.log.warn(`getScreen failed; will retry`,{session:e.slice(0,12),err:M(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{Wr(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(Rt),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&&Gr(o,t.lastKeys,0)>Hr*s){let e=Kr(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>Hr*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,x,S=()=>(v??={type:`screen.snapshot`,...g,cols:n.cols,rows:n.rows,lines:n.lines,reset:l||void 0},v),C=()=>{if(!x&&(x={...S(),lines:n.lines.map(Ce),degraded:!0},!t.oversizeWarned)){let n=b(x).byteLength;n>_&&(this.log.warn(`screen.snapshot exceeds maxEncodedBytes even after stripStyles`,{session:e.slice(0,12),bytes:n,maxEncodedBytes:_}),t.oversizeWarned=!0)}return x},w=e=>e?C():(y??=b(S()).byteLength,y>_?C():S()),ee={type:`screen.diff`,...g,scroll:c,changed:d},te=Object.freeze({generation:t.gen,reported:t.reported,historyRequested:i}),ne=Object.freeze({...te,...n.historyCapture?{capture:n.historyCapture}:{}});t.prepared={gen:t.gen,diff:h?.diff??ee,forceSnapshotAll:h?.forceSnapshotAll??(u||p),snapshotFor:w,fullSnapshot:S,snapshotContext:ne,diffContext:h?.diffContext??te,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:M(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 Wr(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}function Gr(e,t,n){let r=0;for(let i=0;i<e.length;i++)t[i+n]!==e[i]&&r++;return r}function Kr(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 qr=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){if(e.length===0)throw RangeError(`wire scheduler key must not be empty`);let n=Symbol(),r={identity:n,sendOne:t};return this.registrations.set(e,r),()=>this.remove(e,n)}pump(){if(this.pumping)return 0;this.pumping=!0;try{this.refill();let e=this.ownership,t=[...this.registrations],n=0;for(;t.length>0&&this.tokens>=1&&this.ownership===e;){let r=[];for(let[i,a]of t){if(this.tokens<1||this.ownership!==e)break;if(this.registrations.get(i)===a){this.registrations.delete(i),this.registrations.set(i,a),--this.tokens;try{let e=a.sendOne();if(e===!0)n++,r.push([i,a]);else if(e===!1)this.tokens+=1;else throw Jr(e),TypeError(`wire producer must return a synchronous boolean`)}catch(e){this.remove(i,a.identity);try{Jr(this.onError?.(e))}catch{}}}}t=r}return n}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)}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 Jr(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}var Yr=class{options;tracker;scheduler;entries=new Map;viewerOwners=new Map;attachTokens=new Map;started=!1;lifecycle=0;pumping=!1;timer=null;timerEpoch=0;nextViewer=0;constructor(e){if(!(e.backend instanceof ee))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 qr({now:()=>this.options.now(),onError:()=>this.notifyError()}),this.tracker=new Ur({backend:this.options.backend,log:this.options.log,now:()=>this.options.now(),delivery:`scheduled`,onReady:()=>{this.pump()},onSessionGone:(e,t)=>this.sessionGone(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();let e=[...this.entries.values()];this.entries.clear();for(let t of e)t.unregister();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:()=>{},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(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),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}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<=A.envelopeBytes){let e=ce.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))return;if(r.stream=new Lr({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){if(!this.options.backend.capabilitiesOf(t.sessionId)?.vtStream)return!1;let r;try{r=new Br({subscriptionId:t.subscriptionId,sessionId:t.sessionId,source:this.options.backend.openVtStream(t.sessionId),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?(r.cancel(),!0):(t.stream=r,e.view=t,this.viewerOwners.set(t.trackerKey,{entry:e,view:t}),r.start().catch(()=>r.terminate(`invalid-transfer`)),this.arm(),!0)}produce(e){if(!this.current(e))return!1;try{let t=e.view;return!t||(t.stream instanceof Lr&&t.stream.canOfferScreen()&&this.tracker.offerPrepared(t.trackerKey,(e,n)=>e.type!==`screen.snapshot`&&e.type!==`screen.diff`?!1:t.stream instanceof Lr&&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.dropView(e),this.arm())}sessionGone(e,t){let n=[];for(let r of t){let t=this.viewerOwners.get(r);t&&t.view.sessionId===e&&this.current(t.entry)&&t.entry.view===t.view&&(this.viewerOwners.delete(r),t.entry.view=null,n.push(t))}for(let{entry:e,view:t}of n)e.closingView=t,t.stream.terminate(`session-gone`),e.closingView===t&&(e.closingView=null);if(n.length>0)try{Xr(this.options.onSessionGone?.(e))}catch{}this.arm()}notifyError(){try{Xr(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)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 Xr(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}const Zr=`\\u2800-\\u28FF\\u25D0-\\u25D3\\u2722\\u2733\\u2736\\u273B\\u273D\\u00B7\\u2022*`,Qr=RegExp(`^[${Zr}][${Zr}\\uFE0F]*\\s+(?=\\S)`,`u`),$r=/^[⠀-⣿]/u,ei=/^v?\d+(?:\.\d+)+$/;function ti(e){return e.trim().replace(Qr,``)}function ni(e){let t=e?.trim()??``;return Qr.test(t)}function ri(e){let t=e?.trim().toLowerCase()??``;return/^claude(?:[- ]code)?$/.test(t)?`claude`:/^codex(?:[- ]cli)?$/.test(t)?`codex`:V(t,32)}function ii(e,t){let n=rr(e).toLowerCase();if(n===`claude`||n===`codex`)return n;if(n!==``&&n!==`node`&&!ei.test(n)||!ni(t))return;let r=t?.trim()??``;return $r.test(r)&&/ \| [^|]+$/.test(r)?`codex`:`claude`}function ai(e,t=P()){if(!e)return;let n=e=>e.replace(/[\\/]+$/,``);return t&&n(e)===n(t)?`~`:V(n(e).split(/[\\/]/).pop(),128)}const oi=new Set([...tr,`claude`,`codex`,`node`,`tmux`,`[tmux]`]);function si(e,t){let n=e.trim();if(n&&n!==t&&!n.endsWith(`[dead]`)&&!(oi.has(n.toLowerCase())||ei.test(n)))return V(n,128)}function ci(e){let t=rr(e).toLowerCase();return!t||nr.has(t)?!1:tr.has(t)||t===`claude`||t===`codex`||t===`node`||ei.test(t)}function li(e,t,n){if(!e)return;let r=ti(e.replace(/[\r\n\t]+/g,` `));if(n.command){let e=` (${n.command})`;r.endsWith(e)&&(r=r.slice(0,-e.length).trimEnd())}let i=/ \| ([^|]+)$/.exec(r);i&&(t===`codex`||i[1]?.trim()===n.project||i[1]?.trim()===n.folder)&&(r=r.slice(0,i.index).trimEnd());let a=V(r,256);if(!a)return;let o=a.toLowerCase();if(![t,`claude`,`claude code`,`codex`,...n.ignore??[]].some(e=>e.toLowerCase()===o))return a}function ui(e,t){return e.project===t.project&&e.agent?.kind===t.agent?.kind&&e.agent?.task===t.agent?.task}function di(e,t,n){let r={};return e&&(r.project=e),t&&(r.agent=n?{kind:t,task:n}:{kind:t}),r}function fi(e){let t=ai(e.cwd),n=V(e.project,128)??t,r=ii(e.processName,e.title);if(!r)return di(n,void 0);let i=rr(e.processName);return di(n,r,li(e.title,r,{project:n,folder:t,command:i||void 0,ignore:e.ignore}))}function pi(e,t){let n=ai(e.foreground_cwd??e.cwd??void 0),r=V(t,128)??n,i=ri(e.agent||e.display_agent||void 0);return i?di(r,i,li(e.label||e.terminal_title_stripped||e.terminal_title||void 0,i,{project:r,folder:n,ignore:e.display_agent?[e.display_agent]:[]})):di(r,void 0)}var mi=class{git;onChange;now;known=new Map;pending=new Set;constructor(e,t,n=Date.now){this.git=e,this.onChange=t,this.now=n}get size(){return this.known.size}lookup(e){if(!I(e)||e.length>1024)return;let t=this.known.get(e),n=this.now();return(!t||n<t.at||n-t.at>=3e4)&&this.refresh(e,t?.project),t?.project??void 0}refresh(e,t){if(this.pending.has(e)||this.pending.size>=16)return;this.pending.add(e);let n=new AbortController,r;try{r=this.git(e,n.signal)}catch{r=Promise.resolve(void 0)}r.catch(()=>void 0).then(n=>{let r=V(n?.repository,128)??null;for(this.known.delete(e);this.known.size>=256;){let e=this.known.keys().next().value;if(e===void 0)break;this.known.delete(e)}this.known.set(e,{project:r,at:this.now()}),r!==(t??null)&&this.onChange()}).finally(()=>{this.pending.delete(e),n.abort()})}};function hi(e,t=ut){let n=e=>b({type:`sessions`,list:e}).length<=t,r=[({agent:e,...t})=>e?{...t,agent:{kind:e.kind}}:t,({project:e,windowLabel:t,agent:n,...r})=>r,({project:e,windowLabel:t,agent:n,cwd:r,title:i,...a})=>({...a,title:Array.from(i).slice(0,gi).join(``)})];if(n(e))return{type:`sessions`,list:e};let i=e;for(let t of r)if(i=e.map(t),n(i))return{type:`sessions`,list:i};let a=0,o=i.length;for(;a<o;){let e=Math.ceil((a+o)/2);n(i.slice(0,e))?a=e:o=e-1}return{type:`sessions`,list:i.slice(0,a)}}const gi=64;function _i(e){return`no conn.hello within ${e/1e3}s; ignoring this link until one arrives`}var vi=class{o;relay;views;viewLeases=new Map;events;notifier;notificationState;notificationRelayCapable=!1;relayWithheldTurn=!1;pairing;links=new Map;connByFp=new Map;pairings;pairRequests=new Map;sessions=[];tick=null;sessionsDebounce=null;sessionsRefreshes=0;sessionsPublished=0;lastSeenSavedAt=new Map;log;localProcess;projects;stopped=!1;get configurationRevision(){return xe(this.o.config)}backendsKey=null;constructor(e){this.o=e,e={...e,config:Object.freeze(Je.parse(e.config))},this.o=e,this.log=e.log.child({unit:`agent`}),this.pairings=St(e.paths);let t=or();this.projects=new mi(t,()=>{this.stopped||this.scheduleSessions()}),e.registry.onSetupChanged(()=>{this.stopped||this.scheduleSessions()}),this.localProcess={pid:process.pid,agentVersion:e.appVersion,computerFp:e.fp,stateDir:tn(e.paths.dir),serviceInstance:e.serviceInstance??null};let n=e.relayUrlOverride??e.config.relayUrl;this.relay=e.relay??new Ir({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 Yr({backend:e.registry,log:e.log,now:()=>Date.now(),newTransferId:()=>r(p(16)),onSessionGone:()=>this.scheduleSessions()}),this.events=new $n({notifyMinCommandMs:e.config.notifyMinCommandMs,idleQuietMs:e.config.idleQuietMs,idleMinActiveMs:e.config.idleMinActiveMs}),this.notificationState=new mr(e.paths),this.notificationState.retain(new Set(this.pairings.map(e=>e.phoneFp)));let i=new ur({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 gr(e=>this.relay.sendCtrl(e),e.log,Date.now,e=>i.prepare(e)),this.pairing=new Cr({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),confirm:e.confirm,pairingCount:()=>this.pairings.length,log:e.log,onClose:()=>this.o.onPairingClosed?.()}),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:M(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()})},1e3),this.safe(`refresh-sessions`,()=>this.refreshSessions())}stop(){this.stopped=!0,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(_i(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=St(this.o.paths).find(t=>t.phoneFp===e);if(!r||!i||t.length!==32)throw Error(`shellbell: pairing changed before protocol upgrade`);let a=T(i.kPair);if(a.length!==32||r.kPair!==i.kPair||r.ed25519Pub!==i.ed25519Pub||r.x25519Pub!==i.x25519Pub||!Sn(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=Dt(this.o.paths,o),n!==this.linkForPhone(e)&&this.dropLinkFor(e)}removePairing(e){let t=this.pairings.filter(t=>t!==e);return this.pairings=Dt(this.o.paths,t),this.notificationState.forget(e.phoneFp),this.relay.sendCtrl({type:`unpair`,phoneFp:e.phoneFp}),this.pairRequests.delete(e.phoneFp),this.dropLinkFor(e.phoneFp),this.lastSeenSavedAt.delete(e.phoneFp),!0}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=Me(t,e),r=[...this.pairings.filter(t=>t.phoneFp!==e.phoneFp),n];this.pairings=Dt(this.o.paths,r),this.notificationState.forget(e.phoneFp),(t?.kPair!==e.kPair||t?.ed25519Pub!==e.ed25519Pub||t?.x25519Pub!==e.x25519Pub)&&(this.pairRequests.delete(e.phoneFp),this.dropLinkFor(e.phoneFp))}acceptsRelayUnpair(e,t){if(e.minProtocolVersion!==2)return!0;if(!t)return!1;try{return xt(t,{computerFp:this.o.fp,phoneFp:e.phoneFp,kPair:T(e.kPair),phoneEd25519Pub:T(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=Dt(this.o.paths,i)),this.notificationState.forget(e),this.pairRequests.delete(e),this.dropLinkFor(e),this.lastSeenSavedAt.delete(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=Dt(this.o.paths,e);for(let e of r)this.notificationState.forget(e),this.pairRequests.delete(e),this.dropLinkFor(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:T(e.ed25519Pub),name:e.name,pairId:ft(T(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=Dt(this.o.paths,this.pairings))}newV2Link(e,t,n){let r=T(e.kPair),i;return i=new Ar({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:T(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(hi(this.sessions))))}helloMessage(e=this.o.registry.connected()){return{type:`hello`,features:[Re],agentVersion:this.o.appVersion,hostPlatform:er(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.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})}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===`notification.enroll`){this.notificationState.enroll(e.phoneFp,t.generation)&&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.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&&i.lease.receive(t,n);return}if(!(`reqId`in t)){await this.execute(e,t,r);return}if(_r(t)){let n=this.pairRequests.get(e.phoneFp);n||(n=new vr,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(e,t,n){let r=this.o.registry,i=()=>this.ownsHandshake(e,n),a=(e,t={})=>({type:`ack`,reqId:e,ok:!0,...t}),o=(e,t)=>({type:`ack`,reqId:e,ok:!1,error:t});try{switch(t.type){case`input.line`:return this.log.info(`input`,{kind:`line`,len:t.text.length}),await r.sendText(t.sessionId,`${t.text}\r`,i),a(t.reqId);case`input.text`:return this.log.info(`input`,{kind:`text`,len:t.text.length}),await r.sendText(t.sessionId,t.text,i),a(t.reqId);case`input.key`:return await r.sendText(t.sessionId,Ze(t.key),i),a(t.reqId);case`input.terminal`:return await r.sendInput(t.sessionId,t.data,i),a(t.reqId);case`input.paste`:return await r.paste(t.sessionId,t.text,t.submit,i),a(t.reqId);case`input.mouse`:return await r.clickMouse(t.sessionId,t,i),a(t.reqId);case`session.create`:{let e=await r.createSession(t.in);return this.scheduleSessions(),a(t.reqId,{sessionId:e})}case`session.focus`:{let e=r.capabilitiesOf(t.sessionId);if(e===null)throw new k(t.sessionId);return e.focus?(await r.focus(t.sessionId),a(t.reqId)):o(t.reqId,`unsupported`)}default:return null}}catch(e){let n=e instanceof De?e.message:e instanceof k?`session-gone`:e instanceof E?`unsupported`:e instanceof C?`bad-window`:e instanceof ke?e.code:`failed`;return this.log.warn(`inner message failed`,{type:t.type,error:n,err:M(e)}),`reqId`in t?o(t.reqId,n):null}}broadcast(e){for(let t of this.links.values())t.send(e)}onBackendEvent(e){switch(this.events.onBackendEvent(e),e.type){case`screen-changed`:return;case`session-removed`:this.notifier.forget(e.sessionId),this.events.forget(e.sessionId),this.scheduleSessions();return;case`layout-changed`:case`session-added`:case`focus-changed`:case`title-changed`:case`command-start`:case`command-end`:case`prompt`:case`agent-state`:this.scheduleSessions();return;default:return}}scheduleSessions(){this.sessionsDebounce||=setTimeout(()=>{this.sessionsDebounce=null,this.refreshSessions()},100)}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,this.sessions=t.map(e=>{let t=this.o.registry.projectFolder(e.id),n=t?this.projects.lookup(t):void 0,r=n?{...e,project:n}:e,i=this.events.stateOf(r.id);return i===`unknown`?r:{...r,state:i}}),this.broadcast(hi(this.sessions))}catch(e){this.log.warn(`listSessions failed`,{err:M(e)})}finally{this.broadcastHelloIfBackendProfilesChanged()}}};const yi=[0,7,2],bi=`Install Herdr: curl -fsSL https://herdr.dev/install.sh | sh, then start it with "herdr".`,xi=`Upgrade Herdr to 0.7.2 or newer: curl -fsSL https://herdr.dev/install.sh | sh, then restart it.`;var H=class extends Error{code;constructor(e,t){super(`herdr ${e}: ${t}`),this.code=e,this.name=`HerdrError`}};const Si=new Set([`not_found`,`pane_not_found`,`stale_pane_target`]),Ci=new Set([`invalid_request`,`unsupported`,`unknown_method`,`method_not_found`]);function wi(e,t){let n=/^\s*v?(\d+)\.(\d+)\.(\d+)/.exec(e);if(!n)return null;let r=[Number(n[1]),Number(n[2]),Number(n[3])];for(let e=0;e<3;e++){let n=r[e],i=t[e];if(n!==i)return n>i}return!0}function Ti(e=process.env,t=P()){let n=e.HERDR_SOCKET_PATH;if(n)return n;let r=e.XDG_CONFIG_HOME?L(e.XDG_CONFIG_HOME,`herdr`):L(t,`.config`,`herdr`),i=e.HERDR_SESSION;return i?L(r,`sessions`,i,`herdr.sock`):L(r,`herdr.sock`)}function Ei(e,t,n){let r=e.code??``;return r===`ENOENT`||r===`ECONNREFUSED`||r===`EACCES`||r===`EPERM`?new H(`unavailable`,`cannot reach the herdr socket at ${n} (${r})`):new H(`socket`,`${t}: ${e.message}`)}function Di(e,t,n,r=1048576){let i=new On(`utf8`),a=``;e.on(`data`,e=>{a+=i.write(e);let o=a.indexOf(`
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,Cn as l,Ct as u,Dn as d,Dt as f,E as p,En as m,Et as h,F as g,Fn as _,Ft as v,G as y,Gn as ee,Gt as b,Hn as x,Ht as S,In as te,It as ne,J as C,Jn as w,Jt as re,K as ie,Kn as ae,Kt as oe,Ln as T,Lt as se,M as ce,Mn as le,Mt as ue,N as de,Nn as E,Nt as fe,On as pe,Ot as me,Pn as he,Pt as ge,Q as _e,Qn as ve,Qt as ye,R as be,Rn as xe,Rt as Se,Sn as Ce,St as we,Tn as Te,Tt as Ee,U as De,Un as Oe,Ut as ke,V as Ae,Vn as je,Vt as Me,W as Ne,Wn as Pe,Wt as Fe,X as Ie,Xn as Le,Xt as Re,Y as ze,Yn as Be,Yt as Ve,Z as D,Zn as He,Zt as Ue,_n as We,_t as Ge,a as Ke,an as qe,at as Je,bn as Ye,bt as Xe,cn as Ze,ct as Qe,d as $e,dn as et,dt as tt,en as nt,et as rt,fn as it,ft as at,gn as ot,gt as st,hn as ct,ht as lt,in as ut,it as dt,j as ft,jn as pt,jt as mt,k as ht,kn as gt,kt as _t,l as vt,ln as yt,lt as bt,mn as xt,mt as St,n as Ct,nn as wt,nt as O,o as Tt,on as Et,ot as Dt,pn as Ot,pt as kt,q as At,qt as jt,r as Mt,rn as Nt,s as Pt,sn as Ft,st as It,t as Lt,tn as Rt,tt as zt,u as Bt,un as Vt,ut as Ht,vn as Ut,vt as Wt,wn as Gt,wt as k,xn as Kt,xt as qt,yn as Jt,yt as Yt,z as Xt,zn as Zt,zt as Qt}from"./service-lifecycle-8i-MHBoO.js";import{execFile as A,spawn as $t}from"node:child_process";import{accessSync as en,closeSync as tn,constants as j,existsSync as nn,fstatSync as rn,fsyncSync as an,linkSync as on,lstatSync as sn,mkdirSync as cn,openSync as ln,opendirSync as un,readFileSync as dn,readSync as fn,readdirSync as pn,readlinkSync as mn,realpathSync as hn,renameSync as gn,statSync as _n,statfsSync as vn,symlinkSync as yn,unlinkSync as bn,writeFileSync as xn}from"node:fs";import{homedir as M,hostname as Sn,tmpdir as Cn}from"node:os";import{basename as wn,delimiter as Tn,dirname as N,isAbsolute as P,join as F,normalize as En,relative as Dn,resolve as On,sep as kn}from"node:path";import{createInterface as An}from"node:readline";import{fileURLToPath as jn,pathToFileURL as Mn}from"node:url";import{z as I}from"zod";import{Command as Nn}from"commander";import Pn from"qrcode-terminal";import{createHash as Fn,randomUUID as L,timingSafeEqual as In}from"node:crypto";import{EventEmitter as Ln}from"node:events";import{connect as Rn,createConnection as zn,isIP as Bn}from"node:net";import{lstat as Vn,mkdtemp as Hn,open as Un,opendir as Wn,readlink as Gn,realpath as R,rm as Kn}from"node:fs/promises";import qn from"ws";import{StringDecoder as Jn}from"node:string_decoder";import{isDeepStrictEqual as Yn,promisify as Xn}from"node:util";import{create as z,fromBinary as Zn,toBinary as Qn}from"@bufbuild/protobuf";import{fileDesc as $n,messageDesc as B}from"@bufbuild/protobuf/codegenv2";import{importTerminalPlugin as er}from"#terminal-plugin-loader";import{performance as tr}from"node:perf_hooks";import{createInterface as nr}from"node:readline/promises";const rr=e=>/^turns?:/.test(e),ir=e=>!/:53(\?|$)/.test(e);function ar(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=>rr(e)&&ir(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 or=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 ar(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)}};const sr=[[768,879],[1155,1161],[1425,1469],[1471,1471],[1473,1474],[1476,1477],[1479,1479],[1552,1562],[1611,1631],[1648,1648],[1750,1756],[1759,1764],[1767,1768],[1770,1773],[1809,1809],[1840,1866],[1958,1968],[2070,2093],[2304,2306],[2362,2362],[2364,2364],[2369,2376],[2381,2381],[2385,2391],[2402,2403],[3633,3633],[3636,3642],[3655,3662],[6832,6911],[7616,7679],[8203,8207],[8232,8238],[8288,8292],[8400,8432],[65024,65039],[65056,65071],[65279,65279],[127995,127999],[917760,917999]],cr=[[4352,4447],[8986,8987],[9001,9002],[9193,9196],[9200,9200],[9203,9203],[9725,9726],[9748,9749],[9800,9811],[9855,9855],[9875,9875],[9889,9889],[9898,9899],[9917,9918],[9924,9925],[9934,9934],[9940,9940],[9962,9962],[9970,9971],[9973,9973],[9978,9978],[9981,9981],[9989,9989],[9994,9995],[10024,10024],[10060,10060],[10062,10062],[10067,10069],[10071,10071],[10133,10135],[10160,10160],[10175,10175],[11035,11036],[11088,11088],[11093,11093],[11904,12350],[12353,13311],[13312,19903],[19968,40959],[40960,42191],[43360,43391],[44032,55203],[63744,64255],[65040,65049],[65072,65135],[65280,65376],[65504,65510],[94176,94180],[94208,101119],[110592,111359],[126980,126980],[127183,127183],[127374,127374],[127377,127386],[127488,127569],[127744,127776],[127789,127797],[127799,127868],[127870,127891],[127904,127946],[127951,127955],[127968,127984],[127988,127988],[127992,128062],[128064,128064],[128066,128252],[128255,128317],[128331,128334],[128336,128359],[128378,128378],[128405,128406],[128420,128420],[128507,128591],[128640,128709],[128716,128716],[128720,128722],[128725,128727],[128747,128748],[128756,128764],[128992,129003],[129292,129338],[129340,129349],[129351,129535],[129648,129791],[131072,196605],[196608,262141]];function lr(e,t){let n=0,r=t.length-1;for(;n<=r;){let i=n+r>>1,a=t[i];if(e<a[0])r=i-1;else if(e>a[1])n=i+1;else return!0}return!1}function ur(e){return e===0||e<32||e>=127&&e<160||lr(e,sr)?0:lr(e,cr)?2:1}function dr(e){let t=0,n=!1,r=0;for(let i of e){let e=i.codePointAt(0);if(e===8205){n=!0;continue}let a=ur(e);if(a!==0||n){if(n){r=Math.max(r,a),n=!1;continue}t+=r,r=a}}return t+r}function fr(e,t){let n={t:e},r=t.fg,i=t.bg;if(t.inv){let e=r??15;r=i??0,i=e}r!==void 0&&(n.fg=r),i!==void 0&&(n.bg=i),t.b&&(n.b=!0),t.i&&(n.i=!0),t.u&&(n.u=!0),t.s&&(n.s=!0),t.f&&(n.f=!0);let a=dr(e);return a!==c(e)&&(n.n=a),n}function pr(e){return Math.max(0,Math.min(255,e|0))}function mr(e,t){let n=e[t];if(n.length>1){let e=n[1],t=n.slice(2);if(e===5&&t.length>=1)return{color:pr(t[0]),consumed:0};if(e===2){let e=t.length>=4?t.slice(1,4):t.slice(0,3);if(e.length===3)return{color:[pr(e[0]),pr(e[1]),pr(e[2])],consumed:0}}return{consumed:0}}let r=e[t+1]?.[0];return r===5&&e[t+2]?{color:pr(e[t+2]?.[0]??0),consumed:2}:r===2&&e[t+4]?{color:[pr(e[t+2]?.[0]??0),pr(e[t+3]?.[0]??0),pr(e[t+4]?.[0]??0)],consumed:4}:{consumed:0}}function hr(e,t){let n={...e},r=(t===``?[`0`]:t.split(`;`)).map(e=>e.split(`:`).map(e=>e===``?0:Number(e)));for(let e=0;e<r.length;e++){let t=r[e]?.[0]??0;if(t===0)for(let e of Object.keys(n))delete n[e];else if(t===1)n.b=!0;else if(t===2)n.f=!0;else if(t===3)n.i=!0;else if(t===4)n.u=!0;else if(t===7)n.inv=!0;else if(t===9)n.s=!0;else if(t===22)delete n.b,delete n.f;else if(t===23)delete n.i;else if(t===24)delete n.u;else if(t===27)delete n.inv;else if(t===29)delete n.s;else if(t>=30&&t<=37)n.fg=t-30;else if(t===39)delete n.fg;else if(t>=40&&t<=47)n.bg=t-40;else if(t===49)delete n.bg;else if(t>=90&&t<=97)n.fg=t-90+8;else if(t>=100&&t<=107)n.bg=t-100+8;else if(t===38||t===48){let{color:i,consumed:a}=mr(r,e);i!==void 0&&(t===38?n.fg=i:n.bg=i),e+=a}}return n}function gr(e){return vr(e,{}).line}function _r(e){let t={};return e.map(e=>{let n=vr(e,t);return t=n.style,n.line})}function vr(e,t){let n=[],r=t,i=``,a=0,o=()=>{i&&n.push(fr(i,r)),i=``},s=0;for(;s<e.length;){let t=e[s];if(t===`\x1B`){let n=e[s+1];if(n===`[`){let n=s+2,a=``;for(;n<e.length&&n-(s+2)<32;){let t=e.charCodeAt(n);if(t>=64&&t<=126)break;a+=e[n],n++}if(n>=e.length||n-(s+2)>=32){i+=t,s++;continue}e[n]===`m`&&(o(),r=hr(r,a)),s=n+1;continue}if(n===`]`){let t=s+2;for(;t<e.length&&e[t]!==`\x07`&&(e[t]!==`\x1B`||e[t+1]!==`\\`);)t++;s=e[t]===`\x07`?t+1:t+2;continue}s+=n===void 0?1:2,(n===`(`||n===`)`)&&(s+=1);continue}let n=e.charCodeAt(s);if(t===` `){let e=8-a%8;i+=` `.repeat(e),a+=e,s++;continue}if(n<32||n===127){s++;continue}let c=e.codePointAt(s);i+=String.fromCodePoint(c),a+=ur(c),s+=c>65535?2:1}return o(),{line:{r:b(ke(n))},style:r}}function yr(e){return e.issue!==void 0&&[`needs-consent`,`automation-denied`,`iterm2-denied`,`timed-out`,`too-old`,`failed`,`limited`].includes(e.issue)}const br={iterm2:`iTerm2`,tmux:`tmux`,herdr:`Herdr`};function xr(e,t){let n=br[e.name]??e.name;if(e.connected&&!e.issue)return{status:`Connected. Ready for your paired phone.`};if(t===`phone`)return yr(e)?{status:`${n} needs one more step on your Mac.`,fix:`Open Shellbell → Settings → Terminals on that Mac, or run shellbell doctor there.`}:{status:`${n} isn't connected right now.`};let r=t===`mac-app`?`Click Connect iTerm2.`:`Run shellbell connect iterm2.`;switch(e.issue){case`not-installed`:return{status:`Shellbell couldn't find ${n}. Optional.`,...e.name===`tmux`?{fix:`Install tmux 3.2 or newer, for example: brew install tmux`}:{}};case`not-running`:return e.name===`iterm2`?{status:`iTerm2 isn't open. Open it to see its tabs on your phone.`}:{status:`${n} isn't running.`,fix:`In any terminal, run: ${e.name}`};case`no-session`:return{status:`No tmux session is running.`,fix:`In any terminal, run: tmux`};case`api-off`:return{status:`Turn on iTerm2's Python API to connect.`,fix:`In iTerm2, open Settings → General → Magic and turn on Enable Python API.`};case`needs-consent`:return{status:`Ready to connect.`,fix:`${r} macOS will ask to let Shellbell control iTerm2, and iTerm2 may ask to allow Shellbell. Allow both. Your paired phone can then read and type in your iTerm2 tabs.`};case`connecting`:return{status:`Finish connecting in the macOS or iTerm2 dialog.`};case`automation-denied`:return{status:`macOS is blocking Shellbell from iTerm2.`,fix:`Open System Settings → Privacy & Security → Automation, find Shellbell (or node, for the background service) and turn on iTerm2.`};case`iterm2-denied`:return{status:`iTerm2 is blocking Shellbell.`,fix:`In iTerm2, open Settings → General → Magic and check who may use the Python API. Then ${r.charAt(0).toLowerCase()}${r.slice(1)}`};case`timed-out`:return{status:`Connecting wasn't finished.`,fix:`Check for an open macOS or iTerm2 dialog, then try again. ${r}`};case`too-old`:return e.name===`iterm2`?{status:`Update iTerm2 to connect.`,fix:`Shellbell needs iTerm2 3.3 or newer.`}:e.name===`tmux`?{status:`Shellbell needs tmux 3.2 or newer.`,fix:`Update tmux, for example: brew upgrade tmux`}:{status:`Update ${n} to connect.`};case`limited`:return{status:`Viewing and typing work. Opening new sessions from your phone doesn't.`,...e.detail?{fix:e.detail}:{}};default:return{status:`Shellbell couldn't connect to ${n}.`,fix:e.name===`iterm2`?`Try again. ${r}`:`Shellbell keeps trying.`}}}const Sr=`\x1B[?1049l\x1B[!p\x1B[20l\x1B[?12l\x1B[?9l\x1B[?1000l\x1B[?1002l\x1B[?1003l\x1B[?1006l\x1B[?1015l\x1B]104\x07\x1B]110\x07\x1B]111\x07\x1B]112\x07\x1B[0m\x1B[2J\x1B[H`;var Cr=class extends Ln{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`}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},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);n.promptState=`running`,n.commandStartedAt=t,n.command=e.command;return}case`command-end`:{let n=this.get(e.sessionId);n.promptState=`finished`;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,n.promptState=`editing`,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,n.promptState=`running`,n.workingSince=t;return}if(e.state===`blocked`){n.promptState=`blocked`,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`){n.promptState=`finished`;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.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 wr(e){return e===`darwin`||e===`linux`||e===`win32`?e:`unknown`}const Tr=new Set([`sh`,`bash`,`zsh`,`fish`,`dash`,`ksh`,`pwsh`,`powershell`,`cmd`]),Er=new Set([`ssh`,`mosh`,`docker`,`podman`,`kubectl`,`wsl`]);function Dr(e){return wn(e??``).replace(/^-/,``).replace(/\.exe$/i,``)}function Or(e,t,n){let r=Dr(t),i=Tr.has(r)?r:void 0,a=r===`claude`?`Claude`:r===`codex`?`Codex`:void 0,o=Er.has(r);return{...e,shell:i,agentName:a,locality:o?`guest`:n===`local-process`&&(i||a)?`local`:`unknown`,revision:JSON.stringify([e.sessionId,e.cwd,e.title,e.sessionLabel,r,n])}}function V(e,t){if(e===void 0)return;let n=e.replace(/[\r\n\t\u2028\u2029]+/gu,` `).replace(/[\p{Cc}\p{Cs}\u061c\u200e\u200f\u202a-\u202e\u2066-\u2069]/gu,``).replace(/\s+/gu,` `).trim();if(/(?:^|[\s("'=:])(?:\/|~[\\/]|[a-z]:[\\/])|\\\\|[a-z][a-z0-9+.-]*:\/\/|[^\s@]+@[^\s:]+:/iu.test(n))return;let r=``,i=0;for(let e of n){let n=Buffer.byteLength(e,`utf8`);if(i+n>t)break;i+=n,r+=e}return r||void 0}function kr(e,t){return[...[`Desktop`,`Documents`,`Downloads`].map(e=>F(t,e)),F(t,`Library`,`Mobile Documents`),F(t,`Library`,`CloudStorage`),`/Volumes`].some(t=>{let n=Dn(t,e);return n===``||!n.startsWith(`..${kn}`)&&n!==`..`&&!P(n)})}function Ar(e={}){let t=e.now??Date.now,n=e.platform??process.platform,r=e.home??M(),i=new Map,a=0,o=new Set;async function s(e){if(e.aborted||o.size>=32)throw Error(`git context unavailable`);if(a>=2?await new Promise((t,n)=>{let r=()=>{o.delete(i),n(Error(`git context unavailable`))},i=()=>{o.delete(i),e.removeEventListener(`abort`,r),a+=1,t()};o.add(i),e.addEventListener(`abort`,r,{once:!0})}):a+=1,e.aborted)throw--a,o.values().next().value?.(),Error(`git context unavailable`);return()=>{--a,o.values().next().value?.()}}let c={NODE_ENV:`production`,PATH:process.env.PATH,SystemRoot:process.env.SystemRoot,GIT_CONFIG_NOSYSTEM:`1`,GIT_CONFIG_GLOBAL:process.platform===`win32`?`NUL`:`/dev/null`,GIT_CONFIG_COUNT:`0`,GIT_TERMINAL_PROMPT:`0`,GIT_OPTIONAL_LOCKS:`0`,GIT_NO_REPLACE_OBJECTS:`1`},l=(e,t,n)=>new Promise((r,i)=>{A(`git`,[`-c`,`core.fsmonitor=false`,`-C`,e,...t],{env:c,encoding:`utf8`,signal:n,timeout:250,killSignal:`SIGKILL`,maxBuffer:8192,windowsHide:!0},(e,t)=>e?i(e):r(t.trim()))});return async(e,a)=>{if(!P(e)||e.length>1024||a.aborted||n===`darwin`&&kr(e,r))return;let o=t();for(let[e,t]of i)(o<t.observedAt||o-t.observedAt>=5e3)&&i.delete(e);let c=i.get(e);if(c)return c;let u=new AbortController,d=()=>u.abort();a.addEventListener(`abort`,d,{once:!0});let f=setTimeout(d,250),p;try{p=await s(u.signal);let t=await l(e,[`rev-parse`,`--show-toplevel`],u.signal),n;try{n=await l(e,[`symbolic-ref`,`--quiet`,`--short`,`HEAD`],u.signal)}catch(e){!u.signal.aborted&&e.code===1&&(n=`detached HEAD`)}if(u.signal.aborted)return;let r=V(wn(t),256);if(!r)return;let a={repository:r,branch:V(n,256),observedAt:o};return i.size>=500&&i.delete(i.keys().next().value),i.set(e,a),a}catch{return}finally{clearTimeout(f),a.removeEventListener(`abort`,d),p?.()}}}async function jr(e,t){let n=t.now(),r=new AbortController,i,a=new Promise(e=>{i=setTimeout(()=>{r.abort(),e(void 0)},250)}),o=async()=>{if(!await Promise.race([Promise.resolve().then(()=>t.stillCurrent(e)),a]))throw Error(`stale notification context`)};try{await o();let i;e.locality===`local`&&e.cwd&&P(e.cwd)&&(i=await Promise.race([Promise.resolve().then(()=>t.git(e.cwd,r.signal)).catch(()=>void 0),a]));let s=t.stillCurrent(e);if(typeof s==`boolean`?!s:!await Promise.race([s,a]))throw Error(`stale notification context`);let c={computerName:V(t.computerName,128)??`Computer`,sessionLabel:V(e.sessionLabel,128)??`Session`,observedAt:Math.min(n,i?.observedAt??n)};for(let[t,n]of[[`customName`,256],[`title`,256],[`shell`,64],[`agentName`,64]]){let r=V(e[t],n);r&&(c[t]=r)}let l=V(i?.repository,256),u=V(i?.branch,256);return l&&(c.repository=l),l&&u&&(c.branch=u),c}finally{clearTimeout(i),r.abort()}}function Mr(e){return{type:`notify`,sessionId:e.sessionId,kind:e.kind,exitCode:e.exitCode,durationMs:e.durationMs}}function Nr(e){let t={...e,context:{...e.context}};for(let e of[`branch`,`title`,`agentName`,`shell`,`customName`,`repository`]){if(ot.safeParse(t).success)return t;delete t.context[e]}return ot.safeParse(t).success?t:void 0}var Pr=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(Mr(e))},250)}),c=Promise.race([this.build(e,()=>i||performance.now()-a>=250,r),s]).catch(()=>Mr(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>=xt.freshnessMs)return Mr(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}:Mr(e)});return this.cache.set(e,l),l()}async build(e,t,n){let r=this.options,i=r.now??Date.now,a=Mr(e);if(!r.capable()||!e.reason)return a;let o=Zt(pt(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 jr(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>=xt.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=Nr({computerFp:r.computerFp,phoneFp:i.phoneFp,generation:a.generation,sessionId:e.sessionId,eventId:o,sequence:a.sequence,issuedAt:d,expiresAt:n+xt.freshnessMs,reason:e.reason,context:u,exitCode:e.exitCode,durationMs:e.durationMs});if(!s)continue;let c,l;try{c=T(i.kPair),l=Ve(c,s),f.push(Re(l,s)),Buffer.byteLength(JSON.stringify(p),`utf8`)>16384&&f.pop()}catch{}finally{c?.fill(0),l?.fill(0)}}return f.length?p:a}};const Fr=I.string().regex(/^(0|[1-9][0-9]{0,19})$/).refine(e=>BigInt(e)<=18446744073709551615n),Ir=I.strictObject({generation:ct,used:I.number().int().min(0).max(xt.encryptions)}),Lr=I.strictObject({version:I.literal(1),phones:I.array(I.strictObject({phoneFp:ae,sequence:Fr,current:Ir,previous:I.strictObject({generation:ct,expiresAt:I.number().int().nonnegative().max(2**53-1)}).optional()})).max(10).refine(e=>new Set(e.map(e=>e.phoneFp)).size===e.length)});var Rr=class{paths;now;data={version:1,phones:[]};healthy=!0;file;constructor(e,t=Date.now){this.paths=e,this.now=t,this.file=F(e.dir,`notifications.json`);try{Dt(e);let t=F(e.dir,`notifications.initialized`),n=f(t)!==void 0;if(n&&Ee(t,8,process.getuid?.()).toString(`utf8`)!==`v1
3
+ `)throw Error(`invalid marker`);try{this.data=Lr.parse(JSON.parse(Ee(this.file,16384,process.getuid?.()).toString(`utf8`)))}catch(e){if(n||!(e instanceof k&&e.kind===`missing`))throw e;if(!this.commit(this.data))return}n||(kt(t,`v1
4
+ `),this.syncDirectory())}catch{this.healthy=!1}}syncDirectory(){if(process.platform===`win32`)return;let e=ln(this.paths.dir,`r`);try{an(e)}finally{tn(e)}}commit(e){if(!this.healthy)return!1;try{return Dt(this.paths),kt(this.file,JSON.stringify(e)),this.syncDirectory(),this.data=e,!0}catch{return this.healthy=!1,!1}}enroll(e,t){if(!this.healthy||!ae.safeParse(e).success||!ct.safeParse(t).success)return!1;let n=this.data.phones.find(t=>t.phoneFp===e);if(n?.current.generation===t)return n.current.used<xt.encryptions;if(n?.previous?.generation===t||!n&&this.data.phones.length>=10)return!1;let r=structuredClone(this.data);return r.phones=r.phones.filter(t=>t.phoneFp!==e),r.phones.push({phoneFp:e,sequence:n?.sequence??`0`,current:{generation:t,used:0},...n?{previous:{generation:n.current.generation,expiresAt:this.now()+xt.previousGenerationMs}}:{}}),this.commit(r)}reserve(e){if(!this.healthy)return;let t=structuredClone(this.data),n=t.phones.find(t=>t.phoneFp===e);if(!(!n||n.current.used>=xt.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}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){let t=structuredClone(this.data);t.phones=t.phones.filter(t=>t.phoneFp!==e),this.commit(t)}};const zr=6e4;var Br=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>=zr&&this.last.delete(n);return n!==void 0&&t-n<zr?!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(Mr(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 Vr(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 Hr=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 Ur=I.instanceof(Uint8Array).refine(e=>e.length===32,{message:`expected 32 bytes`}),Wr=I.instanceof(Uint8Array).refine(e=>e.length===64,{message:`expected 64 bytes`});function Gr(e){return e.replace(/[\p{Cc}\p{Cs}\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/gu,` `).replace(/\s+/gu,` `).trim()||`Phone`}const Kr=I.object({ed25519Pub:Ur,x25519Pub:Ur,name:I.string().min(1).max(64).transform(Gr),platform:I.enum([`ios`,`android`]),bind:Wr});var qr=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();let e=pt(16),t=pt(16),n=this.now()+(this.opts.windowMs??3e5),r=oe({v:1,r:this.opts.relayUrl,c:this.opts.fp,e:Zt(this.opts.identity.ed25519.pub),n:this.opts.computerName.slice(0,40),p:Zt(e),g:Zt(t),b:1});jt(r,{allowInsecure:!0}),this.window={code:e,gate:t,expiresAt:n,failures:0,requests:0};let a=this.opts.sendCtrl({type:`pairing-open`,gateHash:i(t),expiresAt:n});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: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:i(this.window.gate),expiresAt:this.window.expiresAt});this.log.debug(e?`pairing window re-advertised`:`pairing window re-advertise dropped`)}closeWindow(){if(!this.window)return;let e=this.window;e.code.fill(0),e.gate.fill(0),this.window=null,this.pending?.window===e&&(this.pending=null),this.opts.sendCtrl({type:`pairing-close`}),this.log.info(`pairing window closed`),this.opts.onClose?.()}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 n=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 n(`window-closed`);let r=this.window;if(r.requests>=5){n(`window-closed`),this.closeIfExhausted(r);return}if(r.requests+=1,this.opts.pairingCount()>=10||this.pending!==null){n(`too-many`),this.closeIfExhausted(r);return}let i=Jt(r.code,this.opts.fp),a;try{if(a=Kr.parse(ve(Gt(i,e.box,Te(`request`,this.opts.fp,e.phoneFp)))),Ye(a.ed25519Pub)!==e.phoneFp)throw Error(`fp mismatch`);let t=m(`phone`,this.opts.fp,e.phoneFp,a.x25519Pub);if(!gt(a.ed25519Pub,t,a.bind))throw Error(`unbound key`)}catch{r.failures+=1,n(`bad-code`),r.failures>=3?this.closeWindow():this.closeIfExhausted(r);return}let o={};this.pending={window:r,token:o};try{let s=await this.confirmWithTimeout(e.phoneFp,a.name);if(this.pending?.token!==o||!this.isOpen||this.window!==r)return;if(!s)return n(`declined`);let c;try{c=Ut(this.opts.identity.x25519.priv,a.x25519Pub,r.code,this.opts.fp,e.phoneFp)}catch{r.failures+=1,n(`bad-code`),r.failures>=3&&this.closeWindow();return}this.opts.savePairing({phoneFp:e.phoneFp,name:a.name,platform:a.platform,ed25519Pub:Zt(a.ed25519Pub),x25519Pub:Zt(a.x25519Pub),kPair:Zt(c),pairedAt:new Date(this.now()).toISOString(),lastSeenAt:null}),this.opts.sendCtrl({type:`pairing-add`,phoneFp:e.phoneFp,ed25519Pub:a.ed25519Pub,name:a.name,pairId:et(c)});let l=d(i,t({x25519Pub:this.opts.identity.x25519.pub,computerName:this.opts.computerName,accent:this.opts.accent,bind:pe(this.opts.identity.ed25519.priv,m(`computer`,this.opts.fp,e.phoneFp,this.opts.identity.x25519.pub))}),Te(`response`,this.opts.fp,e.phoneFp));this.opts.sendCtrl({type:`pairing-response`,phoneFp:e.phoneFp,box:l}),this.log.info(`paired`,{phone:e.phoneFp.slice(0,8)}),this.closeWindow()}finally{this.pending?.token===o&&(this.pending=null,this.closeIfExhausted(r))}}};const Jr=e=>!/^turns:/.test(e)&&!/[?&]transport=tcp(?:&|$)/.test(e);function Yr(e){return e.flatMap(e=>e.urls.filter(Jr).map(t=>e.username&&e.credential?t.replace(/^(turns?):/,`$1:${encodeURIComponent(e.username)}:${encodeURIComponent(e.credential)}@`):t))}function Xr(e){let t=e.trim().replace(/%.*$/,``).toLowerCase();if(Bn(t)!==6)return t;try{return new URL(`http://[${t}]/`).hostname.slice(1,-1)}catch{return t}}function Zr(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:Xr(t[4]),type:t[7]}}function Qr(e,t={}){let n=t.turn!==!1;return t=>$r(t,Yr(n?e():ar()),n)}Qr(()=>ar());const $r=async(e,t,n=!0)=>{let{default:r}=await import(`node-datachannel`),i=new r.PeerConnection(`shellbell-v2`,{iceServers:t}),a=null,o=!1,s=new Set,c=new Set,l=()=>{let e=i.getSelectedCandidatePair();if(!e||e.local.type===`relay`||e.remote.type===`relay`)return!1;let t=Xr(e.remote.address);return s.has(t)&&!c.has(t)},u=n,d=null,f=[],p=()=>{d&&clearInterval(d),d=null},m=()=>{if(p(),!o)try{e.closed()}catch{}},h=e=>{if(!o)try{e()}catch{m()}};return i.onLocalDescription((t,n)=>{h(()=>{(n===`offer`||n===`answer`)&&e.description(t,n)})}),i.onLocalCandidate((t,n)=>{h(()=>e.candidate(t.replace(/^a=candidate:/,`candidate:`),n,null))}),i.onStateChange(e=>{(e===`failed`||e===`closed`||e===`disconnected`)&&m()}),i.onDataChannel(t=>{h(()=>{if(a||t.getLabel()!==`shellbell-v2`){t.close(),m();return}a=t,t.onOpen(()=>{h(()=>{if(n){e.open();return}let t=Date.now()+3e3,r=()=>h(()=>{if(l()){if(u)return;u=!0,e.open();for(let t of f.splice(0))e.message(t)}else(u||Date.now()>=t)&&m()});d=setInterval(r,250),d.unref?.(),r()})}),t.onClosed(m),t.onError(m),t.onMessage(t=>{h(()=>{if(typeof t==`string`){m();return}let n=(t instanceof ArrayBuffer,new Uint8Array(t));if(n.length>61e3){m();return}if(!u){f.length>=16?m():f.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){if(!n){let t=Zr(e);if(!t)return;if(t.type===`relay`){c.add(t.address);return}(t.type===`host`||t.type===`srflx`)&&s.add(t.address)}i.addRemoteCandidate(e,t??`0`)},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=xe(t.value.replaceAll(`:`,``));if(!te(e,n))throw Error(`DTLS fingerprint mismatch`);return n},send(e){if(o||!u||!a?.isOpen()||e.length>61e3||a.bufferedAmount()+e.length>262144)return!1;try{return a.sendMessageBinary(e)}catch{return!1}},close(){o||(o=!0,p(),a?.close(),a=null,i.close())}}};var ei=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;constructor(e){this.phoneFp=e.phoneFp,this.connId=e.connId,this.relayConnId=e.connId,this.name=e.name,this.endpoint=new Qt({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??Qr(e.iceServers??(()=>ar()),{turn:e.turn}),allowDirect:!0,terminal:(t,n)=>{let r;try{r=Et(ve(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)}),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(t(e))}relayLost(){this.endpoint.relayLost()}close(){this.broken=!0,this.handshaken=!1,this.endpoint.close()}},ti=class{options;closed=!1;ended=!1;follower=null;operation=!1;epoch={};due=0;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(!Oe.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>E.envelopeBytes||!_.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,n=()=>!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 r=await e.older(this.cursor.anchor);if(!n()||this.follower!==e)return;if(this.due=this.options.now()+200,r.status===`stopped`)this.stopped(r.reason);else if(r.status===`refresh`)this.snapshotCurrent=!1;else if(r.status===`busy`||r.status===`reading`)this.waitingForSource();else if(r.status===`unavailable`)this.finishHistory(`unavailable`);else if(r.status===`page`){let e=r.branch?.kind===`claude`?r.branch.nodes:[],n=[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=>n.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||=r.history===`unlinked`,this.lastSourceAt=this.options.now(),this.authorizedUntil=this.options.now()+200,this.caughtUp=!1,!r.entries.length)this.finishHistory(r.history===`complete`&&!this.unlinkedHistory?`complete`:`unavailable`);else{let n=new Map([...this.applied,...this.projection].map(e=>[e.local,e.id])),i=r.entries.map(({entry:e,anchor:r})=>{let i=n.get(e.id)??this.id(),a=Object.freeze({...e,id:i}),o=t(a),s=Fn(`sha256`).update(o).digest(`base64url`);return o.fill(0),{local:e.id,id:i,hash:s,entry:a,anchor:r}}),a=this.history,o=this.applied[0],s=this.page(i,`prepend`,o.id,a.requestId);s.length?this.queue(`prepend`,s,this.applied,o.id,a.requestId,void 0,[],{history:this.unlinkedHistory?`unlinked`:r.history,more:s.length<i.length||(r.more??r.history!==`complete`),ancestors:e}):this.finishHistory(`unavailable`)}this.options.wake()}return}if(this.snapshotCurrent&&this.snapshot&&(this.pending||this.history||this.hasUpdate())){let t=await e.confirm(this.snapshot.revision);if(!n()||this.follower!==e)return;if(t.status===`confirmed`){this.lastSourceAt=this.options.now(),this.caughtUp=t.caughtUp,this.authorizedUntil=this.options.now()+200,this.prepare(),this.due=this.options.now()+200,this.options.wake();return}if(t.status===`stopped`){this.stopped(t.reason);return}if(t.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 r=await e.poll();if(!n()||this.follower!==e)return;this.accept(r)}catch{n()&&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+E.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+E.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.status(`checking`);return}this.lastSourceAt=this.options.now();let n=e.snapshot;if(n.state!==`ready`||!n.branch){this.generation?this.invalidate(`unavailable`):(this.status(`unavailable`,n.state===`unsupported`?`unsupported`:`unbound`),this.due=this.options.now()+5e3);return}if(this.branch?.kind===`claude`){let e=this.branch.nodes.at(-1);if(n.branch.kind!==`claude`||!e||!n.branch.nodes.some(t=>t.id===e.id&&t.start===e.start)){let t=n.branch.kind===`claude`&&e&&n.history!==`complete`&&(n.branch.nodes[0]?.start??0)>e.start;this.invalidate(t?`skipped`:`changed`);return}let t=new Map(this.branch.nodes.map(e=>[e.id,e.start]));if(n.branch.nodes.some(e=>t.has(e.id)&&t.get(e.id)!==e.start||this.historicalBranch.has(e.id)&&this.historicalBranch.get(e.id)!==e.start)){this.invalidate(`changed`);return}}if(n.entries!==this.snapshot?.entries){let e=new Map([...this.applied,...this.projection].map(e=>[e.local,e.id])),r=[],i=0;this.projectionClipped=!1;for(let a=n.entries.length-1;a>=0;a--){let o=n.entries[a];if(o.id.startsWith(`history:`))continue;let s=e.get(o.id)??this.id(),c=Object.freeze({...o,id:s}),l=t(c);i+=l.byteLength;let u=Fn(`sha256`).update(l).digest(`base64url`);if(l.fill(0),i>E.queuedBytes-E.batchBytes||r.length>=E.retainedEntries){this.projectionClipped=!0;break}r.push({local:o.id,id:s,hash:u,entry:c})}r.reverse(),this.projection=r}this.snapshot=this.projectionClipped?{...n,history:`truncated`}:n,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>=E.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,n,r,i,a){let o=[],s=n!==`patch`;for(let c=0;c<Math.min(e.length,E.entriesPerBatch);c++){let l=e[s?e.length-c-1:c],u=s?[l,...o]:[...o,l],d=this.message(n,u,r,i,`0`.repeat(22),a);if(t(d).byteLength>E.batchBytes)break;o.splice(0,o.length,...u)}return o}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(!he.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.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(!Oe.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 ni(e,t){return e===t||!!e&&!!t&&e.agent===t.agent&&e.kind===t.kind&&e.value===t.value}function ri(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()||!ni(i,s)||i.owner!==s?.owner?null:Object.freeze({...o,owner:i.owner})}catch{return null}}}const ii=65536;function ai(e,t){return!!t&&e.agent===t.agent&&e.path===t.path&&e.session===t.session&&e.owner===t.owner}function oi(e,t){return e.dev===t.dev&&e.ino===t.ino}function si(e){return P(e)&&e.length<=4096&&!Array.from(e).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)===127)}function ci(e,t){let n=Dn(e,t);return n!==``&&n!==`..`&&!n.startsWith(`..${kn}`)&&!P(n)}function li(e){return e.isFile()&&!e.isSymbolicLink()&&Number.isSafeInteger(e.size)&&e.size>=0&&(process.getuid===void 0||e.uid===process.getuid())}function ui(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 di=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 fi(t,t.signal);if(!i)return{status:`stopped`,reason:t.signal?.aborted?`cancelled`:`unbound`};let a={...i};if(![`claude`,`codex`].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 R(a.path),c=!1;for(let e of o)if(si(e))try{ci(await R(e),s)&&(c=!0)}catch{}if(!c)return{status:`stopped`,reason:`unsafe`};let l=await Vn(a.path);if(!li(l))return{status:`stopped`,reason:`unsafe`};n=await Un(s,j.O_RDONLY|j.O_NOFOLLOW|j.O_NONBLOCK);let u=await n.stat();if(!li(u)||!oi(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 ui(n)}}get stopped(){return this.reason}get size(){return this.observed.size}async read(e,t=ii){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=[],ui(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 fi(this.options,this.controller.signal);if(this.reason)return this.reason;if(!this.options.enabled())return`disabled`;if(!t)return`unbound`;if(!ai(this.identity,t)||await R(this.identity.path)!==this.path)return`changed`;let[n,r]=await Promise.all([Vn(this.path),this.file.stat()]);if(!li(n)||!oi(n,r)||!oi(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 fi(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()}}var pi=class{buffer=null;length=0;skipped;closed=!1;next;start;decoder=new TextDecoder(`utf-8`,{fatal:!0});constructor(e=0,t=!1){if(!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.skipped||(this.length+o>131072?(this.clearBuffer(),this.skipped=`line-too-large`):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.start=this.next,a++}}return{consumed:i,lines:r}}close(){this.clearBuffer(),this.buffer=null,this.skipped=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.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.trim())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 mi=8192,hi=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i,gi=/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,255}$/;function _i(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}function vi(e){return typeof e==`string`&&e.trim()===e&&gi.test(e)?e:null}function yi(e){return typeof e==`string`&&e.length===36&&hi.test(e)?e.toLowerCase():null}function bi(e,t){if(!Number.isSafeInteger(t)||t<0||t>16384)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 xi=class{offset;items=[];bytes=2;clipped=!1;constructor(e){this.offset=e}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=bi(t,16384),o=n===void 0?void 0:bi(n,mi),s={id:`${this.offset}:${this.items.length}`,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}`,kind:`status`,text:`Additional content omitted to keep this entry small.`,truncated:!0})),Object.freeze(this.items)}};function Si(e,t){return Array.isArray(e)?(e.length>64&&(t.clipped=!0),e.slice(0,64)):null}function Ci(e){return typeof e==`string`&&bi(e,128).text||`Tool`}function wi(e){if(typeof e==`string`)return{text:e,clipped:!1};let t=_i(e);if(t){for(let e of[`command`,`cmd`,`file_path`,`path`,`pattern`,`query`,`url`,`description`,`prompt`])if(typeof t[e]==`string`)return{text:`${e}: ${bi(t[e],mi).text}`,clipped:!0}}return{text:`Structured arguments omitted.`,clipped:!0}}function Ti(e){if(typeof e==`string`)try{let t=JSON.parse(e);if(_i(t))return wi(t)}catch{}return{text:`Structured arguments omitted.`,clipped:!0}}function Ei(e){if(typeof e==`string`){let t=bi(e,mi);return{text:t.text,clipped:t.truncated}}if(!Array.isArray(e))return null;let t=``,n=0,r=e.length>64;for(let i of e.slice(0,64)){let e=_i(i);if(!e){r=!0;continue}let a=(e.type===`text`||e.type===`input_text`||e.type===`output_text`)&&typeof e.text==`string`?e.text:`[Non-text content omitted]`,o=Math.max(0,mi-n-!!t),s=bi(a,o);if(t&&o&&(t+=`
5
+ `,n++),t+=s.text,n+=Buffer.byteLength(s.text),r||=s.truncated,!o){r=!0;break}}return{text:t,clipped:r}}function Di(e,t,n=!1){let r=Ei(t);return r?e.add(`tool-result`,n?`Tool error`:`Tool result`,r.text,!0,r.clipped):e.unknown()}function Oi(e,t){let n=e.value,r=_i(n.message),i=vi(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.isCompactSummary===!0||n.type===`system`&&n.subtype===`compact_boundary`,u=!0,d=!1,f=n.type===`user`||n.type===`assistant`?n.type:`other`,p=()=>i?Object.freeze({id:i,parent:n.parentUuid===null?null:vi(n.parentUuid)??void 0,session:yi(n.sessionId),role:f,response:vi(r?.id),scope:s?`side:${vi(n.agentId)??vi(n.teamName)??`unknown`}`:`main`,meta:c,mainMessage:d&&!c&&!s,compact:l,sourceAssistant:vi(n.sourceToolAssistantUUID),calls:Object.freeze(a),results:Object.freeze(o),resultsOnly:u&&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,m=`ignored`;if(!c){if(f!==`other`&&r?.channel!==void 0&&r.channel!==null&&r.channel!==`final`&&r.channel!==`commentary`)t.unknown(),m=`unsupported`;else if(l&&i){let e=n.type===`system`&&n.subtype===`compact_boundary`;if(d=f!==`other`&&r?.role===f&&(typeof r.content==`string`||Array.isArray(r.content)),e||d){let n=e?null:Ei(r?.content);e||t.add(`group`,`Conversation summary`,n?.text,!0,n?.clipped),m=`compaction`}else t.unknown(),m=`unsupported`}else if(f!==`other`){if(m=`message`,!i||!r||r.role!==f)t.unknown(),m=`unsupported`;else if(!c){if(d=typeof r.content==`string`||Array.isArray(r.content),typeof r.content==`string`)t.add(f,r.content),u=!1;else{let e=Si(r.content,t);e||(t.unknown(),m=`unsupported`);for(let n of e??[]){if(t.full){t.clipped=!0;break}let e=_i(n);if(!e){t.unknown(),u=!1;continue}if(e.type===`tool_result`&&f===`user`){let n=vi(e.tool_use_id),r=Di(t,e.content??``,e.is_error===!0);n&&r&&o.push(Object.freeze({id:n,entry:r.id}))}else if(u=!1,e.type===`text`&&typeof e.text==`string`)t.add(f,e.text);else if(e.type===`tool_use`&&f===`assistant`){let n=vi(e.id),r=wi(e.input),i=t.add(`tool-call`,Ci(e.name),r.text,!0,r.clipped);n&&i&&a.push(Object.freeze({id:n,entry:i.id}))}else 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`||![`progress`,`system`,`attachment`,`file-history-snapshot`,`queue-operation`,`summary`,`custom-title`,`tag`,`last-prompt`].includes(n.type))&&(t.unknown(),m=`unsupported`)}let h=p();return{kind:m,...h&&{node:h}}}function ki(e,t){let n=e.value,r=_i(n.payload),i=_i(n.metadata);if(n.type===`session_meta`)return{kind:`session`,session:yi(r?.id),supported:!!r&&(r.history_mode===void 0||r.history_mode===`legacy`)&&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};let e={task_started:`Working`,turn_started:`Working`,task_complete:`Complete`,turn_complete:`Complete`,turn_aborted:`Stopped`,error:`Agent reported an error`};if(typeof r.type==`string`&&Object.hasOwn(e,r.type))return t.add(`status`,e[r.type]),{kind:`status`};if(typeof r.type==`string`&&[`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`].includes(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`&&[`reasoning`,`additional_tools`,`configuration_update`,`compaction`,`context_compaction`].includes(r.type))return{kind:`ignored`};let e={local_shell_call:`Shell command`,tool_search_call:`Tool search`,web_search_call:`Web search`,image_generation_call:`Image generation`};if(typeof r.type==`string`&&Object.hasOwn(e,r.type))return t.add(`tool-call`,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`){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=Ei(r.content);return t.add(`group`,`Conversation summary`,e?.text,!0,e?.clipped),{kind:`compaction`}}let e=Si(r.content,t);e||t.unknown();for(let n of e??[]){if(t.full){t.clipped=!0;break}let e=_i(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`){let e=r.type===`function_call`?Ti(r.arguments):wi(r.input);return t.add(`tool-call`,Ci(r.name),e.text,!0,e.clipped),{kind:`message`}}else if(r.type===`function_call_output`||r.type===`custom_tool_call_output`)return Di(t,r.output),{kind:`message`}}return t.unknown(),{kind:`unsupported`}}function Ai(e,t){if(e!==`claude`&&e!==`codex`)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=new xi(t.start),r;return t.kind===`skipped`?(n.add(`status`,t.reason===`partial-prefix`?`Earlier content is not loaded`:`A transcript entry could not be read`,void 0,!1,!0),r={kind:`skipped`}):t.end-t.start>131073?(n.add(`status`,`A transcript entry exceeded the read limit`,void 0,!1,!0),r={kind:`skipped`}):r=e===`claude`?Oi(t,n):ki(t,n),Object.freeze({start:t.start,end:t.end,...r,entries:n.finish()})}var ji=class{state=`pending`;expected;constructor(e){let t=yi(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`}};function Mi(e){return Fn(`sha256`).update(JSON.stringify(e)).digest(`base64url`)}function Ni(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 Pi(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,mi-r-!!n),o=bi(t,a);if(n&&a&&(n+=`
6
+ `,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 Fi=class{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;precedingEnd=new Map;unplacedMain=-1;coveredThrough=0;constructor(e,t){let n=yi(t);if(!n||e!==`claude`&&e!==`codex`)throw TypeError(`Invalid transcript document identity`);this.expected=n,this.header=e===`codex`?new ji(n):null}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.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){this.header?.observe(t),this.invalidated||=t.invalidates===!0;let e=Buffer.byteLength(JSON.stringify(t));if(e>262144){this.forgetUnseen(t),this.evicted=!0;continue}for(this.records.push({record:t,bytes:e}),this.bytes+=e;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++)}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.revision++}anchor(e){let t=this.latest;if(t?.state!==`ready`)return null;let n=t.entries.find(t=>t.id===e);if(!n)return null;let r=this.records.find(({record:t})=>t.entries.some(t=>t.id===e&&Mi(t)===Mi(n)))?.record;return!r||!this.header&&(t.branch?.kind!==`claude`||!r.node?.mainMessage||r.node.role!==`user`||r.node.meta||r.node.results.length>0||(this.precedingEnd.get(e)??1/0)>r.end||this.unplacedMain>=r.end||!t.branch.nodes.some(e=>e.id===r.node.id&&e.start===r.start))?null:Object.freeze({agent:this.header?`codex`:`claude`,start:r.start,end:r.end,recordHash:Mi(r),entryId:e,entryHash:Mi(n),nodeId:r.node?.id??null})}permits(e){if(this.latest?.state!==`ready`||e.agent!==(this.header?`codex`:`claude`)||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.header?`codex`:`claude`)||this.through!==e.end||!n||n.end!==e.end||Mi(n)!==e.recordHash||!n.entries.some(t=>t.id===e.entryId&&Mi(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})=>e.entries),t,{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=>e.node.parent?[e.node.parent]:[])),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=t.node.parent?r.get(t.node.parent):void 0}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;for(;l;){if(c.has(l.node.id))return this.finish(`unsupported`,[],`unlinked`);if(c.add(l.node.id),s.push(l),l.node.parent===null)break;let e=l.node.parent?r.get(l.node.parent):void 0;if(!e){u=!1;break}l=e}s.reverse();let{entries:d,after:f}=this.mainEntries(r,s,c),p=new Set(d.map(e=>e.id));for(let e of r.values())e.entries.some(e=>!p.has(e.id))&&(this.unplacedMain=Math.max(this.unplacedMain,e.start));let m=new Map,h=new Map,g=!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(h.has(t.node.id)){i=h.get(t.node.id);break}r.add(t.node.id),a=t,t=t.node.parent?n.get(t.node.parent):void 0}t?.node.scope===`main`&&(i={main:t,root:a});for(let e of r)h.set(e,i);if(!i){g=!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=m.get(o)??{records:[],anchor:i.main.node.id};s.records.push(e),m.set(o,s)}let _=[],v=new Map;for(let{records:e,anchor:t}of m.values()){e.sort((e,t)=>e.start-t.start);let n=Pi(e,`side:${e[0].start}`);n&&(_.push({at:f.get(t)??0,start:e[0].start,entry:n}),v.set(n.id,Math.max(...e.map(e=>e.end))))}g&&_.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 y=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`||t.kind===`skipped`&&e!==`complete`&&t.start===this.base&&t.entries[0]?.text===`Earlier content is not loaded`)continue;let n=d.findIndex(e=>(y.get(e.id)??1/0)>=t.start);for(let e of t.entries)_.push({at:n===-1?d.length:n,start:t.start,entry:e})}_.sort((e,t)=>t.at-e.at||t.start-e.start);for(let{at:e,entry:t}of _)d.splice(e,0,t);return this.finish(`ready`,d,!u&&e===`complete`?`unlinked`:e,{kind:`claude`,nodes:Object.freeze(s.map(e=>Object.freeze({id:e.node.id,start:e.start})))},v)}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=t.node.parent?e.get(t.node.parent):void 0;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)&&Ni(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(Ni))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)=>Ni(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 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 s=a.map(e=>{let t=this.entryFingerprints.get(e);return t===void 0&&(t=Mi(e),this.entryFingerprints.set(e,t)),t}),c=this.previous!==null&&this.previous.length<=s.length&&this.previous.every((e,t)=>e===s[t])?this.previous.length===s.length?`unchanged`:`append`:`replace`;this.previous=s;let l=new Map(this.records.flatMap(({record:e})=>e.node?.role===`user`&&e.node.mainMessage&&!e.node.results.length?e.entries.map(t=>[t.id,e.end]):[])),u=new Map(this.records.flatMap(({record:e})=>e.entries.map(t=>[t.id,e.end])));for(let[e,t]of i??[])u.set(e,t);let d=new Set(a.map(e=>e.id));this.precedingEnd.clear();let f=0;for(let e of t){e.id!==`unlinked-side`&&!e.id.startsWith(`history:`)&&(f=Math.max(f,u.get(e.id)??1/0)),d.has(e.id)&&this.precedingEnd.set(e.id,f);let t=l.get(e.id);t!==void 0&&f>t&&(this.unplacedMain=Math.max(this.unplacedMain,t))}return this.coveredThrough=this.through,this.latest=Object.freeze({state:e,entries:Object.freeze(a),history:n,change:c,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 Ii=E.batchBytes-2048;var Li=class{document;decoder;anchor;raw=null;consumed=0;closed=!1;constructor(e,t,n){this.anchor=Object.freeze({...e}),this.document=new Fi(e.agent,t),e.agent===`codex`&&n&&this.document.append([n]);let r=Math.max(0,e.end-262144);this.document.beginWindow(r),this.decoder=new pi(r,r>0)}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){let t=this.anchor.end-this.decoder.offset;if(t<=0)return this.finish();let n=await e(this.decoder.offset,Math.min(t,ii));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,this.document.append(t.lines.map(e=>Ai(this.anchor.agent,e))),this.consumed===this.raw.byteLength&&(this.raw.fill(0),this.raw=null,this.consumed=0)}return this.raw||this.decoder.offset<this.anchor.end?{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.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>=E.entriesPerBatch||i+a>Ii)break;r.push(Object.freeze({entry:t,anchor:this.document.anchor(t.id)})),i+=a}r.reverse();let a=e.history===`complete`&&r.length<n.length?`unloaded`:e.history,o=e.entries.some(e=>e.id===`unlinked-side`)?`unlinked`:a;return this.close(),!r.length&&(n.length||o!==`complete`)?{status:`unavailable`}:Object.freeze({status:`page`,entries:Object.freeze(r),history:o,more:a!==`complete`,branch:e.branch})}};const Ri=262144;var zi=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 Bi(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()}},Bi=class{admission;controller=new AbortController;options;onAbort=()=>this.close();reason=null;file=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;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)}}}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(!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 Li(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.file){let e=await di.open({...this.options,signal:this.controller.signal});if(e.status===`stopped`)return this.stop(e.reason);if(this.file=e.file,this.fileClosed=!1,e.file.closed.then(()=>{this.fileClosed=!0,this.finish()}),!this.available())return e.file.close(),this.stopResult();if(!yi(e.file.identity.session))return this.stop(`unbound`);this.document=new Fi(e.file.identity.agent,e.file.identity.session),e.file.identity.agent===`codex`?(this.header=new ji(e.file.identity.session),this.decoder=new pi):this.window(Math.max(0,e.file.size-Ri))}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?ii:this.target-this.decoder.offset,n=await e.read(this.decoder.offset,Math.max(1,Math.min(ii,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=Ai(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-Ri),this.catchingUp();this.document.append(n.lines.slice(1).map(t=>Ai(e.identity.agent,t)))}else!this.header&&n.lines.length&&this.document.append(n.lines.map(t=>Ai(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`):(this.currentRevision=t.state===`ready`?t.revision:null,this.target=null,{status:`snapshot`,snapshot:t,discontinuity:this.discontinuity,caughtUp:this.decoder.offset===e.size})}lagged(){return this.file.size-this.decoder.offset<=262144?!1:this.discontinuity===2**53-1?(this.stop(`unsafe`),!0):(this.discontinuity++,this.window(Math.max(0,this.file.size-ii)),!0)}window(e){this.anchors=new WeakSet,this.cancelOlder(),this.clearRaw(),this.decoder?.close(),this.decoder=new pi(e,e>0),this.document.beginWindow(e),this.target=this.file.size,this.currentRevision=null}clearRaw(){this.raw?.fill(0),this.raw=null,this.consumed=0}catchingUp(){return this.reason?this.stopResult():{status:`catching-up`,discontinuity:this.discontinuity}}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.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 Vi=2e3,Hi=`[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`,Ui=RegExp(`^${Hi}$`,`i`),Wi=RegExp(`^(${Hi})\\.jsonl$`,`i`),Gi=RegExp(`^rollout-\\d{4}-\\d{2}-\\d{2}T\\d{2}-\\d{2}-\\d{2}-(${Hi})(?:_(${Hi}))?\\.jsonl$`,`i`),Ki=[/^\d{4}$/,/^(0[1-9]|1[0-2])$/,/^(0[1-9]|[12]\d|3[01])$/];var H=class extends Error{reason;constructor(e){super(e),this.reason=e}};function qi(e){return P(e)&&e.length<=4096&&En(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 Ji(e,t){return e.dev===t.dev&&e.ino===t.ino}function Yi(e,t){return Ji(e,t)&&e.mtimeNs===t.mtimeNs&&e.ctimeNs===t.ctimeNs}function Xi(e){return process.getuid===void 0||e.uid===BigInt(process.getuid())}function Zi(e){return e?.code===`ENOENT`}function Qi(e,t){return t.endsWith(`.jsonl`)?(e===`claude`?Wi:Gi).exec(t)?.[1]?.toLowerCase()??null:null}function $i(e,t){return Ki[t]?.test(e)??!1}function ea(e,t){let n=t.split(kn);return P(t)||n.some(e=>e===``||e===`.`||e===`..`)||!Qi(e,n.at(-1))?!1:e===`claude`?n.length===2:n.length===1||n.length===4&&n.slice(0,3).every($i)}var ta=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`),Vi);t?.addEventListener(`abort`,c,{once:!0}),t?.aborted&&c();let u=(async()=>{try{let t=await new na(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 H?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)}}},na=class{options;reference;signal;deadline=performance.now()+Vi;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 H(`cancelled`);if(!this.options.enabled())throw new H(`disabled`);if(performance.now()>=this.deadline)throw new H(`limit`)}async run(){this.check();let{agent:e,kind:t,value:n}=this.reference;if(e!==`claude`&&e!==`codex`||t!==`id`&&t!==`path`||typeof n!=`string`)throw new H(`unsafe`);if(this.session=t===`id`?n.toLowerCase():Qi(e,wn(n))??``,!Ui.test(this.session)||t===`path`&&!qi(n))throw new H(`unbound`);let r=this.options.roots[e];if(!Array.isArray(r)||!r.length||r.length>8)throw new H(`unsafe`);let i=[...r],a=new Set;for(let e of i){if(this.check(),!qi(e))throw new H(`unsafe`);let t=!1;try{let n=await R(e);if(t=!0,this.check(),await this.directory(n),[...a].some(e=>e!==n&&(n.startsWith(e.endsWith(kn)?e:`${e}${kn}`)||e.startsWith(n.endsWith(kn)?n:`${n}${kn}`))))throw new H(`unsafe`);a.add(n)}catch(n){if(!Zi(n))throw n;if(t)throw new H(`changed`);try{throw await Vn(e),new H(`unsafe`)}catch(e){if(!Zi(e))throw e}this.check(),this.missingRoots.add(e)}}if(t===`path`){let t=[...a].find(t=>ea(e,Dn(t,n)));if(!t)throw new H(`unsafe`);let r=await Vn(n,{bigint:!0}).catch(e=>{throw Zi(e)?new H(`unbound`):e});if(this.check(),!r.isFile()||!Xi(r))throw new H(`unsafe`);let i=await R(n);if(this.check(),i!==n)throw new H(`unsafe`);let o=N(i);for(;o!==t;)await this.directory(o),o=N(o);await this.candidate(i);let s=this.candidates.get(i);if(!s||!Ji(r,s))throw new H(`changed`)}else for(let t of a)e===`claude`?await this.claude(t):await this.codex(t,0);for(let[e,t]of this.directories){this.check();let n=await Vn(e,{bigint:!0});if(this.check(),!n.isDirectory()||!Yi(t,n)||await R(e)!==e)throw new H(`changed`)}for(let e of this.missingRoots){this.check();try{throw await Vn(e,{bigint:!0}),new H(`changed`)}catch(e){if(!Zi(e))throw e}}if(!this.candidates.size)throw new H(`unbound`);let[o,s]=[...this.candidates][0],c=await Vn(o,{bigint:!0});if(this.check(),!c.isFile()||!Xi(c)||!Ji(s,c))throw new H(`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 H(`limit`);if(!qi(e))throw new H(`unsafe`);let t=await Vn(e,{bigint:!0});if(this.check(),!t.isDirectory()||!Xi(t)||await R(e)!==e)throw new H(`unsafe`);this.check(),this.directories.set(e,t)}async candidate(e){if(this.check(),!qi(e))throw new H(`unsafe`);let t;try{t=await Vn(e,{bigint:!0})}catch(e){if(Zi(e))return;throw e}if(this.check(),!t.isFile()||!Xi(t)||await R(e)!==e)throw new H(`unsafe`);if(this.check(),this.candidates.set(e,t),this.candidates.size>1)throw new H(`ambiguous`)}async visit(e,t){await this.directory(e),this.check();let n=await Wn(e,{bufferSize:32});try{for(;;){this.check();let e=await n.read();if(this.check(),!e)break;if(++this.entries>16384)throw new H(`limit`);await t(e.name)}}finally{await n.close()}}async claude(e){await this.visit(e,async t=>{let n=F(e,t),r=await Vn(n,{bigint:!0});if(this.check(),r.isSymbolicLink())throw new H(`unsafe`);r.isDirectory()&&(await this.directory(n),await this.candidate(F(n,`${this.session}.jsonl`)))})}async codex(e,t){await this.visit(e,async n=>{let r=F(e,n);if((t===0||t===3)&&Qi(`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 H(`unbound`);else t<3&&$i(n,t)&&await this.codex(r,t+1)})}},ra=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:[F(process.env.CLAUDE_CONFIG_DIR||F(M(),`.claude`),`projects`)],codex:[F(process.env.CODEX_HOME||F(M(),`.codex`),`sessions`)]},this.followers=e.followers??new zi,this.locator=e.locator??new ta({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=_.safeParse(e);if(!(!r.success||!Number.isSafeInteger(n)||n<1||n>E.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 ti({subscriptionId:e.subscriptionId,sessionId:n,now:()=>this.options.now?.()??performance.now(),newId:()=>this.options.newId?.()??Zt(pt(16)),enabled:i,follow:()=>this.followers.create({enabled:i,roots:this.roots,identity:ri({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(){this.closed||this.timer||![...this.entries].some(e=>e.source)||(this.timer=setTimeout(()=>{this.timer=null,this.pump()},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.schedule()}}};const ia=new Set([`bad-sig`,`fp-mismatch`]),aa=x.unacked*x.envelopeBytes;function oa(e){if(e.t!==`ctrl`)return!1;let t=e.body;return typeof t==`object`&&!!t&&t.type===`auth`}function sa(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 ca(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 la=class extends Ln{opts;ws=null;stopped=!0;attempt=0;reconnectTimer=null;pingTimer=null;pongTimer=null;authed=!1;relayWithholdsTurn=!1;ice=new or;log;constructor(e){super(),this.opts=e,this.log=e.log.child({unit:`relay`})}get online(){return this.authed&&this.ws?.readyState===qn.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&&!oa(e)?(this.log.debug(`dropped send: not authenticated`,{type:sa(e)}),!1):this.ws?.readyState===qn.OPEN?(this.ws.send(e.v===2?Le(e):Be(e),{binary:!0}),!0):(this.log.debug(`dropped send: socket not open`,{type:sa(e)}),!1)}sendBoundedEnvelope(e){let t=this.ws;if(!this.authed||t?.readyState!==qn.OPEN)return!1;let n=e.v===2?Le(e):Be(e);if(n.byteLength>x.envelopeBytes)return!1;let r=t.bufferedAmount;return typeof r!=`number`||!Number.isFinite(r)||r<0||r>aa-n.byteLength?!1:(t.send(n,{binary:!0}),!0)}connect(){if(this.stopped)return;let e=re(this.opts.relayUrl,this.opts.fp);this.log.info(`connecting`,{attempt:this.attempt});let t=new qn(e,{handshakeTimeout:1e4}),n=t;this.ws=t,t.on(`open`,()=>{this.ws===n&&this.log.debug(`socket open`)}),t.on(`message`,(e,t)=>{if(this.ws!==n||!t)return;let r=new Uint8Array(e),i;try{i=w(r)}catch(e){this.log.warn(`malformed frame from relay`,{code:e instanceof He?e.code:O(e)});return}if(i.t===`e2e`){this.authed&&this.emit(`e2e`,i,r.byteLength);return}let a;try{a=Vt(i.body)}catch(e){this.log.warn(`malformed ctrl from relay`,{code:e instanceof He?e.code:O(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:O(e)})})}onCtrl(e){if(e.type===`challenge`){let t=pe(this.opts.identity.ed25519.priv,We(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.ice=new or,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}),ia.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=ca(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===qn.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.reconnectTimer=this.pingTimer=this.pongTimer=null}},ua=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(!Oe.safeParse(e.subscriptionId).success||!ee.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 ge({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=ne(i);if(!a.ok)return this.close(a.code),!1;n=a.bytes}else{let{type:t,sessionId:r,...i}=e;n=v(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>=x.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>x.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>=x.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+x.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=se({...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()+x.progressMs}catch{this.close(`invalid-transfer`);return}if(this.open&&this.nativeHistory===e)try{da(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 D?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&&(da(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+x.progressMs),this.refusalAt!==null&&e.push(this.refusalAt+x.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 da(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{da(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{da(this.options.sendControl({type:`stream.error`,subscriptionId:this.options.subscriptionId,code:e}))}catch{}try{da(this.options.onClosed(e))}catch{}}};function da(e,t){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>t?.())}var fa=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()+x.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=se({...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()+x.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}:{}})}},pa=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 ma=new TextEncoder;var ha=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 pa;nextProbeAt=null;probeDeadline=null;probeToken=0;probePending=!1;probeExpired=!1;status=null;controlRetryAt=null;seeded=!1;constructor(e){this.options=e,this.extensions=Se(e.extensions,e.source.continuation?[...s,...e.source.history?[je]:[]]:[]),this.negotiationPending=e.extensions!==void 0,this.sender=new ge({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 fa({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?Ue(n.cols,s.lines.map(e=>e.r.map(e=>e.t).join(``))):null,l=ma.encode(r&&o&&!a?n.continuation.data:c?s.replay:n.data);if(l.length>x.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(ga(e)))}start(){return this.negotiationPending&&(this.negotiationDeadline=this.readClock()+x.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>x.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 ga(e){return e===`pane-gone`?`session-gone`:e===`herdr-unreadable`?`stalled`:`unsupported`}const _a=.6;var va=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 ya(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:O(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{ya(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:O(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 D)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:O(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:O(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:O(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 D)this.sessionRemoved(e);else{this.opts.onCaptureResult?.(e,n),this.log.warn(`getScreen failed; will retry`,{session:e.slice(0,12),err:O(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{ya(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,n,r,i,a){if(n.viewers.size===0)return;let o=this.opts.backend.capabilitiesOf?.(e)?.absoluteLines??this.opts.backend.capabilities.absoluteLines,s=r.lines.map(S),c=r.rows,l=0,u=!1,d=n.lastKeys.length===0||n.lastCols!==r.cols||n.lastRows!==r.rows;if(n.lastBackendScrollback===null)n.reported=r.scrollbackTotal;else{let e=r.scrollbackTotal-n.lastBackendScrollback;if(e<0)u=!0,d=!0,n.reported=r.scrollbackTotal;else if(e>=c)d=!0,n.reported+=e;else if(e>0)l=e,n.reported+=e;else if(!o&&!d&&ba(s,n.lastKeys,0)>_a*c){let e=xa(s,n.lastKeys,c);e>0&&(l=e,n.reported+=e)}}n.lastBackendScrollback=r.scrollbackTotal,this.opts.backend.setReported?.(e,n.reported);let f=[];if(!d){for(let e=0;e<c;e++){let t=e+l<n.lastKeys.length?n.lastKeys[e+l]:void 0;(t===void 0||t!==s[e])&&f.push({i:e,line:r.lines[e]})}f.length>_a*c&&(d=!0)}let p=!n.lastCursor||n.lastCursor.x!==r.cursor.x||n.lastCursor.y!==r.cursor.y,m=!d&&l===0&&f.length===0&&!p;m||(n.gen+=1);let h=m&&n.prepared?.gen===n.gen&&![...i].some(e=>e.needsHistory),g=this.opts.delivery===`scheduled`&&m&&n.prepared?.gen===n.gen?n.prepared:null;if(n.lastKeys=s,n.lastCols=r.cols,n.lastRows=r.rows,n.lastCursor=r.cursor,h)return;let _={sessionId:e,cursor:r.cursor,scrollbackTotal:n.reported,gen:n.gen},v=this.opts.maxEncodedBytes??262144,y,ee,b,x=()=>(y??={type:`screen.snapshot`,..._,cols:r.cols,rows:r.rows,lines:r.lines,reset:u||void 0},y),te=()=>{if(!b&&(b={...x(),lines:r.lines.map(Fe),degraded:!0},!n.oversizeWarned)){let r=t(b).byteLength;r>v&&(this.log.warn(`screen.snapshot exceeds maxEncodedBytes even after stripStyles`,{session:e.slice(0,12),bytes:r,maxEncodedBytes:v}),n.oversizeWarned=!0)}return b},ne=e=>e?te():(ee??=t(x()).byteLength,ee>v?te():x()),C={type:`screen.diff`,..._,scroll:l,changed:f},w=Object.freeze({generation:n.gen,reported:n.reported,historyRequested:a}),re=Object.freeze({...w,...r.historyCapture?{capture:r.historyCapture}:{}});n.prepared={gen:n.gen,diff:g?.diff??C,forceSnapshotAll:g?.forceSnapshotAll??(d||m),snapshotFor:ne,fullSnapshot:x,snapshotContext:re,diffContext:g?.diffContext??w,historyViewers:i}}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:O(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 ya(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}function ba(e,t,n){let r=0;for(let i=0;i<e.length;i++)t[i+n]!==e[i]&&r++;return r}function xa(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 Sa=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 Ca(e),TypeError(`wire producer must return a synchronous boolean`)}catch(n){this.remove(e,t.identity);try{Ca(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 Ca(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}var wa=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 ie))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 Sa({now:()=>this.options.now(),onError:()=>this.notifyError()}),this.tracker=new va({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<=x.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 ua({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 ha({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 ua&&t.stream.canOfferScreen()&&this.tracker.offerPrepared(t.trackerKey,(e,n)=>e.type!==`screen.snapshot`&&e.type!==`screen.diff`?!1:t.stream instanceof ua&&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(At(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 ua&&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{Ta(this.options.onSessionGone?.(e))}catch{}this.arm()}notifyError(){try{Ta(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 Ta(e){e===null||typeof e!=`object`&&typeof e!=`function`||new Promise(t=>t(e)).catch(()=>{})}const Ea=`\\u2800-\\u28FF\\u25D0-\\u25D3\\u2722\\u2733\\u2736\\u273B\\u273D\\u00B7\\u2022*`,Da=RegExp(`^[${Ea}][${Ea}\\uFE0F]*\\s+(?=\\S)`,`u`),Oa=/^[⠀-⣿]/u,ka=/^v?\d+(?:\.\d+)+$/;function Aa(e){return e.trim().replace(Da,``)}function ja(e){let t=e?.trim()??``;return Da.test(t)}function Ma(e){let t=e?.trim().toLowerCase()??``;return/^claude(?:[- ]code)?$/.test(t)?`claude`:/^codex(?:[- ]cli)?$/.test(t)?`codex`:V(t,32)}function Na(e,t){let n=Dr(e).toLowerCase();if(n===`claude`||n===`codex`)return n;if(n!==``&&n!==`node`&&!ka.test(n)||!ja(t))return;let r=t?.trim()??``;return Oa.test(r)&&/ \| [^|]+$/.test(r)?`codex`:`claude`}function Pa(e,t=M()){if(!e)return;let n=e=>e.replace(/[\\/]+$/,``);return t&&n(e)===n(t)?`~`:V(n(e).split(/[\\/]/).pop(),128)}const Fa=new Set([...Tr,`claude`,`codex`,`node`,`tmux`,`[tmux]`]);function Ia(e,t){let n=e.trim();if(n&&n!==t&&!n.endsWith(`[dead]`)&&!(Fa.has(n.toLowerCase())||ka.test(n)))return V(n,128)}function La(e){let t=Dr(e).toLowerCase();return!t||Er.has(t)?!1:Tr.has(t)||t===`claude`||t===`codex`||t===`node`||ka.test(t)}function Ra(e,t,n){if(!e)return;let r=Aa(e.replace(/[\r\n\t]+/g,` `));if(n.command){let e=` (${n.command})`;r.endsWith(e)&&(r=r.slice(0,-e.length).trimEnd())}let i=/ \| ([^|]+)$/.exec(r);i&&(t===`codex`||i[1]?.trim()===n.project||i[1]?.trim()===n.folder)&&(r=r.slice(0,i.index).trimEnd());let a=V(r,256);if(!a)return;let o=a.toLowerCase();if(![t,`claude`,`claude code`,`codex`,...n.ignore??[]].some(e=>e.toLowerCase()===o))return a}function za(e,t){return e.project===t.project&&e.agent?.kind===t.agent?.kind&&e.agent?.task===t.agent?.task}function Ba(e,t,n){let r={};return e&&(r.project=e),t&&(r.agent=n?{kind:t,task:n}:{kind:t}),r}function Va(e){let t=Pa(e.cwd),n=V(e.project,128)??t,r=Na(e.processName,e.title);if(!r)return Ba(n,void 0);let i=Dr(e.processName);return Ba(n,r,Ra(e.title,r,{project:n,folder:t,command:i||void 0,ignore:e.ignore}))}function Ha(e,t){let n=Pa(e.foreground_cwd??e.cwd??void 0),r=V(t,128)??n,i=Ma(e.agent||e.display_agent||void 0);return i?Ba(r,i,Ra(e.label||e.terminal_title_stripped||e.terminal_title||void 0,i,{project:r,folder:n,ignore:e.display_agent?[e.display_agent]:[]})):Ba(r,void 0)}var Ua=class{git;onChange;now;known=new Map;pending=new Set;constructor(e,t,n=Date.now){this.git=e,this.onChange=t,this.now=n}get size(){return this.known.size}lookup(e){if(!P(e)||e.length>1024)return;let t=this.known.get(e),n=this.now();return(!t||n<t.at||n-t.at>=3e4)&&this.refresh(e,t?.project),t?.project??void 0}refresh(e,t){if(this.pending.has(e)||this.pending.size>=16)return;this.pending.add(e);let n=new AbortController,r;try{r=this.git(e,n.signal)}catch{r=Promise.resolve(void 0)}r.catch(()=>void 0).then(n=>{let r=V(n?.repository,128)??null;for(this.known.delete(e);this.known.size>=256;){let e=this.known.keys().next().value;if(e===void 0)break;this.known.delete(e)}this.known.set(e,{project:r,at:this.now()}),r!==(t??null)&&this.onChange()}).finally(()=>{this.pending.delete(e),n.abort()})}};function Wa(e,n=Ft){let r=e=>t({type:`sessions`,list:e}).length<=n,i=[({agent:e,...t})=>e?{...t,agent:{kind:e.kind}}:t,({project:e,windowLabel:t,agent:n,...r})=>r,({project:e,windowLabel:t,agent:n,cwd:r,title:i,...a})=>({...a,title:Array.from(i).slice(0,Ga).join(``)})];if(r(e))return{type:`sessions`,list:e};let a=e;for(let t of i)if(a=e.map(t),r(a))return{type:`sessions`,list:a};let o=0,s=a.length;for(;o<s;){let e=Math.ceil((o+s)/2);r(a.slice(0,e))?o=e:s=e-1}return{type:`sessions`,list:a.slice(0,o)}}const Ga=64;function Ka(e){return`no conn.hello within ${e/1e3}s; ignoring this link until one arrives`}var qa=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=[];tick=null;sessionsDebounce=null;sessionsRefreshes=0;sessionsPublished=0;lastSeenSavedAt=new Map;log;localProcess;projects;stopped=!1;conversationsEnabled;get agentConversationsEnabled(){return!this.stopped&&this.conversationsEnabled}get configurationRevision(){return Ae({...this.o.config,showAgentConversations:this.conversationsEnabled})}applyConversationSetting(e){if(this.stopped)throw Error(`Agent stopped`);try{return It(this.o.paths,t=>(t.showAgentConversations!==!0&&this.setConversationConsent(!1),Ae(t)===e?(this.setConversationConsent(t.showAgentConversations===!0),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(Wt.parse(e.config))},this.o=e,this.conversationsEnabled=e.config.showAgentConversations===!0,this.log=e.log.child({unit:`agent`}),this.pairings=bt(e.paths);let t=Ar();this.projects=new Ua(t,()=>{this.stopped||this.scheduleSessions()}),e.registry.onSetupChanged(()=>{this.stopped||this.scheduleSessions()}),this.localProcess={pid:process.pid,agentVersion:e.appVersion,computerFp:e.fp,stateDir:hn(e.paths.dir),serviceInstance:e.serviceInstance??null};let n=e.relayUrlOverride??e.config.relayUrl;this.relay=e.relay??new la({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 wa({backend:e.registry,log:e.log,now:()=>Date.now(),newTransferId:()=>Zt(pt(16)),onSessionGone:()=>this.scheduleSessions(),onError:()=>this.log.warn(`terminal-view-delivery-failed`)}),this.conversations=new ra({backend:e.registry,enabled:()=>this.agentConversationsEnabled}),this.events=new Cr({notifyMinCommandMs:e.config.notifyMinCommandMs,idleQuietMs:e.config.idleQuietMs,idleMinActiveMs:e.config.idleMinActiveMs}),this.notificationState=new Rr(e.paths),this.notificationState.retain(new Set(this.pairings.map(e=>e.phoneFp)));let r=new Pr({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 Br(e=>this.relay.sendCtrl(e),e.log,Date.now,e=>r.prepare(e)),this.pairing=new qr({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),confirm:e.confirm,pairingCount:()=>this.pairings.length,log:e.log,onClose:()=>this.o.onPairingClosed?.()}),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:O(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()})},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(Ka(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=bt(this.o.paths).find(t=>t.phoneFp===e);if(!r||!i||t.length!==32)throw Error(`shellbell: pairing changed before protocol upgrade`);let a=T(i.kPair);if(a.length!==32||r.kPair!==i.kPair||r.ed25519Pub!==i.ed25519Pub||r.x25519Pub!==i.x25519Pub||!In(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=at(this.o.paths,o),n!==this.linkForPhone(e)&&this.dropLinkFor(e)}removePairing(e){let t=this.pairings.filter(t=>t!==e);return this.pairings=at(this.o.paths,t),this.notificationState.forget(e.phoneFp),this.relay.sendCtrl({type:`unpair`,phoneFp:e.phoneFp}),this.pairRequests.delete(e.phoneFp),this.dropLinkFor(e.phoneFp),this.lastSeenSavedAt.delete(e.phoneFp),!0}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=Yt(t,e),r=[...this.pairings.filter(t=>t.phoneFp!==e.phoneFp),n];this.pairings=at(this.o.paths,r),this.notificationState.forget(e.phoneFp),(t?.kPair!==e.kPair||t?.ed25519Pub!==e.ed25519Pub||t?.x25519Pub!==e.x25519Pub)&&(this.pairRequests.delete(e.phoneFp),this.dropLinkFor(e.phoneFp))}acceptsRelayUnpair(e,t){if(e.minProtocolVersion!==2)return!0;if(!t)return!1;try{return it(t,{computerFp:this.o.fp,phoneFp:e.phoneFp,kPair:T(e.kPair),phoneEd25519Pub:T(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=at(this.o.paths,i)),this.notificationState.forget(e),this.pairRequests.delete(e),this.dropLinkFor(e),this.lastSeenSavedAt.delete(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=at(this.o.paths,e);for(let e of r)this.notificationState.forget(e),this.pairRequests.delete(e),this.dropLinkFor(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:T(e.ed25519Pub),name:e.name,pairId:et(T(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=at(this.o.paths,this.pairings))}newV2Link(e,t,n){let r=T(e.kPair),i;return i=new ei({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:T(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(Wa(this.sessions))))}helloMessage(e=this.o.registry.connected()){return{type:`hello`,features:[Ot,le],conversationEnabled:this.agentConversationsEnabled,agentVersion:this.o.appVersion,hostPlatform:wr(process.platform),backends:e.filter(e=>y.includes(e.name)),launchableBackends:this.o.registry.launchable().filter(e=>y.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)&&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(Vr(t)){let n=this.pairRequests.get(e.phoneFp);n||(n=new Hr,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,yt(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 D(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 Ie?t.message:t instanceof D?`session-gone`:t instanceof e?`unsupported`:t instanceof ze?`bad-window`:t instanceof _e?t.code:`failed`;return this.log.warn(`inner message failed`,{type:n.type,error:r,err:O(t)}),`reqId`in n?s(n.reqId,r):null}}broadcast(e){for(let t of this.links.values())t.send(e)}onBackendEvent(e){switch(this.events.onBackendEvent(e),e.type){case`screen-changed`:return;case`session-removed`:this.notifier.forget(e.sessionId),this.events.forget(e.sessionId),this.scheduleSessions();return;case`layout-changed`:case`session-added`:case`focus-changed`:case`title-changed`:case`command-start`:case`command-end`:case`prompt`:case`agent-state`:this.scheduleSessions();return;default:return}}scheduleSessions(){this.sessionsDebounce||=setTimeout(()=>{this.sessionsDebounce=null,this.refreshSessions()},100)}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,this.sessions=t.map(e=>{let t=this.o.registry.projectFolder(e.id),n=t?this.projects.lookup(t):void 0,r=n?{...e,project:n}:e,i=this.events.stateOf(r.id);return i===`unknown`?r:{...r,state:i}}),this.broadcast(Wa(this.sessions))}catch(e){this.log.warn(`listSessions failed`,{err:O(e)})}finally{this.broadcastHelloIfBackendProfilesChanged()}}};const Ja=[0,7,2],Ya=`Install Herdr: curl -fsSL https://herdr.dev/install.sh | sh, then start it with "herdr".`,Xa=`Upgrade Herdr to 0.7.2 or newer: curl -fsSL https://herdr.dev/install.sh | sh, then restart it.`;var U=class extends Error{code;constructor(e,t){super(`herdr ${e}: ${t}`),this.code=e,this.name=`HerdrError`}};const Za=new Set([`not_found`,`pane_not_found`,`stale_pane_target`]),Qa=new Set([`invalid_request`,`unsupported`,`unknown_method`,`method_not_found`]);function $a(e,t){let n=/^\s*v?(\d+)\.(\d+)\.(\d+)/.exec(e);if(!n)return null;let r=[Number(n[1]),Number(n[2]),Number(n[3])];for(let e=0;e<3;e++){let n=r[e],i=t[e];if(n!==i)return n>i}return!0}function eo(e=process.env,t=M()){let n=e.HERDR_SOCKET_PATH;if(n)return n;let r=e.XDG_CONFIG_HOME?F(e.XDG_CONFIG_HOME,`herdr`):F(t,`.config`,`herdr`),i=e.HERDR_SESSION;return i?F(r,`sessions`,i,`herdr.sock`):F(r,`herdr.sock`)}function to(e,t,n){let r=e.code??``;return r===`ENOENT`||r===`ECONNREFUSED`||r===`EACCES`||r===`EPERM`?new U(`unavailable`,`cannot reach the herdr socket at ${n} (${r})`):new U(`socket`,`${t}: ${e.message}`)}function no(e,t,n,r=1048576){let i=new Jn(`utf8`),a=``;e.on(`data`,e=>{a+=i.write(e);let o=a.indexOf(`
5
7
  `);for(;o>=0;){let e=a.slice(0,o);a=a.slice(o+1),e.trim()&&t(e),o=a.indexOf(`
6
- `)}Buffer.byteLength(a,`utf8`)>r&&(a=``,n())})}var Oi=class{opts;log;nextId=1;constructor(e){this.opts=e,this.log=e.log.child({unit:`herdr`})}get socketPath(){return this.opts.socketPath??Ti()}request(e,t={}){let n=`sb${this.nextId++}`,r=this.opts.requestTimeoutMs??5e3,i=this.socketPath;return new Promise((a,o)=>{let s=!1,c=wn({path:i}),l=(e,t)=>{s||(s=!0,clearTimeout(u),c.destroy(),e?o(e):a(t))},u=setTimeout(()=>l(new H(`timeout`,`${e} did not answer within ${r} ms`)),r);c.on(`connect`,()=>{c.write(`${JSON.stringify({id:n,method:e,params:t})}\n`)}),Di(c,t=>{let r;try{r=JSON.parse(t)}catch{l(new H(`malformed`,`${e} answered with a non-JSON line`));return}if(r.id!==void 0&&r.id!==n&&this.log.debug(`herdr echoed a different id`,{method:e}),r.error){l(new H(r.error.code||`error`,r.error.message||e));return}if(r.result===void 0||r.result===null){l(new H(`malformed`,`${e} answered without a result`));return}l(null,r.result)},()=>l(new H(`overflow`,`${e} answered with an oversized line`)),8388608),c.on(`error`,t=>l(Ei(t,e,i))),c.on(`close`,()=>l(new H(`closed`,`herdr closed the connection before answering ${e}`)))})}subscribe(e,t){let n=`sb${this.nextId++}`,r=this.opts.requestTimeoutMs??5e3,i=this.socketPath;return new Promise((a,o)=>{let s=wn({path:i}),c=!1,l=!1,u=!1,d={close(){u=!0,s.destroy()}},f=e=>{c||(clearTimeout(m),s.destroy(),o(e))},p=e=>{l||(l=!0,t.onEnd(u?`closed`:e))},m=setTimeout(()=>f(new H(`timeout`,`events.subscribe was not acknowledged`)),r);s.on(`connect`,()=>{s.write(`${JSON.stringify({id:n,method:`events.subscribe`,params:{subscriptions:e}})}\n`)}),Di(s,e=>{let n;try{n=JSON.parse(e)}catch{this.log.warn(`undecodable herdr stream line`,{chars:e.length});return}if(!c){if(n.error){f(new H(n.error.code||`error`,n.error.message||`events.subscribe`));return}let e=n.result?.type;if(e!==`subscription_started`){f(new H(`malformed`,`events.subscribe answered ${e}`));return}c=!0,clearTimeout(m),a(d);return}if(typeof n.event==`string`){let e=n.data&&typeof n.data==`object`?n.data:{};t.onEvent({event:n.event,data:e})}},()=>{c?(s.destroy(),p(`overflow`)):f(new H(`overflow`,`events.subscribe line too long`))}),s.on(`error`,e=>{c?p(`error`):f(Ei(e,`events.subscribe`,i))}),s.on(`close`,()=>{if(!c){f(new H(`closed`,`herdr closed the connection before acknowledging the stream`));return}p(`eof`)})})}async ping(){let e;try{e=await this.request(`ping`,{})}catch(e){let t=e instanceof Error?e.message:String(e);throw new j(t,bi)}let t=typeof e.version==`string`?e.version:``,n=wi(t,yi);if(n===!1)throw new j(`herdr ${t} is older than 0.7.2 (session.snapshot and scroll metrics landed there)`,xi);return n===null&&this.log.warn(`herdr reported an unparseable version; relying on the feature probe`),this.log.debug(`herdr ping ok`,{version:/^\d{1,4}\.\d{1,4}\.\d{1,4}$/.test(t)?t:`unknown`,protocol:typeof e.protocol==`number`&&Number.isSafeInteger(e.protocol)&&e.protocol>=0?e.protocol:`unknown`}),e}};function ki(e){if(e===``)return[];let t=e.split(`
7
- `);return t.length>1&&t[t.length-1]===``&&t.pop(),t.map(Yn)}function Ai(e,t){if(e.length>t)return e.slice(e.length-t);let n=e.slice();for(;n.length<t;)n.push(ge());return n}function ji(e){return e.r.reduce((e,t)=>e+(t.n??Wn(t.t)),0)}function Mi(e,t){let n=Math.max(0,t-1);for(let t=e.length-1;t>=0;t--){let r=e[t];if(r.r.some(e=>e.t.trim().length>0))return{x:Math.min(n,ji(r)),y:t}}return{x:0,y:0}}function Ni(e){let t=Math.max(1,e.rows),n=Math.max(1,e.cols),r=Ai(ki(e.text),t);return{cols:n,rows:t,cursor:Mi(r,n),lines:r,scrollbackTotal:Math.max(0,e.scrollMax)}}function Pi(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function Fi(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function Ii(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0}function Li(e,t,n){if(!Pi(e)||e.type!==`pane_info`||!Pi(e.pane))return null;let r=e.pane;if(typeof r.pane_id!=`string`||r.pane_id.length===0||r.pane_id!==t||typeof r.terminal_id!=`string`||r.terminal_id.length===0||r.terminal_id!==n||!Fi(r.revision)||!Pi(r.scroll))return null;let i=r.scroll;return!Fi(i.offset_from_bottom)||!Fi(i.max_offset_from_bottom)||!Ii(i.viewport_rows)||i.offset_from_bottom>i.max_offset_from_bottom||i.max_offset_from_bottom>2**53-1-i.viewport_rows?null:{paneId:r.pane_id,terminalId:r.terminal_id,revision:r.revision,history:i.max_offset_from_bottom,viewportRows:i.viewport_rows,offset:i.offset_from_bottom}}function Ri(e,t){if(!Ii(t.rows)||!Ii(t.cols)||t.minRows!==void 0&&(!Fi(t.minRows)||t.minRows>t.rows)||typeof t.paneId!=`string`||t.paneId.length===0||t.source!==`visible`&&t.source!==`recent`||!Pi(e)||e.type!==`pane_read`||!Pi(e.read))return null;let n=e.read;if(typeof n.pane_id!=`string`||n.pane_id.length===0||n.pane_id!==t.paneId||n.source!==t.source||n.format!==`ansi`||typeof n.text!=`string`||typeof n.truncated!=`boolean`)return null;let r=ki(n.text);return r.length<(t.minRows??t.rows)||r.length>t.rows||r.some(e=>ji(e)>t.cols)?null:r}function zi(e,t){let{visible:n,historyRows:r,viewportRows:i,requestedRows:a}=t;if(n.length===0||n.length>i)return null;let o=i-n.length,s=Ri(e,{paneId:t.paneId,source:`recent`,cols:t.cols,rows:a,minRows:Math.max(n.length,Math.min(a,r+i)-o)});if(!s||!kn(s.slice(-n.length),n))return null;let c=r+n.length-s.length;return c>=0?{from:c,lines:s}:null}const Bi=An(zt),Vi={iTerm:`iTerm2`},Hi=/\/([^/]+)\.app\/Contents\/MacOS\//;function Ui(e){let t=new Map;for(let n of e.split(`
8
- `)){let e=/^\s*(\d+)\s+(\d+)\s+(.*)$/.exec(n);e&&t.set(Number(e[1]),{ppid:Number(e[2]),args:e[3]})}return t}async function Wi(){if(process.platform===`darwin`)try{let{stdout:e}=await Bi(`/bin/ps`,[`-axww`,`-o`,`pid=,ppid=,args=`],{timeout:2e3,maxBuffer:8388608});return Ui(e)}catch{return}}function Gi(e,t){let n=t.get(e)?.ppid;for(let e=0;n!==void 0&&n>1&&e<32;e++){let e=t.get(n);if(!e)return;let r=Hi.exec(e.args)?.[1];if(r)return Vi[r]??r;n=e.ppid}}function Ki(e){let[t,...n]=e.trim().split(/\s+/);if(t&&un(t)===`herdr`){if(n.length===0)return``;if(n[0]===`--session`&&n.length===2)return n[1];if(n.length===1&&n[0].startsWith(`--session=`))return n[0].slice(10);if(n[0]===`session`&&n[1]===`attach`&&n.length===3)return n[2]}}function qi(e,t,n=process.env){let r=new Set;for(let[i,a]of e){let o=Ki(a.args);if(o===void 0||Ti({XDG_CONFIG_HOME:n.XDG_CONFIG_HOME,...o?{HERDR_SESSION:o}:{}})!==t)continue;let s=Gi(i,e);s&&r.add(s)}return[...r].sort((e,t)=>e.localeCompare(t)).slice(0,4)}async function Ji(e){let t=await Wi();return t&&qi(t,e)}const Yi=Xi();function Xi(){let e={enter:`enter`,tab:`tab`,"shift-tab":`shift+tab`,esc:`esc`,backspace:`backspace`,up:`up`,down:`down`,left:`left`,right:`right`};for(let t of Object.keys(vt))/^ctrl-[a-z]$/.test(t)?e[t]=`ctrl+${t.slice(5)}`:/^f([1-9]|1[0-2])$/.test(t)&&(e[t]=t);return e}const Zi=Qi();function Qi(){let e=new Map([[`\r`,`enter`],[`
9
- `,`enter`],[` `,`tab`]]);for(let[t,n]of Object.entries(vt)){let r=Yi[t];r&&!e.has(n)&&e.set(n,r)}return e}function $i(e){return Zi.get(e)}const ea=[`.local/bin`,`.cargo/bin`];function ta(e,t=process.env,n=e=>{try{return Vt(e,N.X_OK),rn(e).isFile()}catch{return!1}}){let r=t.HOME||P(),i=I(r)?ea.map(e=>L(r,e)):[];return[...t.PATH?.split(dn)??[],...i].map(t=>pn(t,e)).find(n)}const na=An(zt);function ra(e=process.env,t){return ta(`herdr`,e,t)}async function ia(e={}){let t=e.platform??process.platform,n;try{if(t===`darwin`)n=await oa(e);else if(t===`linux`)n=sa(e);else return}catch{return}let r=[...new Set(n)],i=e.executable??ca;return r.length===1&&I(r[0])&&i(r[0])?r[0]:void 0}function aa(e){return e.length===2&&un(e[0])===`herdr`&&e[1]===`server`}async function oa(e){let t=e.ps??(async e=>(await na(`/bin/ps`,e,{timeout:2e3,maxBuffer:8388608})).stdout),n=(await t([`-x`,`-ww`,`-o`,`pid=,args=`])).split(`
8
+ `)}Buffer.byteLength(a,`utf8`)>r&&(a=``,n())})}var ro=class{opts;log;nextId=1;constructor(e){this.opts=e,this.log=e.log.child({unit:`herdr`})}get socketPath(){return this.opts.socketPath??eo()}request(e,t={},n={}){let r=n.signal;if(r?.aborted)return Promise.reject(new U(`cancelled`,`request cancelled`));let i=`sb${this.nextId++}`,a=this.opts.requestTimeoutMs??5e3,o=this.socketPath;return new Promise((n,s)=>{let c=!1,l=Rn({path:o}),u=(e,t)=>{c||(c=!0,clearTimeout(d),r?.removeEventListener(`abort`,f),l.destroy(),e?s(e):n(t))},d=setTimeout(()=>u(new U(`timeout`,`${e} did not answer within ${a} ms`)),a),f=()=>u(new U(`cancelled`,`request cancelled`));r?.addEventListener(`abort`,f,{once:!0}),l.on(`connect`,()=>{c||l.write(`${JSON.stringify({id:i,method:e,params:t})}\n`)}),no(l,t=>{let n;try{n=JSON.parse(t)}catch{u(new U(`malformed`,`${e} answered with a non-JSON line`));return}if(n.id!==void 0&&n.id!==i&&this.log.debug(`herdr echoed a different id`,{method:e}),n.error){u(new U(n.error.code||`error`,n.error.message||e));return}if(n.result===void 0||n.result===null){u(new U(`malformed`,`${e} answered without a result`));return}u(null,n.result)},()=>u(new U(`overflow`,`${e} answered with an oversized line`)),8388608),l.on(`error`,t=>u(to(t,e,o))),l.on(`close`,()=>u(new U(`closed`,`herdr closed the connection before answering ${e}`))),r?.aborted&&f()})}subscribe(e,t){let n=`sb${this.nextId++}`,r=this.opts.requestTimeoutMs??5e3,i=this.socketPath;return new Promise((a,o)=>{let s=Rn({path:i}),c=!1,l=!1,u=!1,d={close(){u=!0,s.destroy()}},f=e=>{c||(clearTimeout(m),s.destroy(),o(e))},p=e=>{l||(l=!0,t.onEnd(u?`closed`:e))},m=setTimeout(()=>f(new U(`timeout`,`events.subscribe was not acknowledged`)),r);s.on(`connect`,()=>{s.write(`${JSON.stringify({id:n,method:`events.subscribe`,params:{subscriptions:e}})}\n`)}),no(s,e=>{let n;try{n=JSON.parse(e)}catch{this.log.warn(`undecodable herdr stream line`,{chars:e.length});return}if(!c){if(n.error){f(new U(n.error.code||`error`,n.error.message||`events.subscribe`));return}let e=n.result?.type;if(e!==`subscription_started`){f(new U(`malformed`,`events.subscribe answered ${e}`));return}c=!0,clearTimeout(m),a(d);return}if(typeof n.event==`string`){let e=n.data&&typeof n.data==`object`?n.data:{};t.onEvent({event:n.event,data:e})}},()=>{c?(s.destroy(),p(`overflow`)):f(new U(`overflow`,`events.subscribe line too long`))}),s.on(`error`,e=>{c?p(`error`):f(to(e,`events.subscribe`,i))}),s.on(`close`,()=>{if(!c){f(new U(`closed`,`herdr closed the connection before acknowledging the stream`));return}p(`eof`)})})}async ping(){let e;try{e=await this.request(`ping`,{})}catch(e){let t=e instanceof Error?e.message:String(e);throw new C(t,Ya)}let t=typeof e.version==`string`?e.version:``,n=$a(t,Ja);if(n===!1)throw new C(`herdr ${t} is older than 0.7.2 (session.snapshot and scroll metrics landed there)`,Xa);return n===null&&this.log.warn(`herdr reported an unparseable version; relying on the feature probe`),this.log.debug(`herdr ping ok`,{version:/^\d{1,4}\.\d{1,4}\.\d{1,4}$/.test(t)?t:`unknown`,protocol:typeof e.protocol==`number`&&Number.isSafeInteger(e.protocol)&&e.protocol>=0?e.protocol:`unknown`}),e}};function io(e){if(typeof e!=`object`||!e||Array.isArray(e))return null;let t=e;return t.agent!==`claude`&&t.agent!==`codex`||t.source!==`herdr:${t.agent}`||typeof t.value!=`string`?null:t.kind===`id`&&/^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,255}$/.test(t.value)?Object.freeze({agent:t.agent,kind:`id`,value:t.value}):t.kind===`path`&&t.value.length<=4096&&P(t.value)&&En(t.value)===t.value&&t.value.endsWith(`.jsonl`)&&!Array.from(t.value).some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)>=127&&e.charCodeAt(0)<=159||e.length===1&&e.charCodeAt(0)>=55296&&e.charCodeAt(0)<=57343)?Object.freeze({agent:t.agent,kind:`path`,value:t.value}):null}function ao(e){if(e===``)return[];let t=e.split(`
9
+ `);return t.length>1&&t[t.length-1]===``&&t.pop(),t.map(gr)}function oo(e,t){if(e.length>t)return e.slice(e.length-t);let n=e.slice();for(;n.length<t;)n.push(Me());return n}function so(e){return e.r.reduce((e,t)=>e+(t.n??dr(t.t)),0)}function co(e,t){let n=Math.max(0,t-1);for(let t=e.length-1;t>=0;t--){let r=e[t];if(r.r.some(e=>e.t.trim().length>0))return{x:Math.min(n,so(r)),y:t}}return{x:0,y:0}}function lo(e){let t=Math.max(1,e.rows),n=Math.max(1,e.cols),r=oo(ao(e.text),t);return{cols:n,rows:t,cursor:co(r,n),lines:r,scrollbackTotal:Math.max(0,e.scrollMax)}}function uo(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function fo(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function po(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>0}function mo(e,t,n){if(!uo(e)||e.type!==`pane_info`||!uo(e.pane))return null;let r=e.pane;if(typeof r.pane_id!=`string`||r.pane_id.length===0||r.pane_id!==t||typeof r.terminal_id!=`string`||r.terminal_id.length===0||r.terminal_id!==n||!fo(r.revision)||!uo(r.scroll))return null;let i=r.scroll;return!fo(i.offset_from_bottom)||!fo(i.max_offset_from_bottom)||!po(i.viewport_rows)||i.offset_from_bottom>i.max_offset_from_bottom||i.max_offset_from_bottom>2**53-1-i.viewport_rows?null:{paneId:r.pane_id,terminalId:r.terminal_id,revision:r.revision,history:i.max_offset_from_bottom,viewportRows:i.viewport_rows,offset:i.offset_from_bottom}}function ho(e,t){if(!po(t.rows)||!po(t.cols)||t.minRows!==void 0&&(!fo(t.minRows)||t.minRows>t.rows)||typeof t.paneId!=`string`||t.paneId.length===0||t.source!==`visible`&&t.source!==`recent`||!uo(e)||e.type!==`pane_read`||!uo(e.read))return null;let n=e.read;if(typeof n.pane_id!=`string`||n.pane_id.length===0||n.pane_id!==t.paneId||n.source!==t.source||n.format!==`ansi`||typeof n.text!=`string`||typeof n.truncated!=`boolean`)return null;let r=ao(n.text);return r.length<(t.minRows??t.rows)||r.length>t.rows||r.some(e=>so(e)>t.cols)?null:r}function go(e,t){let{visible:n,historyRows:r,viewportRows:i,requestedRows:a}=t;if(n.length===0||n.length>i)return null;let o=i-n.length,s=ho(e,{paneId:t.paneId,source:`recent`,cols:t.cols,rows:a,minRows:Math.max(n.length,Math.min(a,r+i)-o)});if(!s||!Yn(s.slice(-n.length),n))return null;let c=r+n.length-s.length;return c>=0?{from:c,lines:s}:null}const _o=Xn(A),vo={iTerm:`iTerm2`},yo=/\/([^/]+)\.app\/Contents\/MacOS\//;function bo(e){let t=new Map;for(let n of e.split(`
10
+ `)){let e=/^\s*(\d+)\s+(\d+)\s+(.*)$/.exec(n);e&&t.set(Number(e[1]),{ppid:Number(e[2]),args:e[3]})}return t}async function xo(){if(process.platform===`darwin`)try{let{stdout:e}=await _o(`/bin/ps`,[`-axww`,`-o`,`pid=,ppid=,args=`],{timeout:2e3,maxBuffer:8388608});return bo(e)}catch{return}}function So(e,t){let n=t.get(e)?.ppid;for(let e=0;n!==void 0&&n>1&&e<32;e++){let e=t.get(n);if(!e)return;let r=yo.exec(e.args)?.[1];if(r)return vo[r]??r;n=e.ppid}}function Co(e){let[t,...n]=e.trim().split(/\s+/);if(t&&wn(t)===`herdr`){if(n.length===0)return``;if(n[0]===`--session`&&n.length===2)return n[1];if(n.length===1&&n[0].startsWith(`--session=`))return n[0].slice(10);if(n[0]===`session`&&n[1]===`attach`&&n.length===3)return n[2]}}function wo(e,t,n=process.env){let r=new Set;for(let[i,a]of e){let o=Co(a.args);if(o===void 0||eo({XDG_CONFIG_HOME:n.XDG_CONFIG_HOME,...o?{HERDR_SESSION:o}:{}})!==t)continue;let s=So(i,e);s&&r.add(s)}return[...r].sort((e,t)=>e.localeCompare(t)).slice(0,4)}async function To(e){let t=await xo();return t&&wo(t,e)}const Eo=Do();function Do(){let e={enter:`enter`,tab:`tab`,"shift-tab":`shift+tab`,esc:`esc`,backspace:`backspace`,up:`up`,down:`down`,left:`left`,right:`right`};for(let t of Object.keys(Ze))/^ctrl-[a-z]$/.test(t)?e[t]=`ctrl+${t.slice(5)}`:/^f([1-9]|1[0-2])$/.test(t)&&(e[t]=t);return e}const Oo=ko();function ko(){let e=new Map([[`\r`,`enter`],[`
11
+ `,`enter`],[` `,`tab`]]);for(let[t,n]of Object.entries(Ze)){let r=Eo[t];r&&!e.has(n)&&e.set(n,r)}return e}function Ao(e){return Oo.get(e)}const jo=[`.local/bin`,`.cargo/bin`];function Mo(e,t=process.env,n=e=>{try{return en(e,j.X_OK),_n(e).isFile()}catch{return!1}}){let r=t.HOME||M(),i=P(r)?jo.map(e=>F(r,e)):[];return[...t.PATH?.split(Tn)??[],...i].map(t=>On(t,e)).find(n)}const No=Xn(A);function Po(e=process.env,t){return Mo(`herdr`,e,t)}async function Fo(e={}){let t=e.platform??process.platform,n;try{if(t===`darwin`)n=await Lo(e);else if(t===`linux`)n=Ro(e);else return}catch{return}let r=[...new Set(n)],i=e.executable??zo;return r.length===1&&P(r[0])&&i(r[0])?r[0]:void 0}function Io(e){return e.length===2&&wn(e[0])===`herdr`&&e[1]===`server`}async function Lo(e){let t=e.ps??(async e=>(await No(`/bin/ps`,e,{timeout:2e3,maxBuffer:8388608})).stdout),n=(await t([`-x`,`-ww`,`-o`,`pid=,args=`])).split(`
10
12
  `).flatMap(e=>{let t=/^\s*(\d+)\s+(?:.*\/)?herdr server\s*$/.exec(e);return t?[t[1]]:[]});return n.length===0?[]:(await t([`-ww`,`-o`,`comm=`,`-p`,n.join(`,`)])).split(`
11
- `).map(e=>e.trim()).filter(e=>un(e)===`herdr`)}function sa(e){let t=e.procRoot??`/proc`,n=e.uid??process.getuid?.(),r=[];for(let e of $t(t))if(/^\d+$/.test(e))try{if(n!==void 0&&rn(L(t,e)).uid!==n)continue;let i=Zt(L(t,e,`cmdline`),`latin1`).split(`\0`);if(i.at(-1)===``&&i.pop(),!aa(i))continue;let a=en(L(t,e,`exe`));a.endsWith(` (deleted)`)||r.push(a)}catch{}return r}function ca(e){try{return Vt(e,N.X_OK),rn(e).isFile()}catch{return!1}}const la=An(zt);var ua=class{opts;executable;issue;env;active=new Map;generation=0;constructor(e){this.opts=e,this.env={...e.env??process.env,HERDR_SOCKET_PATH:e.socketPath}}get available(){return this.executable!==void 0}get verifiedExecutable(){return this.executable===void 0?void 0:pn(this.executable)}get unavailableReason(){return this.executable===void 0?this.issue:void 0}async configure(e){this.close();let t=this.generation;if(!e||wi(e,[0,9,3])!==!0){this.issue=`Update Herdr to 0.9.3 or newer to open Herdr sessions from your phone${e?` (this computer runs ${e.replace(/^v/,``)})`:``}.`;return}let n=this.opts.executable===void 0&&this.defaultSocket()?await(this.opts.findRunningServer??ia)():void 0;if(t!==this.generation)return;let r=this.opts.executable?[this.opts.executable]:[...new Set([n,ra(this.env)])].filter(e=>e!==void 0);if(r.length===0){this.issue=`Herdr is running, but Shellbell can't find the herdr program. Install it in ~/.local/bin, /opt/homebrew/bin or /usr/local/bin.`;return}let i=e.replace(/^v/,``),a;for(let e of r){let n;try{let t=this.opts.readVersion?await this.opts.readVersion(e):(await la(e,[`--version`],{env:this.env,timeout:3e3,maxBuffer:4096})).stdout;n=/\b(?:herdr\s+)?v?(\d+\.\d+\.\d+(?:-[\w.-]+)?)/.exec(t)?.[1]}catch{if(t!==this.generation)return;a??=`Shellbell couldn't run the herdr program. Reinstall Herdr on this computer.`;continue}if(t!==this.generation)return;if(n===i){this.executable=e;return}a??=n?`The herdr program (${n}) and the running Herdr (${i}) are different versions. Quit Herdr and open it again.`:`Shellbell couldn't read the herdr program's version. Reinstall Herdr on this computer.`}this.issue=a}defaultSocket(){let{HERDR_SOCKET_PATH:e,HERDR_SESSION:t,...n}=this.env;return pn(this.opts.socketPath)===pn(Ti(n))}close(){this.generation++,this.executable=void 0,this.issue=void 0;for(let e of this.active.values())e();this.active.clear()}async click(e,t,n){let r=this.executable;if(!r||!n()||this.active.has(e)||this.active.size>=4)throw new E(`mouse control unavailable`);if(t.column>=t.cols||t.row>=t.rows)throw new E(`mouse coordinates`);let i=this.generation,a=[`terminal`,`session`,`control`,e,`--cols`,String(t.cols),`--rows`,String(t.rows)],o=this.opts.spawn?this.opts.spawn(r,a,this.env):Bt(r,a,{env:this.env,stdio:[`pipe`,`pipe`,`pipe`]});await new Promise((r,a)=>{let s=!1,c=!1,l=Buffer.alloc(0),u=t=>{s||(s=!0,clearTimeout(f),this.active.delete(e),o.kill(`SIGKILL`),t?a(t):r())},d=()=>u(c?Error(`mouse delivery unknown`):new E(`mouse control unavailable`)),f=setTimeout(d,this.opts.timeoutMs??3e3);this.active.set(e,d),o.on(`error`,d),o.stdin.on(`error`,d),o.stderr.resume(),o.stdout.on(`data`,e=>{if(s||c)return;if(l=Buffer.concat([l,e]),l.length>1048576)return d();let r=l.indexOf(10);if(r<0)return;let a;try{a=JSON.parse(l.subarray(0,r).toString(`utf8`))}catch{return d()}if(a.type!==`terminal.frame`||a.width!==t.cols||a.height!==t.rows||i!==this.generation||!n())return d();c=!0,l=Buffer.alloc(0);let u={type:`terminal.mouse`,button:t.button,column:t.column,row:t.row,modifiers:t.modifiers};o.stdin.end(`${[{...u,action:`down`},{...u,action:`up`},{type:`terminal.release`}].map(e=>JSON.stringify(e)).join(`
12
- `)}\n`)}),o.on(`close`,e=>u(e===0&&c?void 0:c?Error(`mouse delivery unknown`):new E(`mouse control unavailable`)))})}},da=class{options;run;timer;busy=!1;watched=new Set;observations=new Map;watchedMs;backgroundMs;constructor(e){this.options=e,this.watchedMs=Math.max(125,e.watchedMs??125),this.backgroundMs=Math.max(this.watchedMs,e.backgroundMs??1e3)}start(){this.timer&&clearTimeout(this.timer),this.timer=void 0,this.run={};for(let e of this.observations.values())e.due=0;this.schedule()}stop(){this.run=void 0,this.timer&&clearTimeout(this.timer),this.timer=void 0,this.observations.clear()}setWatched(e){let t=new Set(e);for(let e of t)if(!this.watched.has(e)){let t=this.observations.get(e);t&&(t.due=0)}this.watched=t}schedule(){this.run&&!this.timer&&(this.timer=setTimeout(()=>{this.timer=void 0,this.pass().catch(()=>this.reportFailure())},this.watchedMs),this.timer.unref?.())}async pass(){let e=this.run;if(e){if(this.busy){this.schedule();return}this.busy=!0;try{let t=this.options.targets(),n=new Set(t.map(e=>e.id));for(let e of this.observations.keys())n.has(e)||this.observations.delete(e);let r=Date.now(),i=t.map(e=>{let t=this.observations.get(e.id);return(!t||t.identity!==e.identity)&&(t={identity:e.identity,digest:t?.digest,due:0},this.observations.set(e.id,t)),{target:e,observation:t}}).filter(({observation:e})=>e.due<=r).sort((e,t)=>e.observation.due-t.observation.due).slice(0,16),a=0;await Promise.all(Array.from({length:Math.min(4,i.length)},async()=>{for(;this.run===e&&a<i.length;){let t=i[a++];if(!t)return;let{target:n,observation:r}=t;try{let t=await n.read();if(this.run!==e||!n.current())continue;let i=bn(`sha256`).update(JSON.stringify([t.cols,t.rows,t.cursor,t.lines,t.scrollbackTotal])).digest(`hex`);r.digest!==void 0&&r.digest!==i&&this.options.changed(n.id),r.digest=i}catch{this.run===e&&n.current()&&this.reportFailure()}finally{r.due=Date.now()+(this.watched.has(n.id)?this.watchedMs:this.backgroundMs)}}}))}finally{this.busy=!1,this.schedule()}}}reportFailure(){try{this.options.failed()}catch{}}};function fa(e,t){return typeof t==`number`?`${e};5;${t}`:`${e};2;${t[0]};${t[1]};${t[2]}`}function pa(e){let t=[`0`];return e.b&&t.push(`1`),e.f&&t.push(`2`),e.i&&t.push(`3`),e.u&&t.push(`4`),e.s&&t.push(`9`),e.fg!==void 0&&t.push(fa(38,e.fg)),e.bg!==void 0&&t.push(fa(48,e.bg)),`\x1b[${t.join(`;`)}m`}function ma(e){let t=``;for(let n of e.r)t+=pa(n)+n.t.replace(/[\x00-\x1f\x7f]/g,``);return`${t}\x1b[0m`}const ha=1e3;var ga=class extends Error{},_a=class extends Cn{opts;log;generation=0;historyLines=ha;timer=null;busy=!1;seedWanted=!1;ended=!1;failures=0;seedFailures=0;shown;constructor(e){super(),this.opts=e,this.log=e.log.child({backend:`herdr`,stream:`vt`})}async start(e){e!==void 0&&(this.historyLines=e),await this.reseed()}async reseed(e){e!==void 0&&(this.historyLines=e),this.seedWanted=!0,await this.run()}close(){this.end(void 0)}async run(){if(!(this.ended||this.busy)){this.busy=!0,this.timer&&clearTimeout(this.timer),this.timer=null;try{this.seedWanted?await this.seed():await this.poll(),this.failures=0}catch(e){e instanceof k||e instanceof H&&Si.has(e.code)?this.end(`pane-gone`):!(e instanceof ga)&&++this.failures>=20&&(this.log.debug(`herdr vt stream failed`,{error:e instanceof Error?e.name:`unknown`}),this.end(`failed`))}finally{this.busy=!1,this.ended||(this.timer=setTimeout(()=>void this.run(),this.opts.pollMs??200),this.timer.unref?.())}}}current(){let e=this.opts.pane();if(!e)throw this.end(`pane-gone`),new ga;return e}async facts(e){let t=Li(await this.opts.request(`pane.get`,{pane_id:e.paneId}),e.paneId,e.terminalId);if(!t)throw new ga;return t}async frame(e,t){let n=await this.facts(e);if(n.offset!==0)throw new ga;let r=Ri(await this.opts.request(`pane.read`,{pane_id:e.paneId,source:`visible`,format:`ansi`}),{paneId:e.paneId,source:`visible`,rows:e.rows,cols:e.cols,minRows:0});if(!r)throw new ga;let i=t(n),a=[];if(i>0&&r.length>0){let t=Math.min(ha,i+r.length),n=Ri(await this.opts.request(`pane.read`,{pane_id:e.paneId,source:`recent`,format:`ansi`,lines:t}),{paneId:e.paneId,source:`recent`,rows:t,cols:e.cols,minRows:r.length});if(!n||!ba(n.slice(-r.length),r))throw new ga;a=n.slice(0,-r.length)}let o=await this.facts(e);if(!ya(n,o))throw new ga;return{facts:o,visible:r,above:a}}async seed(){let e=this.current(),t;try{t=await this.frame(e,t=>Math.min(e.agent&&va(e.agentStatus)?this.historyLines:t.history,this.historyLines))}catch(e){throw e instanceof ga&&++this.seedFailures>=50&&this.end(`unsettled`),e}this.seedFailures=0;let n=xa(t.visible,e.rows),r=Sa(t.visible,e.cols),i=[...t.above.map(ma),...n];this.seedWanted=!1,this.generation++,this.shown={cols:e.cols,rows:e.rows,history:t.facts.history,screen:n,cursor:r,idle:va(e.agentStatus)},this.emit(`seed`,{generation:this.generation,cols:e.cols,rows:e.rows,data:`\x1bc${i.join(`\r
13
- `)}${r}`})}async poll(){let e=this.shown,t=this.current();if(!e||t.cols!==e.cols||t.rows!==e.rows){this.seedWanted=!0;return}let n=va(t.agentStatus);if(t.agent&&n&&!e.idle){this.seedWanted=!0;return}e.idle=n;let r=!1,i=await this.frame(t,n=>{let i=n.history-e.history;return r=i<0||i+t.rows>1e3,r?0:i});if(r||i.above.length!==i.facts.history-e.history){this.seedWanted=!0;return}let a=i.above,o=xa(i.visible,t.rows),s=Sa(i.visible,t.cols),c=``;if(a.length>0)c=`\x1b[H${[...a.map(ma),...o].map(e=>`\x1b[2K${e}`).join(`\r
14
- `)}`;else for(let t=0;t<o.length;t++)o[t]!==e.screen[t]&&(c+=`\x1b[${t+1};1H\x1b[2K${o[t]}`);(c||s!==e.cursor)&&(c+=s),e.history=i.facts.history,e.screen=o,e.cursor=s,c&&this.emit(`bytes`,new TextEncoder().encode(c),this.generation)}end(e){this.ended||(this.ended=!0,this.timer&&clearTimeout(this.timer),this.timer=null,e&&this.emit(`end`,e))}};function va(e){return e===`idle`||e===`done`}function ya(e,t){return e.revision===t.revision&&e.history===t.history&&e.viewportRows===t.viewportRows&&e.offset===t.offset}function ba(e,t){return e.length===t.length&&e.every((e,n)=>ma(e)===ma(t[n]))}function xa(e,t){return Array.from({length:t},(t,n)=>ma(e[n]??{r:[]}))}function Sa(e,t){let{x:n,y:r}=Mi(e,t);return`\x1b[${r+1};${n+1}H`}const Ca=1e3,wa=1e3;function Ta(e){let t=[{type:`pane.created`},{type:`pane.closed`},{type:`pane.exited`},{type:`pane.updated`},{type:`pane.focused`},{type:`pane.moved`},{type:`pane.agent_detected`},{type:`tab.created`},{type:`tab.closed`},{type:`tab.focused`},{type:`tab.renamed`},{type:`tab.moved`},{type:`workspace.created`},{type:`workspace.updated`},{type:`workspace.closed`},{type:`workspace.focused`},{type:`workspace.renamed`},{type:`workspace.moved`},{type:`workspace.reordered`},{type:`layout.updated`}];for(let n of e)t.push({type:`pane.agent_status_changed`,pane_id:n}),t.push({type:`pane.scroll_changed`,pane_id:n});return t}const Ea=new Set([`working`,`blocked`,`idle`,`done`,`unknown`]);function Da(e){return typeof e==`string`&&Ea.has(e)?e:`unknown`}const Oa={working:`running`,blocked:`blocked`,idle:`finished`,done:`finished`,unknown:`unknown`};function ka(e){let t=e.foreground_cwd??e.cwd,n=t?t.split(`/`).filter(Boolean).pop():void 0;return e.display_agent||e.agent||e.title||e.terminal_title_stripped||n||`Pane`}function Aa(e){return M(e)}function ja(e){return typeof e==`string`?e:void 0}function Ma(e){return e&&typeof e==`object`?e:void 0}function Na(e,t){return e.length===t.size&&e.every(e=>t.has(e))}function Pa(e,t){return e.paneId===t.paneId&&e.terminalId===t.terminalId&&e.revision===t.revision&&e.history===t.history&&e.viewportRows===t.viewportRows&&e.offset===t.offset}var Fa=class{opts;name=`herdr`;get capabilities(){return{subscribe:!0,prompts:!1,createSession:!0,terminalInput:!0,terminalPaste:!0,focus:!0,history:!0,absoluteLines:!1,vtStream:!0,...this.mouse.available?{mouseClick:!0}:{}}}mouse;panes=new Map;historyEpochs=new Map;historyCaptures=new WeakMap;byPaneId=new Map;order=[];workspaces=new Set;focusedWorkspace=null;eventSeq=0;handlers=new Set;log;client;screenObserver;active=null;subscribedPaneIds=new Set;closed=!0;retryTimer=null;syncTimer=null;syncBusy=!1;wantSnapshot=!1;wantResubscribe=!1;shownIn=[];hostAppTimer=null;hostAppGeneration=0;constructor(e){this.opts=e,this.client=e.client,this.mouse=e.mouse??new ua({socketPath:this.client.socketPath}),this.log=e.log.child({backend:`herdr`}),this.screenObserver=new da({watchedMs:e.screenPollMs,backgroundMs:e.backgroundScreenPollMs,targets:()=>{let e=this.active;return this.closed||!e?.live?[]:[...this.panes].map(([t,n])=>({id:t,identity:n.paneId,current:()=>{let r=this.panes.get(t);return!this.closed&&this.active===e&&r?.paneId===n.paneId&&r.rows===n.rows&&r.cols===n.cols},read:()=>this.getScreen(t)}))},changed:e=>{this.historyEpochs.delete(e),this.emit({type:`screen-changed`,sessionId:e})},failed:()=>this.log.warn(`herdr screen observation failed`)})}get isConnected(){return!this.closed&&this.active!==null}async connect(){this.closed=!1;let e=await this.client.ping();await this.mouse.configure(e.version);let t=[];try{t=Ia((await this.client.request(`session.snapshot`,{}))?.snapshot).panes.map(e=>e.pane_id)}catch(e){throw this.unavailable(e)}try{await this.openStream(t)}catch(e){throw e instanceof j?e:this.unavailable(e)}this.hostAppTimer&&clearTimeout(this.hostAppTimer),this.hostAppGeneration++,this.refreshHostApps()}async refreshHostApps(){this.hostAppTimer=null;let e=this.hostAppGeneration,t=await(this.opts.hostApps??Ji)(this.client.socketPath).catch(()=>void 0)??[];this.closed||e!==this.hostAppGeneration||(t.join(`
13
+ `).map(e=>e.trim()).filter(e=>wn(e)===`herdr`)}function Ro(e){let t=e.procRoot??`/proc`,n=e.uid??process.getuid?.(),r=[];for(let e of pn(t))if(/^\d+$/.test(e))try{if(n!==void 0&&_n(F(t,e)).uid!==n)continue;let i=dn(F(t,e,`cmdline`),`latin1`).split(`\0`);if(i.at(-1)===``&&i.pop(),!Io(i))continue;let a=mn(F(t,e,`exe`));a.endsWith(` (deleted)`)||r.push(a)}catch{}return r}function zo(e){try{return en(e,j.X_OK),_n(e).isFile()}catch{return!1}}const Bo=Xn(A);var Vo=class{opts;executable;issue;env;active=new Map;generation=0;constructor(e){this.opts=e,this.env={...e.env??process.env,HERDR_SOCKET_PATH:e.socketPath}}get available(){return this.executable!==void 0}get verifiedExecutable(){return this.executable===void 0?void 0:On(this.executable)}get unavailableReason(){return this.executable===void 0?this.issue:void 0}async configure(e){this.close();let t=this.generation;if(!e||$a(e,[0,9,3])!==!0){this.issue=`Update Herdr to 0.9.3 or newer to open Herdr sessions from your phone${e?` (this computer runs ${e.replace(/^v/,``)})`:``}.`;return}let n=this.opts.executable===void 0&&this.defaultSocket()?await(this.opts.findRunningServer??Fo)():void 0;if(t!==this.generation)return;let r=this.opts.executable?[this.opts.executable]:[...new Set([n,Po(this.env)])].filter(e=>e!==void 0);if(r.length===0){this.issue=`Herdr is running, but Shellbell can't find the herdr program. Install it in ~/.local/bin, /opt/homebrew/bin or /usr/local/bin.`;return}let i=e.replace(/^v/,``),a;for(let e of r){let n;try{let t=this.opts.readVersion?await this.opts.readVersion(e):(await Bo(e,[`--version`],{env:this.env,timeout:3e3,maxBuffer:4096})).stdout;n=/\b(?:herdr\s+)?v?(\d+\.\d+\.\d+(?:-[\w.-]+)?)/.exec(t)?.[1]}catch{if(t!==this.generation)return;a??=`Shellbell couldn't run the herdr program. Reinstall Herdr on this computer.`;continue}if(t!==this.generation)return;if(n===i){this.executable=e;return}a??=n?`The herdr program (${n}) and the running Herdr (${i}) are different versions. Quit Herdr and open it again.`:`Shellbell couldn't read the herdr program's version. Reinstall Herdr on this computer.`}this.issue=a}defaultSocket(){let{HERDR_SOCKET_PATH:e,HERDR_SESSION:t,...n}=this.env;return On(this.opts.socketPath)===On(eo(n))}close(){this.generation++,this.executable=void 0,this.issue=void 0;for(let e of this.active.values())e();this.active.clear()}async click(t,n,r){let i=this.executable;if(!i||!r()||this.active.has(t)||this.active.size>=4)throw new e(`mouse control unavailable`);if(n.column>=n.cols||n.row>=n.rows)throw new e(`mouse coordinates`);let a=this.generation,o=[`terminal`,`session`,`control`,t,`--cols`,String(n.cols),`--rows`,String(n.rows)],s=this.opts.spawn?this.opts.spawn(i,o,this.env):$t(i,o,{env:this.env,stdio:[`pipe`,`pipe`,`pipe`]});await new Promise((i,o)=>{let c=!1,l=!1,u=Buffer.alloc(0),d=e=>{c||(c=!0,clearTimeout(p),this.active.delete(t),s.kill(`SIGKILL`),e?o(e):i())},f=()=>d(l?Error(`mouse delivery unknown`):new e(`mouse control unavailable`)),p=setTimeout(f,this.opts.timeoutMs??3e3);this.active.set(t,f),s.on(`error`,f),s.stdin.on(`error`,f),s.stderr.resume(),s.stdout.on(`data`,e=>{if(c||l)return;if(u=Buffer.concat([u,e]),u.length>1048576)return f();let t=u.indexOf(10);if(t<0)return;let i;try{i=JSON.parse(u.subarray(0,t).toString(`utf8`))}catch{return f()}if(i.type!==`terminal.frame`||i.width!==n.cols||i.height!==n.rows||a!==this.generation||!r())return f();l=!0,u=Buffer.alloc(0);let o={type:`terminal.mouse`,button:n.button,column:n.column,row:n.row,modifiers:n.modifiers};s.stdin.end(`${[{...o,action:`down`},{...o,action:`up`},{type:`terminal.release`}].map(e=>JSON.stringify(e)).join(`
14
+ `)}\n`)}),s.on(`close`,t=>d(t===0&&l?void 0:l?Error(`mouse delivery unknown`):new e(`mouse control unavailable`)))})}},Ho=class{options;run;timer;busy=!1;watched=new Set;observations=new Map;watchedMs;backgroundMs;constructor(e){this.options=e,this.watchedMs=Math.max(125,e.watchedMs??125),this.backgroundMs=Math.max(this.watchedMs,e.backgroundMs??1e3)}start(){this.timer&&clearTimeout(this.timer),this.timer=void 0,this.run={};for(let e of this.observations.values())e.due=0;this.schedule()}stop(){this.run=void 0,this.timer&&clearTimeout(this.timer),this.timer=void 0,this.observations.clear()}setWatched(e){let t=new Set(e);for(let e of t)if(!this.watched.has(e)){let t=this.observations.get(e);t&&(t.due=0)}this.watched=t}schedule(){this.run&&!this.timer&&(this.timer=setTimeout(()=>{this.timer=void 0,this.pass().catch(()=>this.reportFailure())},this.watchedMs),this.timer.unref?.())}async pass(){let e=this.run;if(e){if(this.busy){this.schedule();return}this.busy=!0;try{let t=this.options.targets(),n=new Set(t.map(e=>e.id));for(let e of this.observations.keys())n.has(e)||this.observations.delete(e);let r=Date.now(),i=t.map(e=>{let t=this.observations.get(e.id);return(!t||t.identity!==e.identity)&&(t={identity:e.identity,digest:t?.digest,due:0},this.observations.set(e.id,t)),{target:e,observation:t}}).filter(({observation:e})=>e.due<=r).sort((e,t)=>e.observation.due-t.observation.due).slice(0,16),a=0;await Promise.all(Array.from({length:Math.min(4,i.length)},async()=>{for(;this.run===e&&a<i.length;){let t=i[a++];if(!t)return;let{target:n,observation:r}=t;try{let t=await n.read();if(this.run!==e||!n.current())continue;let i=Fn(`sha256`).update(JSON.stringify([t.cols,t.rows,t.cursor,t.lines,t.scrollbackTotal])).digest(`hex`);r.digest!==void 0&&r.digest!==i&&this.options.changed(n.id),r.digest=i}catch{this.run===e&&n.current()&&this.reportFailure()}finally{r.due=Date.now()+(this.watched.has(n.id)?this.watchedMs:this.backgroundMs)}}}))}finally{this.busy=!1,this.schedule()}}}reportFailure(){try{this.options.failed()}catch{}}};function Uo(e,t){return typeof t==`number`?`${e};5;${t}`:`${e};2;${t[0]};${t[1]};${t[2]}`}function Wo(e){let t=[`0`];return e.b&&t.push(`1`),e.f&&t.push(`2`),e.i&&t.push(`3`),e.u&&t.push(`4`),e.s&&t.push(`9`),e.fg!==void 0&&t.push(Uo(38,e.fg)),e.bg!==void 0&&t.push(Uo(48,e.bg)),`\x1b[${t.join(`;`)}m`}function Go(e){let t=``;for(let n of e.r)t+=Wo(n)+n.t.replace(/[\x00-\x1f\x7f]/g,``);return`${t}\x1b[0m`}function Ko(e){if(typeof e!=`object`||!e||!(`pane`in e))return;let t=e.pane;if(typeof t!=`object`||!t||!(`agent_status`in t))return;let n=t.agent_status;if(typeof n!=`string`||![`idle`,`working`,`blocked`,`done`,`unknown`].includes(n))return;let r=`agent`in t?t.agent:null,i=`display_agent`in t?t.display_agent:null;if(!(r!=null&&typeof r!=`string`||i!=null&&typeof i!=`string`))return{agent:r||null,displayAgent:i||null,status:n}}var qo=class{options;enabled=!1;closed=!1;busy=!1;evidence=null;constructor(e){this.options=e}enable(){this.enabled=!0}invalidate(){this.evidence=null}close(){this.closed=!0,this.invalidate()}observe(e,t){let n=this.evidence;n&&(!Jo(e,n.pane)||!Yo(t,n.facts))&&this.invalidate()}capture(e,t,n){this.invalidate();let{facts:r,above:i,visible:a}=t;if(!this.enabled||this.closed||!Jo(this.options.pane(),e)||e.agent&&(e.agentStatus===`idle`||e.agentStatus===`done`)||!r.source||(r.source.agent!==null||r.source.displayAgent!==null)&&(r.source.status===`idle`||r.source.status===`done`)||r.paneId!==e.paneId||r.terminalId!==e.terminalId||r.offset!==0||r.viewportRows!==e.rows||i.length>r.history||i.length+a.length>1e3||r.history>0&&a.length===0||Buffer.byteLength(n)>x.screenBytes)return;let o=Object.freeze({});return this.evidence={capture:o,pane:{...e},facts:{...r,source:{...r.source}},visible:a},{capture:o,from:r.history-i.length,to:r.history,lines:i,replay:n}}async read(e){if(rt(e),e.signal.aborted)return{status:`cancelled`};let t=this.evidence;if(!t||e.capture!==t.capture||e.reported!==t.facts.history)return{status:`unavailable`,reason:`unanchored`};if(!this.owns(t))return{status:`reset`};if(this.busy)return{status:`unavailable`,reason:`busy`};this.busy=!0;let n=()=>e.signal.aborted?{status:`cancelled`}:this.owns(t)?void 0:{status:`reset`};try{if(!await this.confirm(t))return n()??{status:`reset`};let r=n();if(r)return r;let i;if(e.before===0)i={status:`boundary`,reason:`end`,oldestAvailable:0};else{let r=Math.max(0,e.before-e.count),a=Math.max(0,e.reported+t.visible.length-1e3);if(e.before<=a)return{status:`unavailable`,reason:`fetch-window`};let o=Math.min(1e3,t.facts.viewportRows+e.reported-r),s=await this.options.request(`pane.read`,{pane_id:t.pane.paneId,source:`recent`,format:`ansi`,lines:o}),c=n();if(c)return c;let l=go(s,{paneId:t.pane.paneId,cols:t.pane.cols,viewportRows:t.facts.viewportRows,historyRows:t.facts.history,requestedRows:o,visible:t.visible});if(!l)return{status:`unavailable`,reason:`changed`};let u=Math.max(r,l.from);if(u>=e.before)return{status:`unavailable`,reason:`fetch-window`};i={status:`page`,from:u,to:e.before,oldestAvailable:0,lines:l.lines.slice(u-l.from,e.before-l.from)}}return await this.confirm(t)?n()??i:n()??{status:`reset`}}catch{return this.evidence===t&&this.invalidate(),n()??{status:`reset`}}finally{this.busy=!1}}owns(e){return!this.closed&&this.evidence===e&&Jo(this.options.pane(),e.pane)}async confirm(e){let t=await this.options.request(`pane.get`,{pane_id:e.pane.paneId}),n=mo(t,e.pane.paneId,e.pane.terminalId),r=n?{...n,source:Ko(t)}:null;return!r||!Yo(r,e.facts)?(this.evidence===e&&this.invalidate(),!1):!0}};function Jo(e,t){return!!e&&e.paneId===t.paneId&&e.terminalId===t.terminalId&&e.cols===t.cols&&e.rows===t.rows&&e.agent===t.agent&&e.agentStatus===t.agentStatus}function Yo(e,t){return e.paneId===t.paneId&&e.terminalId===t.terminalId&&e.revision===t.revision&&e.history===t.history&&e.offset===t.offset&&e.viewportRows===t.viewportRows&&e.source?.agent===t.source?.agent&&e.source?.displayAgent===t.source?.displayAgent&&e.source?.status===t.source?.status}const Xo=1e3;var Zo=class extends Error{},Qo=class extends Ln{opts;log;history;generation=0;historyLines=Xo;timer=null;busy=!1;seedWanted=!1;ended=!1;failures=0;readFailureSince=null;waitSupported=!0;wakeSeq=0;seedReason=`refresh`;lastSeedReason=`refresh`;probing=null;continuation={cursor:`guessed`,alternate:`unknown`,probe:()=>(this.probing??=this.probe().finally(()=>{this.probing=null}),this.probing)};shown;constructor(e){super(),this.opts=e,this.log=e.log.child({backend:`herdr`,stream:`vt`}),this.history=new qo(e)}async start(e){e!==void 0&&(this.historyLines=e),await this.reseed()}async reseed(e){this.history.invalidate(),e!==void 0&&e<this.historyLines&&(this.seedReason=this.lastSeedReason),e!==void 0&&(this.historyLines=e),this.seedWanted=!0,await this.run()}close(){this.end(void 0)}async run(){if(!(this.ended||this.busy)){++this.wakeSeq,this.busy=!0,this.timer&&clearTimeout(this.timer),this.timer=null;try{this.seedWanted?await this.seed():await this.poll(),this.failures=0,this.readFailureSince=null}catch(e){if(this.readFailureSince??=Date.now(),e instanceof D||e instanceof U&&Za.has(e.code))this.end(`pane-gone`);else if(Date.now()-this.readFailureSince>=2e3){let t=await this.probeBottomSnapshot();this.ended||this.end(t?e instanceof Zo?`unsettled`:`failed`:`herdr-unreadable`)}else if(!(e instanceof Zo)&&++this.failures>=20){this.log.debug(`herdr vt stream failed`,{error:e instanceof Error?e.name:`unknown`});let t=await this.probeBottomSnapshot();this.ended||this.end(t?`failed`:`herdr-unreadable`)}}finally{if(this.busy=!1,!this.ended){if(this.opts.pollMs===void 0&&this.waitSupported&&this.shown&&!this.seedWanted&&this.readFailureSince===null){let e=this.opts.pane();e?this.waitForOutput(this.wakeSeq,e.paneId,this.shown.revision):this.end(`pane-gone`)}else this.schedulePoll(this.opts.pollMs??200)}}}}schedulePoll(e){this.ended||(this.timer=setTimeout(()=>void this.run(),e),this.timer.unref?.())}async waitForOutput(e,t,n){let r=Date.now(),i;try{await Promise.race([this.opts.request(`events.wait`,{match_event:{event:`pane_output_changed`,pane_id:t,min_revision:n+1},timeout_ms:1800}),new Promise(e=>{i=setTimeout(e,2e3),i.unref?.()})])}catch(e){this.waitSupported=!1,e instanceof U&&Qa.has(e.code)||this.log.debug(`herdr output wait failed`,{error:e instanceof Error?e.name:`unknown`})}finally{i&&clearTimeout(i)}this.ended||e!==this.wakeSeq||this.schedulePoll(Math.max(0,200-(Date.now()-r)))}current(){let e=this.opts.pane();if(!e)throw this.end(`pane-gone`),new Zo;return e}async facts(e){let t=await this.opts.request(`pane.get`,{pane_id:e.paneId}),n=mo(t,e.paneId,e.terminalId);if(!n)throw new Zo;return{...n,source:Ko(t)}}async probeBottomSnapshot(){let e=async()=>{try{let e=this.current(),t=await this.opts.request(`pane.read`,{pane_id:e.paneId,source:`detection`,format:`text`});if(t?.type!==`pane_read`||t.read?.pane_id!==e.paneId||t.read.source!==`detection`||t.read.format!==`text`||t.read.truncated||typeof t.read.text!=`string`)return!1;let n=this.current();return n.paneId===e.paneId&&n.terminalId===e.terminalId}catch{return!1}},t;try{return await Promise.race([e(),new Promise(e=>{t=setTimeout(()=>e(!1),1e3)})])}finally{t&&clearTimeout(t)}}async frame(e,t){let n=await this.facts(e);if(n.offset!==0)throw new Zo;let r=ho(await this.opts.request(`pane.read`,{pane_id:e.paneId,source:`visible`,format:`ansi`}),{paneId:e.paneId,source:`visible`,rows:n.viewportRows,cols:e.cols,minRows:0});if(!r)throw new Zo;let i=t(n),a=[];if(i>0&&r.length>0){let t=Math.min(Xo,i+r.length),n=ho(await this.opts.request(`pane.read`,{pane_id:e.paneId,source:`recent`,format:`ansi`,lines:t}),{paneId:e.paneId,source:`recent`,rows:t,cols:e.cols,minRows:r.length});if(!n||!ts(n.slice(-r.length),r))throw new Zo;a=n.slice(0,-r.length)}let o=await this.facts(e);if(!es(n,o))throw new Zo;return this.history.observe(e,o),{facts:o,visible:r,above:a}}async seed(){let e=this.current(),t=await this.frame(e,t=>Math.min(e.agent&&$o(e.agentStatus)?this.historyLines:t.history,this.historyLines)),n=ns(t.visible,t.facts.viewportRows),r=rs(t.visible,e.cols),i=[...t.above.map(Go),...n],a=e.agent&&$o(e.agentStatus)&&!this.shown?.idle?`herdr-idle`:this.seedReason;this.lastSeedReason=a,this.seedReason=`refresh`,this.seedWanted=!1,this.generation++,this.shown={cols:e.cols,rows:t.facts.viewportRows,history:t.facts.history,screen:n,cursor:r,idle:$o(e.agentStatus),revision:t.facts.revision};let o=this.history.capture(e,t,`${Sr}${i.join(`\r
15
+ `)}${r}`);this.emit(`seed`,{generation:this.generation,cols:e.cols,rows:t.facts.viewportRows,data:`\x1bc${i.join(`\r
16
+ `)}${r}`,...o?{nativeHistory:o}:{},continuation:{data:`${Sr}${n.join(`\r
17
+ `)}${r}`,reason:a}})}async poll(){let e=this.shown,t=this.current();if(!e||t.cols!==e.cols){this.seedReason=`resize`,this.seedWanted=!0;return}let n=$o(t.agentStatus);if(t.agent&&n&&!e.idle){this.seedWanted=!0,this.seedReason=`herdr-idle`;return}e.idle=n;let r=!1,i=await this.frame(t,t=>{let n=t.history-e.history;return r=n<0||n+t.viewportRows>1e3,r?0:n});if(r||i.facts.viewportRows!==e.rows||i.above.length!==i.facts.history-e.history){this.seedReason=i.facts.viewportRows===e.rows?`source-gap`:`resize`,this.seedWanted=!0;return}let a=i.above,o=ns(i.visible,i.facts.viewportRows),s=rs(i.visible,t.cols),c=``;if(a.length>0)c=`\x1b[H${[...a.map(Go),...o].map(e=>`\x1b[2K${e}`).join(`\r
18
+ `)}`;else for(let t=0;t<o.length;t++)o[t]!==e.screen[t]&&(c+=`\x1b[${t+1};1H\x1b[2K${o[t]}`);(c||s!==e.cursor)&&(c+=s),e.history=i.facts.history,e.revision=i.facts.revision,e.screen=o,e.cursor=s,c&&this.emit(`bytes`,new TextEncoder().encode(c),this.generation)}end(e){this.ended||(this.ended=!0,this.history.close(),++this.wakeSeq,this.timer&&clearTimeout(this.timer),this.timer=null,e&&this.emit(`end`,e))}async probe(){let e=this.generation,t=await this.frame(this.current(),()=>0);return{generation:e,quiescent:!this.ended&&!this.seedWanted&&e===this.generation&&t.facts.revision===this.shown?.revision&&t.facts.viewportRows===this.shown.rows}}};function $o(e){return e===`idle`||e===`done`}function es(e,t){return e.revision===t.revision&&e.history===t.history&&e.viewportRows===t.viewportRows&&e.offset===t.offset&&e.source?.agent===t.source?.agent&&e.source?.displayAgent===t.source?.displayAgent&&e.source?.status===t.source?.status}function ts(e,t){return e.length===t.length&&e.every((e,n)=>Go(e)===Go(t[n]))}function ns(e,t){return Array.from({length:t},(t,n)=>Go(e[n]??{r:[]}))}function rs(e,t){let{x:n,y:r}=co(e,t);return`\x1b[${r+1};${n+1}H`}const is=1e3,as=1e3;function os(e){let t=[{type:`pane.created`},{type:`pane.closed`},{type:`pane.exited`},{type:`pane.updated`},{type:`pane.focused`},{type:`pane.moved`},{type:`pane.agent_detected`},{type:`tab.created`},{type:`tab.closed`},{type:`tab.focused`},{type:`tab.renamed`},{type:`tab.moved`},{type:`workspace.created`},{type:`workspace.updated`},{type:`workspace.closed`},{type:`workspace.focused`},{type:`workspace.renamed`},{type:`workspace.moved`},{type:`workspace.reordered`},{type:`layout.updated`}];for(let n of e)t.push({type:`pane.agent_status_changed`,pane_id:n}),t.push({type:`pane.scroll_changed`,pane_id:n});return t}const ss=new Set([`working`,`blocked`,`idle`,`done`,`unknown`]);function cs(e){return typeof e==`string`&&ss.has(e)?e:`unknown`}const ls={working:`running`,blocked:`blocked`,idle:`finished`,done:`finished`,unknown:`unknown`};function us(e){let t=e.foreground_cwd??e.cwd,n=t?t.split(`/`).filter(Boolean).pop():void 0;return e.display_agent||e.agent||e.title||e.terminal_title_stripped||n||`Pane`}function ds(e){return O(e)}function fs(e){return typeof e==`string`?e:void 0}function ps(e){return e&&typeof e==`object`?e:void 0}function ms(e,t){return e.length===t.size&&e.every(e=>t.has(e))}function hs(e,t){return e.paneId===t.paneId&&e.terminalId===t.terminalId&&e.revision===t.revision&&e.history===t.history&&e.viewportRows===t.viewportRows&&e.offset===t.offset}var gs=class{opts;name=`herdr`;get capabilities(){return{subscribe:!0,prompts:!1,createSession:!0,terminalInput:!0,terminalPaste:!0,focus:!0,history:!0,absoluteLines:!1,vtStream:!0,...this.mouse.available?{mouseClick:!0}:{}}}mouse;panes=new Map;historyEpochs=new Map;historyCaptures=new WeakMap;byPaneId=new Map;order=[];workspaces=new Set;focusedWorkspace=null;eventSeq=0;conversationEpoch=L();conversationSupported=!1;conversationPending=!0;conversationHintRevision=0;handlers=new Set;log;client;screenObserver;active=null;subscribedPaneIds=new Set;closed=!0;retryTimer=null;syncTimer=null;syncBusy=!1;wantSnapshot=!1;wantResubscribe=!1;shownIn=[];hostAppTimer=null;hostAppGeneration=0;constructor(e){this.opts=e,this.client=e.client,this.mouse=e.mouse??new Vo({socketPath:this.client.socketPath}),this.log=e.log.child({backend:`herdr`}),this.screenObserver=new Ho({watchedMs:e.screenPollMs,backgroundMs:e.backgroundScreenPollMs,targets:()=>{let e=this.active;return this.closed||!e?.live?[]:[...this.panes].map(([t,n])=>({id:t,identity:n.paneId,current:()=>{let r=this.panes.get(t);return!this.closed&&this.active===e&&r?.paneId===n.paneId&&r.rows===n.rows&&r.cols===n.cols},read:()=>this.getScreen(t)}))},changed:e=>{this.historyEpochs.delete(e),this.emit({type:`screen-changed`,sessionId:e})},failed:()=>this.log.warn(`herdr screen observation failed`)})}get isConnected(){return!this.closed&&this.active!==null}async connect(){this.closed=!1,this.conversationSupported=!1;let e=await this.client.ping();this.conversationSupported=typeof e.version==`string`&&/^v?\d+\.\d+\.\d+$/.test(e.version.trim())&&$a(e.version,[0,9,5])===!0,await this.mouse.configure(e.version);let t=[];try{t=_s((await this.client.request(`session.snapshot`,{}))?.snapshot).panes.map(e=>e.pane_id)}catch(e){throw this.unavailable(e)}try{await this.openStream(t)}catch(e){throw e instanceof C?e:this.unavailable(e)}this.hostAppTimer&&clearTimeout(this.hostAppTimer),this.hostAppGeneration++,this.refreshHostApps()}async refreshHostApps(){this.hostAppTimer=null;let e=this.hostAppGeneration,t=await(this.opts.hostApps??To)(this.client.socketPath).catch(()=>void 0)??[];this.closed||e!==this.hostAppGeneration||(t.join(`
15
19
  `)!==this.shownIn.join(`
16
- `)&&(this.shownIn=t,this.emit({type:`layout-changed`})),this.hostAppTimer=setTimeout(()=>void this.refreshHostApps(),this.opts.hostAppPollMs??1e4),this.hostAppTimer.unref?.())}unavailable(e){if(e instanceof j)return e;let t=e instanceof Error?e.message:String(e);return e instanceof H&&Ci.has(e.code)?new j(`herdr does not support session.snapshot (${t})`,xi):e instanceof H&&e.code===`malformed`?new j(`herdr answered session.snapshot with junk (${t})`,xi):new j(t,bi)}async close(){this.closed=!0,this.mouse.close(),this.screenObserver.stop(),this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=null,this.syncTimer&&clearTimeout(this.syncTimer),this.syncTimer=null,this.hostAppTimer&&clearTimeout(this.hostAppTimer),this.hostAppTimer=null,this.hostAppGeneration++,this.shownIn=[];let e=this.active;this.active=null,e&&(e.cancelled=!0,e.stream?.close()),this.panes.clear(),this.historyEpochs.clear(),this.byPaneId.clear(),this.order=[],this.wantSnapshot=!1,this.wantResubscribe=!1,this.syncBusy=!1,this.subscribedPaneIds.clear(),this.handlers.clear()}on(e){return this.handlers.add(e),()=>this.handlers.delete(e)}async notificationFacts(e){let t=this.panes.get(e);if(t&&this.isConnected)return ir({sessionId:e,cwd:t.cwd,title:t.title,sessionLabel:`Herdr · Window ${t.windowNumber} · Tab ${t.tabIndex+1} · Pane ${t.paneIndex+1}`},void 0,`reported`)}async listSessions(){return this.order.map(e=>this.panes.get(e)).filter(e=>e!==void 0).map(e=>this.toInfo(e))}async getScreen(e,t){let n=this.pane(e),r=t?.history?this.captureEpoch(n):void 0;n.scrollStale&&await this.refreshScroll(n);let i=r&&this.ownsHistory(r)?await this.historyFacts(r):void 0,a=await this.call(e,`pane.read`,{pane_id:n.paneId,source:`visible`,format:`ansi`}),o=Ni({text:a?.read?.text??``,rows:n.rows,cols:n.cols,scrollMax:n.scrollMax});if(!r||!this.ownsHistory(r)||!i||!(`facts`in i))return o;let s=Ri(a,{paneId:r.paneId,source:`visible`,rows:r.rows,cols:r.cols,minRows:0});if(!s||i.facts.offset!==0)return o;let c=await this.historyFacts(r);if(!this.ownsHistory(r)||!(`facts`in c))return o;if(!Pa(i.facts,c.facts))return this.revokeHistory(r),o;r.certified=c.facts;let l=Object.freeze({});return this.historyCaptures.set(l,{epoch:r,facts:c.facts,visible:s}),o.historyCapture=l,o}async getHistoryPage(t,n){if(e(n),n.signal.aborted)return{status:`cancelled`};this.pane(t);let r=this.historyCaptures.get(n.capture);if(!r||r.epoch.sessionId!==t)return{status:`unavailable`,reason:`unanchored`};let{epoch:i,facts:a}=r,o=()=>n.signal.aborted?{status:`cancelled`}:this.ownsHistory(i)?void 0:{status:`reset`},s=o();if(s)return s;if(n.reported<a.history||n.reported>2**53-1-a.viewportRows)return{status:`unavailable`,reason:`unanchored`};let c=await this.historyFacts(i),l=o();if(l)return l;if(!(`facts`in c))return{status:`unavailable`,reason:c.reason};if(!Pa(a,c.facts))return this.revokeHistory(i),{status:`reset`};let u=n.reported-a.history,d;if(n.before<=u)d={status:`boundary`,reason:n.before===u?`end`:`truncated`,oldestAvailable:u};else{let e=Math.max(n.before-n.count,u),t=n.reported+r.visible.length-Ca;if(n.before<=t)return{status:`unavailable`,reason:`fetch-window`};let s=Math.min(Ca,a.viewportRows+(n.reported-e));if(!Number.isSafeInteger(s)||s<1||s>Ca)return{status:`unavailable`,reason:`fetch-window`};let c;try{c=await this.client.request(`pane.read`,{pane_id:i.paneId,source:`recent`,format:`ansi`,lines:s})}catch(e){return o()??{status:`unavailable`,reason:e instanceof H&&e.code===`agent_not_idle`?`busy`:`changed`}}let l=o();if(l)return l;let f=zi(c,{paneId:i.paneId,cols:i.cols,viewportRows:a.viewportRows,historyRows:a.history,requestedRows:s,visible:r.visible});if(!f)return{status:`unavailable`,reason:`changed`};let p=u+f.from,m=Math.max(e,p);if(m>=n.before)return{status:`unavailable`,reason:`fetch-window`};d={status:`page`,from:m,to:n.before,oldestAvailable:u,lines:f.lines.slice(m-p,n.before-p)}}let f=await this.historyFacts(i);return o()||(`facts`in f?Pa(a,f.facts)?(i.certified=f.facts,d):(this.revokeHistory(i),{status:`reset`}):{status:`unavailable`,reason:f.reason})}captureEpoch(e){if(this.closed||!this.active||this.active.cancelled||e.scrollOffset!==void 0&&e.scrollOffset!==0)return;let t=this.historyEpochs.get(e.terminalId);if(t&&this.ownsHistory(t))return t;let n={sessionId:e.terminalId,paneId:e.paneId,stream:this.active,revision:e.revision,cols:e.cols,rows:e.rows};return this.historyEpochs.set(e.terminalId,n),n}ownsHistory(e){let t=this.panes.get(e.sessionId);return!this.closed&&this.active===e.stream&&!e.stream.cancelled&&this.historyEpochs.get(e.sessionId)===e&&t?.paneId===e.paneId&&t.cols===e.cols&&t.rows===e.rows&&t.revision===e.revision}revokeHistory(e){this.historyEpochs.get(e.sessionId)===e&&this.historyEpochs.delete(e.sessionId)}async historyFacts(e){try{let t=await this.client.request(`pane.get`,{pane_id:e.paneId}),n=Li(t,t?.pane?.pane_id,t?.pane?.terminal_id);return n?(this.ownsHistory(e)&&(n.paneId!==e.paneId||n.terminalId!==e.sessionId||n.viewportRows!==e.rows||e.certified&&!Pa(e.certified,n))&&this.revokeHistory(e),{facts:n}):{reason:`changed`}}catch(e){return{reason:e instanceof H&&e.code===`agent_not_idle`?`busy`:`changed`}}}async getHistory(e,t,n){let r=this.pane(e),i=this.active,{scrollMax:a,rows:o,cols:s}=r,c=Math.max(0,a-t),l=Math.min(Ca,c+n+o),u=await this.call(e,`pane.read`,{pane_id:r.paneId,source:`recent`,format:`ansi`,lines:l}),d=()=>new j(`History temporarily unavailable`,`Retry history after output settles.`),f=Ri(await this.call(e,`pane.read`,{pane_id:r.paneId,source:`visible`,format:`ansi`}),{paneId:r.paneId,source:`visible`,rows:o,cols:s,minRows:0});if(!f)throw d();let p=zi(u,{paneId:r.paneId,cols:s,viewportRows:o,historyRows:a,requestedRows:l,visible:f});if(!p||t>0&&p.from>=t||this.closed||this.active!==i||i?.cancelled||this.panes.get(e)!==r||r.rows!==o||r.cols!==s||r.scrollMax!==a)throw d();let m=Math.max(0,a-c-p.from),h=Math.max(0,m-n),g=p.lines.slice(h,m);return{lines:g,oldestAvailable:p.from===0&&h===0?Math.max(0,t-g.length):0}}async sendText(e,t){let n=this.pane(e),r=$i(t);if(r){this.log.debug(`herdr key`),await this.call(e,`pane.send_keys`,{pane_id:n.paneId,keys:[r]});return}if(this.log.debug(`herdr text`,{len:t.length}),t.endsWith(`\r`)||t.endsWith(`
17
- `)){let r=t.slice(0,-1);r&&await this.call(e,`pane.send_text`,{pane_id:n.paneId,text:r}),await this.call(e,`pane.send_keys`,{pane_id:n.paneId,keys:[`enter`]});return}await this.call(e,`pane.send_text`,{pane_id:n.paneId,text:t})}async clickMouse(e,t){let n=this.pane(e),r=this.active,i=()=>{let i=this.panes.get(e);return!this.closed&&this.active===r&&r?.live===!0&&i?.paneId===n.paneId&&i.cols===t.cols&&i.rows===t.rows&&(i.scrollOffset??0)===0};if(!this.mouse.available||!i())throw new E(`mouse input unavailable`);let a=Ia((await this.client.request(`session.snapshot`,{}))?.snapshot),o=a.panes.find(t=>t.terminal_id===e),s=a.layouts.flatMap(e=>e.panes).find(e=>e.pane_id===n.paneId)?.rect;if(!i()||o?.pane_id!==n.paneId||o.scroll?.offset_from_bottom!==0||s?.width!==t.cols||s.height!==t.rows)throw new E(`mouse grid changed`);await this.mouse.click(e,t,i)}async sendInput(e,t){let n=this.pane(e);await this.call(e,`pane.send_text`,{pane_id:n.paneId,text:t})}async paste(e,t,n){let r=this.pane(e);await this.call(e,`pane.send_input`,{pane_id:r.paneId,text:t,keys:n?[`Enter`]:[]})}async createSession(e){if(e.kind===`split`){let t=this.pane(e.sessionId),n=ja((await this.client.request(`pane.split`,{target_pane_id:t.paneId,direction:e.direction===`vertical`?`right`:`down`,focus:!1}))?.pane?.terminal_id);if(!n)throw Error(`herdr pane.split returned no terminal_id`);return this.scheduleSync(`snapshot`),n}if(e.windowId!==void 0&&!this.workspaces.has(e.windowId))throw new C(e.windowId);let t=e.windowId??this.focusedWorkspace??[...this.workspaces][0];if(!t)return this.createWorkspaceSession();let n=ja((await this.client.request(`tab.create`,{workspace_id:t,focus:!1}))?.root_pane?.terminal_id);if(!n)throw Error(`herdr tab.create returned no terminal_id`);return this.scheduleSync(`snapshot`),n}async createWorkspaceSession(){return(await this.createWorkspace()).terminalId}async createWorkspace(){let e=await this.client.request(`workspace.create`,{cwd:P(),focus:!1}),t=ja(e?.root_pane?.terminal_id);if(!t)throw Error(`herdr workspace.create returned no terminal_id`);this.scheduleSync(`snapshot`);let n=ja(e?.workspace?.workspace_id)??ja(e?.root_pane?.workspace_id);return n?{terminalId:t,workspaceId:n}:{terminalId:t}}async closeWorkspace(e){await this.client.request(`workspace.close`,{workspace_id:e}),this.scheduleSync(`snapshot`)}get terminalSocketPath(){return this.client.socketPath}get terminalAttachExecutable(){return this.isConnected?this.mouse.verifiedExecutable:void 0}get terminalAttachIssue(){return this.isConnected&&this.terminalAttachExecutable===void 0?this.mouse.unavailableReason:void 0}async focus(e){let t=this.pane(e);await this.call(e,`pane.focus`,{pane_id:t.paneId})}setWatched(e){this.screenObserver.setWatched(e)}emit(e){for(let t of this.handlers)try{t(e)}catch(e){this.log.warn(`event handler failed`,{error:Aa(e)})}}openVtStream(e){return this.pane(e),new _a({request:(t,n)=>this.call(e,t,n),pane:()=>{let t=this.closed?void 0:this.panes.get(e);return t&&{paneId:t.paneId,terminalId:t.terminalId,cols:t.cols,rows:t.rows,agentStatus:t.agentStatus,agent:t.naming.agent!==void 0}},log:this.opts.log})}pane(e){let t=this.panes.get(e);if(!t)throw new k(e);return t}async call(e,t,n){try{return await this.client.request(t,n)}catch(t){throw t instanceof H&&Si.has(t.code)?(this.scheduleSync(`snapshot`),new k(e)):t}}toInfo(e){return{id:e.terminalId,backend:`herdr`,title:e.title,cwd:e.cwd,...e.naming,...e.windowLabel?{windowLabel:e.windowLabel}:{},cols:Math.max(1,e.cols),rows:Math.max(1,e.rows),windowId:e.workspaceId,windowNumber:e.windowNumber,tabId:e.tabId,tabIndex:e.tabIndex,paneIndex:e.paneIndex,isFocusedOnMac:e.focused,state:Oa[e.agentStatus],...this.shownIn.length>0?{shownIn:[...this.shownIn]}:{}}}sortOrder(){this.order=[...this.panes.values()].sort((e,t)=>e.windowNumber-t.windowNumber||e.tabIndex-t.tabIndex||e.paneIndex-t.paneIndex||e.paneId.localeCompare(t.paneId)).map(e=>e.terminalId)}async openStream(e){let t=e??[...this.byPaneId.keys()],n={cancelled:!1,live:!1,buffer:[],stream:null,overflowed:!1},r=await this.client.subscribe(Ta(t),{onEvent:e=>{if(!n.cancelled){if(n.live){this.onEvent(e);return}if(n.buffer.length<wa){n.buffer.push(e);return}n.overflowed||(n.overflowed=!0,this.log.warn(`herdr bootstrap event buffer overflowed; dropping events`,{max:wa})),this.scheduleSync(`snapshot`)}},onEnd:e=>{!n.cancelled&&this.active===n&&this.onStreamEnd(e)}});if(n.stream=r,this.closed){n.cancelled=!0,r.close();return}let i=this.active;this.active=n,this.historyEpochs.clear(),this.subscribedPaneIds=new Set(t),i&&(i.cancelled=!0,i.stream?.close());try{await this.refreshSnapshot()}catch(e){throw n.cancelled=!0,r.close(),this.active===n&&(this.active=null),e}if(n.cancelled||this.closed||this.active!==n)return;n.live=!0;let a=n.buffer;n.buffer=[];for(let e of a)this.onEvent(e);this.screenObserver.start(),this.emit({type:`layout-changed`})}async refreshSnapshot(){let e=this.eventSeq,t=this.active;try{let n=await this.client.request(`session.snapshot`,{});if(this.closed||this.active!==t)return;this.applySnapshot(Ia(n?.snapshot),e)}catch(e){if(this.closed||this.active!==t)return;throw e}}scheduleSync(e){this.closed||(e===`resubscribe`?this.wantResubscribe=!0:this.wantSnapshot=!0,!this.syncTimer&&(this.syncTimer=setTimeout(()=>{this.syncTimer=null,this.runSync().catch(e=>{this.log.warn(`herdr sync crashed`,{error:Aa(e)})})},this.opts.syncDebounceMs??250),this.syncTimer.unref?.()))}async runSync(){if(!(this.syncBusy||this.closed)){this.syncBusy=!0;try{for(;(this.wantResubscribe||this.wantSnapshot)&&!this.closed&&this.active;){let e=this.wantResubscribe;this.wantResubscribe=!1,this.wantSnapshot=!1,e?await this.openStream():await this.refreshSnapshot()}}catch(e){this.log.warn(`herdr sync failed`,{error:Aa(e)}),this.onStreamEnd(`sync-failed`)}finally{this.syncBusy=!1}}}onStreamEnd(e){if(this.closed)return;this.screenObserver.stop();let t=this.active;this.active=null,this.historyEpochs.clear(),t&&(t.cancelled=!0,t.stream?.close()),this.log.info(`herdr stream ended`,{reason:e});let n=[...this.order];this.panes.clear(),this.byPaneId.clear(),this.order=[],this.subscribedPaneIds.clear();for(let e of n)this.emit({type:`session-removed`,sessionId:e});this.emit({type:`layout-changed`}),this.scheduleReconnect()}scheduleReconnect(){if(this.closed||this.retryTimer)return;let e=this.opts.reconnectMs??2e3;this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.connect().catch(e=>{this.log.debug(`herdr reconnect failed`,{error:Aa(e)}),this.scheduleReconnect()})},e),this.retryTimer.unref?.()}applySnapshot(e,t=0){let n=new Map,r=new Map,i=new Set;for(let t of e.workspaces??[]){i.add(t.workspace_id),n.set(t.workspace_id,t.number??0);let e=V(typeof t.label==`string`?t.label:void 0,128);e&&r.set(t.workspace_id,e)}let a=new Map;for(let t of e.tabs??[])a.set(t.tab_id,t.number??0);let o=La(e.layouts??[]),s=this.panes,c=new Map,l=new Map,u=[],d=new Set,f=new Set;for(let p of e.panes){let m=p.terminal_id??p.pane_id,h=s.get(m),g=o.get(p.pane_id),_=Da(p.agent_status),v=h?.statusSeq??0,y=v>t,b=y?h?.agentStatus??_:_,x=p.scroll?.viewport_rows,S=ka(p),C=p.foreground_cwd??p.cwd,w=r.get(p.workspace_id),ee=pi(p,w);h&&(h.title!==S||h.cwd!==C||h.windowLabel!==w||!ui(h.naming,ee))&&d.add(m);let te=y?h?.revision??(typeof p.revision==`number`?p.revision:0):typeof p.revision==`number`?p.revision:h?.revision??0;!y&&h&&typeof p.revision==`number`&&typeof h.revision==`number`&&p.revision!==h.revision&&f.add(m),c.set(m,{terminalId:m,paneId:p.pane_id,workspaceId:p.workspace_id,tabId:p.tab_id,title:S,cwd:C,naming:ee,windowLabel:w,cols:g?.cols??h?.cols??80,rows:Math.max(1,g?.rows??x??h?.rows??24),rowsFromRect:g!==void 0,windowNumber:n.get(p.workspace_id)??0,tabIndex:a.get(p.tab_id)??0,paneIndex:g?.order??0,focused:p.focused===!0||p.pane_id===e.focused_pane_id,agentStatus:b,scrollMax:p.scroll?.max_offset_from_bottom??h?.scrollMax??0,scrollOffset:p.scroll?.offset_from_bottom??h?.scrollOffset,scrollStale:h?.scrollStale??!1,scrollFetchedAt:h?.scrollFetchedAt??0,statusSeq:v,revision:te}),l.set(p.pane_id,m),i.add(p.workspace_id),!y&&h?.agentStatus!==b&&u.push({id:m,state:b,agent:p.display_agent??p.agent})}let p=[...s.keys()].filter(e=>!c.has(e)),m=new Set([...c.keys()].filter(e=>!s.has(e))),h=new Map(u.map(e=>[e.id,e]));for(let[e,t]of this.historyEpochs){let n=s.get(e),r=c.get(e);(!r||r.paneId!==t.paneId||r.cols!==t.cols||r.rows!==t.rows||r.revision!==t.revision||r.scrollMax!==n?.scrollMax||r.scrollOffset!==n?.scrollOffset)&&this.revokeHistory(t)}this.panes=c,this.byPaneId=l,this.workspaces=i,this.focusedWorkspace=e.focused_workspace_id??null,this.sortOrder();for(let e of p)this.emit({type:`session-removed`,sessionId:e});for(let e of this.order)m.has(e)&&this.emit({type:`session-added`,sessionId:e});let g=Date.now();for(let e of this.order){let t=h.get(e);t&&this.emit({type:`agent-state`,sessionId:t.id,state:t.state,agent:t.agent,at:g})}for(let e of this.order)d.has(e)&&this.emit({type:`title-changed`,sessionId:e});for(let e of this.order)f.has(e)&&this.emit({type:`screen-changed`,sessionId:e});(p.length>0||m.size>0)&&this.emit({type:`layout-changed`}),Na([...l.keys()],this.subscribedPaneIds)||this.scheduleSync(`resubscribe`)}onEvent(e){try{this.handleEvent(e)}catch(e){this.log.warn(`herdr event handling failed`,{error:Aa(e)})}}handleEvent(e){let t=e.event.replaceAll(`.`,`_`),n=e.data;switch(t){case`pane_created`:case`pane_closed`:case`pane_exited`:case`pane_moved`:case`pane_agent_detected`:case`tab_created`:case`tab_closed`:case`tab_renamed`:case`tab_moved`:case`workspace_created`:case`workspace_updated`:case`workspace_closed`:case`workspace_renamed`:case`workspace_moved`:case`workspace_reordered`:this.historyEpochs.clear(),this.scheduleSync(`snapshot`);return;case`pane_updated`:{let e=n.pane,t=ja(e?.pane_id);if(!t)return;let r=this.paneByPaneId(t);if(!r){this.scheduleSync(`snapshot`);return}if(typeof e?.revision==`number`&&typeof r.revision==`number`&&e.revision<=r.revision)return;this.historyEpochs.delete(r.terminalId),(ka(e)!==r.title||(e?.foreground_cwd??e?.cwd)!==r.cwd||!ui(pi(e,r.windowLabel),r.naming))&&this.scheduleSync(`snapshot`);let i=Ma(e?.scroll);typeof i?.offset_from_bottom==`number`&&(r.scrollOffset=i.offset_from_bottom),i&&typeof i.max_offset_from_bottom==`number`&&(r.scrollMax=i.max_offset_from_bottom,!r.rowsFromRect&&typeof i.viewport_rows==`number`&&(r.rows=Math.max(1,i.viewport_rows)),r.scrollStale=!1),r.statusSeq=++this.eventSeq;let a=Da(e?.agent_status);r.agentStatus!==a&&(r.agentStatus=a,this.emit({type:`agent-state`,sessionId:r.terminalId,state:a,at:Date.now()})),typeof e?.revision==`number`&&e.revision!==r.revision&&(r.revision=e.revision,this.emit({type:`screen-changed`,sessionId:r.terminalId}));return}case`pane_agent_status_changed`:if(!this.paneByPaneId(ja(n.pane_id)))return;this.scheduleSync(`snapshot`);return;case`pane_scroll_changed`:{let e=this.paneByPaneId(ja(n.pane_id));if(!e)return;this.historyEpochs.delete(e.terminalId);let t=Ma(n.scroll);if(typeof t?.offset_from_bottom==`number`&&(e.scrollOffset=t.offset_from_bottom),t&&typeof t.max_offset_from_bottom==`number`){e.scrollMax=t.max_offset_from_bottom,!e.rowsFromRect&&typeof t.viewport_rows==`number`&&(e.rows=Math.max(1,t.viewport_rows)),e.scrollStale=!1;return}e.scrollStale=!0;return}case`layout_updated`:{this.historyEpochs.clear();let e=n.layout;if(e){for(let[t,n]of La([e])){let e=this.paneByPaneId(t);e&&(e.cols=n.cols,e.rows=Math.max(1,n.rows),e.rowsFromRect=!0,e.paneIndex=n.order)}this.sortOrder()}this.emit({type:`layout-changed`});return}case`pane_focused`:{let e=this.paneByPaneId(ja(n.pane_id));if(e)for(let t of this.panes.values())t.focused=t===e;else this.scheduleSync(`snapshot`);this.emit({type:`focus-changed`});return}case`tab_focused`:case`workspace_focused`:this.emit({type:`focus-changed`});return;default:this.log.debug(`unhandled herdr event`);return}}paneByPaneId(e){let t=e?this.byPaneId.get(e):void 0;return t?this.panes.get(t):void 0}async refreshScroll(e){let t=Date.now(),n=this.opts.scrollRefreshMs??1e3;if(!(t-e.scrollFetchedAt<n)){e.scrollFetchedAt=t;try{let t=(await this.client.request(`pane.get`,{pane_id:e.paneId}))?.pane?.scroll;this.panes.get(e.terminalId)===e&&t&&(t.max_offset_from_bottom!==e.scrollMax||t.viewport_rows!==e.rows||t.offset_from_bottom!==e.scrollOffset)&&this.historyEpochs.delete(e.terminalId),typeof t?.offset_from_bottom==`number`&&(e.scrollOffset=t.offset_from_bottom),t&&typeof t.max_offset_from_bottom==`number`&&(e.scrollMax=t.max_offset_from_bottom,!e.rowsFromRect&&typeof t.viewport_rows==`number`&&(e.rows=Math.max(1,t.viewport_rows))),e.scrollStale=!1}catch(e){this.log.debug(`herdr scroll refresh failed`,{error:Aa(e)})}}}};function Ia(e){let t=e;if(!t||typeof t!=`object`||!Array.isArray(t.panes))throw new H(`malformed`,`session.snapshot returned no panes array`);return t}function La(e){let t=new Map;for(let n of e)[...n.panes??[]].sort((e,t)=>(e.rect?.y??0)-(t.rect?.y??0)||(e.rect?.x??0)-(t.rect?.x??0)).forEach((e,n)=>{t.set(e.pane_id,{cols:Math.max(1,e.rect?.width??80),rows:Math.max(1,e.rect?.height??24),order:n})});return t}function Ra(e=process.env){return ra(e)!==void 0}async function za(e={}){let t=e.log??We({stdout:!1}),n=e.client??new Oi({log:t,socketPath:e.socketPath,requestTimeoutMs:3e3});if(!Ut(n.socketPath))return{name:`herdr`,ok:!0,detail:(e.herdrOnPath??Ra)()?`installed but not running (optional)`:`not installed (optional)`};let r;try{r=await n.ping()}catch(e){return e instanceof j?{name:`herdr`,ok:!1,detail:e.message,fix:e.hint}:{name:`herdr`,ok:!1,detail:String(e),fix:bi}}try{Ia((await n.request(`session.snapshot`,{}))?.snapshot)}catch(e){return{name:`herdr`,ok:!1,detail:e instanceof H&&Ci.has(e.code)?`herdr ${r.version??`?`} has no session.snapshot`:`session.snapshot failed: ${e instanceof Error?e.message:String(e)}`,fix:xi}}return{name:`herdr`,ok:!0,detail:`v${r.version??`?`} protocol ${r.protocol??`?`}`}}function Ba(e){let t=e.log.child({unit:`herdr-start`}),n=new Fa({client:e.client??new Oi({log:e.log,socketPath:e.socketPath}),log:e.log,...e.backendOptions}),r=null,i=!1,a=!1,o=!1;e.registry.add(n);let s=e.registry.registerSetupReporter(`herdr`,e=>{if(!e)return{issue:Ra()?`not-running`:`not-installed`};let t=n.terminalAttachIssue;return t?{issue:`limited`,detail:t}:{}}),c=()=>{i||r||(r=setTimeout(()=>{r=null,l()},e.retryMs??1e4),r.unref?.())},l=async()=>{if(!(i||n.isConnected)){try{await n.connect()}catch(n){t.debug(`herdr not available`,{error:M(n)}),e.onUnavailable&&!o&&n instanceof j&&(o=!0,e.onUnavailable()),c();return}try{if(i)return;if(t.info(`herdr connected`),e.onConnected&&!a){a=!0;let t=await n.listSessions().catch(()=>[]);e.onConnected(t.length)}}catch(e){t.debug(`herdr post-connect setup failed`,{error:M(e)})}}};return l(),{stop(){s(),i=!0,r&&clearTimeout(r),r=null,n.close(),e.registry.remove(`herdr`)}}}const Va=An(zt);var U=class extends Error{kind;constructor(e,t){super(e),this.kind=t,this.name=`ITerm2AuthError`}};const Ha=12e4;async function Ua(e,t=Ha){let n=Date.now()+t;if((await Wa(`if application "iTerm2" is running then
20
+ `)&&(this.shownIn=t,this.emit({type:`layout-changed`})),this.hostAppTimer=setTimeout(()=>void this.refreshHostApps(),this.opts.hostAppPollMs??1e4),this.hostAppTimer.unref?.())}unavailable(e){if(e instanceof C)return e;let t=e instanceof Error?e.message:String(e);return e instanceof U&&Qa.has(e.code)?new C(`herdr does not support session.snapshot (${t})`,Xa):e instanceof U&&e.code===`malformed`?new C(`herdr answered session.snapshot with junk (${t})`,Xa):new C(t,Ya)}async close(){this.closed=!0,this.mouse.close(),this.screenObserver.stop(),this.retryTimer&&clearTimeout(this.retryTimer),this.retryTimer=null,this.syncTimer&&clearTimeout(this.syncTimer),this.syncTimer=null,this.hostAppTimer&&clearTimeout(this.hostAppTimer),this.hostAppTimer=null,this.hostAppGeneration++,this.shownIn=[];let e=this.active;this.active=null,e&&(e.cancelled=!0,e.stream?.close()),this.panes.clear(),this.historyEpochs.clear(),this.byPaneId.clear(),this.order=[],this.wantSnapshot=!1,this.wantResubscribe=!1,this.syncBusy=!1,this.subscribedPaneIds.clear(),this.handlers.clear()}on(e){return this.handlers.add(e),()=>this.handlers.delete(e)}async conversationReference(e,t){let n=this.panes.get(e),r=this.active;if(t.aborted||!n||!this.isConnected||!r?.live||this.conversationPending||!this.conversationSupported)return null;let i=n.conversationOwner,a=n.conversationRevision,o=this.conversationEpoch;try{let s=await this.client.request(`pane.get`,{pane_id:n.paneId},{signal:t}),c=this.panes.get(e);if(t.aborted||this.closed||this.active!==r||this.conversationPending||this.conversationEpoch!==o||!c||c.paneId!==n.paneId||c.conversationOwner!==i||s?.pane?.pane_id!==n.paneId||s.pane.terminal_id!==e||!Number.isSafeInteger(s.pane.revision)||s.pane.revision<a)return null;let l=io(s.pane.agent_session);return this.setConversationReference(c,l,s.pane.revision),c.conversationSeq=++this.eventSeq,t.aborted||this.closed||this.active!==r||this.conversationPending||this.conversationEpoch!==o||this.panes.get(e)!==c||!ni(l,c.conversation)?null:l?Object.freeze({...l,owner:`${o}:${c.conversationOwner}`}):null}catch(e){return e instanceof U&&Za.has(e.code)&&(this.invalidateConversations(),this.scheduleSync(`snapshot`)),null}}setConversationReference(e,t,n){n<e.conversationRevision||(n>e.conversationRevision&&(e.conversationRevision=n,e.conversationSeq=++this.eventSeq),!ni(e.conversation,t)&&(e.conversation=t,e.conversationOwner=L(),e.conversationSeq=++this.eventSeq,this.emit({type:`conversation-changed`,sessionId:e.terminalId})))}invalidateConversations(){if(this.conversationHintRevision++,!this.conversationPending){this.conversationPending=!0,this.conversationEpoch=L();for(let e of this.panes.values())this.emit({type:`conversation-changed`,sessionId:e.terminalId})}}async notificationFacts(e){let t=this.panes.get(e);if(t&&this.isConnected)return Or({sessionId:e,cwd:t.cwd,title:t.title,sessionLabel:`Herdr · Window ${t.windowNumber} · Tab ${t.tabIndex+1} · Pane ${t.paneIndex+1}`},void 0,`reported`)}async listSessions(){return this.order.map(e=>this.panes.get(e)).filter(e=>e!==void 0).map(e=>this.toInfo(e))}async getScreen(e,t){let n=this.pane(e),r=t?.history?this.captureEpoch(n):void 0;n.scrollStale&&await this.refreshScroll(n);let i=r&&this.ownsHistory(r)?await this.historyFacts(r):void 0,a=!n.scrollStale&&n.scrollOffset===0&&(!i||!(`facts`in i)||i.facts.offset===0)?`visible`:`detection`,o=t=>this.call(e,`pane.read`,{pane_id:n.paneId,source:t,format:t===`visible`?`ansi`:`text`}),s=await o(a);if(a===`visible`&&(n.scrollStale||n.scrollOffset!==0)&&(a=`detection`,s=await o(a)),a===`detection`&&(s?.type!==`pane_read`||s.read?.pane_id!==n.paneId||s.read.source!==`detection`||s.read.format!==`text`||s.read.truncated||typeof s.read.text!=`string`))throw Error(`Herdr live bottom screen unavailable`);let c=lo({text:s?.read?.text??``,rows:n.rows,cols:n.cols,scrollMax:n.scrollMax});if(a===`detection`||!r||!this.ownsHistory(r)||!i||!(`facts`in i))return c;let l=ho(s,{paneId:r.paneId,source:`visible`,rows:r.rows,cols:r.cols,minRows:0});if(!l||i.facts.offset!==0)return c;let u=await this.historyFacts(r);if(!this.ownsHistory(r)||!(`facts`in u))return c;if(!hs(i.facts,u.facts))return this.revokeHistory(r),c;r.certified=u.facts;let d=Object.freeze({});this.historyCaptures.set(d,{epoch:r,facts:u.facts,visible:l}),c.scrollbackTotal=u.facts.history;let f=this.pane(e);return f.scrollMax=u.facts.history,f.scrollOffset=u.facts.offset,f.scrollEventSeq=++this.eventSeq,c.historyCapture=d,c}async getHistoryPage(e,t){if(rt(t),t.signal.aborted)return{status:`cancelled`};this.pane(e);let n=this.historyCaptures.get(t.capture);if(!n||n.epoch.sessionId!==e)return{status:`unavailable`,reason:`unanchored`};let{epoch:r,facts:i}=n,a=()=>t.signal.aborted?{status:`cancelled`}:this.ownsHistory(r)?void 0:{status:`reset`},o=a();if(o)return o;if(t.reported<i.history||t.reported>2**53-1-i.viewportRows)return{status:`unavailable`,reason:`unanchored`};let s=await this.historyFacts(r),c=a();if(c)return c;if(!(`facts`in s))return{status:`unavailable`,reason:s.reason};if(!hs(i,s.facts))return this.revokeHistory(r),{status:`reset`};let l=t.reported-i.history,u;if(t.before<=l)u={status:`boundary`,reason:t.before===l?`end`:`truncated`,oldestAvailable:l};else{let e=Math.max(t.before-t.count,l),o=t.reported+n.visible.length-is;if(t.before<=o)return{status:`unavailable`,reason:`fetch-window`};let s=Math.min(is,i.viewportRows+(t.reported-e));if(!Number.isSafeInteger(s)||s<1||s>is)return{status:`unavailable`,reason:`fetch-window`};let c;try{c=await this.client.request(`pane.read`,{pane_id:r.paneId,source:`recent`,format:`ansi`,lines:s})}catch(e){return a()??{status:`unavailable`,reason:e instanceof U&&e.code===`agent_not_idle`?`busy`:`changed`}}let d=a();if(d)return d;let f=go(c,{paneId:r.paneId,cols:r.cols,viewportRows:i.viewportRows,historyRows:i.history,requestedRows:s,visible:n.visible});if(!f)return{status:`unavailable`,reason:`changed`};let p=l+f.from,m=Math.max(e,p);if(m>=t.before)return{status:`unavailable`,reason:`fetch-window`};u={status:`page`,from:m,to:t.before,oldestAvailable:l,lines:f.lines.slice(m-p,t.before-p)}}let d=await this.historyFacts(r);return a()||(`facts`in d?hs(i,d.facts)?(r.certified=d.facts,u):(this.revokeHistory(r),{status:`reset`}):{status:`unavailable`,reason:d.reason})}captureEpoch(e){if(this.closed||!this.active||this.active.cancelled||e.scrollOffset!==void 0&&e.scrollOffset!==0)return;let t=this.historyEpochs.get(e.terminalId);if(t&&this.ownsHistory(t))return t;let n={sessionId:e.terminalId,paneId:e.paneId,stream:this.active,revision:e.revision,cols:e.cols,rows:e.rows};return this.historyEpochs.set(e.terminalId,n),n}ownsHistory(e){let t=this.panes.get(e.sessionId);return!this.closed&&this.active===e.stream&&!e.stream.cancelled&&this.historyEpochs.get(e.sessionId)===e&&t?.paneId===e.paneId&&t.cols===e.cols&&t.rows===e.rows&&t.revision===e.revision}revokeHistory(e){this.historyEpochs.get(e.sessionId)===e&&this.historyEpochs.delete(e.sessionId)}async historyFacts(e){try{let t=await this.client.request(`pane.get`,{pane_id:e.paneId}),n=mo(t,t?.pane?.pane_id,t?.pane?.terminal_id);return n?(this.ownsHistory(e)&&(n.paneId!==e.paneId||n.terminalId!==e.sessionId||n.viewportRows!==e.rows||e.certified&&!hs(e.certified,n))&&this.revokeHistory(e),{facts:n}):{reason:`changed`}}catch(e){return{reason:e instanceof U&&e.code===`agent_not_idle`?`busy`:`changed`}}}async getHistory(e,t,n){let r=this.pane(e),i=this.active,{scrollMax:a,rows:o,cols:s}=r,c=Math.max(0,a-t),l=Math.min(is,c+n+o),u=await this.call(e,`pane.read`,{pane_id:r.paneId,source:`recent`,format:`ansi`,lines:l}),d=()=>new C(`History temporarily unavailable`,`Retry history after output settles.`),f=ho(await this.call(e,`pane.read`,{pane_id:r.paneId,source:`visible`,format:`ansi`}),{paneId:r.paneId,source:`visible`,rows:o,cols:s,minRows:0});if(!f)throw d();let p=go(u,{paneId:r.paneId,cols:s,viewportRows:o,historyRows:a,requestedRows:l,visible:f});if(!p||t>0&&p.from>=t||this.closed||this.active!==i||i?.cancelled||this.panes.get(e)!==r||r.rows!==o||r.cols!==s||r.scrollMax!==a)throw d();let m=Math.max(0,a-c-p.from),h=Math.max(0,m-n),g=p.lines.slice(h,m);return{lines:g,oldestAvailable:p.from===0&&h===0?Math.max(0,t-g.length):0}}async sendText(e,t){let n=this.pane(e),r=Ao(t);if(r){this.log.debug(`herdr key`),await this.call(e,`pane.send_keys`,{pane_id:n.paneId,keys:[r]});return}if(this.log.debug(`herdr text`,{len:t.length}),t.endsWith(`\r`)||t.endsWith(`
21
+ `)){let r=t.slice(0,-1);r&&await this.call(e,`pane.send_text`,{pane_id:n.paneId,text:r}),await this.call(e,`pane.send_keys`,{pane_id:n.paneId,keys:[`enter`]});return}await this.call(e,`pane.send_text`,{pane_id:n.paneId,text:t})}async clickMouse(t,n){let r=this.pane(t),i=this.active,a=()=>{let e=this.panes.get(t);return!this.closed&&this.active===i&&i?.live===!0&&e?.paneId===r.paneId&&e.cols===n.cols&&e.rows===n.rows&&(e.scrollOffset??0)===0};if(!this.mouse.available||!a())throw new e(`mouse input unavailable`);let o=_s((await this.client.request(`session.snapshot`,{}))?.snapshot),s=o.panes.find(e=>e.terminal_id===t),c=o.layouts.flatMap(e=>e.panes).find(e=>e.pane_id===r.paneId)?.rect;if(!a()||s?.pane_id!==r.paneId||s.scroll?.offset_from_bottom!==0||c?.width!==n.cols||c.height!==n.rows)throw new e(`mouse grid changed`);await this.mouse.click(t,n,a)}async sendInput(e,t){let n=this.pane(e);await this.call(e,`pane.send_text`,{pane_id:n.paneId,text:t})}async paste(e,t,n){let r=this.pane(e);await this.call(e,`pane.send_input`,{pane_id:r.paneId,text:t,keys:n?[`Enter`]:[]})}async createSession(e){if(e.kind===`split`){let t=this.pane(e.sessionId),n=fs((await this.client.request(`pane.split`,{target_pane_id:t.paneId,direction:e.direction===`vertical`?`right`:`down`,focus:!1}))?.pane?.terminal_id);if(!n)throw Error(`herdr pane.split returned no terminal_id`);return this.scheduleSync(`snapshot`),n}if(e.windowId!==void 0&&!this.workspaces.has(e.windowId))throw new ze(e.windowId);let t=e.windowId??this.focusedWorkspace??[...this.workspaces][0];if(!t)return this.createWorkspaceSession();let n=fs((await this.client.request(`tab.create`,{workspace_id:t,focus:!1}))?.root_pane?.terminal_id);if(!n)throw Error(`herdr tab.create returned no terminal_id`);return this.scheduleSync(`snapshot`),n}async createWorkspaceSession(){return(await this.createWorkspace()).terminalId}async createWorkspace(){let e=await this.client.request(`workspace.create`,{cwd:M(),focus:!1}),t=fs(e?.root_pane?.terminal_id);if(!t)throw Error(`herdr workspace.create returned no terminal_id`);this.scheduleSync(`snapshot`);let n=fs(e?.workspace?.workspace_id)??fs(e?.root_pane?.workspace_id);return n?{terminalId:t,workspaceId:n}:{terminalId:t}}async closeWorkspace(e){await this.client.request(`workspace.close`,{workspace_id:e}),this.scheduleSync(`snapshot`)}get terminalSocketPath(){return this.client.socketPath}get terminalAttachExecutable(){return this.isConnected?this.mouse.verifiedExecutable:void 0}get terminalAttachIssue(){return this.isConnected&&this.terminalAttachExecutable===void 0?this.mouse.unavailableReason:void 0}async focus(e){let t=this.pane(e);await this.call(e,`pane.focus`,{pane_id:t.paneId})}setWatched(e){this.screenObserver.setWatched(e)}emit(e){for(let t of this.handlers)try{t(e)}catch(e){this.log.warn(`event handler failed`,{error:ds(e)})}}openVtStream(e){return this.pane(e),new Qo({request:(t,n)=>this.call(e,t,n),pane:()=>{let t=this.closed?void 0:this.panes.get(e);return t&&{paneId:t.paneId,terminalId:t.terminalId,cols:t.cols,rows:t.rows,agentStatus:t.agentStatus,agent:t.naming.agent!==void 0}},log:this.opts.log})}pane(e){let t=this.panes.get(e);if(!t)throw new D(e);return t}async call(e,t,n){try{return await this.client.request(t,n)}catch(t){throw t instanceof U&&Za.has(t.code)?(this.scheduleSync(`snapshot`),new D(e)):t}}toInfo(e){return{id:e.terminalId,backend:`herdr`,title:e.title,cwd:e.cwd,...e.naming,...e.windowLabel?{windowLabel:e.windowLabel}:{},cols:Math.max(1,e.cols),rows:Math.max(1,e.rows),windowId:e.workspaceId,windowNumber:e.windowNumber,tabId:e.tabId,tabIndex:e.tabIndex,paneIndex:e.paneIndex,isFocusedOnMac:e.focused,state:ls[e.agentStatus],...this.shownIn.length>0?{shownIn:[...this.shownIn]}:{}}}sortOrder(){this.order=[...this.panes.values()].sort((e,t)=>e.windowNumber-t.windowNumber||e.tabIndex-t.tabIndex||e.paneIndex-t.paneIndex||e.paneId.localeCompare(t.paneId)).map(e=>e.terminalId)}async openStream(e){let t=e??[...this.byPaneId.keys()],n={cancelled:!1,live:!1,buffer:[],stream:null,overflowed:!1},r=await this.client.subscribe(os(t),{onEvent:e=>{if(!n.cancelled){if(n.live){this.onEvent(e);return}if(n.buffer.length<as){n.buffer.push(e);return}n.overflowed||(n.overflowed=!0,this.log.warn(`herdr bootstrap event buffer overflowed; dropping events`,{max:as})),this.active===n&&this.invalidateConversations(),this.scheduleSync(`snapshot`)}},onEnd:e=>{!n.cancelled&&this.active===n&&this.onStreamEnd(e)}});if(n.stream=r,this.closed){n.cancelled=!0,r.close();return}let i=this.active;this.active=n,this.conversationEpoch=L(),this.conversationPending=!0,this.conversationHintRevision++;for(let e of this.panes.values())this.emit({type:`conversation-changed`,sessionId:e.terminalId});this.historyEpochs.clear(),this.subscribedPaneIds=new Set(t),i&&(i.cancelled=!0,i.stream?.close());try{await this.refreshSnapshot()}catch(e){throw n.cancelled=!0,r.close(),this.active===n&&(this.active=null),e}if(n.cancelled||this.closed||this.active!==n)return;n.live=!0;let a=n.buffer;n.buffer=[];for(let e of a)this.onEvent(e);this.screenObserver.start(),this.emit({type:`layout-changed`})}async refreshSnapshot(){let e=this.eventSeq,t=this.active,n=this.conversationHintRevision;try{let r=await this.client.request(`session.snapshot`,{});if(this.closed||this.active!==t)return;this.applySnapshot(_s(r?.snapshot),e),this.conversationHintRevision===n&&(this.conversationPending=!1)}catch(e){if(this.closed||this.active!==t)return;throw e}}scheduleSync(e){this.closed||(e===`resubscribe`?this.wantResubscribe=!0:this.wantSnapshot=!0,!this.syncTimer&&(this.syncTimer=setTimeout(()=>{this.syncTimer=null,this.runSync().catch(e=>{this.log.warn(`herdr sync crashed`,{error:ds(e)})})},this.opts.syncDebounceMs??250),this.syncTimer.unref?.()))}async runSync(){if(!(this.syncBusy||this.closed)){this.syncBusy=!0;try{for(;(this.wantResubscribe||this.wantSnapshot)&&!this.closed&&this.active;){let e=this.wantResubscribe;this.wantResubscribe=!1,this.wantSnapshot=!1,e?await this.openStream():await this.refreshSnapshot()}}catch(e){this.log.warn(`herdr sync failed`,{error:ds(e)}),this.onStreamEnd(`sync-failed`)}finally{this.syncBusy=!1}}}onStreamEnd(e){if(this.closed)return;this.screenObserver.stop();let t=this.active;this.active=null,this.historyEpochs.clear(),t&&(t.cancelled=!0,t.stream?.close()),this.log.info(`herdr stream ended`,{reason:e});let n=[...this.order];this.panes.clear(),this.byPaneId.clear(),this.order=[],this.subscribedPaneIds.clear();for(let e of n)this.emit({type:`session-removed`,sessionId:e});this.emit({type:`layout-changed`}),this.scheduleReconnect()}scheduleReconnect(){if(this.closed||this.retryTimer)return;let e=this.opts.reconnectMs??2e3;this.retryTimer=setTimeout(()=>{this.retryTimer=null,this.connect().catch(e=>{this.log.debug(`herdr reconnect failed`,{error:ds(e)}),this.scheduleReconnect()})},e),this.retryTimer.unref?.()}applySnapshot(e,t=0){let n=new Map,r=new Map,i=new Set;for(let t of e.workspaces??[]){i.add(t.workspace_id),n.set(t.workspace_id,t.number??0);let e=V(typeof t.label==`string`?t.label:void 0,128);e&&r.set(t.workspace_id,e)}let a=new Map;for(let t of e.tabs??[])a.set(t.tab_id,t.number??0);let o=vs(e.layouts??[]),s=this.panes,c=new Map,l=new Map,u=[],d=new Set,f=new Set,p=new Set;for(let m of e.panes){let h=m.terminal_id??m.pane_id,g=s.get(h),_=!this.conversationPending&&g?.paneId===m.pane_id?g:void 0,v=_&&(_.conversationSeq>t||m.revision<_.conversationRevision)?_.conversation:io(m.agent_session),y=_&&ni(_.conversation,v),ee=y?_.conversationOwner:L(),b=y?_.conversationSeq:++this.eventSeq,x=Math.max(_?.conversationRevision??0,Number.isSafeInteger(m.revision)?m.revision:0);g&&!y&&f.add(h);let S=o.get(m.pane_id),te=cs(m.agent_status),ne=g?.statusSeq??0,C=ne>t,w=g?.paneId===m.pane_id&&g.scrollEventSeq>t,re=g?.paneId===m.pane_id&&g.layoutEventSeq>t,ie=C?g?.agentStatus??te:te,ae=m.scroll?.viewport_rows,oe=us(m),T=m.foreground_cwd??m.cwd,se=r.get(m.workspace_id),ce=Ha(m,se);g&&(g.title!==oe||g.cwd!==T||g.windowLabel!==se||!za(g.naming,ce))&&d.add(h);let le=C?g?.revision??(typeof m.revision==`number`?m.revision:0):typeof m.revision==`number`?m.revision:g?.revision??0;!C&&g&&typeof m.revision==`number`&&typeof g.revision==`number`&&m.revision!==g.revision&&p.add(h),c.set(h,{conversation:v,conversationOwner:ee,conversationSeq:b,conversationRevision:x,terminalId:h,paneId:m.pane_id,workspaceId:m.workspace_id,tabId:m.tab_id,title:oe,cwd:T,naming:ce,windowLabel:se,cols:re?g.cols:S?.cols??g?.cols??80,rows:w?g.rows:Math.max(1,ae??S?.rows??g?.rows??24),windowNumber:n.get(m.workspace_id)??0,tabIndex:a.get(m.tab_id)??0,paneIndex:re?g.paneIndex:S?.order??0,focused:m.focused===!0||m.pane_id===e.focused_pane_id,agentStatus:ie,scrollMax:w?g.scrollMax:m.scroll?.max_offset_from_bottom??g?.scrollMax??0,scrollOffset:w?g.scrollOffset:m.scroll?.offset_from_bottom??g?.scrollOffset,scrollStale:w?g.scrollStale:(g?.scrollStale??!1)||S!==void 0&&(ae===void 0||ae!==S.rows),scrollFetchedAt:w?g.scrollFetchedAt:S!==void 0&&(ae===void 0||ae!==S.rows)?0:g?.scrollFetchedAt??0,scrollEventSeq:g?.scrollEventSeq??0,layoutEventSeq:g?.layoutEventSeq??0,statusSeq:ne,revision:le}),l.set(m.pane_id,h),i.add(m.workspace_id),!C&&g?.agentStatus!==ie&&u.push({id:h,state:ie,agent:m.display_agent??m.agent})}let m=[...s.keys()].filter(e=>!c.has(e)),h=new Set([...c.keys()].filter(e=>!s.has(e))),g=new Map(u.map(e=>[e.id,e]));for(let[e,t]of this.historyEpochs){let n=s.get(e),r=c.get(e);(!r||r.paneId!==t.paneId||r.cols!==t.cols||r.rows!==t.rows||r.revision!==t.revision||r.scrollMax!==n?.scrollMax||r.scrollOffset!==n?.scrollOffset)&&this.revokeHistory(t)}this.panes=c,this.byPaneId=l,this.workspaces=i,this.focusedWorkspace=e.focused_workspace_id??null,this.sortOrder();for(let e of m)this.emit({type:`session-removed`,sessionId:e});for(let e of this.order)h.has(e)&&this.emit({type:`session-added`,sessionId:e});for(let e of this.order)f.has(e)&&this.emit({type:`conversation-changed`,sessionId:e});let _=Date.now();for(let e of this.order){let t=g.get(e);t&&this.emit({type:`agent-state`,sessionId:t.id,state:t.state,agent:t.agent,at:_})}for(let e of this.order)d.has(e)&&this.emit({type:`title-changed`,sessionId:e});for(let e of this.order)p.has(e)&&this.emit({type:`screen-changed`,sessionId:e});(m.length>0||h.size>0)&&this.emit({type:`layout-changed`}),ms([...l.keys()],this.subscribedPaneIds)||this.scheduleSync(`resubscribe`)}onEvent(e){try{this.handleEvent(e)}catch(e){this.log.warn(`herdr event handling failed`,{error:ds(e)})}}handleEvent(e){let t=e.event.replaceAll(`.`,`_`),n=e.data;switch([`pane_created`,`pane_closed`,`pane_exited`,`pane_moved`,`pane_agent_detected`,`tab_created`,`tab_closed`,`tab_moved`,`workspace_created`,`workspace_closed`].includes(t)&&this.invalidateConversations(),t){case`pane_created`:case`pane_closed`:case`pane_exited`:case`pane_moved`:case`pane_agent_detected`:case`tab_created`:case`tab_closed`:case`tab_renamed`:case`tab_moved`:case`workspace_created`:case`workspace_updated`:case`workspace_closed`:case`workspace_renamed`:case`workspace_moved`:case`workspace_reordered`:this.historyEpochs.clear(),this.scheduleSync(`snapshot`);return;case`pane_updated`:{let e=n.pane,t=fs(e?.pane_id);if(!t)return;let r=this.paneByPaneId(t);if(!r){this.scheduleSync(`snapshot`);return}if(typeof e?.revision==`number`&&typeof r.revision==`number`&&e.revision<=r.revision)return;this.historyEpochs.delete(r.terminalId),Number.isSafeInteger(e?.revision)&&e.revision>r.conversationRevision&&this.setConversationReference(r,io(e?.agent_session),e.revision),(us(e)!==r.title||(e?.foreground_cwd??e?.cwd)!==r.cwd||!za(Ha(e,r.windowLabel),r.naming))&&this.scheduleSync(`snapshot`);let i=ps(e?.scroll);typeof i?.offset_from_bottom==`number`&&(r.scrollOffset=i.offset_from_bottom),i&&typeof i.max_offset_from_bottom==`number`&&(r.scrollMax=i.max_offset_from_bottom,typeof i.viewport_rows==`number`&&(r.rows=Math.max(1,i.viewport_rows)),r.scrollStale=!1),r.statusSeq=++this.eventSeq,i&&(r.scrollEventSeq=r.statusSeq);let a=cs(e?.agent_status);r.agentStatus!==a&&(r.agentStatus=a,this.emit({type:`agent-state`,sessionId:r.terminalId,state:a,at:Date.now()})),typeof e?.revision==`number`&&e.revision!==r.revision&&(r.revision=e.revision,this.emit({type:`screen-changed`,sessionId:r.terminalId}));return}case`pane_agent_status_changed`:if(!this.paneByPaneId(fs(n.pane_id)))return;this.scheduleSync(`snapshot`);return;case`pane_scroll_changed`:{let e=this.paneByPaneId(fs(n.pane_id));if(!e)return;e.scrollEventSeq=++this.eventSeq,this.historyEpochs.delete(e.terminalId);let t=ps(n.scroll);if(typeof t?.offset_from_bottom==`number`&&(e.scrollOffset=t.offset_from_bottom),t&&typeof t.max_offset_from_bottom==`number`){e.scrollMax=t.max_offset_from_bottom,typeof t.viewport_rows==`number`&&(e.rows=Math.max(1,t.viewport_rows)),e.scrollStale=!1,this.emit({type:`screen-changed`,sessionId:e.terminalId});return}e.scrollStale=!0,this.emit({type:`screen-changed`,sessionId:e.terminalId});return}case`layout_updated`:{this.historyEpochs.clear();let e=n.layout;if(e){for(let[t,n]of vs([e])){let e=this.paneByPaneId(t);e&&(e.cols=n.cols,e.rows=Math.max(1,n.rows),e.scrollStale=!0,e.scrollFetchedAt=0,e.scrollEventSeq=++this.eventSeq,e.layoutEventSeq=e.scrollEventSeq,e.paneIndex=n.order)}this.sortOrder()}this.emit({type:`layout-changed`});return}case`pane_focused`:{let e=this.paneByPaneId(fs(n.pane_id));if(e)for(let t of this.panes.values())t.focused=t===e;else this.scheduleSync(`snapshot`);this.emit({type:`focus-changed`});return}case`tab_focused`:case`workspace_focused`:this.emit({type:`focus-changed`});return;default:this.log.debug(`unhandled herdr event`);return}}paneByPaneId(e){let t=e?this.byPaneId.get(e):void 0;return t?this.panes.get(t):void 0}async refreshScroll(e){let t=Date.now(),n=this.opts.scrollRefreshMs??1e3;if(t-e.scrollFetchedAt<n)return;e.scrollFetchedAt=t;let r=e.scrollEventSeq;try{let t=await this.client.request(`pane.get`,{pane_id:e.paneId});if(this.panes.get(e.terminalId)!==e)return;if(e.scrollEventSeq!==r){e.scrollStale&&(e.scrollFetchedAt=0,this.emit({type:`screen-changed`,sessionId:e.terminalId}));return}let n=t?.pane?.scroll;this.panes.get(e.terminalId)===e&&n&&(n.max_offset_from_bottom!==e.scrollMax||n.viewport_rows!==e.rows||n.offset_from_bottom!==e.scrollOffset)&&this.historyEpochs.delete(e.terminalId),typeof n?.offset_from_bottom==`number`&&(e.scrollOffset=n.offset_from_bottom),n&&typeof n.max_offset_from_bottom==`number`&&(e.scrollMax=n.max_offset_from_bottom,typeof n.viewport_rows==`number`&&(e.rows=Math.max(1,n.viewport_rows))),e.scrollStale=!1}catch(e){this.log.debug(`herdr scroll refresh failed`,{error:ds(e)})}}};function _s(e){let t=e;if(!t||typeof t!=`object`||!Array.isArray(t.panes))throw new U(`malformed`,`session.snapshot returned no panes array`);return t}function vs(e){let t=new Map;for(let n of e)[...n.panes??[]].sort((e,t)=>(e.rect?.y??0)-(t.rect?.y??0)||(e.rect?.x??0)-(t.rect?.x??0)).forEach((e,n)=>{t.set(e.pane_id,{cols:Math.max(1,e.rect?.width??80),rows:Math.max(1,e.rect?.height??24),order:n})});return t}function ys(e=process.env){return Po(e)!==void 0}async function bs(e={}){let t=e.log??zt({stdout:!1}),n=e.client??new ro({log:t,socketPath:e.socketPath,requestTimeoutMs:3e3});if(!nn(n.socketPath))return{name:`herdr`,ok:!0,detail:(e.herdrOnPath??ys)()?`installed but not running (optional)`:`not installed (optional)`};let r;try{r=await n.ping()}catch(e){return e instanceof C?{name:`herdr`,ok:!1,detail:e.message,fix:e.hint}:{name:`herdr`,ok:!1,detail:String(e),fix:Ya}}try{_s((await n.request(`session.snapshot`,{}))?.snapshot)}catch(e){return{name:`herdr`,ok:!1,detail:e instanceof U&&Qa.has(e.code)?`herdr ${r.version??`?`} has no session.snapshot`:`session.snapshot failed: ${e instanceof Error?e.message:String(e)}`,fix:Xa}}return{name:`herdr`,ok:!0,detail:`v${r.version??`?`} protocol ${r.protocol??`?`}`}}function xs(e){let t=e.log.child({unit:`herdr-start`}),n=new gs({client:e.client??new ro({log:e.log,socketPath:e.socketPath}),log:e.log,...e.backendOptions}),r=null,i=!1,a=!1,o=!1;e.registry.add(n);let s=e.registry.registerSetupReporter(`herdr`,e=>{if(!e)return{issue:ys()?`not-running`:`not-installed`};let t=n.terminalAttachIssue;return t?{issue:`limited`,detail:t}:{}}),c=()=>{i||r||(r=setTimeout(()=>{r=null,l()},e.retryMs??1e4),r.unref?.())},l=async()=>{if(!(i||n.isConnected)){try{await n.connect()}catch(n){t.debug(`herdr not available`,{error:O(n)}),e.onUnavailable&&!o&&n instanceof C&&(o=!0,e.onUnavailable()),c();return}try{if(i)return;if(t.info(`herdr connected`),e.onConnected&&!a){a=!0;let t=await n.listSessions().catch(()=>[]);e.onConnected(t.length)}}catch(e){t.debug(`herdr post-connect setup failed`,{error:O(e)})}}};return l(),{stop(){s(),i=!0,r&&clearTimeout(r),r=null,n.close(),e.registry.remove(`herdr`)}}}const Ss=Xn(A);var Cs=class extends Error{kind;constructor(e,t){super(e),this.kind=t,this.name=`ITerm2AuthError`}};const ws=12e4;async function Ts(e,t=ws){let n=Date.now()+t;if((await Es(`if application "iTerm2" is running then
18
22
  return "yes"
19
23
  else
20
24
  return "no"
21
- end if`,n)).trim()!==`yes`)throw new U(`iTerm2 is not running`,`not-running`);let r=e.replace(/[\\"]/g,``),i;try{i=await Wa(`tell application "iTerm2" to request cookie and key for app named "${r}"`,n)}catch(e){if(e instanceof U)throw e;let t=String(e.stderr??e);throw/-274[01]/.test(t)?new U(`iTerm2 is too old (need 3.3+)`,`too-old`):/denied|not allowed|user/i.test(t)?new U(t.trim(),`denied`):new U(t.trim(),`unknown`)}let[a,o]=i.trim().split(` `);if(!a||!o)throw new U(`unexpected osascript output (${i.trim().split(` `).length} token(s), ${i.length} chars)`,`unknown`);return{cookie:a,key:o}}async function Wa(e,t){try{let{stdout:n}=await Va(`/usr/bin/osascript`,[`-e`,e],{timeout:Math.max(1,t-Date.now()),killSignal:`SIGKILL`});return n}catch(e){throw e.killed?new U(`osascript timed out waiting for iTerm2`,`unknown`):e}}const Ga=An(zt);var Ka=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??Ja)())throw this.set(`not-running`),new U(`iTerm2 is not running`,`not-running`);if(!await(this.opts.apiListening??Ya)(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 U(`waiting for Connect iTerm2`,`unknown`);this.allowance=!1,t&&this.set(`connecting`);try{let t=await(this.opts.requestCookie??Ua)(this.opts.appName??`Shellbell`,e);return this.granted=!0,this.paused=void 0,this.persist(),this.set(void 0),t}catch(e){let t=qa(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(Zt(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{He(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 qa(e){return e instanceof U?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 Ja(){try{let e=process.getuid?.();return await Ga(`/usr/bin/pgrep`,[...e===void 0?[]:[`-U`,String(e)],`-x`,`iTerm2`],{timeout:2e3}),!0}catch{return!1}}async function Ya(e){try{if(!rn(e).isSocket())return!1}catch{return!1}return new Promise(t=>{let n=wn({path:e}),r=e=>{n.destroy(),t(e)};n.setTimeout(1e3,()=>r(!1)),n.once(`connect`,()=>r(!0)),n.once(`error`,()=>r(!1))})}const W=Nn(`CgxpdGVybTIucHJvdG8SBml0ZXJtMiLcBQoXQ2xpZW50T3JpZ2luYXRlZE1lc3NhZ2USCgoCaWQYASABKAMSNgoSZ2V0X2J1ZmZlcl9yZXF1ZXN0GGQgASgLMhguaXRlcm0yLkdldEJ1ZmZlclJlcXVlc3RIABI2ChJnZXRfcHJvbXB0X3JlcXVlc3QYZSABKAsyGC5pdGVybTIuR2V0UHJvbXB0UmVxdWVzdEgAEjsKFG5vdGlmaWNhdGlvbl9yZXF1ZXN0GGcgASgLMhsuaXRlcm0yLk5vdGlmaWNhdGlvblJlcXVlc3RIABI8ChVsaXN0X3Nlc3Npb25zX3JlcXVlc3QYaiABKAsyGy5pdGVybTIuTGlzdFNlc3Npb25zUmVxdWVzdEgAEjQKEXNlbmRfdGV4dF9yZXF1ZXN0GGsgASgLMhcuaXRlcm0yLlNlbmRUZXh0UmVxdWVzdEgAEjYKEmNyZWF0ZV90YWJfcmVxdWVzdBhsIAEoCzIYLml0ZXJtMi5DcmVhdGVUYWJSZXF1ZXN0SAASNgoSc3BsaXRfcGFuZV9yZXF1ZXN0GG0gASgLMhguaXRlcm0yLlNwbGl0UGFuZVJlcXVlc3RIABI6ChRnZXRfcHJvcGVydHlfcmVxdWVzdBhwIAEoCzIaLml0ZXJtMi5HZXRQcm9wZXJ0eVJlcXVlc3RIABIzChBhY3RpdmF0ZV9yZXF1ZXN0GHIgASgLMhcuaXRlcm0yLkFjdGl2YXRlUmVxdWVzdEgAEjMKEHZhcmlhYmxlX3JlcXVlc3QYcyABKAsyFy5pdGVybTIuVmFyaWFibGVSZXF1ZXN0SAASLQoNZm9jdXNfcmVxdWVzdBh1IAEoCzIULml0ZXJtMi5Gb2N1c1JlcXVlc3RIABJBChdpbnZva2VfZnVuY3Rpb25fcmVxdWVzdBiEASABKAsyHS5pdGVybTIuSW52b2tlRnVuY3Rpb25SZXF1ZXN0SABCDAoKc3VibWVzc2FnZSK0BgoXU2VydmVyT3JpZ2luYXRlZE1lc3NhZ2USCgoCaWQYASABKAMSDwoFZXJyb3IYAiABKAlIABI4ChNnZXRfYnVmZmVyX3Jlc3BvbnNlGGQgASgLMhkuaXRlcm0yLkdldEJ1ZmZlclJlc3BvbnNlSAASOAoTZ2V0X3Byb21wdF9yZXNwb25zZRhlIAEoCzIZLml0ZXJtMi5HZXRQcm9tcHRSZXNwb25zZUgAEj0KFW5vdGlmaWNhdGlvbl9yZXNwb25zZRhnIAEoCzIcLml0ZXJtMi5Ob3RpZmljYXRpb25SZXNwb25zZUgAEj4KFmxpc3Rfc2Vzc2lvbnNfcmVzcG9uc2UYaiABKAsyHC5pdGVybTIuTGlzdFNlc3Npb25zUmVzcG9uc2VIABI2ChJzZW5kX3RleHRfcmVzcG9uc2UYayABKAsyGC5pdGVybTIuU2VuZFRleHRSZXNwb25zZUgAEjgKE2NyZWF0ZV90YWJfcmVzcG9uc2UYbCABKAsyGS5pdGVybTIuQ3JlYXRlVGFiUmVzcG9uc2VIABI4ChNzcGxpdF9wYW5lX3Jlc3BvbnNlGG0gASgLMhkuaXRlcm0yLlNwbGl0UGFuZVJlc3BvbnNlSAASPAoVZ2V0X3Byb3BlcnR5X3Jlc3BvbnNlGHAgASgLMhsuaXRlcm0yLkdldFByb3BlcnR5UmVzcG9uc2VIABI1ChFhY3RpdmF0ZV9yZXNwb25zZRhyIAEoCzIYLml0ZXJtMi5BY3RpdmF0ZVJlc3BvbnNlSAASNQoRdmFyaWFibGVfcmVzcG9uc2UYcyABKAsyGC5pdGVybTIuVmFyaWFibGVSZXNwb25zZUgAEi8KDmZvY3VzX3Jlc3BvbnNlGHUgASgLMhUuaXRlcm0yLkZvY3VzUmVzcG9uc2VIABJDChhpbnZva2VfZnVuY3Rpb25fcmVzcG9uc2UYhAEgASgLMh4uaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVzcG9uc2VIABItCgxub3RpZmljYXRpb24Y6AcgASgLMhQuaXRlcm0yLk5vdGlmaWNhdGlvbkgAQgwKCnN1Ym1lc3NhZ2UiHQoFQ29vcmQSCQoBeBgBIAEoBRIJCgF5GAIgASgDIkYKCkNvb3JkUmFuZ2USHAoFc3RhcnQYASABKAsyDS5pdGVybTIuQ29vcmQSGgoDZW5kGAIgASgLMg0uaXRlcm0yLkNvb3JkIikKBVJhbmdlEhAKCGxvY2F0aW9uGAEgASgDEg4KBmxlbmd0aBgCIAEoAyJdChJXaW5kb3dlZENvb3JkUmFuZ2USJwoLY29vcmRfcmFuZ2UYASABKAsyEi5pdGVybTIuQ29vcmRSYW5nZRIeCgdjb2x1bW5zGAIgASgLMg0uaXRlcm0yLlJhbmdlIh0KBVBvaW50EgkKAXgYASABKAUSCQoBeRgCIAEoBSIlCgRTaXplEg0KBXdpZHRoGAEgASgFEg4KBmhlaWdodBgCIAEoBSJCCgVGcmFtZRIdCgZvcmlnaW4YASABKAsyDS5pdGVybTIuUG9pbnQSGgoEc2l6ZRgCIAEoCzIMLml0ZXJtMi5TaXplInsKCUxpbmVSYW5nZRIcChRzY3JlZW5fY29udGVudHNfb25seRgBIAEoCBIWCg50cmFpbGluZ19saW5lcxgCIAEoBRI4ChR3aW5kb3dlZF9jb29yZF9yYW5nZRgDIAEoCzIaLml0ZXJtMi5XaW5kb3dlZENvb3JkUmFuZ2UiYgoQR2V0QnVmZmVyUmVxdWVzdBIPCgdzZXNzaW9uGAEgASgJEiUKCmxpbmVfcmFuZ2UYAiABKAsyES5pdGVybTIuTGluZVJhbmdlEhYKDmluY2x1ZGVfc3R5bGVzGAMgASgIIjQKCFJHQkNvbG9yEgsKA3JlZBgBIAEoDRINCgVncmVlbhgCIAEoDRIMCgRibHVlGAMgASgNIowDCglDZWxsU3R5bGUSFAoKZmdTdGFuZGFyZBgBIAEoDUgAEi0KC2ZnQWx0ZXJuYXRlGAIgASgOMhYuaXRlcm0yLkFsdGVybmF0ZUNvbG9ySAASIQoFZmdSZ2IYAyABKAsyEC5pdGVybTIuUkdCQ29sb3JIABIUCgpiZ1N0YW5kYXJkGAUgASgNSAESLQoLYmdBbHRlcm5hdGUYBiABKA4yFi5pdGVybTIuQWx0ZXJuYXRlQ29sb3JIARIhCgViZ1JnYhgHIAEoCzIQLml0ZXJtMi5SR0JDb2xvckgBEgwKBGJvbGQYCSABKAgSDQoFZmFpbnQYCiABKAgSDgoGaXRhbGljGAsgASgIEg0KBWJsaW5rGAwgASgIEhEKCXVuZGVybGluZRgNIAEoCBIVCg1zdHJpa2V0aHJvdWdoGA4gASgIEhEKCWludmlzaWJsZRgPIAEoCBIPCgdpbnZlcnNlGBAgASgIEg8KB3JlcGVhdHMYFiABKA1CCQoHZmdDb2xvckIJCgdiZ0NvbG9yIkAKEUNvZGVQb2ludHNQZXJDZWxsEhoKD251bV9jb2RlX3BvaW50cxgBIAEoBToBMRIPCgdyZXBlYXRzGAIgASgFIo0CCgxMaW5lQ29udGVudHMSDAoEdGV4dBgBIAEoCRI3ChRjb2RlX3BvaW50c19wZXJfY2VsbBgCIAMoCzIZLml0ZXJtMi5Db2RlUG9pbnRzUGVyQ2VsbBJOCgxjb250aW51YXRpb24YAyABKA4yIS5pdGVybTIuTGluZUNvbnRlbnRzLkNvbnRpbnVhdGlvbjoVQ09OVElOVUFUSU9OX0hBUkRfRU9MEiAKBXN0eWxlGAQgAygLMhEuaXRlcm0yLkNlbGxTdHlsZSJECgxDb250aW51YXRpb24SGQoVQ09OVElOVUFUSU9OX0hBUkRfRU9MEAESGQoVQ09OVElOVUFUSU9OX1NPRlRfRU9MEAIiogIKEUdldEJ1ZmZlclJlc3BvbnNlEjQKBnN0YXR1cxgBIAEoDjIgLml0ZXJtMi5HZXRCdWZmZXJSZXNwb25zZS5TdGF0dXM6Ak9LEiYKCGNvbnRlbnRzGAMgAygLMhQuaXRlcm0yLkxpbmVDb250ZW50cxIdCgZjdXJzb3IYBCABKAsyDS5pdGVybTIuQ29vcmQSOAoUd2luZG93ZWRfY29vcmRfcmFuZ2UYBiABKAsyGi5pdGVybTIuV2luZG93ZWRDb29yZFJhbmdlIlYKBlN0YXR1cxIGCgJPSxAAEhUKEVNFU1NJT05fTk9UX0ZPVU5EEAESFgoSSU5WQUxJRF9MSU5FX1JBTkdFEAISFQoRUkVRVUVTVF9NQUxGT1JNRUQQAyIVChNMaXN0U2Vzc2lvbnNSZXF1ZXN0InkKDlNlc3Npb25TdW1tYXJ5EhkKEXVuaXF1ZV9pZGVudGlmaWVyGAEgASgJEhwKBWZyYW1lGAIgASgLMg0uaXRlcm0yLkZyYW1lEh8KCWdyaWRfc2l6ZRgDIAEoCzIMLml0ZXJtMi5TaXplEg0KBXRpdGxlGAQgASgJIsEBCg1TcGxpdFRyZWVOb2RlEhAKCHZlcnRpY2FsGAEgASgIEjIKBWxpbmtzGAIgAygLMiMuaXRlcm0yLlNwbGl0VHJlZU5vZGUuU3BsaXRUcmVlTGluaxpqCg1TcGxpdFRyZWVMaW5rEikKB3Nlc3Npb24YASABKAsyFi5pdGVybTIuU2Vzc2lvblN1bW1hcnlIABIlCgRub2RlGAIgASgLMhUuaXRlcm0yLlNwbGl0VHJlZU5vZGVIAEIHCgVjaGlsZCKbAgoUTGlzdFNlc3Npb25zUmVzcG9uc2USNAoHd2luZG93cxgBIAMoCzIjLml0ZXJtMi5MaXN0U2Vzc2lvbnNSZXNwb25zZS5XaW5kb3caeQoGV2luZG93Ei4KBHRhYnMYASADKAsyIC5pdGVybTIuTGlzdFNlc3Npb25zUmVzcG9uc2UuVGFiEhEKCXdpbmRvd19pZBgCIAEoCRIcCgVmcmFtZRgDIAEoCzINLml0ZXJtMi5GcmFtZRIOCgZudW1iZXIYBCABKAUaUgoDVGFiEiMKBHJvb3QYAyABKAsyFS5pdGVybTIuU3BsaXRUcmVlTm9kZRIOCgZ0YWJfaWQYAiABKAkSFgoOdG11eF93aW5kb3dfaWQYBCABKAkiTAoPU2VuZFRleHRSZXF1ZXN0Eg8KB3Nlc3Npb24YASABKAkSDAoEdGV4dBgCIAEoCRIaChJzdXBwcmVzc19icm9hZGNhc3QYAyABKAgibAoQU2VuZFRleHRSZXNwb25zZRIvCgZzdGF0dXMYASABKA4yHy5pdGVybTIuU2VuZFRleHRSZXNwb25zZS5TdGF0dXMiJwoGU3RhdHVzEgYKAk9LEAASFQoRU0VTU0lPTl9OT1RfRk9VTkQQASJbChJHZXRQcm9wZXJ0eVJlcXVlc3QSEwoJd2luZG93X2lkGAEgASgJSAASFAoKc2Vzc2lvbl9pZBgDIAEoCUgAEgwKBG5hbWUYAiABKAlCDAoKaWRlbnRpZmllciKaAQoTR2V0UHJvcGVydHlSZXNwb25zZRIyCgZzdGF0dXMYASABKA4yIi5pdGVybTIuR2V0UHJvcGVydHlSZXNwb25zZS5TdGF0dXMSEgoKanNvbl92YWx1ZRgCIAEoCSI7CgZTdGF0dXMSBgoCT0sQABIVChFVTlJFQ09HTklaRURfTkFNRRABEhIKDklOVkFMSURfVEFSR0VUEAIiQAoUUHJvbXB0TW9uaXRvclJlcXVlc3QSKAoFbW9kZXMYASADKA4yGS5pdGVybTIuUHJvbXB0TW9uaXRvck1vZGUiYAoWVmFyaWFibGVNb25pdG9yUmVxdWVzdBIMCgRuYW1lGAEgASgJEiQKBXNjb3BlGAIgASgOMhUuaXRlcm0yLlZhcmlhYmxlU2NvcGUSEgoKaWRlbnRpZmllchgDIAEoCSL/AQoTTm90aWZpY2F0aW9uUmVxdWVzdBIPCgdzZXNzaW9uGAEgASgJEhEKCXN1YnNjcmliZRgCIAEoCBIzChFub3RpZmljYXRpb25fdHlwZRgDIAEoDjIYLml0ZXJtMi5Ob3RpZmljYXRpb25UeXBlEkIKGHZhcmlhYmxlX21vbml0b3JfcmVxdWVzdBgGIAEoCzIeLml0ZXJtMi5WYXJpYWJsZU1vbml0b3JSZXF1ZXN0SAASPgoWcHJvbXB0X21vbml0b3JfcmVxdWVzdBgJIAEoCzIcLml0ZXJtMi5Qcm9tcHRNb25pdG9yUmVxdWVzdEgAQgsKCWFyZ3VtZW50cyL1AQoUTm90aWZpY2F0aW9uUmVzcG9uc2USMwoGc3RhdHVzGAEgASgOMiMuaXRlcm0yLk5vdGlmaWNhdGlvblJlc3BvbnNlLlN0YXR1cyKnAQoGU3RhdHVzEgYKAk9LEAASFQoRU0VTU0lPTl9OT1RfRk9VTkQQARIVChFSRVFVRVNUX01BTEZPUk1FRBACEhIKDk5PVF9TVUJTQ1JJQkVEEAMSFgoSQUxSRUFEWV9TVUJTQ1JJQkVEEAQSIwofRFVQTElDQVRFX1NFUlZFUl9PUklHSU5BVEVEX1JQQxAFEhYKEklOVkFMSURfSURFTlRJRklFUhAGIisKGFNjcmVlblVwZGF0ZU5vdGlmaWNhdGlvbhIPCgdzZXNzaW9uGAEgASgJIloKGFByb21wdE5vdGlmaWNhdGlvblByb21wdBITCgtwbGFjZWhvbGRlchgBIAEoCRIpCgZwcm9tcHQYAiABKAsyGS5pdGVybTIuR2V0UHJvbXB0UmVzcG9uc2UiMQoeUHJvbXB0Tm90aWZpY2F0aW9uQ29tbWFuZFN0YXJ0Eg8KB2NvbW1hbmQYASABKAkiLgocUHJvbXB0Tm90aWZpY2F0aW9uQ29tbWFuZEVuZBIOCgZzdGF0dXMYASABKAUi+gEKElByb21wdE5vdGlmaWNhdGlvbhIPCgdzZXNzaW9uGAEgASgJEjIKBnByb21wdBgCIAEoCzIgLml0ZXJtMi5Qcm9tcHROb3RpZmljYXRpb25Qcm9tcHRIABI/Cg1jb21tYW5kX3N0YXJ0GAMgASgLMiYuaXRlcm0yLlByb21wdE5vdGlmaWNhdGlvbkNvbW1hbmRTdGFydEgAEjsKC2NvbW1hbmRfZW5kGAQgASgLMiQuaXRlcm0yLlByb21wdE5vdGlmaWNhdGlvbkNvbW1hbmRFbmRIABIYChB1bmlxdWVfcHJvbXB0X2lkGAUgASgJQgcKBWV2ZW50IiwKFk5ld1Nlc3Npb25Ob3RpZmljYXRpb24SEgoKc2Vzc2lvbl9pZBgBIAEoCSIyChxUZXJtaW5hdGVTZXNzaW9uTm90aWZpY2F0aW9uEhIKCnNlc3Npb25faWQYASABKAkiWQoZTGF5b3V0Q2hhbmdlZE5vdGlmaWNhdGlvbhI8ChZsaXN0X3Nlc3Npb25zX3Jlc3BvbnNlGAEgASgLMhwuaXRlcm0yLkxpc3RTZXNzaW9uc1Jlc3BvbnNlIoQDChhGb2N1c0NoYW5nZWROb3RpZmljYXRpb24SHAoSYXBwbGljYXRpb25fYWN0aXZlGAEgASgISAASOQoGd2luZG93GAIgASgLMicuaXRlcm0yLkZvY3VzQ2hhbmdlZE5vdGlmaWNhdGlvbi5XaW5kb3dIABIWCgxzZWxlY3RlZF90YWIYAyABKAlIABIRCgdzZXNzaW9uGAQgASgJSAAa2gEKBldpbmRvdxJLCg13aW5kb3dfc3RhdHVzGAEgASgOMjQuaXRlcm0yLkZvY3VzQ2hhbmdlZE5vdGlmaWNhdGlvbi5XaW5kb3cuV2luZG93U3RhdHVzEhEKCXdpbmRvd19pZBgCIAEoCSJwCgxXaW5kb3dTdGF0dXMSHgoaVEVSTUlOQUxfV0lORE9XX0JFQ0FNRV9LRVkQABIeChpURVJNSU5BTF9XSU5ET1dfSVNfQ1VSUkVOVBABEiAKHFRFUk1JTkFMX1dJTkRPV19SRVNJR05FRF9LRVkQAkIHCgVldmVudCJ9ChtWYXJpYWJsZUNoYW5nZWROb3RpZmljYXRpb24SJAoFc2NvcGUYASABKA4yFS5pdGVybTIuVmFyaWFibGVTY29wZRISCgppZGVudGlmaWVyGAIgASgJEgwKBG5hbWUYAyABKAkSFgoOanNvbl9uZXdfdmFsdWUYBCABKAki9wMKDE5vdGlmaWNhdGlvbhJEChpzY3JlZW5fdXBkYXRlX25vdGlmaWNhdGlvbhgCIAEoCzIgLml0ZXJtMi5TY3JlZW5VcGRhdGVOb3RpZmljYXRpb24SNwoTcHJvbXB0X25vdGlmaWNhdGlvbhgDIAEoCzIaLml0ZXJtMi5Qcm9tcHROb3RpZmljYXRpb24SQAoYbmV3X3Nlc3Npb25fbm90aWZpY2F0aW9uGAYgASgLMh4uaXRlcm0yLk5ld1Nlc3Npb25Ob3RpZmljYXRpb24STAoedGVybWluYXRlX3Nlc3Npb25fbm90aWZpY2F0aW9uGAcgASgLMiQuaXRlcm0yLlRlcm1pbmF0ZVNlc3Npb25Ob3RpZmljYXRpb24SRgobbGF5b3V0X2NoYW5nZWRfbm90aWZpY2F0aW9uGAggASgLMiEuaXRlcm0yLkxheW91dENoYW5nZWROb3RpZmljYXRpb24SRAoaZm9jdXNfY2hhbmdlZF9ub3RpZmljYXRpb24YCSABKAsyIC5pdGVybTIuRm9jdXNDaGFuZ2VkTm90aWZpY2F0aW9uEkoKHXZhcmlhYmxlX2NoYW5nZWRfbm90aWZpY2F0aW9uGAwgASgLMiMuaXRlcm0yLlZhcmlhYmxlQ2hhbmdlZE5vdGlmaWNhdGlvbiI9ChBHZXRQcm9tcHRSZXF1ZXN0Eg8KB3Nlc3Npb24YASABKAkSGAoQdW5pcXVlX3Byb21wdF9pZBgCIAEoCSLkAgoRR2V0UHJvbXB0UmVzcG9uc2USNAoGc3RhdHVzGAEgASgOMiAuaXRlcm0yLkdldFByb21wdFJlc3BvbnNlLlN0YXR1czoCT0sSGQoRd29ya2luZ19kaXJlY3RvcnkYBSABKAkSDwoHY29tbWFuZBgGIAEoCRI1Cgxwcm9tcHRfc3RhdGUYByABKA4yHy5pdGVybTIuR2V0UHJvbXB0UmVzcG9uc2UuU3RhdGUSEwoLZXhpdF9zdGF0dXMYCSABKA0SGAoQdW5pcXVlX3Byb21wdF9pZBgKIAEoCSJWCgZTdGF0dXMSBgoCT0sQABIVChFTRVNTSU9OX05PVF9GT1VORBABEhUKEVJFUVVFU1RfTUFMRk9STUVEEAISFgoSUFJPTVBUX1VOQVZBSUxBQkxFEAMiLwoFU3RhdGUSCwoHRURJVElORxAAEgsKB1JVTk5JTkcQARIMCghGSU5JU0hFRBACIjIKD1Byb2ZpbGVQcm9wZXJ0eRILCgNrZXkYASABKAkSEgoKanNvbl92YWx1ZRgCIAEoCSKeAQoQQ3JlYXRlVGFiUmVxdWVzdBIUCgxwcm9maWxlX25hbWUYASABKAkSEQoJd2luZG93X2lkGAIgASgJEhEKCXRhYl9pbmRleBgDIAEoDRI6ChljdXN0b21fcHJvZmlsZV9wcm9wZXJ0aWVzGAUgAygLMhcuaXRlcm0yLlByb2ZpbGVQcm9wZXJ0eRISCgpzZWxlY3RfdGFiGAYgASgIIvABChFDcmVhdGVUYWJSZXNwb25zZRIwCgZzdGF0dXMYASABKA4yIC5pdGVybTIuQ3JlYXRlVGFiUmVzcG9uc2UuU3RhdHVzEhEKCXdpbmRvd19pZBgCIAEoCRIOCgZ0YWJfaWQYAyABKAUSEgoKc2Vzc2lvbl9pZBgEIAEoCSJyCgZTdGF0dXMSBgoCT0sQABIYChRJTlZBTElEX1BST0ZJTEVfTkFNRRABEhUKEUlOVkFMSURfV0lORE9XX0lEEAISFQoRSU5WQUxJRF9UQUJfSU5ERVgQAxIYChRNSVNTSU5HX1NVQlNUSVRVVElPThAEIqwBChBTcGxpdFBhbmVSZXF1ZXN0Eg8KB3Nlc3Npb24YASABKAkSQAoPc3BsaXRfZGlyZWN0aW9uGAIgASgOMicuaXRlcm0yLlNwbGl0UGFuZVJlcXVlc3QuU3BsaXREaXJlY3Rpb24SFQoGYmVmb3JlGAMgASgIOgVmYWxzZSIuCg5TcGxpdERpcmVjdGlvbhIMCghWRVJUSUNBTBAAEg4KCkhPUklaT05UQUwQASLVAQoRU3BsaXRQYW5lUmVzcG9uc2USMAoGc3RhdHVzGAEgASgOMiAuaXRlcm0yLlNwbGl0UGFuZVJlc3BvbnNlLlN0YXR1cxISCgpzZXNzaW9uX2lkGAIgAygJInoKBlN0YXR1cxIGCgJPSxAAEhUKEVNFU1NJT05fTk9UX0ZPVU5EEAESGAoUSU5WQUxJRF9QUk9GSUxFX05BTUUQAhIQCgxDQU5OT1RfU1BMSVQQAxIlCiFNQUxGT1JNRURfQ1VTVE9NX1BST0ZJTEVfUFJPUEVSVFkQBCKWAgoPQWN0aXZhdGVSZXF1ZXN0EhMKCXdpbmRvd19pZBgBIAEoCUgAEhAKBnRhYl9pZBgCIAEoCUgAEhQKCnNlc3Npb25faWQYAyABKAlIABIaChJvcmRlcl93aW5kb3dfZnJvbnQYBCABKAgSEgoKc2VsZWN0X3RhYhgFIAEoCBIWCg5zZWxlY3Rfc2Vzc2lvbhgGIAEoCBIxCgxhY3RpdmF0ZV9hcHAYByABKAsyGy5pdGVybTIuQWN0aXZhdGVSZXF1ZXN0LkFwcBo9CgNBcHASGQoRcmFpc2VfYWxsX3dpbmRvd3MYASABKAgSGwoTaWdub3Jpbmdfb3RoZXJfYXBwcxgCIAEoCEIMCgppZGVudGlmaWVyIn0KEEFjdGl2YXRlUmVzcG9uc2USLwoGc3RhdHVzGAEgASgOMh8uaXRlcm0yLkFjdGl2YXRlUmVzcG9uc2UuU3RhdHVzIjgKBlN0YXR1cxIGCgJPSxAAEhIKDkJBRF9JREVOVElGSUVSEAESEgoOSU5WQUxJRF9PUFRJT04QAiKLAQoPVmFyaWFibGVSZXF1ZXN0EhQKCnNlc3Npb25faWQYASABKAlIABIoCgNzZXQYAiADKAsyGy5pdGVybTIuVmFyaWFibGVSZXF1ZXN0LlNldBILCgNnZXQYAyADKAkaIgoDU2V0EgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAlCBwoFc2NvcGUi5QEKEFZhcmlhYmxlUmVzcG9uc2USLwoGc3RhdHVzGAEgASgOMh8uaXRlcm0yLlZhcmlhYmxlUmVzcG9uc2UuU3RhdHVzEg4KBnZhbHVlcxgCIAMoCSKPAQoGU3RhdHVzEgYKAk9LEAASFQoRU0VTU0lPTl9OT1RfRk9VTkQQARIQCgxJTlZBTElEX05BTUUQAhIRCg1NSVNTSU5HX1NDT1BFEAMSEQoNVEFCX05PVF9GT1VORBAEEhgKFE1VTFRJX0dFVF9ESVNBTExPV0VEEAUSFAoQV0lORE9XX05PVF9GT1VORBAGIp8BChVJbnZva2VGdW5jdGlvblJlcXVlc3QSNgoGbWV0aG9kGAcgASgLMiQuaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVxdWVzdC5NZXRob2RIABISCgppbnZvY2F0aW9uGAUgASgJEhMKB3RpbWVvdXQYBiABKAE6Ai0xGhoKBk1ldGhvZBIQCghyZWNlaXZlchgBIAEoCUIJCgdjb250ZXh0ItkCChZJbnZva2VGdW5jdGlvblJlc3BvbnNlEjUKBWVycm9yGAEgASgLMiQuaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVzcG9uc2UuRXJyb3JIABI5CgdzdWNjZXNzGAIgASgLMiYuaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVzcG9uc2UuU3VjY2Vzc0gAGlQKBUVycm9yEjUKBnN0YXR1cxgBIAEoDjIlLml0ZXJtMi5JbnZva2VGdW5jdGlvblJlc3BvbnNlLlN0YXR1cxIUCgxlcnJvcl9yZWFzb24YAiABKAkaHgoHU3VjY2VzcxITCgtqc29uX3Jlc3VsdBgBIAEoCSJICgZTdGF0dXMSCwoHVElNRU9VVBABEgoKBkZBSUxFRBACEhUKEVJFUVVFU1RfTUFMRk9STUVEEAMSDgoKSU5WQUxJRF9JRBAEQg0KC2Rpc3Bvc2l0aW9uIg4KDEZvY3VzUmVxdWVzdCJICg1Gb2N1c1Jlc3BvbnNlEjcKDW5vdGlmaWNhdGlvbnMYASADKAsyIC5pdGVybTIuRm9jdXNDaGFuZ2VkTm90aWZpY2F0aW9uKkcKDkFsdGVybmF0ZUNvbG9yEgsKB0RFRkFVTFQQABIUChBSRVZFUlNFRF9ERUZBVUxUEAMSEgoOU1lTVEVNX01FU1NBR0UQBCrZAQoQTm90aWZpY2F0aW9uVHlwZRIbChdOT1RJRllfT05fU0NSRUVOX1VQREFURRACEhQKEE5PVElGWV9PTl9QUk9NUFQQAxIZChVOT1RJRllfT05fTkVXX1NFU1NJT04QBhIfChtOT1RJRllfT05fVEVSTUlOQVRFX1NFU1NJT04QBxIbChdOT1RJRllfT05fTEFZT1VUX0NIQU5HRRAIEhoKFk5PVElGWV9PTl9GT0NVU19DSEFOR0UQCRIdChlOT1RJRllfT05fVkFSSUFCTEVfQ0hBTkdFEAwqQwoRUHJvbXB0TW9uaXRvck1vZGUSCgoGUFJPTVBUEAESEQoNQ09NTUFORF9TVEFSVBACEg8KC0NPTU1BTkRfRU5EEAMqOgoNVmFyaWFibGVTY29wZRILCgdTRVNTSU9OEAESBwoDVEFCEAISCgoGV0lORE9XEAMSBwoDQVBQEAQ`),Xa=B(W,0),Za=B(W,1),Qa=B(W,2),$a=B(W,3),eo=B(W,5),to=B(W,9),no=B(W,10),ro=B(W,16),io=B(W,20);let ao=function(e){return e[e.OK=0]=`OK`,e[e.SESSION_NOT_FOUND=1]=`SESSION_NOT_FOUND`,e}({});const oo=B(W,22),so=B(W,24),co=B(W,25),lo=B(W,26),uo=B(W,42),fo=B(W,44),po=B(W,46),mo=B(W,46,0),ho=B(W,48),go=B(W,52);function _o(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 vo(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 yo(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=_o(r[e]);l.invisible&&(c=` `.repeat(Math.max(1,re(c))));let u=vo(l);a&&a.key===u?(a.text+=c,a.cells+=1):(a&&i.push(bo(a)),a={style:l,key:u,text:c,cells:1})}a&&i.push(bo(a));let c=e.continuation===2,l=s(i),u={r:c?l:x(l)};return c&&(u.w=!0),u}function bo(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!==re(e.text)&&(t.n=e.cells),t}function xo(e,t,n){let r=Number(e.windowedCoordRange?.coordRange?.start?.y??0n),i=e.contents.map(yo);for(;i.length<t;)i.push(ge());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 So(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function Co(e){return typeof e==`bigint`&&e>=0n&&e<=BigInt(2**53-1)}function wo(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(!So(n)||!So(r)||!So(i)||!So(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 To(e,t,n){if(!So(t)||!So(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||!Co(i.y)||!Co(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 Eo(e,t){return e.overflow===t.overflow&&e.history===t.history&&e.grid===t.grid}function Do(e,t){return t!==void 0&&(e.overflow<t.overflow||e.origin<t.origin)}function Oo(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`?Oo(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 ko="iTerm2 → Settings → General → Magic → ✓ Enable Python API, then run `shellbell` again.";function Ao(e){return M(e)}var jo=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:Ao(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 j(String(t),ko)}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:z(lo,{subscribe:!0,notificationType:t})}),!this.ownsConnection(e))return;let t=await this.client.request({case:`listSessionsRequest`,value:z(ro,{})});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:z(go,{})});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 j(String(t),ko)}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 ir({sessionId:e,cwd:t.cwd,title:t.title,sessionLabel:`iTerm2 · Window ${t.windowNumber} · Tab ${t.tabIndex+1} · Pane ${t.paneIndex+1}`},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}))}hostedProcess(e){return this.hostJob(e)}projectFolder(e){let t=this.sessions.get(e);return t?.cwd&&ci(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 k(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||Do(s,o))&&this.revokeHistory(e);let c=await this.client.request({case:`getBufferRequest`,value:z(no,{session:e,lineRange:z(to,{screenContentsOnly:!0}),includeStyles:!0})});if(c.submessage.case!==`getBufferResponse`||c.submessage.value.status!==0)throw new k(e);let l=c.submessage.value,u;if(i&&s&&s.grid===i.rows&&this.ownsHistory(i)&&this.historyOwnership.get(e)?.activityRevision===a&&To(l,s.origin,s.origin+s.grid)){let t=await this.fetchHistoryFacts(e);t&&this.ownsHistory(i)&&(t.grid!==i.rows||Do(t,s))&&this.revokeHistory(e),t&&Eo(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=xo(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:z(oo,{identifier:{case:`sessionId`,value:e},name:`number_of_lines`})});return t.submessage.case===`getPropertyResponse`&&t.submessage.value.status===0?wo(t.submessage.value.jsonValue):null}catch{return null}}async getHistoryPage(t,n){if(e(n),n.signal.aborted)return{status:`cancelled`};if(!this.sessions.has(t))throw new k(t);let r=this.historyCaptures.get(n.capture);if(!r||r.sessionId!==t)return{status:`unavailable`,reason:`unanchored`};let i=()=>{if(n.signal.aborted)return{status:`cancelled`};if(!this.ownsHistory(r))return{status:`reset`}},a=i();if(a)return a;if(n.reported!==r.facts.origin)return{status:`unavailable`,reason:`unanchored`};let o=this.historyOwnership.get(t)?.activityRevision,s=this.historyOwnership.get(t)?.observed??r.facts,c={status:`unavailable`,reason:`changed`},l=(e,n=s)=>{if(!e)return c;if(e.grid!==r.rows||Do(e,n))return this.historyOwnership.get(t)?.coordinateRevision===r.coordinateRevision&&this.revokeHistory(t),{status:`reset`}},u=await this.fetchHistoryFacts(t),d=i()??l(u);if(d)return d;if(!u)return c;let f=u.overflow,p=Math.max(n.before-n.count,f),m;if(n.before>f)try{let e=await this.client.request({case:`getBufferRequest`,value:z(no,{session:t,lineRange:z(to,{windowedCoordRange:z(eo,{coordRange:z($a,{start:z(Qa,{x:0,y:BigInt(p)}),end:z(Qa,{x:0,y:BigInt(n.before)})})})}),includeStyles:!0})}),r=i();if(r)return r;if(e.submessage.case!==`getBufferResponse`||!To(e.submessage.value,p,n.before))return c;m=e.submessage.value.contents.map(yo)}catch{return i()??c}let h=await this.fetchHistoryFacts(t);return(i()??l(h,u))||(!h||!Eo(u,h)||this.historyOwnership.get(t)?.activityRevision!==o?c:(this.observeHistory(t,h),m?{status:`page`,from:p,to:n.before,oldestAvailable:f,lines:m}:{status:`boundary`,reason:n.before===f?`end`:`truncated`,oldestAvailable:f}))}async getHistory(e,t,n){if(!this.sessions.has(e))throw new k(e);let r=Math.max(0,t-n),i=await this.client.request({case:`getBufferRequest`,value:z(no,{session:e,lineRange:z(to,{windowedCoordRange:z(eo,{coordRange:z($a,{start:z(Qa,{x:0,y:BigInt(r)}),end:z(Qa,{x:0,y:BigInt(t)})})})}),includeStyles:!0})});if(i.submessage.case!==`getBufferResponse`||i.submessage.value.status!==0)throw new k(e);let a=i.submessage.value.contents.map(yo);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:z(io,{session:e,text:t,suppressBroadcast:!0})});if(n.submessage.case!==`sendTextResponse`)throw new k(e);let r=n.submessage.value.status;if(r===1)throw new k(e);if(r!==0)throw Error(`sendText failed: ${ao[r]}`)}async sendInput(e,t){await this.sendText(e,t)}async createSession(e){if(e.kind===`tab`){let t=await this.client.request({case:`createTabRequest`,value:z(uo,{windowId:e.windowId,selectTab:!1})});if(t.submessage.case!==`createTabResponse`||!t.submessage.value.sessionId)throw Error(`create tab failed`);return t.submessage.value.sessionId}let t=await this.client.request({case:`splitPaneRequest`,value:z(fo,{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){if(e.length===0||e.length>8192||e.includes(`\0`))throw Error(`Invalid terminal launch command`);let t=this.hostedWindowGrid(),n=await this.client.request({case:`createTabRequest`,value:z(uo,{selectTab:!1,customProfileProperties:[{key:`Custom Command`,jsonValue:JSON.stringify(`Yes`)},{key:`Command`,jsonValue:JSON.stringify(e)},...t?[{key:`Columns`,jsonValue:JSON.stringify(t.cols)},{key:`Rows`,jsonValue:JSON.stringify(t.rows)}]:[]]})});if(n.submessage.case!==`createTabResponse`||n.submessage.value.status!==0||!n.submessage.value.sessionId)throw Error(`iTerm2 could not create the terminal window`);return n.submessage.value.sessionId}async focus(e){await this.client.request({case:`activateRequest`,value:z(po,{identifier:{case:`sessionId`,value:e},orderWindowFront:!0,selectTab:!0,selectSession:!0,activateApp:z(mo,{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:Ao(e)})}}toInfo(e){return{id:e.id,backend:`iterm2`,title:e.title,cwd:e.cwd,...fi({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=Oo(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=[z(lo,{session:e,subscribe:!0,notificationType:2}),z(lo,{session:e,subscribe:!0,notificationType:3,arguments:{case:`promptMonitorRequest`,value:z(so,{modes:[1,2,3]})}}),...[`session.name`,`session.path`,`jobName`].map(t=>z(lo,{session:e,subscribe:!0,notificationType:12,arguments:{case:`variableMonitorRequest`,value:z(co,{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:Ao(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:z(ho,{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:Ao(e)})});return}if(e.newSessionNotification?.sessionId){this.client.request({case:`listSessionsRequest`,value:z(ro,{})}).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:Ao(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 Mo=L(P(),`Library`,`Application Support`,`iTerm2`,`private`,`socket`);var No=class extends Cn{opts;ws=null;connecting=null;nextId=1n;pending=new Map;log;constructor(e){super(),this.opts=e,this.log=e.log.child({unit:`iterm2`})}get connected(){return this.ws?.readyState===Dn.OPEN}connect(){if(this.connecting)return this.connecting;let e=this.open().finally(()=>{this.connecting===e&&(this.connecting=null)});return this.connecting=e,e}async open(){let e=this.opts.appName??`Shellbell`,t=this.opts.socketPath??Mo,n=this.opts.cookieTimeoutMs??12e4,{cookie:r,key:i}=await Po((this.opts.cookieProvider??(()=>Ua(e,n)))(),n,`iTerm2 did not answer the API cookie request`),a={origin:`ws://localhost/`,"x-iterm2-library-version":`shellbell 0.1.0`,"x-iterm2-disable-auth-ui":`true`,"x-iterm2-advisory-name":e,"x-iterm2-cookie":r,"x-iterm2-key":i},o=this.opts.connectTimeoutMs??1e4,s=this.opts.url?new Dn(this.opts.url,[`api.iterm2.com`],{headers:a,handshakeTimeout:o}):new Dn(`ws://localhost/`,[`api.iterm2.com`],{headers:a,handshakeTimeout:o,createConnection:()=>wn({path:t})});this.ws=s,await new Promise((e,t)=>{let n=()=>{s.off(`open`,i),s.off(`error`,a),s.off(`unexpected-response`,o),s.off(`close`,c)},r=e=>{n(),s.on(`error`,()=>{}),s.terminate(),this.ws===s&&(this.ws=null),t(e)},i=()=>{n(),e()},a=e=>r(e),o=(e,t)=>{t.destroy(),e.destroy(),r(Error(`iTerm2 API responded HTTP ${t.statusCode}`))},c=()=>r(Error(`iTerm2 connection closed before open`));s.once(`open`,i),s.once(`error`,a),s.once(`unexpected-response`,o),s.once(`close`,c)}),s.on(`message`,(e,t)=>{if(!t)return;let n;try{n=jn(Za,new Uint8Array(e))}catch(e){this.log.warn(`undecodable message from iTerm2`,{err:M(e)});return}if(n.submessage.case===`notification`){this.emit(`notification`,n.submessage.value);return}let r=this.pending.get(n.id);r&&(clearTimeout(r.timer),this.pending.delete(n.id),r.resolve(n))}),s.on(`close`,()=>{for(let[e,t]of this.pending)t.ws===s&&(clearTimeout(t.timer),t.reject(Error(`iTerm2 connection closed`)),this.pending.delete(e));this.ws===s&&(this.ws=null),this.emit(`close`)}),s.on(`error`,e=>this.log.warn(`iTerm2 socket error`,{err:M(e)})),this.log.info(`connected to iTerm2 API`)}close(){this.ws?.close(),this.ws=null}request(e){let t=this.ws;if(!t||t.readyState!==Dn.OPEN)return Promise.reject(Error(`iTerm2 not connected`));let n=this.nextId++,r=z(Xa,{id:n,submessage:e});return new Promise((i,a)=>{let o=setTimeout(()=>{this.pending.delete(n),a(Error(`iTerm2 request timeout (${e.case})`))},this.opts.requestTimeoutMs??5e3);this.pending.set(n,{resolve:i,reject:a,timer:o,ws:t}),t.send(Mn(Xa,r),{binary:!0})})}};function Po(e,t,n){let r,i=new Promise((e,i)=>{r=setTimeout(()=>i(Error(n)),t)});return Promise.race([e,i]).finally(()=>clearTimeout(r))}const Fo=R.object({apiVersion:R.literal(1),id:Oe,label:w,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()}),Io=R.string().min(1).max(128),Lo=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:Io})),R.object({type:R.literal(`layout-changed`)}),R.object({type:R.literal(`command-start`),sessionId:Io,command:R.string().max(512),at:R.number().finite()}),R.object({type:R.literal(`command-end`),sessionId:Io,exitCode:R.number().int(),at:R.number().finite()}),R.object({type:R.literal(`prompt`),sessionId:Io,at:R.number().finite()}),R.object({type:R.literal(`agent-state`),sessionId:Io,state:R.enum([`working`,`blocked`,`idle`,`done`,`unknown`]),agent:R.string().max(128).optional(),at:R.number().finite()})]),Ro=R.object({cols:R.number().int().min(1).max(A.cols),rows:R.number().int().min(1).max(A.rows),cursor:pe,lines:R.array(t).max(A.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`),zo=R.number().int().nonnegative().max(2**53-1),Bo=R.discriminatedUnion(`status`,[R.object({status:R.literal(`page`),from:zo,to:zo,oldestAvailable:zo,lines:R.array(t).max(A.historyLines)}),R.object({status:R.literal(`boundary`),reason:R.enum([`end`,`truncated`]),oldestAvailable:zo}),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 Vo=class extends Error{};async function Ho(e,t){let n;try{return await Promise.race([e,new Promise((e,r)=>{n=setTimeout(()=>r(new Vo(`Terminal adapter deadline exceeded`)),t),n.unref()})])}finally{n&&clearTimeout(n)}}var Uo=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=Oe.parse(t),e.name!==t)throw Error(`Adapter identity does not match its manifest`);this.capabilities=Object.freeze(Ae.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=Lo.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 j(`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 Ho(n,this.timeoutMs);if(this.closed||t!==this.generation)throw Error(`Terminal adapter generation retired`);return e}catch(e){if(e instanceof Vo){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 j(`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 Ho(Promise.resolve().then(()=>this.raw.close()),this.timeoutMs)}}}async listSessions(){if(!this.isConnected)return[];let e=R.array(Ue).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 Ro.parse(await this.call(()=>this.raw.getScreen(e,t)))}async getHistory(e,n,r){return R.object({lines:R.array(t).max(1e3),oldestAvailable:R.number().int().nonnegative()}).parse(await this.call(()=>this.raw.getHistory(e,n,r)))}async getHistoryPage(e,t){if(!this.raw.getHistoryPage)return{status:`unavailable`,reason:`unsupported`};let n=Bo.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 E(`terminal input`);await this.call(()=>this.raw.sendInput(e,t))}async paste(e,t,n){if(!this.raw.paste)throw new E(`terminal paste`);await this.call(()=>this.raw.paste(e,t,n))}async clickMouse(e,t){if(!this.raw.clickMouse)throw new E(`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: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:Oe,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 Wo(e){let t=!1,n=[],r=new Set(Ee.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,u=!1,d=async e=>{u||(u=!0,await Ho(Promise.resolve().then(()=>e.close()),i).catch(()=>{}))};try{if(e.admitPath)e.admitPath(a);else{if(qt(a).isSymbolicLink()||tn(a)!==a)throw Error(`Adapter path must be canonical`);l(a,262144,process.getuid())}let u=await Ho((e.importModule??Pn)(_n(a).href),i),f=Fo.parse(u.default);if(r.has(f.id))throw Error(`Adapter identity is already registered`);if(!f.platforms.includes(e.platform??process.platform)){o.abort();continue}let p=u.default;if(typeof p.create!=`function`)throw Error(`Adapter factory is missing`);let m=Promise.resolve().then(()=>p.create({log:e.log.child({adapter:f.id}),signal:o.signal}));if(m.then(async e=>{o.signal.aborted&&await d(e)},()=>{}),c=await Ho(m,i),t){o.abort(),await d(c);break}s=new Uo(c,f.id,o,i),r.add(f.id),e.registry.add(s,f.label,f.hostCommands??[]);let h=c.launch?e.registry.registerSessionLauncher(f.id,{available:()=>s?.canLaunch()??!1,start:async()=>(await _.launch(),await _.connect(),{backend:_})}):void 0,g,_=s,v=async()=>{if(!t){if(e.registry.member(f.id)!==_){await _.close().catch(()=>{});return}try{await _.connect()}catch(t){e.log.debug(`terminal adapter unavailable`,{adapter:f.id,error:M(t)})}t||(g=setTimeout(()=>{v()},e.retryMs??1e4),g.unref())}};n.push(()=>{h?.(),g&&clearTimeout(g),e.registry.member(f.id)===_&&e.registry.remove(f.id),_.close().catch(t=>e.log.warn(`terminal adapter cleanup failed`,{adapter:f.id,error:M(t)}))}),v()}catch(t){o.abort(),s?await s.close().catch(()=>{}):c&&await d(c),e.log.warn(`terminal plugin could not be loaded`,{error:M(t)})}}})(),stop(){t=!0;for(let e of n.splice(0))e()}}}const Go={iterm2:{bundle:`iTerm.app`,label:`iTerm2`}},Ko=An(zt);function qo(e,t={}){if((t.platform??process.platform)!==`darwin`)return null;let n=t.roots??[`/Applications`,L(P(),`Applications`)],r=t.exists??Ut,i=Go[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 j(`${i.label} is not installed`,`Install ${i.label} on your computer.`);try{await(t.execute??((e,t)=>Ko(e,t,{timeout:5e3,maxBuffer:4096})))(`/usr/bin/open`,[`-g`,`-a`,e])}catch{throw new j(`Could not launch ${i.label}`,`Open ${i.label} on your computer and check its local API.`)}}}}function Jo(e={}){let t=()=>ra(e.env,e.executable);return{available:()=>t()!==void 0,start:async()=>{let n=t();if(!n)throw new j(`Herdr is not installed`,`Install Herdr on your computer.`);await new Promise((t,r)=>{let i=(e.spawnImpl??Bt)(n,[`server`],{detached:!0,stdio:`ignore`,env:e.env??process.env});i.once(`error`,()=>r(new j(`Could not start Herdr`,`Check your Herdr installation.`))),i.once(`spawn`,()=>{i.unref(),t()})})}}}function Yo(e,t,n=2e4){return new Promise((r,i)=>{let a=setTimeout(()=>{s(),i(new j(`${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 Xo=An(zt);function Zo(e){let t=[e.executable,...e.args],n=e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127);if(!I(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 Qo(e,t){try{await e()}catch{try{await t()}catch{throw new De(`The terminal window could not open on your computer, and the new session could not be closed. Check the session list.`)}throw new De(`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 $o(e={}){if((e.platform??process.platform)!==`darwin`)return null;let t=()=>(e.roots??[`/Applications`,L(P(),`Applications`)]).map(e=>L(e,`Ghostty.app`)).find(e.exists??Ut);return{id:`ghostty`,label:`Ghostty`,available:()=>t()!==void 0,async launch(n){let r=t();if(!r)throw new j(`Ghostty is not installed`,`Install Ghostty on your computer.`);let i=Zo(n);try{await(e.execute??((e,t)=>Xo(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`,`--initial-command=${i}`])}catch{throw new j(`Ghostty could not be launched`,`Check that Ghostty opens on your computer, then try again.`)}}}}async function es(e,t=fetch){let n;try{let t=new URL(e),r={"ws:":`http:`,"wss:":`https:`,"http:":`http:`,"https:":`https:`}[t.protocol];if(!r||!t.hostname)return!1;t.protocol=r,t.username=``,t.password=``,t.pathname=`/healthz`,t.search=``,t.hash=``,n=t.toString()}catch{return!1}let r=new AbortController,i=null,a=setTimeout(()=>{r.abort(),i?.cancel().catch(()=>{})},5e3);try{let e=await t(n,{redirect:`manual`,signal:r.signal});if(!e.body||(i=e.body.getReader(),e.status!==200))return!1;let a=[],o=0;for(;;){let{done:e,value:t}=await i.read();if(e)break;if(o+=t.byteLength,o>4096)return!1;a.push(t)}return!r.signal.aborted&&Buffer.concat(a,o).toString(`utf8`)===`ok`}catch{return!1}finally{if(clearTimeout(a),r.abort(),i){i.cancel().catch(()=>{});try{i.releaseLock()}catch{}}}}const ts=65536,ns=16384,rs=`# shellbell-systemd-v1 `,is=R.string().max(ns).refine(e=>{for(let t of e){let e=t.codePointAt(0);if(e<32||e>=127&&e<=159||e>=55296&&e<=57343)return!1}return!0}),as=is.refine(I),os=R.strictObject({v:R.literal(1),machineId:R.string().regex(/^[0-9a-f]{32}$/).refine(e=>e!==`0`.repeat(32)),nodePath:as.refine(e=>!/["'\\]/.test(e)),cliPath:as,stateDir:as,runtimeRoot:as,serviceInstance:R.uuid(),path:is.refine(e=>{let t=e.split(`:`);return t.every(I)&&new Set(t).size===t.length})});function G(){throw Error(`shellbell: invalid or foreign systemd unit`)}function ss(e){return`"${e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`).replaceAll(`%`,`%%`)}"`}function cs(e,t){return`Environment=${ss(`${e}=${t}`)}`}function ls(e){let t=os.safeParse(e);t.success||G();let n=t.data,r=2;for(let[e,t]of Object.entries(n))r+=e.length+3+(r===2?0:1),r+=typeof t==`number`?1:Buffer.byteLength(t)+2+[...t].filter(e=>e===`"`||e===`\\`).length;r>ns&&G();let i=JSON.stringify(n);Buffer.byteLength(i)>ns&&G();let a=Buffer.from([rs+Buffer.from(i).toString(`base64url`),`[Unit]`,`Description=Shellbell terminal host`,`ConditionHost=${n.machineId}`,`StartLimitIntervalSec=60s`,`StartLimitBurst=3`,``,`[Service]`,`Type=exec`,`ExecStart=${[`:${n.nodePath}`,n.cliPath,`start`,`--service`].map(ss).join(` `)}`,cs(`SHELLBELL_DIR`,n.stateDir),cs(`SHELLBELL_SERVICE_INSTANCE`,n.serviceInstance),cs(`XDG_RUNTIME_DIR`,n.runtimeRoot),cs(`PATH`,n.path),`Restart=on-failure`,`RestartSec=5s`,`TimeoutStopSec=15s`,`UMask=0077`,`StandardInput=null`,`StandardOutput=null`,`StandardError=journal`,`KillMode=control-group`,``,`[Install]`,`WantedBy=default.target`,``].join(`
22
- `));return a.length>ts&&G(),a}function us(e){try{e.byteLength>ts&&G();let t=Buffer.from(e),n=t.subarray(0,t.indexOf(10)).toString(`utf8`);n.startsWith(rs)||G();let r=n.slice(23);(r.length>21846||!/^[A-Za-z0-9_-]+$/.test(r))&&G();let i=Buffer.from(r,`base64url`);(i.length>ns||i.toString(`base64url`)!==r)&&G();let a=os.parse(JSON.parse(i.toString(`utf8`)));return ls(a).equals(t)||G(),a}catch{return G()}}function ds(e,t){let n=O(e);n&&(!n.isDirectory()||n.isSymbolicLink()||n.uid!==t||n.mode&18)&&G()}function fs(e,t){as.safeParse(e).success||G();let n=O(e)?tn(e):jt(e);return ds(n,t),n}function ps(e){let{uid:t,hostScope:n}=e.identity;(!Number.isSafeInteger(t)||t<=0||!/^[0-9a-f]{32}$/.test(n))&&G();let r=fs(e.home,t),i=fs(e.env.XDG_CONFIG_HOME&&I(e.env.XDG_CONFIG_HOME)?e.env.XDG_CONFIG_HOME:L(r,`.config`),t),a=L(i,`systemd`,`user`);for(let e of[L(i,`systemd`),a])ds(e,t);let o=`shellbell-${n}.service`,s=L(a,o),c=O(s);return c&&(!c.isFile()||c.isSymbolicLink()||c.uid!==t||(c.mode&4095)!=384)&&G(),{uid:t,home:r,configRoot:i,unitName:o,unitDir:a,definitionPath:s,enablementPath:L(a,`default.target.wants`,o),managerRuntimeRoot:`/run/user/${t}`}}function K(){throw Error(`shellbell: unsafe, foreign or concurrently changed systemd files`)}function ms(e,t){return d(e,t)&&e.mode===t.mode&&e.uid===t.uid&&e.size===t.size&&e.mtimeMs===t.mtimeMs&&e.ctimeMs===t.ctimeMs}var hs=class{location;machineId;constructor(e,t){this.location=e,this.machineId=t}directory(e,t=!1){let n=O(e);return!n&&t&&(this.directory(F(e),!0),Jt(e,{mode:448}),n=O(e)),n&&(!n.isDirectory()||n.isSymbolicLink()||n.uid!==this.location.uid||n.mode&18)&&K(),n}parents(e=!1){let t=[this.location.home,this.location.configRoot,L(this.location.configRoot,`systemd`),this.location.unitDir,F(this.location.enablementPath)],n=[];for(let r of t){let t=this.directory(r,e&&r!==F(this.location.enablementPath));t&&n.push({path:r,stat:t})}return n}inspect(){let e=this.parents(),t=O(this.location.definitionPath),n=null;if(t){let e=l(this.location.definitionPath,65536,this.location.uid),r=us(e);(r.machineId!==this.machineId||!ms(t,O(this.location.definitionPath)))&&K(),n={stat:t,raw:e,definition:r}}let r=O(this.location.enablementPath),i=null;if(r){let e=r.isSymbolicLink()?en(this.location.enablementPath):null;ms(r,O(this.location.enablementPath))||K(),i={stat:r,target:e,owned:r.uid===this.location.uid&&e===this.location.definitionPath}}for(let t of e){let e=this.directory(t.path);(!e||!d(t.stat,e))&&K()}return{unit:n,link:i,parents:e}}assertUnchanged(e){let t=this.inspect();for(let t of e.parents??[]){let e=this.directory(t.path);(!e||!d(t.stat,e))&&K()}(!!t.unit!=!!e.unit||!!t.link!=!!e.link)&&K(),t.unit&&e.unit&&(!ms(t.unit.stat,e.unit.stat)||!t.unit.raw.equals(e.unit.raw))&&K(),t.link&&e.link&&(!ms(t.link.stat,e.link.stat)||t.link.target!==e.link.target)&&K()}matchesFragment(e){try{let t=O(e);return!!t&&t.isFile()&&!t.isSymbolicLink()&&t.uid===this.location.uid&&(t.mode&4095)==384&&L(tn(F(e)),un(e))===this.location.definitionPath}catch{return!1}}publish(e,t){(t.machineId!==this.machineId||e.link&&!e.link.owned)&&K();let n=ls(t);this.assertUnchanged(e),this.parents(!0);let r=`${this.location.definitionPath}.tmp-${xn()}`,i;try{let t=Yt(r,N.O_WRONLY|N.O_CREAT|N.O_EXCL|N.O_NOFOLLOW,384);try{i=O(r),cn(t,n),Gt(t)}finally{Ht(t)}this.assertUnchanged(e),e.unit?nn(r,this.location.definitionPath):Kt(r,this.location.definitionPath)}finally{let e=O(r);i&&e&&d(i,e)&&sn(r)}return this.inspect()}setEnabled(e,t){return this.assertUnchanged(e),e.link&&!e.link.owned&&K(),t===!!e.link?e:(t?(e.unit||K(),this.directory(F(this.location.enablementPath),!0),this.assertUnchanged(e),on(this.location.definitionPath,this.location.enablementPath)):(this.assertUnchanged(e),sn(this.location.enablementPath)),this.inspect())}remove(e){return this.assertUnchanged(e),e.link?.owned&&K(),e.unit&&sn(this.location.definitionPath),this.inspect()}restore(e,t){try{this.assertUnchanged(t);let n=t;e.unit&&!n.unit?.raw.equals(e.unit.raw)&&(n=this.publish(n,e.unit.definition)),!!n.link!=!!e.link&&(n=this.setEnabled(n,!!e.link)),e.unit||this.remove(n)}catch{try{this.parents(),e.unit&&cn(`${this.location.definitionPath}.recovery-${xn()}`,e.unit.raw,{flag:`wx`,mode:384})}catch{}throw Error(`shellbell: unresolved systemd file recovery; inspect owned artifacts before retrying`)}}};const gs=[`LoadState`,`ActiveState`,`SubState`,`MainPID`,`UnitFileState`,`FragmentPath`,`DropInPaths`,`NeedDaemonReload`,`ConditionResult`],_s=[`--user`,`--no-pager`,`--no-ask-password`],vs=new Set([16914836,61267,1481003842,2435016766]),q=()=>Error(`shellbell: systemd command failed`);function ys(e){for(let t of e){let e=t.codePointAt(0);if(e<32||e>=127&&e<=159||e>=55296&&e<=57343)return!1}return!0}const bs=()=>({available:!1,loadState:`unknown`,activeState:`unknown`,subState:`unknown`,mainPid:null,unitFileState:`unknown`,fragmentPath:``,dropInPaths:``,needDaemonReload:!0,conditionResult:!1,diagnostic:`systemd user manager unavailable or returned unsupported state`});function xs(e){for(let t of[`/usr/bin`,`/bin`]){let n=L(t,e);try{return Vt(n,N.X_OK),n}catch{}}throw q()}const Ss=(e,t,n)=>new Promise((r,i)=>{let a=Bt(e,[...t],{shell:!1,env:n.env,stdio:[`ignore`,`pipe`,`pipe`]}),o=0,s=[],c=!1,l=!1,u,d=setTimeout(p,n.timeoutMs);function f(e){c||(c=!0,clearTimeout(d),clearTimeout(u),a.stdout.destroy(),a.stderr.destroy(),l||e==null?i(q()):r({exitCode:e,stdout:Buffer.concat(s)}))}function p(){c||l||(l=!0,a.kill(`SIGTERM`),u=setTimeout(()=>{a.kill(`SIGKILL`),f()},250))}function m(e,t){if(!(c||l)){if(o+=e.length,o>n.maxOutputBytes){p();return}t&&s.push(Buffer.from(e))}}a.stdout.on(`data`,e=>m(e,!0)),a.stderr.on(`data`,e=>m(e,!1)),a.on(`error`,()=>f()),a.on(`close`,e=>f(e))});function Cs(e){if(e.length>65536)throw q();let t=new TextDecoder(`utf-8`,{fatal:!0}).decode(e),n=t.endsWith(`
25
+ end if`,n)).trim()!==`yes`)throw new Cs(`iTerm2 is not running`,`not-running`);let r=e.replace(/[\\"]/g,``),i;try{i=await Es(`tell application "iTerm2" to request cookie and key for app named "${r}"`,n)}catch(e){if(e instanceof Cs)throw e;let t=String(e.stderr??e);throw/-274[01]/.test(t)?new Cs(`iTerm2 is too old (need 3.3+)`,`too-old`):/denied|not allowed|user/i.test(t)?new Cs(t.trim(),`denied`):new Cs(t.trim(),`unknown`)}let[a,o]=i.trim().split(` `);if(!a||!o)throw new Cs(`unexpected osascript output (${i.trim().split(` `).length} token(s), ${i.length} chars)`,`unknown`);return{cookie:a,key:o}}async function Es(e,t){try{let{stdout:n}=await Ss(`/usr/bin/osascript`,[`-e`,e],{timeout:Math.max(1,t-Date.now()),killSignal:`SIGKILL`});return n}catch(e){throw e.killed?new Cs(`osascript timed out waiting for iTerm2`,`unknown`):e}}const Ds=Xn(A);var Os=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??As)())throw this.set(`not-running`),new Cs(`iTerm2 is not running`,`not-running`);if(!await(this.opts.apiListening??js)(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 Cs(`waiting for Connect iTerm2`,`unknown`);this.allowance=!1,t&&this.set(`connecting`);try{let t=await(this.opts.requestCookie??Ts)(this.opts.appName??`Shellbell`,e);return this.granted=!0,this.paused=void 0,this.persist(),this.set(void 0),t}catch(e){let t=ks(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(dn(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{kt(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 ks(e){return e instanceof Cs?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 As(){try{let e=process.getuid?.();return await Ds(`/usr/bin/pgrep`,[...e===void 0?[]:[`-U`,String(e)],`-x`,`iTerm2`],{timeout:2e3}),!0}catch{return!1}}async function js(e){try{if(!_n(e).isSocket())return!1}catch{return!1}return new Promise(t=>{let n=Rn({path:e}),r=e=>{n.destroy(),t(e)};n.setTimeout(1e3,()=>r(!1)),n.once(`connect`,()=>r(!0)),n.once(`error`,()=>r(!1))})}const W=$n(`CgxpdGVybTIucHJvdG8SBml0ZXJtMiLcBQoXQ2xpZW50T3JpZ2luYXRlZE1lc3NhZ2USCgoCaWQYASABKAMSNgoSZ2V0X2J1ZmZlcl9yZXF1ZXN0GGQgASgLMhguaXRlcm0yLkdldEJ1ZmZlclJlcXVlc3RIABI2ChJnZXRfcHJvbXB0X3JlcXVlc3QYZSABKAsyGC5pdGVybTIuR2V0UHJvbXB0UmVxdWVzdEgAEjsKFG5vdGlmaWNhdGlvbl9yZXF1ZXN0GGcgASgLMhsuaXRlcm0yLk5vdGlmaWNhdGlvblJlcXVlc3RIABI8ChVsaXN0X3Nlc3Npb25zX3JlcXVlc3QYaiABKAsyGy5pdGVybTIuTGlzdFNlc3Npb25zUmVxdWVzdEgAEjQKEXNlbmRfdGV4dF9yZXF1ZXN0GGsgASgLMhcuaXRlcm0yLlNlbmRUZXh0UmVxdWVzdEgAEjYKEmNyZWF0ZV90YWJfcmVxdWVzdBhsIAEoCzIYLml0ZXJtMi5DcmVhdGVUYWJSZXF1ZXN0SAASNgoSc3BsaXRfcGFuZV9yZXF1ZXN0GG0gASgLMhguaXRlcm0yLlNwbGl0UGFuZVJlcXVlc3RIABI6ChRnZXRfcHJvcGVydHlfcmVxdWVzdBhwIAEoCzIaLml0ZXJtMi5HZXRQcm9wZXJ0eVJlcXVlc3RIABIzChBhY3RpdmF0ZV9yZXF1ZXN0GHIgASgLMhcuaXRlcm0yLkFjdGl2YXRlUmVxdWVzdEgAEjMKEHZhcmlhYmxlX3JlcXVlc3QYcyABKAsyFy5pdGVybTIuVmFyaWFibGVSZXF1ZXN0SAASLQoNZm9jdXNfcmVxdWVzdBh1IAEoCzIULml0ZXJtMi5Gb2N1c1JlcXVlc3RIABJBChdpbnZva2VfZnVuY3Rpb25fcmVxdWVzdBiEASABKAsyHS5pdGVybTIuSW52b2tlRnVuY3Rpb25SZXF1ZXN0SABCDAoKc3VibWVzc2FnZSK0BgoXU2VydmVyT3JpZ2luYXRlZE1lc3NhZ2USCgoCaWQYASABKAMSDwoFZXJyb3IYAiABKAlIABI4ChNnZXRfYnVmZmVyX3Jlc3BvbnNlGGQgASgLMhkuaXRlcm0yLkdldEJ1ZmZlclJlc3BvbnNlSAASOAoTZ2V0X3Byb21wdF9yZXNwb25zZRhlIAEoCzIZLml0ZXJtMi5HZXRQcm9tcHRSZXNwb25zZUgAEj0KFW5vdGlmaWNhdGlvbl9yZXNwb25zZRhnIAEoCzIcLml0ZXJtMi5Ob3RpZmljYXRpb25SZXNwb25zZUgAEj4KFmxpc3Rfc2Vzc2lvbnNfcmVzcG9uc2UYaiABKAsyHC5pdGVybTIuTGlzdFNlc3Npb25zUmVzcG9uc2VIABI2ChJzZW5kX3RleHRfcmVzcG9uc2UYayABKAsyGC5pdGVybTIuU2VuZFRleHRSZXNwb25zZUgAEjgKE2NyZWF0ZV90YWJfcmVzcG9uc2UYbCABKAsyGS5pdGVybTIuQ3JlYXRlVGFiUmVzcG9uc2VIABI4ChNzcGxpdF9wYW5lX3Jlc3BvbnNlGG0gASgLMhkuaXRlcm0yLlNwbGl0UGFuZVJlc3BvbnNlSAASPAoVZ2V0X3Byb3BlcnR5X3Jlc3BvbnNlGHAgASgLMhsuaXRlcm0yLkdldFByb3BlcnR5UmVzcG9uc2VIABI1ChFhY3RpdmF0ZV9yZXNwb25zZRhyIAEoCzIYLml0ZXJtMi5BY3RpdmF0ZVJlc3BvbnNlSAASNQoRdmFyaWFibGVfcmVzcG9uc2UYcyABKAsyGC5pdGVybTIuVmFyaWFibGVSZXNwb25zZUgAEi8KDmZvY3VzX3Jlc3BvbnNlGHUgASgLMhUuaXRlcm0yLkZvY3VzUmVzcG9uc2VIABJDChhpbnZva2VfZnVuY3Rpb25fcmVzcG9uc2UYhAEgASgLMh4uaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVzcG9uc2VIABItCgxub3RpZmljYXRpb24Y6AcgASgLMhQuaXRlcm0yLk5vdGlmaWNhdGlvbkgAQgwKCnN1Ym1lc3NhZ2UiHQoFQ29vcmQSCQoBeBgBIAEoBRIJCgF5GAIgASgDIkYKCkNvb3JkUmFuZ2USHAoFc3RhcnQYASABKAsyDS5pdGVybTIuQ29vcmQSGgoDZW5kGAIgASgLMg0uaXRlcm0yLkNvb3JkIikKBVJhbmdlEhAKCGxvY2F0aW9uGAEgASgDEg4KBmxlbmd0aBgCIAEoAyJdChJXaW5kb3dlZENvb3JkUmFuZ2USJwoLY29vcmRfcmFuZ2UYASABKAsyEi5pdGVybTIuQ29vcmRSYW5nZRIeCgdjb2x1bW5zGAIgASgLMg0uaXRlcm0yLlJhbmdlIh0KBVBvaW50EgkKAXgYASABKAUSCQoBeRgCIAEoBSIlCgRTaXplEg0KBXdpZHRoGAEgASgFEg4KBmhlaWdodBgCIAEoBSJCCgVGcmFtZRIdCgZvcmlnaW4YASABKAsyDS5pdGVybTIuUG9pbnQSGgoEc2l6ZRgCIAEoCzIMLml0ZXJtMi5TaXplInsKCUxpbmVSYW5nZRIcChRzY3JlZW5fY29udGVudHNfb25seRgBIAEoCBIWCg50cmFpbGluZ19saW5lcxgCIAEoBRI4ChR3aW5kb3dlZF9jb29yZF9yYW5nZRgDIAEoCzIaLml0ZXJtMi5XaW5kb3dlZENvb3JkUmFuZ2UiYgoQR2V0QnVmZmVyUmVxdWVzdBIPCgdzZXNzaW9uGAEgASgJEiUKCmxpbmVfcmFuZ2UYAiABKAsyES5pdGVybTIuTGluZVJhbmdlEhYKDmluY2x1ZGVfc3R5bGVzGAMgASgIIjQKCFJHQkNvbG9yEgsKA3JlZBgBIAEoDRINCgVncmVlbhgCIAEoDRIMCgRibHVlGAMgASgNIowDCglDZWxsU3R5bGUSFAoKZmdTdGFuZGFyZBgBIAEoDUgAEi0KC2ZnQWx0ZXJuYXRlGAIgASgOMhYuaXRlcm0yLkFsdGVybmF0ZUNvbG9ySAASIQoFZmdSZ2IYAyABKAsyEC5pdGVybTIuUkdCQ29sb3JIABIUCgpiZ1N0YW5kYXJkGAUgASgNSAESLQoLYmdBbHRlcm5hdGUYBiABKA4yFi5pdGVybTIuQWx0ZXJuYXRlQ29sb3JIARIhCgViZ1JnYhgHIAEoCzIQLml0ZXJtMi5SR0JDb2xvckgBEgwKBGJvbGQYCSABKAgSDQoFZmFpbnQYCiABKAgSDgoGaXRhbGljGAsgASgIEg0KBWJsaW5rGAwgASgIEhEKCXVuZGVybGluZRgNIAEoCBIVCg1zdHJpa2V0aHJvdWdoGA4gASgIEhEKCWludmlzaWJsZRgPIAEoCBIPCgdpbnZlcnNlGBAgASgIEg8KB3JlcGVhdHMYFiABKA1CCQoHZmdDb2xvckIJCgdiZ0NvbG9yIkAKEUNvZGVQb2ludHNQZXJDZWxsEhoKD251bV9jb2RlX3BvaW50cxgBIAEoBToBMRIPCgdyZXBlYXRzGAIgASgFIo0CCgxMaW5lQ29udGVudHMSDAoEdGV4dBgBIAEoCRI3ChRjb2RlX3BvaW50c19wZXJfY2VsbBgCIAMoCzIZLml0ZXJtMi5Db2RlUG9pbnRzUGVyQ2VsbBJOCgxjb250aW51YXRpb24YAyABKA4yIS5pdGVybTIuTGluZUNvbnRlbnRzLkNvbnRpbnVhdGlvbjoVQ09OVElOVUFUSU9OX0hBUkRfRU9MEiAKBXN0eWxlGAQgAygLMhEuaXRlcm0yLkNlbGxTdHlsZSJECgxDb250aW51YXRpb24SGQoVQ09OVElOVUFUSU9OX0hBUkRfRU9MEAESGQoVQ09OVElOVUFUSU9OX1NPRlRfRU9MEAIiogIKEUdldEJ1ZmZlclJlc3BvbnNlEjQKBnN0YXR1cxgBIAEoDjIgLml0ZXJtMi5HZXRCdWZmZXJSZXNwb25zZS5TdGF0dXM6Ak9LEiYKCGNvbnRlbnRzGAMgAygLMhQuaXRlcm0yLkxpbmVDb250ZW50cxIdCgZjdXJzb3IYBCABKAsyDS5pdGVybTIuQ29vcmQSOAoUd2luZG93ZWRfY29vcmRfcmFuZ2UYBiABKAsyGi5pdGVybTIuV2luZG93ZWRDb29yZFJhbmdlIlYKBlN0YXR1cxIGCgJPSxAAEhUKEVNFU1NJT05fTk9UX0ZPVU5EEAESFgoSSU5WQUxJRF9MSU5FX1JBTkdFEAISFQoRUkVRVUVTVF9NQUxGT1JNRUQQAyIVChNMaXN0U2Vzc2lvbnNSZXF1ZXN0InkKDlNlc3Npb25TdW1tYXJ5EhkKEXVuaXF1ZV9pZGVudGlmaWVyGAEgASgJEhwKBWZyYW1lGAIgASgLMg0uaXRlcm0yLkZyYW1lEh8KCWdyaWRfc2l6ZRgDIAEoCzIMLml0ZXJtMi5TaXplEg0KBXRpdGxlGAQgASgJIsEBCg1TcGxpdFRyZWVOb2RlEhAKCHZlcnRpY2FsGAEgASgIEjIKBWxpbmtzGAIgAygLMiMuaXRlcm0yLlNwbGl0VHJlZU5vZGUuU3BsaXRUcmVlTGluaxpqCg1TcGxpdFRyZWVMaW5rEikKB3Nlc3Npb24YASABKAsyFi5pdGVybTIuU2Vzc2lvblN1bW1hcnlIABIlCgRub2RlGAIgASgLMhUuaXRlcm0yLlNwbGl0VHJlZU5vZGVIAEIHCgVjaGlsZCKbAgoUTGlzdFNlc3Npb25zUmVzcG9uc2USNAoHd2luZG93cxgBIAMoCzIjLml0ZXJtMi5MaXN0U2Vzc2lvbnNSZXNwb25zZS5XaW5kb3caeQoGV2luZG93Ei4KBHRhYnMYASADKAsyIC5pdGVybTIuTGlzdFNlc3Npb25zUmVzcG9uc2UuVGFiEhEKCXdpbmRvd19pZBgCIAEoCRIcCgVmcmFtZRgDIAEoCzINLml0ZXJtMi5GcmFtZRIOCgZudW1iZXIYBCABKAUaUgoDVGFiEiMKBHJvb3QYAyABKAsyFS5pdGVybTIuU3BsaXRUcmVlTm9kZRIOCgZ0YWJfaWQYAiABKAkSFgoOdG11eF93aW5kb3dfaWQYBCABKAkiTAoPU2VuZFRleHRSZXF1ZXN0Eg8KB3Nlc3Npb24YASABKAkSDAoEdGV4dBgCIAEoCRIaChJzdXBwcmVzc19icm9hZGNhc3QYAyABKAgibAoQU2VuZFRleHRSZXNwb25zZRIvCgZzdGF0dXMYASABKA4yHy5pdGVybTIuU2VuZFRleHRSZXNwb25zZS5TdGF0dXMiJwoGU3RhdHVzEgYKAk9LEAASFQoRU0VTU0lPTl9OT1RfRk9VTkQQASJbChJHZXRQcm9wZXJ0eVJlcXVlc3QSEwoJd2luZG93X2lkGAEgASgJSAASFAoKc2Vzc2lvbl9pZBgDIAEoCUgAEgwKBG5hbWUYAiABKAlCDAoKaWRlbnRpZmllciKaAQoTR2V0UHJvcGVydHlSZXNwb25zZRIyCgZzdGF0dXMYASABKA4yIi5pdGVybTIuR2V0UHJvcGVydHlSZXNwb25zZS5TdGF0dXMSEgoKanNvbl92YWx1ZRgCIAEoCSI7CgZTdGF0dXMSBgoCT0sQABIVChFVTlJFQ09HTklaRURfTkFNRRABEhIKDklOVkFMSURfVEFSR0VUEAIiQAoUUHJvbXB0TW9uaXRvclJlcXVlc3QSKAoFbW9kZXMYASADKA4yGS5pdGVybTIuUHJvbXB0TW9uaXRvck1vZGUiYAoWVmFyaWFibGVNb25pdG9yUmVxdWVzdBIMCgRuYW1lGAEgASgJEiQKBXNjb3BlGAIgASgOMhUuaXRlcm0yLlZhcmlhYmxlU2NvcGUSEgoKaWRlbnRpZmllchgDIAEoCSL/AQoTTm90aWZpY2F0aW9uUmVxdWVzdBIPCgdzZXNzaW9uGAEgASgJEhEKCXN1YnNjcmliZRgCIAEoCBIzChFub3RpZmljYXRpb25fdHlwZRgDIAEoDjIYLml0ZXJtMi5Ob3RpZmljYXRpb25UeXBlEkIKGHZhcmlhYmxlX21vbml0b3JfcmVxdWVzdBgGIAEoCzIeLml0ZXJtMi5WYXJpYWJsZU1vbml0b3JSZXF1ZXN0SAASPgoWcHJvbXB0X21vbml0b3JfcmVxdWVzdBgJIAEoCzIcLml0ZXJtMi5Qcm9tcHRNb25pdG9yUmVxdWVzdEgAQgsKCWFyZ3VtZW50cyL1AQoUTm90aWZpY2F0aW9uUmVzcG9uc2USMwoGc3RhdHVzGAEgASgOMiMuaXRlcm0yLk5vdGlmaWNhdGlvblJlc3BvbnNlLlN0YXR1cyKnAQoGU3RhdHVzEgYKAk9LEAASFQoRU0VTU0lPTl9OT1RfRk9VTkQQARIVChFSRVFVRVNUX01BTEZPUk1FRBACEhIKDk5PVF9TVUJTQ1JJQkVEEAMSFgoSQUxSRUFEWV9TVUJTQ1JJQkVEEAQSIwofRFVQTElDQVRFX1NFUlZFUl9PUklHSU5BVEVEX1JQQxAFEhYKEklOVkFMSURfSURFTlRJRklFUhAGIisKGFNjcmVlblVwZGF0ZU5vdGlmaWNhdGlvbhIPCgdzZXNzaW9uGAEgASgJIloKGFByb21wdE5vdGlmaWNhdGlvblByb21wdBITCgtwbGFjZWhvbGRlchgBIAEoCRIpCgZwcm9tcHQYAiABKAsyGS5pdGVybTIuR2V0UHJvbXB0UmVzcG9uc2UiMQoeUHJvbXB0Tm90aWZpY2F0aW9uQ29tbWFuZFN0YXJ0Eg8KB2NvbW1hbmQYASABKAkiLgocUHJvbXB0Tm90aWZpY2F0aW9uQ29tbWFuZEVuZBIOCgZzdGF0dXMYASABKAUi+gEKElByb21wdE5vdGlmaWNhdGlvbhIPCgdzZXNzaW9uGAEgASgJEjIKBnByb21wdBgCIAEoCzIgLml0ZXJtMi5Qcm9tcHROb3RpZmljYXRpb25Qcm9tcHRIABI/Cg1jb21tYW5kX3N0YXJ0GAMgASgLMiYuaXRlcm0yLlByb21wdE5vdGlmaWNhdGlvbkNvbW1hbmRTdGFydEgAEjsKC2NvbW1hbmRfZW5kGAQgASgLMiQuaXRlcm0yLlByb21wdE5vdGlmaWNhdGlvbkNvbW1hbmRFbmRIABIYChB1bmlxdWVfcHJvbXB0X2lkGAUgASgJQgcKBWV2ZW50IiwKFk5ld1Nlc3Npb25Ob3RpZmljYXRpb24SEgoKc2Vzc2lvbl9pZBgBIAEoCSIyChxUZXJtaW5hdGVTZXNzaW9uTm90aWZpY2F0aW9uEhIKCnNlc3Npb25faWQYASABKAkiWQoZTGF5b3V0Q2hhbmdlZE5vdGlmaWNhdGlvbhI8ChZsaXN0X3Nlc3Npb25zX3Jlc3BvbnNlGAEgASgLMhwuaXRlcm0yLkxpc3RTZXNzaW9uc1Jlc3BvbnNlIoQDChhGb2N1c0NoYW5nZWROb3RpZmljYXRpb24SHAoSYXBwbGljYXRpb25fYWN0aXZlGAEgASgISAASOQoGd2luZG93GAIgASgLMicuaXRlcm0yLkZvY3VzQ2hhbmdlZE5vdGlmaWNhdGlvbi5XaW5kb3dIABIWCgxzZWxlY3RlZF90YWIYAyABKAlIABIRCgdzZXNzaW9uGAQgASgJSAAa2gEKBldpbmRvdxJLCg13aW5kb3dfc3RhdHVzGAEgASgOMjQuaXRlcm0yLkZvY3VzQ2hhbmdlZE5vdGlmaWNhdGlvbi5XaW5kb3cuV2luZG93U3RhdHVzEhEKCXdpbmRvd19pZBgCIAEoCSJwCgxXaW5kb3dTdGF0dXMSHgoaVEVSTUlOQUxfV0lORE9XX0JFQ0FNRV9LRVkQABIeChpURVJNSU5BTF9XSU5ET1dfSVNfQ1VSUkVOVBABEiAKHFRFUk1JTkFMX1dJTkRPV19SRVNJR05FRF9LRVkQAkIHCgVldmVudCJ9ChtWYXJpYWJsZUNoYW5nZWROb3RpZmljYXRpb24SJAoFc2NvcGUYASABKA4yFS5pdGVybTIuVmFyaWFibGVTY29wZRISCgppZGVudGlmaWVyGAIgASgJEgwKBG5hbWUYAyABKAkSFgoOanNvbl9uZXdfdmFsdWUYBCABKAki9wMKDE5vdGlmaWNhdGlvbhJEChpzY3JlZW5fdXBkYXRlX25vdGlmaWNhdGlvbhgCIAEoCzIgLml0ZXJtMi5TY3JlZW5VcGRhdGVOb3RpZmljYXRpb24SNwoTcHJvbXB0X25vdGlmaWNhdGlvbhgDIAEoCzIaLml0ZXJtMi5Qcm9tcHROb3RpZmljYXRpb24SQAoYbmV3X3Nlc3Npb25fbm90aWZpY2F0aW9uGAYgASgLMh4uaXRlcm0yLk5ld1Nlc3Npb25Ob3RpZmljYXRpb24STAoedGVybWluYXRlX3Nlc3Npb25fbm90aWZpY2F0aW9uGAcgASgLMiQuaXRlcm0yLlRlcm1pbmF0ZVNlc3Npb25Ob3RpZmljYXRpb24SRgobbGF5b3V0X2NoYW5nZWRfbm90aWZpY2F0aW9uGAggASgLMiEuaXRlcm0yLkxheW91dENoYW5nZWROb3RpZmljYXRpb24SRAoaZm9jdXNfY2hhbmdlZF9ub3RpZmljYXRpb24YCSABKAsyIC5pdGVybTIuRm9jdXNDaGFuZ2VkTm90aWZpY2F0aW9uEkoKHXZhcmlhYmxlX2NoYW5nZWRfbm90aWZpY2F0aW9uGAwgASgLMiMuaXRlcm0yLlZhcmlhYmxlQ2hhbmdlZE5vdGlmaWNhdGlvbiI9ChBHZXRQcm9tcHRSZXF1ZXN0Eg8KB3Nlc3Npb24YASABKAkSGAoQdW5pcXVlX3Byb21wdF9pZBgCIAEoCSLkAgoRR2V0UHJvbXB0UmVzcG9uc2USNAoGc3RhdHVzGAEgASgOMiAuaXRlcm0yLkdldFByb21wdFJlc3BvbnNlLlN0YXR1czoCT0sSGQoRd29ya2luZ19kaXJlY3RvcnkYBSABKAkSDwoHY29tbWFuZBgGIAEoCRI1Cgxwcm9tcHRfc3RhdGUYByABKA4yHy5pdGVybTIuR2V0UHJvbXB0UmVzcG9uc2UuU3RhdGUSEwoLZXhpdF9zdGF0dXMYCSABKA0SGAoQdW5pcXVlX3Byb21wdF9pZBgKIAEoCSJWCgZTdGF0dXMSBgoCT0sQABIVChFTRVNTSU9OX05PVF9GT1VORBABEhUKEVJFUVVFU1RfTUFMRk9STUVEEAISFgoSUFJPTVBUX1VOQVZBSUxBQkxFEAMiLwoFU3RhdGUSCwoHRURJVElORxAAEgsKB1JVTk5JTkcQARIMCghGSU5JU0hFRBACIjIKD1Byb2ZpbGVQcm9wZXJ0eRILCgNrZXkYASABKAkSEgoKanNvbl92YWx1ZRgCIAEoCSKeAQoQQ3JlYXRlVGFiUmVxdWVzdBIUCgxwcm9maWxlX25hbWUYASABKAkSEQoJd2luZG93X2lkGAIgASgJEhEKCXRhYl9pbmRleBgDIAEoDRI6ChljdXN0b21fcHJvZmlsZV9wcm9wZXJ0aWVzGAUgAygLMhcuaXRlcm0yLlByb2ZpbGVQcm9wZXJ0eRISCgpzZWxlY3RfdGFiGAYgASgIIvABChFDcmVhdGVUYWJSZXNwb25zZRIwCgZzdGF0dXMYASABKA4yIC5pdGVybTIuQ3JlYXRlVGFiUmVzcG9uc2UuU3RhdHVzEhEKCXdpbmRvd19pZBgCIAEoCRIOCgZ0YWJfaWQYAyABKAUSEgoKc2Vzc2lvbl9pZBgEIAEoCSJyCgZTdGF0dXMSBgoCT0sQABIYChRJTlZBTElEX1BST0ZJTEVfTkFNRRABEhUKEUlOVkFMSURfV0lORE9XX0lEEAISFQoRSU5WQUxJRF9UQUJfSU5ERVgQAxIYChRNSVNTSU5HX1NVQlNUSVRVVElPThAEIqwBChBTcGxpdFBhbmVSZXF1ZXN0Eg8KB3Nlc3Npb24YASABKAkSQAoPc3BsaXRfZGlyZWN0aW9uGAIgASgOMicuaXRlcm0yLlNwbGl0UGFuZVJlcXVlc3QuU3BsaXREaXJlY3Rpb24SFQoGYmVmb3JlGAMgASgIOgVmYWxzZSIuCg5TcGxpdERpcmVjdGlvbhIMCghWRVJUSUNBTBAAEg4KCkhPUklaT05UQUwQASLVAQoRU3BsaXRQYW5lUmVzcG9uc2USMAoGc3RhdHVzGAEgASgOMiAuaXRlcm0yLlNwbGl0UGFuZVJlc3BvbnNlLlN0YXR1cxISCgpzZXNzaW9uX2lkGAIgAygJInoKBlN0YXR1cxIGCgJPSxAAEhUKEVNFU1NJT05fTk9UX0ZPVU5EEAESGAoUSU5WQUxJRF9QUk9GSUxFX05BTUUQAhIQCgxDQU5OT1RfU1BMSVQQAxIlCiFNQUxGT1JNRURfQ1VTVE9NX1BST0ZJTEVfUFJPUEVSVFkQBCKWAgoPQWN0aXZhdGVSZXF1ZXN0EhMKCXdpbmRvd19pZBgBIAEoCUgAEhAKBnRhYl9pZBgCIAEoCUgAEhQKCnNlc3Npb25faWQYAyABKAlIABIaChJvcmRlcl93aW5kb3dfZnJvbnQYBCABKAgSEgoKc2VsZWN0X3RhYhgFIAEoCBIWCg5zZWxlY3Rfc2Vzc2lvbhgGIAEoCBIxCgxhY3RpdmF0ZV9hcHAYByABKAsyGy5pdGVybTIuQWN0aXZhdGVSZXF1ZXN0LkFwcBo9CgNBcHASGQoRcmFpc2VfYWxsX3dpbmRvd3MYASABKAgSGwoTaWdub3Jpbmdfb3RoZXJfYXBwcxgCIAEoCEIMCgppZGVudGlmaWVyIn0KEEFjdGl2YXRlUmVzcG9uc2USLwoGc3RhdHVzGAEgASgOMh8uaXRlcm0yLkFjdGl2YXRlUmVzcG9uc2UuU3RhdHVzIjgKBlN0YXR1cxIGCgJPSxAAEhIKDkJBRF9JREVOVElGSUVSEAESEgoOSU5WQUxJRF9PUFRJT04QAiKLAQoPVmFyaWFibGVSZXF1ZXN0EhQKCnNlc3Npb25faWQYASABKAlIABIoCgNzZXQYAiADKAsyGy5pdGVybTIuVmFyaWFibGVSZXF1ZXN0LlNldBILCgNnZXQYAyADKAkaIgoDU2V0EgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAlCBwoFc2NvcGUi5QEKEFZhcmlhYmxlUmVzcG9uc2USLwoGc3RhdHVzGAEgASgOMh8uaXRlcm0yLlZhcmlhYmxlUmVzcG9uc2UuU3RhdHVzEg4KBnZhbHVlcxgCIAMoCSKPAQoGU3RhdHVzEgYKAk9LEAASFQoRU0VTU0lPTl9OT1RfRk9VTkQQARIQCgxJTlZBTElEX05BTUUQAhIRCg1NSVNTSU5HX1NDT1BFEAMSEQoNVEFCX05PVF9GT1VORBAEEhgKFE1VTFRJX0dFVF9ESVNBTExPV0VEEAUSFAoQV0lORE9XX05PVF9GT1VORBAGIp8BChVJbnZva2VGdW5jdGlvblJlcXVlc3QSNgoGbWV0aG9kGAcgASgLMiQuaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVxdWVzdC5NZXRob2RIABISCgppbnZvY2F0aW9uGAUgASgJEhMKB3RpbWVvdXQYBiABKAE6Ai0xGhoKBk1ldGhvZBIQCghyZWNlaXZlchgBIAEoCUIJCgdjb250ZXh0ItkCChZJbnZva2VGdW5jdGlvblJlc3BvbnNlEjUKBWVycm9yGAEgASgLMiQuaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVzcG9uc2UuRXJyb3JIABI5CgdzdWNjZXNzGAIgASgLMiYuaXRlcm0yLkludm9rZUZ1bmN0aW9uUmVzcG9uc2UuU3VjY2Vzc0gAGlQKBUVycm9yEjUKBnN0YXR1cxgBIAEoDjIlLml0ZXJtMi5JbnZva2VGdW5jdGlvblJlc3BvbnNlLlN0YXR1cxIUCgxlcnJvcl9yZWFzb24YAiABKAkaHgoHU3VjY2VzcxITCgtqc29uX3Jlc3VsdBgBIAEoCSJICgZTdGF0dXMSCwoHVElNRU9VVBABEgoKBkZBSUxFRBACEhUKEVJFUVVFU1RfTUFMRk9STUVEEAMSDgoKSU5WQUxJRF9JRBAEQg0KC2Rpc3Bvc2l0aW9uIg4KDEZvY3VzUmVxdWVzdCJICg1Gb2N1c1Jlc3BvbnNlEjcKDW5vdGlmaWNhdGlvbnMYASADKAsyIC5pdGVybTIuRm9jdXNDaGFuZ2VkTm90aWZpY2F0aW9uKkcKDkFsdGVybmF0ZUNvbG9yEgsKB0RFRkFVTFQQABIUChBSRVZFUlNFRF9ERUZBVUxUEAMSEgoOU1lTVEVNX01FU1NBR0UQBCrZAQoQTm90aWZpY2F0aW9uVHlwZRIbChdOT1RJRllfT05fU0NSRUVOX1VQREFURRACEhQKEE5PVElGWV9PTl9QUk9NUFQQAxIZChVOT1RJRllfT05fTkVXX1NFU1NJT04QBhIfChtOT1RJRllfT05fVEVSTUlOQVRFX1NFU1NJT04QBxIbChdOT1RJRllfT05fTEFZT1VUX0NIQU5HRRAIEhoKFk5PVElGWV9PTl9GT0NVU19DSEFOR0UQCRIdChlOT1RJRllfT05fVkFSSUFCTEVfQ0hBTkdFEAwqQwoRUHJvbXB0TW9uaXRvck1vZGUSCgoGUFJPTVBUEAESEQoNQ09NTUFORF9TVEFSVBACEg8KC0NPTU1BTkRfRU5EEAMqOgoNVmFyaWFibGVTY29wZRILCgdTRVNTSU9OEAESBwoDVEFCEAISCgoGV0lORE9XEAMSBwoDQVBQEAQ`),Ms=B(W,0),Ns=B(W,1),Ps=B(W,2),Fs=B(W,3),Is=B(W,5),Ls=B(W,9),Rs=B(W,10),zs=B(W,16),Bs=B(W,20);let Vs=function(e){return e[e.OK=0]=`OK`,e[e.SESSION_NOT_FOUND=1]=`SESSION_NOT_FOUND`,e}({});const Hs=B(W,22),Us=B(W,24),Ws=B(W,25),Gs=B(W,26),Ks=B(W,42),qs=B(W,44),Js=B(W,46),Ys=B(W,46,0),Xs=B(W,48),Zs=B(W,52);function Qs(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 $s(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 ec(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],l;s===0?l=` `:(l=t.slice(o,o+s).join(``),o+=s);let u=Qs(r[e]);u.invisible&&(l=` `.repeat(Math.max(1,c(l))));let d=$s(u);a&&a.key===d?(a.text+=l,a.cells+=1):(a&&i.push(tc(a)),a={style:u,key:d,text:l,cells:1})}a&&i.push(tc(a));let s=e.continuation===2,l=ke(i),u={r:s?l:b(l)};return s&&(u.w=!0),u}function tc(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!==c(e.text)&&(t.n=e.cells),t}function nc(e,t,n){let r=Number(e.windowedCoordRange?.coordRange?.start?.y??0n),i=e.contents.map(ec);for(;i.length<t;)i.push(Me());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 rc(e){return typeof e==`number`&&Number.isSafeInteger(e)&&e>=0}function ic(e){return typeof e==`bigint`&&e>=0n&&e<=BigInt(2**53-1)}function ac(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(!rc(n)||!rc(r)||!rc(i)||!rc(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 oc(e,t,n){if(!rc(t)||!rc(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||!ic(i.y)||!ic(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 sc(e,t){return e.overflow===t.overflow&&e.history===t.history&&e.grid===t.grid}function cc(e,t){return t!==void 0&&(e.overflow<t.overflow||e.origin<t.origin)}function lc(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`?lc(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 uc="iTerm2 → Settings → General → Magic → ✓ Enable Python API, then run `shellbell` again.";function dc(e){return O(e)}var fc=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:dc(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 C(String(t),uc)}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:z(Gs,{subscribe:!0,notificationType:t})}),!this.ownsConnection(e))return;let t=await this.client.request({case:`listSessionsRequest`,value:z(zs,{})});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:z(Zs,{})});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 C(String(t),uc)}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 Or({sessionId:e,cwd:t.cwd,title:t.title,sessionLabel:`iTerm2 · Window ${t.windowNumber} · Tab ${t.tabIndex+1} · Pane ${t.paneIndex+1}`},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}))}hostedProcess(e){return this.hostJob(e)}projectFolder(e){let t=this.sessions.get(e);return t?.cwd&&La(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 D(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||cc(s,o))&&this.revokeHistory(e);let c=await this.client.request({case:`getBufferRequest`,value:z(Rs,{session:e,lineRange:z(Ls,{screenContentsOnly:!0}),includeStyles:!0})});if(c.submessage.case!==`getBufferResponse`||c.submessage.value.status!==0)throw new D(e);let l=c.submessage.value,u;if(i&&s&&s.grid===i.rows&&this.ownsHistory(i)&&this.historyOwnership.get(e)?.activityRevision===a&&oc(l,s.origin,s.origin+s.grid)){let t=await this.fetchHistoryFacts(e);t&&this.ownsHistory(i)&&(t.grid!==i.rows||cc(t,s))&&this.revokeHistory(e),t&&sc(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=nc(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:z(Hs,{identifier:{case:`sessionId`,value:e},name:`number_of_lines`})});return t.submessage.case===`getPropertyResponse`&&t.submessage.value.status===0?ac(t.submessage.value.jsonValue):null}catch{return null}}async getHistoryPage(e,t){if(rt(t),t.signal.aborted)return{status:`cancelled`};if(!this.sessions.has(e))throw new D(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||cc(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:z(Rs,{session:e,lineRange:z(Ls,{windowedCoordRange:z(Is,{coordRange:z(Fs,{start:z(Ps,{x:0,y:BigInt(f)}),end:z(Ps,{x:0,y:BigInt(t.before)})})})}),includeStyles:!0})}),i=r();if(i)return i;if(n.submessage.case!==`getBufferResponse`||!oc(n.submessage.value,f,t.before))return s;p=n.submessage.value.contents.map(ec)}catch{return r()??s}let m=await this.fetchHistoryFacts(e);return(r()??c(m,l))||(!m||!sc(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 D(e);let r=Math.max(0,t-n),i=await this.client.request({case:`getBufferRequest`,value:z(Rs,{session:e,lineRange:z(Ls,{windowedCoordRange:z(Is,{coordRange:z(Fs,{start:z(Ps,{x:0,y:BigInt(r)}),end:z(Ps,{x:0,y:BigInt(t)})})})}),includeStyles:!0})});if(i.submessage.case!==`getBufferResponse`||i.submessage.value.status!==0)throw new D(e);let a=i.submessage.value.contents.map(ec);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:z(Bs,{session:e,text:t,suppressBroadcast:!0})});if(n.submessage.case!==`sendTextResponse`)throw new D(e);let r=n.submessage.value.status;if(r===1)throw new D(e);if(r!==0)throw Error(`sendText failed: ${Vs[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?Nt.parse(e.initialSize):void 0,n=await this.client.request({case:`createTabRequest`,value:z(Ks,{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:z(qs,{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():Nt.parse(t),r=await this.client.request({case:`createTabRequest`,value:z(Ks,{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:z(Js,{identifier:{case:`sessionId`,value:e},orderWindowFront:!0,selectTab:!0,selectSession:!0,activateApp:z(Ys,{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:dc(e)})}}toInfo(e){return{id:e.id,backend:`iterm2`,title:e.title,cwd:e.cwd,...Va({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=lc(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=[z(Gs,{session:e,subscribe:!0,notificationType:2}),z(Gs,{session:e,subscribe:!0,notificationType:3,arguments:{case:`promptMonitorRequest`,value:z(Us,{modes:[1,2,3]})}}),...[`session.name`,`session.path`,`jobName`].map(t=>z(Gs,{session:e,subscribe:!0,notificationType:12,arguments:{case:`variableMonitorRequest`,value:z(Ws,{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:dc(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:z(Xs,{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:dc(e)})});return}if(e.newSessionNotification?.sessionId){this.client.request({case:`listSessionsRequest`,value:z(zs,{})}).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:dc(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 pc=F(M(),`Library`,`Application Support`,`iTerm2`,`private`,`socket`);var mc=class extends Ln{opts;ws=null;connecting=null;nextId=1n;pending=new Map;log;constructor(e){super(),this.opts=e,this.log=e.log.child({unit:`iterm2`})}get connected(){return this.ws?.readyState===qn.OPEN}connect(){if(this.connecting)return this.connecting;let e=this.open().finally(()=>{this.connecting===e&&(this.connecting=null)});return this.connecting=e,e}async open(){let e=this.opts.appName??`Shellbell`,t=this.opts.socketPath??pc,n=this.opts.cookieTimeoutMs??12e4,{cookie:r,key:i}=await hc((this.opts.cookieProvider??(()=>Ts(e,n)))(),n,`iTerm2 did not answer the API cookie request`),a={origin:`ws://localhost/`,"x-iterm2-library-version":`shellbell 0.1.0`,"x-iterm2-disable-auth-ui":`true`,"x-iterm2-advisory-name":e,"x-iterm2-cookie":r,"x-iterm2-key":i},o=this.opts.connectTimeoutMs??1e4,s=this.opts.url?new qn(this.opts.url,[`api.iterm2.com`],{headers:a,handshakeTimeout:o}):new qn(`ws://localhost/`,[`api.iterm2.com`],{headers:a,handshakeTimeout:o,createConnection:()=>Rn({path:t})});this.ws=s,await new Promise((e,t)=>{let n=()=>{s.off(`open`,i),s.off(`error`,a),s.off(`unexpected-response`,o),s.off(`close`,c)},r=e=>{n(),s.on(`error`,()=>{}),s.terminate(),this.ws===s&&(this.ws=null),t(e)},i=()=>{n(),e()},a=e=>r(e),o=(e,t)=>{t.destroy(),e.destroy(),r(Error(`iTerm2 API responded HTTP ${t.statusCode}`))},c=()=>r(Error(`iTerm2 connection closed before open`));s.once(`open`,i),s.once(`error`,a),s.once(`unexpected-response`,o),s.once(`close`,c)}),s.on(`message`,(e,t)=>{if(!t)return;let n;try{n=Zn(Ns,new Uint8Array(e))}catch(e){this.log.warn(`undecodable message from iTerm2`,{err:O(e)});return}if(n.submessage.case===`notification`){this.emit(`notification`,n.submessage.value);return}let r=this.pending.get(n.id);r&&(clearTimeout(r.timer),this.pending.delete(n.id),r.resolve(n))}),s.on(`close`,()=>{for(let[e,t]of this.pending)t.ws===s&&(clearTimeout(t.timer),t.reject(Error(`iTerm2 connection closed`)),this.pending.delete(e));this.ws===s&&(this.ws=null),this.emit(`close`)}),s.on(`error`,e=>this.log.warn(`iTerm2 socket error`,{err:O(e)})),this.log.info(`connected to iTerm2 API`)}close(){this.ws?.close(),this.ws=null}request(e){let t=this.ws;if(!t||t.readyState!==qn.OPEN)return Promise.reject(Error(`iTerm2 not connected`));let n=this.nextId++,r=z(Ms,{id:n,submessage:e});return new Promise((i,a)=>{let o=setTimeout(()=>{this.pending.delete(n),a(Error(`iTerm2 request timeout (${e.case})`))},this.opts.requestTimeoutMs??5e3);this.pending.set(n,{resolve:i,reject:a,timer:o,ws:t}),t.send(Qn(Ms,r),{binary:!0})})}};function hc(e,t,n){let r,i=new Promise((e,i)=>{r=setTimeout(()=>i(Error(n)),t)});return Promise.race([e,i]).finally(()=>clearTimeout(r))}const gc=I.object({apiVersion:I.literal(1),id:n,label:ye,platforms:I.array(I.enum([`darwin`,`linux`])).min(1).max(2),hostCommands:I.array(I.string().regex(/^[a-zA-Z0-9._-]{1,64}$/)).max(16).optional()}),_c=I.string().min(1).max(128),vc=I.discriminatedUnion(`type`,[I.object({type:I.literal(`focus-changed`)}),...[`screen-changed`,`session-added`,`session-removed`,`title-changed`].map(e=>I.object({type:I.literal(e),sessionId:_c})),I.object({type:I.literal(`layout-changed`)}),I.object({type:I.literal(`command-start`),sessionId:_c,command:I.string().max(512),at:I.number().finite()}),I.object({type:I.literal(`command-end`),sessionId:_c,exitCode:I.number().int(),at:I.number().finite()}),I.object({type:I.literal(`prompt`),sessionId:_c,at:I.number().finite()}),I.object({type:I.literal(`agent-state`),sessionId:_c,state:I.enum([`working`,`blocked`,`idle`,`done`,`unknown`]),agent:I.string().max(128).optional(),at:I.number().finite()})]),yc=I.object({cols:I.number().int().min(1).max(x.cols),rows:I.number().int().min(1).max(x.rows),cursor:wt,lines:I.array(ut).max(x.rows),scrollbackTotal:I.number().int().nonnegative().max(2**53-1),historyCapture:I.custom(e=>typeof e==`object`&&!!e&&!Array.isArray(e)).optional()}).refine(e=>e.lines.length===e.rows,`screen must contain every viewport row`),bc=I.number().int().nonnegative().max(2**53-1),xc=I.discriminatedUnion(`status`,[I.object({status:I.literal(`page`),from:bc,to:bc,oldestAvailable:bc,lines:I.array(ut).max(x.historyLines)}),I.object({status:I.literal(`boundary`),reason:I.enum([`end`,`truncated`]),oldestAvailable:bc}),I.object({status:I.literal(`unavailable`),reason:I.enum([`unsupported`,`unanchored`,`busy`,`changed`,`fetch-window`])}),I.object({status:I.literal(`reset`)}),I.object({status:I.literal(`cancelled`)})]);var Sc=class extends Error{};async function Cc(e,t){let n;try{return await Promise.race([e,new Promise((e,r)=>{n=setTimeout(()=>r(new Sc(`Terminal adapter deadline exceeded`)),t),n.unref()})])}finally{n&&clearTimeout(n)}}var wc=class{raw;abort;timeoutMs;name;capabilities;connected=!1;closed=!1;generation=0;pending=0;handlers=new Set;unsubscribe;constructor(e,t,r,i=5e3){if(this.raw=e,this.abort=r,this.timeoutMs=i,this.name=n.parse(t),e.name!==t)throw Error(`Adapter identity does not match its manifest`);this.capabilities=Object.freeze(Rt.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=vc.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 C(`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 Cc(n,this.timeoutMs);if(this.closed||t!==this.generation)throw Error(`Terminal adapter generation retired`);return e}catch(e){if(e instanceof Sc){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 C(`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 Cc(Promise.resolve().then(()=>this.raw.close()),this.timeoutMs)}}}async listSessions(){if(!this.isConnected)return[];let e=I.array(qe).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 yc.parse(await this.call(()=>this.raw.getScreen(e,t)))}async getHistory(e,t,n){return I.object({lines:I.array(ut).max(1e3),oldestAvailable:I.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=xc.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:I.string().max(128).refine(e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127)).parse(t)}representedWindows(){return I.array(I.object({backend:n,windowId:I.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:I.string().min(1).max(128).parse(t)}};function Tc(e){let t=!1,n=[],r=new Set(nt.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 Cc(Promise.resolve().then(()=>e.close()),i).catch(()=>{}))};try{if(e.admitPath)e.admitPath(a);else{if(sn(a).isSymbolicLink()||hn(a)!==a)throw Error(`Adapter path must be canonical`);Ee(a,262144,process.getuid())}let l=await Cc((e.importModule??er)(Mn(a).href),i),d=gc.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 Cc(p,i),t){o.abort(),await u(c);break}s=new wc(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:O(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:O(t)}))}),_()}catch(t){o.abort(),s?await s.close().catch(()=>{}):c&&await u(c),e.log.warn(`terminal plugin could not be loaded`,{error:O(t)})}}})(),stop(){t=!0;for(let e of n.splice(0))e()}}}const Ec={iterm2:{bundle:`iTerm.app`,label:`iTerm2`}},Dc=Xn(A);function Oc(e,t={}){if((t.platform??process.platform)!==`darwin`)return null;let n=t.roots??[`/Applications`,F(M(),`Applications`)],r=t.exists??nn,i=Ec[e],a=()=>n.map(e=>F(e,i.bundle)).find(r);return{available:()=>a()!==void 0,start:async()=>{let e=a();if(!e)throw new C(`${i.label} is not installed`,`Install ${i.label} on your computer.`);try{await(t.execute??((e,t)=>Dc(e,t,{timeout:5e3,maxBuffer:4096})))(`/usr/bin/open`,[`-g`,`-a`,e])}catch{throw new C(`Could not launch ${i.label}`,`Open ${i.label} on your computer and check its local API.`)}}}}function kc(e={}){let t=()=>Po(e.env,e.executable);return{available:()=>t()!==void 0,start:async()=>{let n=t();if(!n)throw new C(`Herdr is not installed`,`Install Herdr on your computer.`);await new Promise((t,r)=>{let i=(e.spawnImpl??$t)(n,[`server`],{detached:!0,stdio:`ignore`,env:e.env??process.env});i.once(`error`,()=>r(new C(`Could not start Herdr`,`Check your Herdr installation.`))),i.once(`spawn`,()=>{i.unref(),t()})})}}}function Ac(e,t,n=2e4){return new Promise((r,i)=>{let a=setTimeout(()=>{s(),i(new C(`${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 jc=Xn(A);function Mc(e){let t=[e.executable,...e.args],n=e=>[...e].every(e=>e.charCodeAt(0)>=32&&e.charCodeAt(0)!==127);if(!P(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 Nc(e,t){try{await e()}catch{try{await t()}catch{throw new Ie(`The terminal window could not open on your computer, and the new session could not be closed. Check the session list.`)}throw new Ie(`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 Pc(e={}){if((e.platform??process.platform)!==`darwin`)return null;let t=()=>(e.roots??[`/Applications`,F(M(),`Applications`)]).map(e=>F(e,`Ghostty.app`)).find(e.exists??nn);return{id:`ghostty`,label:`Ghostty`,available:()=>t()!==void 0,async launch(n){let r=t();if(!r)throw new C(`Ghostty is not installed`,`Install Ghostty on your computer.`);let i=Mc(n),a=n.initialSize===void 0?void 0:Nt.parse(n.initialSize);try{await(e.execute??((e,t)=>jc(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 C(`Ghostty could not be launched`,`Check that Ghostty opens on your computer, then try again.`)}}}}async function Fc(e,t=fetch){let n;try{let t=new URL(e),r={"ws:":`http:`,"wss:":`https:`,"http:":`http:`,"https:":`https:`}[t.protocol];if(!r||!t.hostname)return!1;t.protocol=r,t.username=``,t.password=``,t.pathname=`/healthz`,t.search=``,t.hash=``,n=t.toString()}catch{return!1}let r=new AbortController,i=null,a=setTimeout(()=>{r.abort(),i?.cancel().catch(()=>{})},5e3);try{let e=await t(n,{redirect:`manual`,signal:r.signal});if(!e.body||(i=e.body.getReader(),e.status!==200))return!1;let a=[],o=0;for(;;){let{done:e,value:t}=await i.read();if(e)break;if(o+=t.byteLength,o>4096)return!1;a.push(t)}return!r.signal.aborted&&Buffer.concat(a,o).toString(`utf8`)===`ok`}catch{return!1}finally{if(clearTimeout(a),r.abort(),i){i.cancel().catch(()=>{});try{i.releaseLock()}catch{}}}}const Ic=65536,Lc=16384,Rc=`# shellbell-systemd-v1 `,zc=I.string().max(Lc).refine(e=>{for(let t of e){let e=t.codePointAt(0);if(e<32||e>=127&&e<=159||e>=55296&&e<=57343)return!1}return!0}),Bc=zc.refine(P),Vc=I.strictObject({v:I.literal(1),machineId:I.string().regex(/^[0-9a-f]{32}$/).refine(e=>e!==`0`.repeat(32)),nodePath:Bc.refine(e=>!/["'\\]/.test(e)),cliPath:Bc,stateDir:Bc,runtimeRoot:Bc,serviceInstance:I.uuid(),path:zc.refine(e=>{let t=e.split(`:`);return t.every(P)&&new Set(t).size===t.length})});function G(){throw Error(`shellbell: invalid or foreign systemd unit`)}function Hc(e){return`"${e.replaceAll(`\\`,`\\\\`).replaceAll(`"`,`\\"`).replaceAll(`%`,`%%`)}"`}function Uc(e,t){return`Environment=${Hc(`${e}=${t}`)}`}function Wc(e){let t=Vc.safeParse(e);t.success||G();let n=t.data,r=2;for(let[e,t]of Object.entries(n))r+=e.length+3+(r===2?0:1),r+=typeof t==`number`?1:Buffer.byteLength(t)+2+[...t].filter(e=>e===`"`||e===`\\`).length;r>Lc&&G();let i=JSON.stringify(n);Buffer.byteLength(i)>Lc&&G();let a=Buffer.from([Rc+Buffer.from(i).toString(`base64url`),`[Unit]`,`Description=Shellbell terminal host`,`ConditionHost=${n.machineId}`,`StartLimitIntervalSec=60s`,`StartLimitBurst=3`,``,`[Service]`,`Type=exec`,`ExecStart=${[`:${n.nodePath}`,n.cliPath,`start`,`--service`].map(Hc).join(` `)}`,Uc(`SHELLBELL_DIR`,n.stateDir),Uc(`SHELLBELL_SERVICE_INSTANCE`,n.serviceInstance),Uc(`XDG_RUNTIME_DIR`,n.runtimeRoot),Uc(`PATH`,n.path),`Restart=on-failure`,`RestartSec=5s`,`TimeoutStopSec=15s`,`UMask=0077`,`StandardInput=null`,`StandardOutput=null`,`StandardError=journal`,`KillMode=control-group`,``,`[Install]`,`WantedBy=default.target`,``].join(`
26
+ `));return a.length>Ic&&G(),a}function Gc(e){try{e.byteLength>Ic&&G();let t=Buffer.from(e),n=t.subarray(0,t.indexOf(10)).toString(`utf8`);n.startsWith(Rc)||G();let r=n.slice(23);(r.length>21846||!/^[A-Za-z0-9_-]+$/.test(r))&&G();let i=Buffer.from(r,`base64url`);(i.length>Lc||i.toString(`base64url`)!==r)&&G();let a=Vc.parse(JSON.parse(i.toString(`utf8`)));return Wc(a).equals(t)||G(),a}catch{return G()}}function Kc(e,t){let n=f(e);n&&(!n.isDirectory()||n.isSymbolicLink()||n.uid!==t||n.mode&18)&&G()}function qc(e,t){Bc.safeParse(e).success||G();let n=f(e)?hn(e):h(e);return Kc(n,t),n}function Jc(e){let{uid:t,hostScope:n}=e.identity;(!Number.isSafeInteger(t)||t<=0||!/^[0-9a-f]{32}$/.test(n))&&G();let r=qc(e.home,t),i=qc(e.env.XDG_CONFIG_HOME&&P(e.env.XDG_CONFIG_HOME)?e.env.XDG_CONFIG_HOME:F(r,`.config`),t),a=F(i,`systemd`,`user`);for(let e of[F(i,`systemd`),a])Kc(e,t);let o=`shellbell-${n}.service`,s=F(a,o),c=f(s);return c&&(!c.isFile()||c.isSymbolicLink()||c.uid!==t||(c.mode&4095)!=384)&&G(),{uid:t,home:r,configRoot:i,unitName:o,unitDir:a,definitionPath:s,enablementPath:F(a,`default.target.wants`,o),managerRuntimeRoot:`/run/user/${t}`}}function K(){throw Error(`shellbell: unsafe, foreign or concurrently changed systemd files`)}function Yc(e,t){return _t(e,t)&&e.mode===t.mode&&e.uid===t.uid&&e.size===t.size&&e.mtimeMs===t.mtimeMs&&e.ctimeMs===t.ctimeMs}var Xc=class{location;machineId;constructor(e,t){this.location=e,this.machineId=t}directory(e,t=!1){let n=f(e);return!n&&t&&(this.directory(N(e),!0),cn(e,{mode:448}),n=f(e)),n&&(!n.isDirectory()||n.isSymbolicLink()||n.uid!==this.location.uid||n.mode&18)&&K(),n}parents(e=!1){let t=[this.location.home,this.location.configRoot,F(this.location.configRoot,`systemd`),this.location.unitDir,N(this.location.enablementPath)],n=[];for(let r of t){let t=this.directory(r,e&&r!==N(this.location.enablementPath));t&&n.push({path:r,stat:t})}return n}inspect(){let e=this.parents(),t=f(this.location.definitionPath),n=null;if(t){let e=Ee(this.location.definitionPath,65536,this.location.uid),r=Gc(e);(r.machineId!==this.machineId||!Yc(t,f(this.location.definitionPath)))&&K(),n={stat:t,raw:e,definition:r}}let r=f(this.location.enablementPath),i=null;if(r){let e=r.isSymbolicLink()?mn(this.location.enablementPath):null;Yc(r,f(this.location.enablementPath))||K(),i={stat:r,target:e,owned:r.uid===this.location.uid&&e===this.location.definitionPath}}for(let t of e){let e=this.directory(t.path);(!e||!_t(t.stat,e))&&K()}return{unit:n,link:i,parents:e}}assertUnchanged(e){let t=this.inspect();for(let t of e.parents??[]){let e=this.directory(t.path);(!e||!_t(t.stat,e))&&K()}(!!t.unit!=!!e.unit||!!t.link!=!!e.link)&&K(),t.unit&&e.unit&&(!Yc(t.unit.stat,e.unit.stat)||!t.unit.raw.equals(e.unit.raw))&&K(),t.link&&e.link&&(!Yc(t.link.stat,e.link.stat)||t.link.target!==e.link.target)&&K()}matchesFragment(e){try{let t=f(e);return!!t&&t.isFile()&&!t.isSymbolicLink()&&t.uid===this.location.uid&&(t.mode&4095)==384&&F(hn(N(e)),wn(e))===this.location.definitionPath}catch{return!1}}publish(e,t){(t.machineId!==this.machineId||e.link&&!e.link.owned)&&K();let n=Wc(t);this.assertUnchanged(e),this.parents(!0);let r=`${this.location.definitionPath}.tmp-${L()}`,i;try{let t=ln(r,j.O_WRONLY|j.O_CREAT|j.O_EXCL|j.O_NOFOLLOW,384);try{i=f(r),xn(t,n),an(t)}finally{tn(t)}this.assertUnchanged(e),e.unit?gn(r,this.location.definitionPath):on(r,this.location.definitionPath)}finally{let e=f(r);i&&e&&_t(i,e)&&bn(r)}return this.inspect()}setEnabled(e,t){return this.assertUnchanged(e),e.link&&!e.link.owned&&K(),t===!!e.link?e:(t?(e.unit||K(),this.directory(N(this.location.enablementPath),!0),this.assertUnchanged(e),yn(this.location.definitionPath,this.location.enablementPath)):(this.assertUnchanged(e),bn(this.location.enablementPath)),this.inspect())}remove(e){return this.assertUnchanged(e),e.link?.owned&&K(),e.unit&&bn(this.location.definitionPath),this.inspect()}restore(e,t){try{this.assertUnchanged(t);let n=t;e.unit&&!n.unit?.raw.equals(e.unit.raw)&&(n=this.publish(n,e.unit.definition)),!!n.link!=!!e.link&&(n=this.setEnabled(n,!!e.link)),e.unit||this.remove(n)}catch{try{this.parents(),e.unit&&xn(`${this.location.definitionPath}.recovery-${L()}`,e.unit.raw,{flag:`wx`,mode:384})}catch{}throw Error(`shellbell: unresolved systemd file recovery; inspect owned artifacts before retrying`)}}};const Zc=[`LoadState`,`ActiveState`,`SubState`,`MainPID`,`UnitFileState`,`FragmentPath`,`DropInPaths`,`NeedDaemonReload`,`ConditionResult`],Qc=[`--user`,`--no-pager`,`--no-ask-password`],$c=new Set([16914836,61267,1481003842,2435016766]),q=()=>Error(`shellbell: systemd command failed`);function el(e){for(let t of e){let e=t.codePointAt(0);if(e<32||e>=127&&e<=159||e>=55296&&e<=57343)return!1}return!0}const tl=()=>({available:!1,loadState:`unknown`,activeState:`unknown`,subState:`unknown`,mainPid:null,unitFileState:`unknown`,fragmentPath:``,dropInPaths:``,needDaemonReload:!0,conditionResult:!1,diagnostic:`systemd user manager unavailable or returned unsupported state`});function nl(e){for(let t of[`/usr/bin`,`/bin`]){let n=F(t,e);try{return en(n,j.X_OK),n}catch{}}throw q()}const rl=(e,t,n)=>new Promise((r,i)=>{let a=$t(e,[...t],{shell:!1,env:n.env,stdio:[`ignore`,`pipe`,`pipe`]}),o=0,s=[],c=!1,l=!1,u,d=setTimeout(p,n.timeoutMs);function f(e){c||(c=!0,clearTimeout(d),clearTimeout(u),a.stdout.destroy(),a.stderr.destroy(),l||e==null?i(q()):r({exitCode:e,stdout:Buffer.concat(s)}))}function p(){c||l||(l=!0,a.kill(`SIGTERM`),u=setTimeout(()=>{a.kill(`SIGKILL`),f()},250))}function m(e,t){if(!(c||l)){if(o+=e.length,o>n.maxOutputBytes){p();return}t&&s.push(Buffer.from(e))}}a.stdout.on(`data`,e=>m(e,!0)),a.stderr.on(`data`,e=>m(e,!1)),a.on(`error`,()=>f()),a.on(`close`,e=>f(e))});function il(e){if(e.length>65536)throw q();let t=new TextDecoder(`utf-8`,{fatal:!0}).decode(e),n=t.endsWith(`
23
27
  `)?t.slice(0,-1).split(`
24
28
  `):t.split(`
25
- `),r=new Map;for(let e of n){let t=e.indexOf(`=`),n=e.slice(0,t),i=e.slice(t+1);if(t<0||!gs.includes(n)||r.has(n)||!ys(i))throw q();r.set(n,i)}if(r.size!==gs.length)throw q();let i=e=>r.get(e);for(let[e,t]of Object.entries({LoadState:[`stub`,`loaded`,`not-found`,`bad-setting`,`error`,`merged`,`masked`],ActiveState:[`active`,`reloading`,`inactive`,`failed`,`activating`,`deactivating`,`maintenance`],SubState:[`dead`,`condition`,`start-pre`,`start`,`start-post`,`running`,`exited`,`reload`,`stop`,`stop-watchdog`,`stop-sigterm`,`stop-sigkill`,`stop-post`,`final-sigterm`,`final-sigkill`,`failed`,`auto-restart`,`cleaning`],UnitFileState:[``,`enabled`,`enabled-runtime`,`linked`,`linked-runtime`,`alias`,`masked`,`masked-runtime`,`static`,`disabled`,`indirect`,`generated`,`transient`,`bad`]}))if(!t.includes(i(e)))throw q();if(!/^(0|[1-9][0-9]*)$/.test(i(`MainPID`)))throw q();let a=Number(i(`MainPID`));if(!Number.isSafeInteger(a))throw q();for(let e of[`NeedDaemonReload`,`ConditionResult`])if(![`yes`,`no`].includes(i(e)))throw q();let o=i(`FragmentPath`);if(o&&!I(o))throw q();return{available:!0,loadState:i(`LoadState`),activeState:i(`ActiveState`),subState:i(`SubState`),mainPid:a||null,unitFileState:i(`UnitFileState`),fragmentPath:o,dropInPaths:i(`DropInPaths`),needDaemonReload:i(`NeedDaemonReload`)===`yes`,conditionResult:i(`ConditionResult`)===`yes`}}function ws(e){return`unix:path=${[...Buffer.from(e)].map(e=>/[A-Za-z0-9_./-]/.test(String.fromCharCode(e))?String.fromCharCode(e):`%${e.toString(16).padStart(2,`0`)}`).join(``)}`}function Ts(e){let t={...e.location},n=e.run??Ss;async function r(r,i){try{let{uid:a}=t;if(!Number.isSafeInteger(a)||a<=0||a!==process.getuid?.()||a!==process.geteuid?.()||!/^shellbell-[0-9a-f]{32}\.service$/.test(t.unitName))throw q();for(let e of[t.home,t.configRoot,t.managerRuntimeRoot])if(!I(e)||!ys(e))throw q();m(t.managerRuntimeRoot,a);let o=e.runtimeFsType?.(t.managerRuntimeRoot)??an(t.managerRuntimeRoot).type;if(!vs.has(Number(o)))throw q();let s=await n(e.run?`/usr/bin/${r}`:xs(r),i,{timeoutMs:3e4,maxOutputBytes:65536,env:{HOME:t.home,XDG_CONFIG_HOME:t.configRoot,XDG_RUNTIME_DIR:t.managerRuntimeRoot,DBUS_SESSION_BUS_ADDRESS:ws(L(t.managerRuntimeRoot,`bus`)),PATH:`/usr/bin:/bin`,LANG:`C`,LC_ALL:`C`}});if(s.exitCode!==0||s.stdout.length>65536)throw q();return s.stdout}catch{throw q()}}return{async observe(){try{return Cs(await r(`systemctl`,[..._s,`show`,`--property=${gs.join(`,`)}`,t.unitName]))}catch{return bs()}},async execute(e){if(![`start`,`stop`,`daemon-reload`].includes(e))throw q();await r(`systemctl`,[..._s,e,...e===`daemon-reload`?[]:[t.unitName]])},async linger(){try{let e=(await r(`loginctl`,[`--no-pager`,`--no-ask-password`,`show-user`,String(t.uid),`--property=Linger`,`--value`])).toString(`utf8`);if(e===`yes
29
+ `),r=new Map;for(let e of n){let t=e.indexOf(`=`),n=e.slice(0,t),i=e.slice(t+1);if(t<0||!Zc.includes(n)||r.has(n)||!el(i))throw q();r.set(n,i)}if(r.size!==Zc.length)throw q();let i=e=>r.get(e);for(let[e,t]of Object.entries({LoadState:[`stub`,`loaded`,`not-found`,`bad-setting`,`error`,`merged`,`masked`],ActiveState:[`active`,`reloading`,`inactive`,`failed`,`activating`,`deactivating`,`maintenance`],SubState:[`dead`,`condition`,`start-pre`,`start`,`start-post`,`running`,`exited`,`reload`,`stop`,`stop-watchdog`,`stop-sigterm`,`stop-sigkill`,`stop-post`,`final-sigterm`,`final-sigkill`,`failed`,`auto-restart`,`cleaning`],UnitFileState:[``,`enabled`,`enabled-runtime`,`linked`,`linked-runtime`,`alias`,`masked`,`masked-runtime`,`static`,`disabled`,`indirect`,`generated`,`transient`,`bad`]}))if(!t.includes(i(e)))throw q();if(!/^(0|[1-9][0-9]*)$/.test(i(`MainPID`)))throw q();let a=Number(i(`MainPID`));if(!Number.isSafeInteger(a))throw q();for(let e of[`NeedDaemonReload`,`ConditionResult`])if(![`yes`,`no`].includes(i(e)))throw q();let o=i(`FragmentPath`);if(o&&!P(o))throw q();return{available:!0,loadState:i(`LoadState`),activeState:i(`ActiveState`),subState:i(`SubState`),mainPid:a||null,unitFileState:i(`UnitFileState`),fragmentPath:o,dropInPaths:i(`DropInPaths`),needDaemonReload:i(`NeedDaemonReload`)===`yes`,conditionResult:i(`ConditionResult`)===`yes`}}function al(e){return`unix:path=${[...Buffer.from(e)].map(e=>/[A-Za-z0-9_./-]/.test(String.fromCharCode(e))?String.fromCharCode(e):`%${e.toString(16).padStart(2,`0`)}`).join(``)}`}function ol(e){let t={...e.location},n=e.run??rl;async function r(r,i){try{let{uid:a}=t;if(!Number.isSafeInteger(a)||a<=0||a!==process.getuid?.()||a!==process.geteuid?.()||!/^shellbell-[0-9a-f]{32}\.service$/.test(t.unitName))throw q();for(let e of[t.home,t.configRoot,t.managerRuntimeRoot])if(!P(e)||!el(e))throw q();me(t.managerRuntimeRoot,a);let o=e.runtimeFsType?.(t.managerRuntimeRoot)??vn(t.managerRuntimeRoot).type;if(!$c.has(Number(o)))throw q();let s=await n(e.run?`/usr/bin/${r}`:nl(r),i,{timeoutMs:3e4,maxOutputBytes:65536,env:{HOME:t.home,XDG_CONFIG_HOME:t.configRoot,XDG_RUNTIME_DIR:t.managerRuntimeRoot,DBUS_SESSION_BUS_ADDRESS:al(F(t.managerRuntimeRoot,`bus`)),PATH:`/usr/bin:/bin`,LANG:`C`,LC_ALL:`C`}});if(s.exitCode!==0||s.stdout.length>65536)throw q();return s.stdout}catch{throw q()}}return{async observe(){try{return il(await r(`systemctl`,[...Qc,`show`,`--property=${Zc.join(`,`)}`,t.unitName]))}catch{return tl()}},async execute(e){if(![`start`,`stop`,`daemon-reload`].includes(e))throw q();await r(`systemctl`,[...Qc,e,...e===`daemon-reload`?[]:[t.unitName]])},async linger(){try{let e=(await r(`loginctl`,[`--no-pager`,`--no-ask-password`,`show-user`,String(t.uid),`--property=Linger`,`--value`])).toString(`utf8`);if(e===`yes
26
30
  `||e===`yes`)return`yes`;if(e===`no
27
- `||e===`no`)return`no`}catch{}return`unknown`}}}const J=e=>e.activeState===`inactive`||e.activeState===`failed`,Es=e=>[`enabled`,`enabled-runtime`].includes(e.unitFileState);function Y(e){throw Error(`shellbell: ${e}`)}var Ds=class{options;machine;location;files;manager;readiness;clock;constructor(e){this.options=e,this.machine=Nt(e.machine),this.location=ps({identity:this.machine,env:e.env,home:e.home??P()}),this.files=new hs(this.location,this.machine.machineId),this.manager=e.manager??Ts({location:this.location,runtimeFsType:e.runtimeFsType}),this.readiness=new dt(e),this.clock=e.clock??{now:()=>Fn.now(),sleep:e=>new Promise(t=>setTimeout(t,e))}}select(e,t,n=!1){let r=e.unit?.definition;r&&this.options.env.SHELLBELL_DIR!==void 0&&jt(this.options.env.SHELLBELL_DIR)!==r.stateDir&&Y(`SHELLBELL_DIR conflicts with installed service state; explicit migration is required`);let i;try{let e={...this.options.env,...r?{SHELLBELL_DIR:r.stateDir,...n?{}:{XDG_RUNTIME_DIR:r.runtimeRoot}}:{}};i=(this.options.selectPaths??(e=>Ft({...this.options.machine,env:e,home:this.options.home,runtimeFsType:this.options.runtimeFsType})))(e),(i.linuxHost.uid!==this.machine.uid||i.linuxHost.hostDigest!==this.machine.hostDigest||r&&i.dir!==r.stateDir)&&Y(`selected Linux paths do not match owned service`)}catch{return t&&Y(`Linux service runtime/state selection is unsafe or unavailable`),{degraded:!0}}try{let e=ct(i);return{paths:i,degraded:!1,expected:{computerFp:e.fp,stateDir:i.dir,...r?{serviceInstance:r.serviceInstance}:{}}}}catch{return t&&Y(`Linux host state is not ready; restore initialized credentials before granting service access`),{paths:i,degraded:!0}}}ownedManager(e,t,n=!1){return!t.available||t.dropInPaths!==``||t.needDaemonReload?!1:n&&!e.unit&&[``,`disabled`,`enabled`,`enabled-runtime`].includes(t.unitFileState)&&t.loadState===`not-found`&&t.fragmentPath===``&&J(t)&&t.mainPid===null?!0:![`disabled`,`enabled`,`enabled-runtime`,`linked`,`linked-runtime`].includes(t.unitFileState)||![`inactive`,`failed`,`active`,`activating`,`deactivating`].includes(t.activeState)?!1:!!e.unit&&t.loadState===`loaded`&&this.files.matchesFragment(t.fragmentPath)}assertManager(e,t,n=!1){this.files.assertUnchanged(e),this.ownedManager(e,t,n)||Y(`systemd manager ownership is unavailable, foreign or unresolved; inspect exact unit discovery and overrides`)}async local(e,t,n,r=500){if(!t.paths)return{kind:`unverified`,local:null,diagnostic:`Local certification degraded; runtime is unsafe or unavailable`};let i=await this.readiness.observe(t.paths.sock,t.expected?{...t.expected,...n.mainPid?{pid:n.mainPid}:{}}:void 0,r);return i.local&&e.unit&&(i.local.process.pid!==n.mainPid||!bt(i.local,{computerFp:t.expected?.computerFp??i.local.process.computerFp,stateDir:e.unit.definition.stateDir,serviceInstance:e.unit.definition.serviceInstance}))?{kind:`foreign`,local:i.local,diagnostic:`Local endpoint contradicts owned manager job`}:i}async result(e,t,n,r=!1){let i=await this.manager.observe(),a=this.ownedManager(e,i,!0),o=await this.local(e,t,i),s=await this.manager.observe(),c=!0;try{this.files.assertUnchanged(e)}catch{c=!1}let l=c&&a&&this.ownedManager(e,s,!0)&&i.mainPid===s.mainPid&&i.activeState===s.activeState,u=!!e.unit&&l&&!t.degraded&&i.activeState===`active`&&i.mainPid!==null&&i.conditionResult&&s.conditionResult&&o.kind===`verified`;r&&(!l||!J(s)||s.mainPid!==null||t.paths&&o.kind!==`absent`)&&Y(`service stop final confirmation is unresolved; current job or endpoint is not verified stopped`);let d=Es(s)&&!e.link?.owned||e.link&&!e.link.owned;return{manager:`systemd`,unitName:this.location.unitName,definitionPath:this.location.definitionPath,installed:!!e.unit,enabled:Es(s),startupEnabled:s.available?Es(s):null,autostartConfigured:!!e.link?.owned,activeState:s.activeState,managedPid:s.mainPid,ownership:!l||o.kind===`foreign`?`foreign`:t.degraded?`degraded`:e.unit?`verified`:`none`,ready:u,local:o.local,linger:await this.manager.linger(),...n||d||t.degraded||!l||o.diagnostic?{diagnostic:[n,d?`Remaining external enablement is outside Shellbell's owned link`:void 0,t.degraded?`Local identity/runtime certification degraded; credentials were not repaired`:void 0,l?void 0:`Manager ownership is unresolved`,o.diagnostic].filter(Boolean).join(`; `)}:{}}}async status(){let e=this.files.inspect();return this.result(e,this.select(e,!1))}async serialized(e,t,n){let r=this.files.inspect(),i=this.select(r,e,t),a=async()=>{let t;try{return i.paths&&(kt(i.paths),t=ue(L(i.paths.runtimeDir,`service`))),this.files.assertUnchanged(r),e&&ct(i.paths),await n(r,i,!!t)}finally{t?.()}},o=i.paths?.dir??r.unit?.definition.stateDir;return o?Be({stateDir:o,uid:this.machine.uid,create:t,startupPreference:e=>e.autostartConfigured},a):a()}async execute(e,t){this.files.assertUnchanged(t);try{await this.manager.execute(e)}catch{Y(`systemd ${e} failed or timed out; manager effect may be unresolved`)}}async install(){let e=(this.options.resolveRuntime??Ne)(),t=[`/usr/local/bin`,`/usr/bin`,`/bin`],n=(this.options.env.PATH??``).split(`:`).filter(e=>I(e)&&!t.includes(e));return this.serialized(!0,!0,async(r,i)=>{let a=r.unit?.definition,o={v:1,machineId:this.machine.machineId,nodePath:e.nodePath,cliPath:e.cliPath,stateDir:i.paths.dir,runtimeRoot:F(F(i.paths.runtimeDir)),serviceInstance:a?.serviceInstance??xn(),path:[...new Set([F(e.nodePath),...n,...t])].join(`:`)},s=ls(o),c=await this.manager.observe();if(this.assertManager(r,c,!r.unit),r.unit?.raw.equals(s))return this.result(r,i);(!J(c)||c.mainPid!==null)&&Y(`active service definition cannot be updated; stop, install, then start explicitly`),(await this.local(r,i,c)).kind!==`absent`&&Y(`local endpoint ownership is foreign or unverified; stop foreground owner before install`);let l=await this.manager.observe();this.assertManager(r,l,!r.unit),(!J(l)||l.mainPid!==null)&&Y(`active service job changed during install admission; stop before updating`),a&&(o.serviceInstance=xn());let u;try{return u=this.files.publish(r,o),await this.execute(`daemon-reload`,u),this.assertManager(u,await this.manager.observe()),await this.result(u,i)}catch{if(u){this.files.restore(r,u);try{await this.manager.execute(`daemon-reload`)}catch{Y(`systemd install failed; definition restored but manager reload remains unresolved`)}}Y(`systemd install failed; owned definition restored where possible, inspect manager discovery`)}})}enable(){return this.link(!0)}disable(){return this.link(!1)}link(e){return this.serialized(e,!1,async(t,n,r)=>{let i=await this.manager.observe();if(this.assertManager(t,i,!t.unit&&!e),!t.unit&&e&&Y(`service is not installed; run service install first`),t.link&&!t.link.owned)return e&&Y(`foreign autostart leaf prevents service enablement`),this.result(t,n,`Foreign autostart artifact remains; inspect it explicitly`);if(!r)return this.result(t,n,`Owned autostart cleanup remains; restore a safe local runtime before changing files`);if(!!t.link===e)return this.result(t,n);let a=this.files.setEnabled(t,e);try{await this.execute(`daemon-reload`,a),this.assertManager(a,await this.manager.observe(),!a.unit)}catch{e&&this.files.restore(t,a),Y(`systemd ${e?`enable`:`disable`} reload failed; inspect remaining manager state`)}return this.result(a,n)})}start(){return this.run(`start`)}restart(){return this.run(`restart`)}stop(){return this.run(`stop`)}uninstall(){return this.run(`uninstall`)}async stopped(e,t,n){let r=this.clock.now()+1e4;for(;this.clock.now()<r;){let i=await this.manager.observe();this.assertManager(e,i),i.mainPid!==null&&i.mainPid!==n&&Y(`service stop manager job changed; ownership unresolved`);let a=await this.local(e,t,{...i,mainPid:n},Math.min(500,r-this.clock.now()));a.kind===`foreign`&&Y(`service stop ownership changed; endpoint is foreign`);let o=await this.manager.observe();if(this.assertManager(e,o),(o.mainPid!==null&&o.mainPid!==n||J(i)&&!J(o))&&Y(`service stop manager job changed during local probe; ownership unresolved`),J(o)&&o.mainPid===null&&(!t.paths||a.kind===`absent`))return;await this.clock.sleep(Math.min(100,Math.max(0,r-this.clock.now())))}Y(`service stop timed out; stopped state remains unresolved`)}async stopOwned(e,t){let n=await this.manager.observe();this.assertManager(e,n);let r=await this.local(e,t,n);r.kind===`foreign`&&Y(`local endpoint ownership is foreign; refusing service stop`);let i=await this.manager.observe();this.assertManager(e,i),(i.mainPid!==n.mainPid||J(n)&&!J(i))&&Y(`service stop ownership changed during local probe`),(!J(i)||i.mainPid!==null||t.paths&&r.kind!==`absent`)&&(await this.execute(`stop`,e),await this.stopped(e,t,n.mainPid))}async ready(e,t,n={}){let r=this.clock.now()+1e4;for(;this.clock.now()<r;){let i=await this.manager.observe();this.assertManager(e,i),n.pid!==void 0&&i.mainPid!==n.pid&&Y(`service readiness manager job changed`),i.mainPid!==null&&(n.pid??=i.mainPid);let a=await this.local(e,t,i,Math.min(500,r-this.clock.now()));a.kind===`foreign`&&Y(`service readiness ownership is foreign`);let o=await this.manager.observe();if(this.assertManager(e,o),o.mainPid!==i.mainPid&&Y(`service readiness manager job changed`),o.activeState===`active`&&o.conditionResult&&o.mainPid!==null&&a.kind===`verified`)return a.local;await this.clock.sleep(Math.min(100,Math.max(0,r-this.clock.now())))}Y(`service readiness timed out`)}async cleanupStart(e,t,n){let r=await this.manager.observe();this.assertManager(e,r);let i=await this.local(e,t,r),a=await this.manager.observe();this.assertManager(e,a),(a.mainPid!==r.mainPid||J(r)&&!J(a))&&Y(`start ownership changed during local probe; cleanup unresolved`),!(J(a)&&a.mainPid===null&&i.kind===`absent`)&&((r.mainPid===null||n.pid!==void 0&&n.pid!==r.mainPid||![`verified`,`absent`].includes(i.kind))&&Y(`start ownership unresolved; no cleanup stop was attempted`),await this.execute(`stop`,e),await this.stopped(e,t,r.mainPid))}run(e){let t=e===`stop`||e===`uninstall`;return this.serialized(!t,!1,async(n,r,i)=>{let a=await this.manager.observe();if(this.assertManager(n,a,!n.unit&&t),!n.unit)return t||Y(`service is not installed; run service install first`),this.result(n,r);let o=await this.local(n,r,a);if(o.kind===`foreign`&&Y(`local endpoint ownership is foreign`),e!==`start`&&await this.stopOwned(n,r),t){let t=n;e===`uninstall`&&i&&((!t.link||t.link.owned)&&(t=this.files.setEnabled(t,!1)),t=this.files.remove(t),await this.execute(`daemon-reload`,t),this.assertManager(t,await this.manager.observe(),!0));let a=e===`uninstall`?i?`Service uninstalled; credentials remain unchanged`:`Service stopped; owned definition and autostart cleanup remain until runtime is safe`:`Service stopped; if enabled, it may start after a later user-manager restart`;return this.result(t,r,a,!0)}if(e===`start`&&a.activeState===`active`){await this.ready(n,r);let e=await this.result(n,r);return e.ready||Y(`service start readiness changed during final confirmation`),e}e===`start`&&(!J(a)||a.mainPid!==null||o.kind!==`absent`)&&Y(`service start ownership is unresolved; stop the foreground or pending owner first`);let s=await this.manager.observe();this.assertManager(n,s),(!J(s)||s.mainPid!==null)&&Y(`service start manager job changed before command; ownership unresolved`);let c={};try{await this.execute(`start`,n),await this.ready(n,r,c);let e=await this.result(n,r);return e.ready||Y(`service start readiness changed during final confirmation`),e}catch{try{await this.cleanupStart(n,r,c)}catch{Y(`service start failed; ownership or cleanup remains unresolved`)}Y(`service start failed; newly started owned job was stopped`)}})}};const Os=An(zt);function ks(e){let t=/(\d+)\.(\d+)/.exec(e);return t?Number(t[1])+Number(t[2])/100:null}function As(e){return+!!e.some(e=>e.severity===`error`)}function js(e,t){return{name:e,ok:!0,severity:`pass`,detail:t}}function X(e,t,n){return{name:e,ok:!0,severity:`warning`,detail:t,...n?{fix:n}:{}}}function Z(e,t,n){return{name:e,ok:!1,severity:`error`,detail:t,...n?{fix:n}:{}}}function Ms(e,t,n,r){return t?{...js(e,`connected to the local agent`),...n?{required:n}:{}}:n?{...Z(e,`required backend is not connected; ${r.detail}`,r.fix),required:!0}:r}function Ns(e,t){for(let n of t.PATH?.split(dn)??[])if(n)try{return Vt(L(n,e),N.X_OK),!0}catch{}return!1}async function Ps(e){return(await Os(`tmux`,[`-V`],{env:e,timeout:3e3,maxBuffer:65536})).stdout}async function Fs(e){return za({socketPath:Ti(e),herdrOnPath:()=>Ns(`herdr`,e)})}function Is(e,t){if(!e.installed||!e.definition)return{env:t,context:`current shell setup`};let n=e.definition.environment;return{env:{PATH:n.PATH,HERDR_SOCKET_PATH:n.HERDR_SOCKET_PATH,XDG_CONFIG_HOME:n.XDG_CONFIG_HOME},context:`installed service setup`}}function Ls(e,t){return e.loaded&&!e.installed?Z(`service manager`,`loaded service has no installed definition`):e.installed?e.definition?e.loaded?e.definition.serviceInstance?t?t.process.serviceInstance===e.definition.serviceInstance?js(`service manager`,`loaded job matches the local service instance`):Z(`service manager`,`loaded job does not match the local service instance`,`stop the foreground owner and restart the service`):X(`service manager`,`loaded job cannot be matched until local control responds`):X(`service manager`,`legacy service definition has no verifiable instance marker`,`reinstall the service to record a service instance`):X(`service manager`,`installed service is stopped`,"run `shellbell service start` if background operation is wanted"):Z(`service manager`,`installed service definition is unreadable`,`reinstall the service after checking its definition`):X(`service manager`,`no service definition installed; foreground agent can still run`,"run `shellbell service install` for autostart")}function Rs(e){let t=`installed=${e.installed}; enabled=${e.enabled}; active=${e.activeState}; authenticated ready=${e.ready}; linger=${e.linger}; ownership=${e.ownership}${e.diagnostic?`; ${e.diagnostic}`:``}`;return e.activeState===`unknown`?X(`service manager`,t,`restore access to the current user's systemd manager; foreground readiness is independent`):e.ownership===`foreign`?Z(`service manager`,t,`inspect the exact unit and any drop-ins; Shellbell refuses foreign definitions`):e.ready?js(`service manager`,t):X(`service manager`,t,`inspect shellbell service status; install, start, and enable are separate choices; foreground readiness is independent`)}function zs(e,t){let n=e=>t.includes(e)?{...Z(e,`required backend unavailable until service state is selected`),required:!0}:X(e,`unavailable until service state is selected`);return[X(`identity`,e),Z(`service manager`,e),X(`control`,`unavailable until service state is selected`),X(`relay`,`unavailable until service state is selected`),n(`iterm2`),n(`tmux`),n(`herdr`),X(`terminal readiness`,`unavailable until service state is selected`)]}async function Bs(e,t={}){let r=(e.platform??process.platform)===`linux`,i=X(`service manager`,`Linux systemd user-manager inspection unavailable; foreground readiness is independent`,`inspect shellbell service status and the current user's systemd manager`),a=e.requiredBackends.filter(e=>e!==`tmux`).map(e=>({...Z(e,e===`herdr`?`Shellbell's Herdr backend is not yet qualified for Linux delivery (Herdr itself supports Linux)`:`iTerm2 is not supported on Linux`),required:!0})),o=null,s;if(r){let n,r={...e.env,SHELLBELL_DIR:e.requestedStateDir??e.env.SHELLBELL_DIR},o=e=>(r=e,n=(t.selectLinuxPaths??(e=>Ft({env:e})))(e),n);try{i=Rs(await(t.inspectLinuxService??(()=>new Ds({env:r,selectPaths:o}).status()))(o))}catch{}let c;try{let e=n??o(r);s=e;let t=Ke(e);c=t.status===`ready`?js(`host state`,`Linux host state admitted`):Z(`host state`,t.reason??`Linux host state is absent`,`initialize absent state with shellbell host init --new, or inspect existing state before recovery`)}catch{c=Z(`host state`,`Linux state or runtime selection is unsafe or unavailable`,`use a nonroot matching real/effective user, a valid machine ID, and a private 0700 local runtime directory`)}if(c.severity===`error`)return[c,i,X(`control`,`unavailable until host state is admitted`),X(`relay`,`unavailable until host state is admitted`),...a,e.requiredBackends.includes(`tmux`)?{...Z(`tmux`,`required backend unavailable until host state is admitted`),required:!0}:X(`tmux`,`unavailable until host state is admitted`)]}else{try{o=await(t.inspectManager??(()=>f().inspect()))()}catch{return zs(`service manager inspection failed; state unavailable`,e.requiredBackends)}try{s=_t(o,e.requestedStateDir,e.defaultStateDir)}catch{return zs(`state selection unavailable; check SHELLBELL_DIR against installed service`,e.requiredBackends)}}let c,l=null;try{let e=n(s);e?(l=e.fp,c=js(`identity`,r?`valid admitted Linux identity`:`valid identity at ${s.identity}`)):c=Z(`identity`,`identity missing at ${s.identity}`,`start Shellbell once to create an identity`)}catch{c=Z(`identity`,r?`Linux identity invalid or unreadable`:`identity invalid or unreadable at ${s.identity}`,`restore the original identity file; do not replace paired keys`)}let u=null,d;if(!l)d=Z(`control`,`cannot verify local process without a valid identity`);else try{let e=await(t.controlStatus??(e=>se(e,`status`,void 0,{timeoutMs:500,maxResponseBytes:65536})))(s.sock),n=me.safeParse(e);n.success?bt(n.data,{computerFp:l,stateDir:s.dir})?(u=n.data,d=js(`control`,`local agent identity and state verified`)):d=Z(`control`,`local endpoint belongs to a different identity or state directory`):d=Z(`control`,`local endpoint returned malformed or unsupported status`)}catch{d=Z(`control`,`local endpoint is absent or did not return bounded status`,`start Shellbell, or inspect the configured service`)}let p=r?i:Ls(o,u),m=null,h=null;try{h=ot(s).relayUrl}catch{m=Z(`relay`,r?`Linux configuration invalid or unreadable`:`configuration invalid or unreadable at ${s.config}`,`repair the existing config without replacing identity files`)}if(!m){if(u?.relayOnline)m=js(`relay`,`local agent reports relay connected`);else{let e=`configured relay`,n=!1;try{let r=new URL(h);[`ws:`,`wss:`,`http:`,`https:`].includes(r.protocol)&&(e=`${r.protocol===`ws:`?`http:`:r.protocol===`wss:`?`https:`:r.protocol}//${r.host}/healthz`,n=await(t.relayHealth??es)(h))}catch{}m=Z(`relay`,`local agent is not relay-connected; ${e} ${n?`is reachable`:`is not confirmed reachable`} (HTTP health does not prove WebSocket authorization)`,`check the relay URL, network, and running agent`)}}let{env:g,context:_}=r?{env:e.env,context:`current shell setup`}:Is(o,e.env),v=new Set(e.requiredBackends),y=e=>u?.backends.find(t=>t.name===e)?.connected===!0,b=X(`iterm2`,`${_}: iTerm2 API socket unavailable`,`enable iTerm2 Python API, then start Shellbell to authorize access`);if(!r&&!y(`iterm2`))try{(t.itermSocketExists??(()=>Ut(Mo)))()&&(b=X(`iterm2`,`${_}: API socket exists but agent is disconnected`,`start Shellbell to authorize iTerm2 API access`))}catch{b=Z(`iterm2`,`iTerm2 API socket inspection failed`)}let x=Ms(`iterm2`,y(`iterm2`),v.has(`iterm2`),b),S=X(`tmux`,`${_}: tmux is unavailable`,`install tmux 3.2 or newer`);if(!y(`tmux`))try{let e=ks(await(t.tmuxVersion??Ps)(g));S=e===null||e<3.02?Z(`tmux`,`${_}: tmux version is unsupported or unrecognizable`,`install tmux 3.2 or newer`):X(`tmux`,`${_}: tmux 3.2+ is installed but not connected`,`start a tmux session and Shellbell`)}catch(e){S=e.code===`ENOENT`?X(`tmux`,`${_}: tmux executable not found`,`install tmux 3.2 or newer`):Z(`tmux`,`${_}: tmux version probe failed`,`check installed tmux and the saved PATH`)}let C=Ms(`tmux`,y(`tmux`),v.has(`tmux`),S),w=X(`herdr`,`${_}: Herdr is unavailable`,bi);if(!r&&!y(`herdr`))try{let e=await(t.checkHerdr??Fs)(g);w=e.ok?e.detail===`not installed (optional)`?X(`herdr`,`${_}: Herdr not found on PATH`,bi):e.detail===`installed but not running (optional)`?X(`herdr`,`${_}: Herdr is installed but not running`,`start Herdr and Shellbell`):X(`herdr`,`${_}: Herdr API available but agent is disconnected`,`start Shellbell with Herdr enabled`):Z(`herdr`,`${_}: Herdr API is broken or unsupported`,xi)}catch{w=Z(`herdr`,`${_}: Herdr API probe failed`,xi)}let ee=Ms(`herdr`,y(`herdr`),v.has(`herdr`),w),te=u?await(t.terminalSetup??Vs)(s.sock).catch(()=>null):null,ne=(e,t)=>{let n=te?.find(e=>e.name===t);if(!n?.issue)return e;let{status:r,fix:i}=Qn(n,`command-line`);return n.connected?{...X(t,r,i),...e.required?{required:!0}:{}}:Ms(t,!1,v.has(t),X(t,r,i))},re=(r?y(`tmux`):u?.terminalReady)?js(`terminal readiness`,`at least one backend connected to the verified local agent`):Z(`terminal readiness`,`no backend connected to a verified local agent`,`start Shellbell with a supported terminal backend`);return[...r?[js(`host state`,`Linux host state admitted`)]:[],c,p,d,m,...r?a:[ne(x,`iterm2`)],ne(C,`tmux`),...r?[]:[ne(ee,`herdr`)],re]}async function Vs(e){let t=await h(e);try{return await t.terminals()}finally{t.close()}}var Hs=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 Us(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&&Ws(e[r+1])&&Ws(e[r+2])&&Ws(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 Ws(e){return e!==void 0&&e>=48&&e<=55}const Gs=Buffer.from(`%output `),Ks=Buffer.from(`%extended-output `),qs=Buffer.from(` : `);function Js(e){let t;if(e.subarray(0,Gs.length).equals(Gs))t=e.subarray(Gs.length);else if(e.subarray(0,Ks.length).equals(Ks))t=e.subarray(Ks.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]===Gs[1])return{pane:r,data:t.subarray(n+1)};let i=t.indexOf(qs,n);if(i!==-1)return{pane:r,data:t.subarray(i+qs.length)}}function Ys(e){return`'${e.replace(/'/g,`'\\''`)}'`}function Xs(e){return e.trim().split(/\s+/,1)[0]||`?`}const Zs=/^%(?:end|error) (\S+) (\S+) \S+$/;function Qs(e,t){let n=Zs.exec(e);return n!==null&&n[1]===t.time&&n[2]===t.num}var $s=class extends Cn{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??Bt)(this.opts.executable??`tmux`,e,{stdio:[`pipe`,`pipe`,`pipe`]});this.child=t,this.alive=!0;let n=new Hs,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&&!Qs(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.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:M(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=Js(t);if(!e)return!1;let n=++this.outputSeq;return this.emit(`output`,e.pane),this.listenerCount(`bytes`)>0&&this.emit(`bytes`,e.pane,Us(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(e=>new Promise((n,r)=>{let i=setTimeout(()=>{r(Error(`tmux command timeout: ${Xs(e)}`)),this.stop()},this.opts.commandTimeoutMs??5e3);i.unref?.(),t.push({resolve:(e,t)=>n({lines:e,outputSeq:t}),reject:r,timer:i,verb:Xs(e)})}));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
28
- `)}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 ec={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 tc(e){let t=ec[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 nc=rc();function rc(){let e=new Map([[`\r`,`Enter`],[`
29
- `,`Enter`],[` `,`Tab`]]);for(let[t,n]of Object.entries(vt))e.has(n)||e.set(n,tc(t));return e}function ic(e){return e?nc.get(e):void 0}const ac=`#{session_id}\\t#{client_control_mode}\\t#{client_pid}`,oc=e=>Ys(e.replace(/\\t/g,` `)),sc=oc(`#{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}`),cc=oc(ac),lc=oc(`#{cursor_x}\\t#{cursor_y}\\t#{history_size}\\t#{pane_width}\\t#{pane_height}\\t#{alternate_on}`),uc=oc(`#{cursor_x}\\t#{cursor_y}\\t#{history_size}\\t#{pane_width}\\t#{pane_height}\\t#{history_limit}\\t#{alternate_on}`),Q=e=>Number.parseInt(e??`0`,10)||0,dc=/^%\d+$/,fc=/^\$\d+$/,pc=/^@\d+$/;function mc(e){let t=e.split(` `);return t.length!==18||!dc.test(t[0]??``)||!fc.test(t[1]??``)||!pc.test(t[3]??``)?null:{paneId:t[0]??``,sessionId:t[1]??``,sessionName:t[2]??``,windowId:t[3]??``,windowIndex:Q(t[4]),windowName:t[5]??``,paneIndex:Q(t[6]),paneTitle:t[7]??``,cwd:t[8]??``,width:Q(t[9]),height:Q(t[10]),paneActive:t[11]===`1`,windowActive:t[12]===`1`,historySize:Q(t[13]),cursorX:Q(t[14]),cursorY:Q(t[15]),dead:t[16]===`1`,currentCommand:t[17]??``}}const hc=({sessionId:e,sessionName:t,windowIndex:n,windowActive:r,...i})=>JSON.stringify(i);function gc(e){let t=e.map(mc).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===hc(e)?hc(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 _c(e){let t=e.split(` `),n=/^\d{1,10}$/.test(t[2]??``)?Number(t[2]):void 0;return{sessionId:t[0]??``,controlMode:t[1]===`1`,...n?{pid:n}:{}}}function vc(e){let t=e.split(` `);return{cursorX:Q(t[0]),cursorY:Q(t[1]),historySize:Q(t[2]),width:Q(t[3]),height:Q(t[4])}}function yc(e){let t=e.split(` `);if(!(t.length!==6||t[5]!==`0`&&t[5]!==`1`))return t[5]===`1`}function bc(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 Sc(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 Cc=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)}};const wc=[`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 Tc(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} '${wc.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 Ec={block:2,underline:4,bar:6};function Dc(e){let t=``,n=``;return e.forEach((e,r)=>{r>0&&(n+=t?`\x1b[49m\r\n${t}`:`\r
30
- `),n+=e;for(let[,n=``]of e.matchAll(/\x1b\[([\d;:]*)m/g))t=Oc(t,n)}),n}function Oc(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 kc(e){let[t=[],n=[],r=[],i=[],a=[]]=e,o=(t[0]??``).split(` `);if(o.length!==wc.length)throw Error(`unexpected tmux pane state`);let s=Object.fromEntries(wc.map((e,t)=>[e,o[t]])),c=e=>{if(!/^\d{1,6}$/.test(s[e]))throw Error(`unexpected tmux ${e}`);return Number(s[e])},l=s.alternate_on===`1`,u=c(`pane_height`),d=`\x1Bc\x1B[3g`,f=s.pane_tabs.split(`,`).filter(Boolean);if(!f.every(e=>/^\d{1,6}$/.test(e)))throw Error(`unexpected tmux pane_tabs`);for(let e of f)d+=`\x1b[1;${Number(e)+1}H\x1bH`;d+=`\x1B[H`;let p=[...c(`history_size`)>0?n:[],...l?i:r];d+=Dc(p),l&&(d+=`\x1b[0m\x1b[${c(`alternate_saved_y`)+1};${c(`alternate_saved_x`)+1}H`,d+=`\x1b[?1049h${Dc(r.slice(0,u))}`),d+=`\x1B[0m`;let m=c(`scroll_region_upper`);d+=`\x1b[${m+1};${c(`scroll_region_lower`)+1}r`,s.wrap_flag===`0`&&(d+=`\x1B[?7l`),s.insert_flag===`1`&&(d+=`\x1B[4h`),s.keypad_cursor_flag===`1`&&(d+=`\x1B[?1h`),s.keypad_flag===`1`&&(d+=`\x1B=`),s.cursor_flag===`0`&&(d+=`\x1B[?25l`);let h=Ec[s.cursor_shape];h!==void 0&&(d+=`\x1b[${h-+(s.cursor_blinking===`1`)} q`);let g=s.origin_flag===`1`;g&&(d+=`\x1B[?6h`);let _=c(`cursor_y`)-(g?m:0);return d+=`\x1b[${_+1};${c(`cursor_x`)+1}H`,{cols:c(`pane_width`),rows:u,data:d+a.join(`
31
- `)}}var Ac=class extends Cn{opts;control;log;generation=0;held=[];size;seeding=!1;reseedWanted=!1;resizeTimer=null;muting=null;ended=!1;historyLines;names=new Cc;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 $s({sessionId:t,socketName:e.socketName,executable:e.executable,log:e.log})))(e.tmuxSessionId),this.control.on(`bytes`,(t,n,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.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(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{replies:t,sentSeq:n,outputSeq:r}=await this.control.checkpoint(Tc(this.opts.paneId,this.historyLines)),i=this.held;if(i.some(e=>e.pane!==this.opts.paneId&&e.seq>n&&e.seq<=r)){e++,await this.mutePanes();continue}let a=kc(t);this.size={cols:a.cols,rows:a.rows},this.held=void 0,this.generation++,this.names=new Cc;let o=Buffer.from(this.names.write(Buffer.from(a.data))).toString();this.emit(`seed`,{...a,data:o,generation:this.generation});for(let e of i)e.pane===this.opts.paneId&&e.seq>r&&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}`&&await this.reseed()}end(e){this.ended||(this.ended=!0,this.resizeTimer&&clearTimeout(this.resizeTimer),this.resizeTimer=null,this.held=void 0,this.control.stop(),e&&this.emit(`end`,e))}};const jc=An(zt),Mc=`brew install tmux (3.2+), then start a tmux session`,Nc=5e3,Pc=10485760;function Fc(e,t){return fi({cwd:e.cwd||void 0,project:si(e.windowName,e.currentCommand),processName:e.currentCommand,title:e.paneTitle,ignore:[t]})}function Ic(e){return M(e)}function Lc(e){return`historySize`in e}function Rc(e,t){return new Promise((n,r)=>{let i=setTimeout(()=>r(Error(`tmux exec timeout: ${t}`)),Nc);i.unref?.(),e.then(e=>{clearTimeout(i),n(e)},e=>{clearTimeout(i),r(e instanceof Error?e:Error(String(e)))})})}var zc=class t{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;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 jc(this.program(),[...e.socketName?[`-L`,e.socketName]:[],...t],{timeout:Nc,maxBuffer:Pc})).stdout);this.exec=e=>Rc(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 jc(n,e,{timeout:Nc,maxBuffer:Pc})).stdout),i=e=>Rc(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=ks(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 e=this.closes,n=await t.detect(this.exec);if(e===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 j(n.reason??`tmux unavailable`,Mc);this.watcher&&clearInterval(this.watcher),this.closed=!1,await this.syncControls(),await this.refreshPanes(),!(this.closed||e!==this.closes)&&(this.watcher=setInterval(()=>{this.syncControls().then(()=>this.refreshPanes()).catch(e=>this.log.warn(`tmux watcher failed`,{error:Ic(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.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:Ic(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(`
32
- `).filter(Boolean)}catch(e){this.log.debug(`tmux list-sessions failed; keeping the existing clients`,{error:Ic(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 $s({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:Ic(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.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 ${sc}`))}catch(e){this.log.warn(`list-panes failed`,{error:Ic(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??ln(),o=[...n.keys()].filter(e=>{let r=t.get(e);if(!r)return!1;let i=n.get(e);return Sc(r,a)!==Sc(i,a)||r.cwd!==i.cwd||!ui(Fc(r,a),Fc(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 k(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} ${uc}`))[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=bc(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 ir({sessionId:e,cwd:t.cwd,title:Sc(t,this.opts.hostname??ln()),sessionLabel:`tmux · ${t.sessionId} · Tab ${t.windowIndex+1} · Pane ${t.paneIndex+1}`},t.currentCommand,`local-process`)}async listSessions(){let e=new Set,t=new Map;try{let n=(await this.channel().command(`list-clients -F ${cc}`)).map(_c).filter(e=>!e.controlMode);e=new Set(n.map(e=>e.sessionId)),t=await this.hostApps(n)}catch(e){this.log.debug(`list-clients failed; no pane reported focused`,{error:Ic(e)})}let n=this.opts.hostname??ln(),r=e=>this.sessionIndex.get(e)??2**53-1;return[...this.panes.values()].sort((e,t)=>r(e.sessionId)-r(t.sessionId)||e.windowIndex-t.windowIndex||e.paneIndex-t.paneIndex).map(r=>({id:r.paneId,backend:`tmux`,title:Sc(r,n),cwd:r.cwd||void 0,...Fc(r,n),cols:Math.max(1,r.width),rows:Math.max(1,r.height),windowId:r.sessionId,windowNumber:this.sessionIndex.get(r.sessionId)??0,tabId:r.windowId,tabIndex:r.windowIndex,paneIndex:r.paneIndex,isFocusedOnMac:r.paneActive&&r.windowActive&&e.has(r.sessionId),state:`unknown`,...this.alternate.has(r.paneId)&&{alternateScreen:this.alternate.get(r.paneId)},...t.has(r.sessionId)&&{shownIn:t.get(r.sessionId)}}))}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??Wi)().catch(()=>void 0)});let r=this.processes.table;if(!r)return t;for(let{sessionId:n,pid:i}of e){let e=i?Gi(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 Ac({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&&!si(t.windowName,t.currentCommand))return ci(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}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?uc:lc,o=await n.command(`display-message -p -t ${e} ${a}`),s=await n.command(`capture-pane -p -e -N -t ${e}`),c=vc(o[0]??``);this.observeAlternate(e,r?bc(o[0]??``)?.alternate:yc(o[0]??``));let l=Math.max(1,c.height),u=s.map(Yn);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=bc(o[0]??``);if(!f||f.alternate||!this.panes.has(e)||this.channel(e)!==n||!n.alive)return d;let p;try{p=bc((await n.command(`display-message -p -t ${e} ${uc}`))[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=vc((await i.command(`display-message -p -t ${e} ${lc}`))[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(Yn),oldestAvailable:o}}async getHistoryPage(t,n){if(e(n),n.signal.aborted)return{status:`cancelled`};this.pane(t);let r=this.historyEvidence.get(n.capture);if(!r||r.paneId!==t)return{status:`unavailable`,reason:`unanchored`};let i=this.readOutcome(r,n.signal);if(i)return i;if(n.reported<r.facts.historySize)return{status:`unavailable`,reason:`unanchored`};let a=await this.checkedFacts(r,n.signal),o=this.readOutcome(r,n.signal);if(o)return o;if(!Lc(a))return a;let s=Math.max(0,n.reported-r.facts.historySize);if(n.before<s){let e=await this.checkedFacts(r,n.signal);return this.readOutcome(r,n.signal)||(Lc(e)?{status:`boundary`,reason:`truncated`,oldestAvailable:s}:e)}if(n.before===s){let e=await this.checkedFacts(r,n.signal);return this.readOutcome(r,n.signal)||(Lc(e)?{status:`boundary`,reason:`end`,oldestAvailable:s}:e)}let c=Math.max(n.before-n.count,s),l=c-n.reported,u=n.before-1-n.reported;if(l<-2147483648||u<-2147483648||l>-1||u>-1)return{status:`unavailable`,reason:`fetch-window`};if(n.signal.aborted)return{status:`cancelled`};if(!this.ownsEvidence(r))return{status:`reset`};let d;try{d=await r.channel.command(`capture-pane -p -e -N -t ${t} -S ${l} -E ${u}`)}catch{return n.signal.aborted?{status:`cancelled`}:this.ownsEvidence(r)?{status:`unavailable`,reason:`changed`}:{status:`reset`}}if(n.signal.aborted)return{status:`cancelled`};if(!this.ownsEvidence(r))return{status:`reset`};let f=await this.checkedFacts(r,n.signal);return this.readOutcome(r,n.signal)||(Lc(f)?d.length===n.before-c?{status:`page`,from:c,to:n.before,oldestAvailable:s,lines:d.map(Yn)}:{status:`unavailable`,reason:`changed`}:f)}async sendText(e,t){this.pane(e);let n=this.channel(e),r=ic(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 -- ${Ys(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 E(`paste containing NUL`);let r=`shellbell-${xn()}`,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(){let e=await t.detect(this.exec,{requireServer:!1});if(!e.ok)throw new j(e.reason??`tmux unavailable`,Mc);let n=(await this.exec([`new-session`,`-d`,`-P`,`-F`,`#{pane_id}`])).trim();if(!/^%\d+$/.test(n))throw Error(`tmux new-session returned an invalid pane id`);try{await this.connect()}catch(e){throw await this.exec([`kill-pane`,`-t`,n]).catch(()=>void 0),e}return n}async hostedSessionTarget(e){if(!/^%\d+$/.test(e))throw new k(e);let t=(await this.exec([`display-message`,`-p`,`-t`,e,`#{session_id}`])).trim();if(!/^\$\d+$/.test(t))throw new k(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 k(e);this.scheduleRefresh()}async waitForVisibleClient(e,{timeoutMs:t=15e3,intervalMs:n=250}={}){if(!/^\$\d+$/.test(e))throw new k(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 k(e.windowId);t=e.windowId}else return!1;return this.hasDesktopClient(t)}async hasDesktopClient(e){let t=ac.replace(/\\t/g,` `),n=(await this.exec([`list-clients`,`-t`,e,`-F`,t])).split(`
33
- `).filter(Boolean).map(_c).filter(e=>!e.controlMode);if(n.length===0)return!1;let r=await(this.opts.processTable??Wi)().catch(()=>void 0);return r?n.some(e=>e.pid!==void 0&&Gi(e.pid,r)!==void 0):(this.opts.platform??process.platform)!==`darwin`}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 k(e.windowId);t=this.channelForSession(e.windowId),n=`new-window -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 E(`focus`)}};function Bc(e){let t=e.log.child({unit:`tmux-start`}),n=e.terminalExecutable??(()=>ta(`tmux`)),r=()=>n()??`tmux`,i=new zc({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`,zc.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()=>({backend:i,sessionId:await i.createFirstSession()})});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)=>{if(c||r!==i)throw new j(`tmux was replaced`,`Try again after the service reconnects.`);let o=n();if(!o)throw new j(`tmux is not installed`,`Install tmux 3.2 or newer.`);let s=a??await i.createFirstSession(),l=s;return await Qo(async()=>{let n=await i.hostedSessionTarget(s);if(l=n.sessionId,c)throw new j(`tmux stopped`,`Reconnect your computer.`);if(await t.launch({executable:o,args:[...n.socketName?[`-L`,n.socketName]:[],`attach-session`,`-t`,n.sessionId]}),!await i.waitForVisibleClient(n.sessionId,{timeoutMs:e.attachTimeoutMs}))throw new j(`terminal window did not attach`,`Unlock your computer and try again.`)},()=>i.discardHostedSession(l)),s}}))}).catch(e=>{f=`none`,t.debug(`tmux startup discovery failed`,{error:M(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:M(n)}),e.onUnavailable&&!u&&n instanceof j&&(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:M(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 Vc(e){return new Promise(t=>{let n=Tn(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 Hc(e,t,n){let r=L(F(t.runtimeDir),bn(`sha256`).update(e).digest(`hex`).slice(0,32));for(let a of[e,r]){if(!O(a))continue;m(a,t.linuxHost.uid),a===r&&Le(t,a);let e=L(a,`agent.pid`);if(O(e)){let r=i(l(e,64,t.linuxHost.uid).toString(`utf8`).trim());if(!r||(n.processAlive??rt)(r))throw new D(`unsafe`)}let o=[`agent.sock.lock`,`init.sock.lock`,`service.lock`],s=Xt(a);try{for(let e=s.readSync();e;e=s.readSync())if(o.some(t=>e.name===t||e.name.startsWith(`${t}-candidate-`)))throw new D(`unsafe`)}finally{s.closeSync()}let c=L(a,`agent.sock`);if(Buffer.byteLength(c)>107)throw new D(`unsafe`);let u=O(c);if(u&&(!u.isSocket()||u.uid!==t.linuxHost.uid||(u.mode&4095)!=384)||await(n.probeSocket??Vc)(c)!==`absent`)throw new D(`unsafe`)}}function Uc(e,t){let n=t===void 0?O(e):m(e,t),r=Yt(e,N.O_RDONLY|N.O_DIRECTORY|N.O_NOFOLLOW);try{if(!n||!d(n,Wt(r)))throw new D(`unsafe`);Gt(r)}finally{Ht(r)}}function Wc(e,t){let n=O(e);if(n){if(!n.isDirectory()||n.isSymbolicLink())throw new D(`unsafe`);return}Wc(F(e),t);try{Jt(e,{mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}m(e,t),Uc(F(e))}async function Gc(e,t,n,r={}){let i;try{if(jt(e.dir)!==e.dir)throw new D(`unsafe`);let a=Ke(e);if(a.status===`ready`)return{status:`already-initialized`,stateDir:e.dir};if(a.status!==`absent`)throw new D(`unsafe`);let o,s,c;if(t.kind===`adopt`){if(t.confirmSourceInactive!==!0||!I(t.source)||(s=jt(t.source),s===e.dir))throw new D(`unsafe`);o=ht(s,e.linuxHost.uid),await Hc(s,e,r)}else if(t.kind===`new`){if(c=Je.parse(n),Buffer.byteLength(`${JSON.stringify(c,null,2)}\n`)>65536)throw new D(`invalid`)}else throw new D(`invalid`);kt(e),i=ue(L(e.runtimeDir,`init.sock`));let l=Ke(e);if(l.status===`ready`)return{status:`already-initialized`,stateDir:e.dir};if(l.status!==`absent`)throw new D(`unsafe`);if(s){await Hc(s,e,r);let t=ht(s,e.linuxHost.uid);if(!o||!t.identity.equals(o.identity)||!t.config.equals(o.config)||!t.pairings.equals(o.pairings))throw new D(`unsafe`)}if(Wc(F(e.dir),e.linuxHost.uid),jt(e.dir)!==e.dir)throw new D(`unsafe`);Jt(e.dir,{mode:448});let u=m(e.dir,e.linuxHost.uid);Uc(F(e.dir));let f=()=>{if(!d(u,m(e.dir,e.linuxHost.uid)))throw new D(`unsafe`)},p=o??{identity:Buffer.from(`${JSON.stringify(Ot(je()),null,2)}\n`),config:Buffer.from(`${JSON.stringify(c,null,2)}\n`),pairings:Buffer.from(`{"v":1,"phones":[]}
34
- `)};for(let t of[`identity`,`config`,`pairings`]){r.checkpoint?.(`before-${t}`),f();let n=L(e.dir,`${t}.json`);if(O(n))throw new D(`unsafe`);He(n,p[t],()=>{if(f(),O(n))throw new D(`unsafe`)}),r.checkpoint?.(`after-${t}`)}ht(e.dir,e.linuxHost.uid),Uc(e.dir,e.linuxHost.uid),r.checkpoint?.(`before-marker`),f();let h=L(e.dir,`host.json`);return He(h,`${JSON.stringify({v:1,hostDigest:e.linuxHost.hostDigest,installationId:xn()})}\n`,()=>{if(f(),O(h))throw new D(`unsafe`)}),r.checkpoint?.(`after-marker`),r.checkpoint?.(`before-directory-fsync`),Uc(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?.()}}function Kc(e=process.platform,t){if(e!==`linux`)return ze();let n=Ft(t);return Xe(n),n}function qc(e,t={}){e.command(`host`).description(`manage explicit 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&&(!I(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 Gc((t.selectPaths??Ft)(),n.new?{kind:`new`}:{kind:`adopt`,source:n.adopt,confirmSourceInactive:!0},{...yt(),computerName:(t.hostname??ln)().replace(/\.local$/,``)||`Linux`}),i={status:e.status,next:`shellbell start`};console.log(r?JSON.stringify(i):` host state ${e.status}; run shellbell start for foreground operation`);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}`)})}const Jc=et,$=new vn().name(`shellbell`).version(Jc).option(`--relay <url>`,`override relay url`).option(`--json`,`machine output`).option(`--verbose`,`debug logging`).option(`--insecure`,`allow a ws:// relay url (LAN dev only)`);function Yc(){let e=$.opts(),t=Kc();return{opts:e,p:t,cfg:pt(t),log:We({file:t.log,verbose:e.verbose,stdout:process.stdout.isTTY&&!e.json})}}const Xc=e=>`${e.slice(0,4)}-${e.slice(4,8)}`;function Zc(e,t){return Qc(`\n Pair "${xr(t)}"?\n Phone fingerprint ${qe(e)}\n Check that your phone shows the same fingerprint. [y/N] (60 s) `,6e4)}function Qc(e,t){return new Promise(n=>{let r=hn({input:process.stdin,output:process.stdout}),i=setTimeout(()=>{r.close(),console.log(`
35
- (timed out — declined)`),n(!1)},t);r.question(e,e=>{clearTimeout(i),r.close(),n(/^y(es)?$/i.test(e.trim()))})})}function $c(e,t){console.log(`\n Computer ${e.computerName} (${Xc(t)})\n Relay ${e.relayUrl}\n\n Scan this with the Shellbell app:\n`)}function el(e,t){yn.generate(e,{small:!0},e=>{console.log(e.split(`
31
+ `||e===`no`)return`no`}catch{}return`unknown`}}}const J=e=>e.activeState===`inactive`||e.activeState===`failed`,sl=e=>[`enabled`,`enabled-runtime`].includes(e.unitFileState);function Y(e){throw Error(`shellbell: ${e}`)}var cl=class{options;machine;location;files;manager;readiness;clock;constructor(e){this.options=e,this.machine=u(e.machine),this.location=Jc({identity:this.machine,env:e.env,home:e.home??M()}),this.files=new Xc(this.location,this.machine.machineId),this.manager=e.manager??ol({location:this.location,runtimeFsType:e.runtimeFsType}),this.readiness=new Tt(e),this.clock=e.clock??{now:()=>tr.now(),sleep:e=>new Promise(t=>setTimeout(t,e))}}select(e,t,n=!1){let r=e.unit?.definition;r&&this.options.env.SHELLBELL_DIR!==void 0&&h(this.options.env.SHELLBELL_DIR)!==r.stateDir&&Y(`SHELLBELL_DIR conflicts with installed service state; explicit migration is required`);let i;try{let e={...this.options.env,...r?{SHELLBELL_DIR:r.stateDir,...n?{}:{XDG_RUNTIME_DIR:r.runtimeRoot}}:{}};i=(this.options.selectPaths??(e=>qt({...this.options.machine,env:e,home:this.options.home,runtimeFsType:this.options.runtimeFsType})))(e),(i.linuxHost.uid!==this.machine.uid||i.linuxHost.hostDigest!==this.machine.hostDigest||r&&i.dir!==r.stateDir)&&Y(`selected Linux paths do not match owned service`)}catch{return t&&Y(`Linux service runtime/state selection is unsafe or unavailable`),{degraded:!0}}try{let e=st(i);return{paths:i,degraded:!1,expected:{computerFp:e.fp,stateDir:i.dir,...r?{serviceInstance:r.serviceInstance}:{}}}}catch{return t&&Y(`Linux host state is not ready; restore initialized credentials before granting service access`),{paths:i,degraded:!0}}}ownedManager(e,t,n=!1){return!t.available||t.dropInPaths!==``||t.needDaemonReload?!1:n&&!e.unit&&[``,`disabled`,`enabled`,`enabled-runtime`].includes(t.unitFileState)&&t.loadState===`not-found`&&t.fragmentPath===``&&J(t)&&t.mainPid===null?!0:![`disabled`,`enabled`,`enabled-runtime`,`linked`,`linked-runtime`].includes(t.unitFileState)||![`inactive`,`failed`,`active`,`activating`,`deactivating`].includes(t.activeState)?!1:!!e.unit&&t.loadState===`loaded`&&this.files.matchesFragment(t.fragmentPath)}assertManager(e,t,n=!1){this.files.assertUnchanged(e),this.ownedManager(e,t,n)||Y(`systemd manager ownership is unavailable, foreign or unresolved; inspect exact unit discovery and overrides`)}async local(e,t,n,r=500){if(!t.paths)return{kind:`unverified`,local:null,diagnostic:`Local certification degraded; runtime is unsafe or unavailable`};let i=await this.readiness.observe(t.paths.sock,t.expected?{...t.expected,...n.mainPid?{pid:n.mainPid}:{}}:void 0,r);return i.local&&e.unit&&(i.local.process.pid!==n.mainPid||!Pt(i.local,{computerFp:t.expected?.computerFp??i.local.process.computerFp,stateDir:e.unit.definition.stateDir,serviceInstance:e.unit.definition.serviceInstance}))?{kind:`foreign`,local:i.local,diagnostic:`Local endpoint contradicts owned manager job`}:i}async result(e,t,n,r=!1){let i=await this.manager.observe(),a=this.ownedManager(e,i,!0),o=await this.local(e,t,i),s=await this.manager.observe(),c=!0;try{this.files.assertUnchanged(e)}catch{c=!1}let l=c&&a&&this.ownedManager(e,s,!0)&&i.mainPid===s.mainPid&&i.activeState===s.activeState,u=!!e.unit&&l&&!t.degraded&&i.activeState===`active`&&i.mainPid!==null&&i.conditionResult&&s.conditionResult&&o.kind===`verified`;r&&(!l||!J(s)||s.mainPid!==null||t.paths&&o.kind!==`absent`)&&Y(`service stop final confirmation is unresolved; current job or endpoint is not verified stopped`);let d=sl(s)&&!e.link?.owned||e.link&&!e.link.owned;return{manager:`systemd`,unitName:this.location.unitName,definitionPath:this.location.definitionPath,installed:!!e.unit,enabled:sl(s),startupEnabled:s.available?sl(s):null,autostartConfigured:!!e.link?.owned,activeState:s.activeState,managedPid:s.mainPid,ownership:!l||o.kind===`foreign`?`foreign`:t.degraded?`degraded`:e.unit?`verified`:`none`,ready:u,local:o.local,linger:await this.manager.linger(),...n||d||t.degraded||!l||o.diagnostic?{diagnostic:[n,d?`Remaining external enablement is outside Shellbell's owned link`:void 0,t.degraded?`Local identity/runtime certification degraded; credentials were not repaired`:void 0,l?void 0:`Manager ownership is unresolved`,o.diagnostic].filter(Boolean).join(`; `)}:{}}}async status(){let e=this.files.inspect();return this.result(e,this.select(e,!1))}async serialized(e,t,n){let r=this.files.inspect(),i=this.select(r,e,t),o=async()=>{let t;try{return i.paths&&(Xe(i.paths),t=a(F(i.paths.runtimeDir,`service`))),this.files.assertUnchanged(r),e&&st(i.paths),await n(r,i,!!t)}finally{t?.()}},s=i.paths?.dir??r.unit?.definition.stateDir;return s?$e({stateDir:s,uid:this.machine.uid,create:t,startupPreference:e=>e.autostartConfigured},o):o()}async execute(e,t){this.files.assertUnchanged(t);try{await this.manager.execute(e)}catch{Y(`systemd ${e} failed or timed out; manager effect may be unresolved`)}}async install(){let e=(this.options.resolveRuntime??Ke)(),t=[`/usr/local/bin`,`/usr/bin`,`/bin`],n=(this.options.env.PATH??``).split(`:`).filter(e=>P(e)&&!t.includes(e));return this.serialized(!0,!0,async(r,i)=>{let a=r.unit?.definition,o={v:1,machineId:this.machine.machineId,nodePath:e.nodePath,cliPath:e.cliPath,stateDir:i.paths.dir,runtimeRoot:N(N(i.paths.runtimeDir)),serviceInstance:a?.serviceInstance??L(),path:[...new Set([N(e.nodePath),...n,...t])].join(`:`)},s=Wc(o),c=await this.manager.observe();if(this.assertManager(r,c,!r.unit),r.unit?.raw.equals(s))return this.result(r,i);(!J(c)||c.mainPid!==null)&&Y(`active service definition cannot be updated; stop, install, then start explicitly`),(await this.local(r,i,c)).kind!==`absent`&&Y(`local endpoint ownership is foreign or unverified; stop foreground owner before install`);let l=await this.manager.observe();this.assertManager(r,l,!r.unit),(!J(l)||l.mainPid!==null)&&Y(`active service job changed during install admission; stop before updating`),a&&(o.serviceInstance=L());let u;try{return u=this.files.publish(r,o),await this.execute(`daemon-reload`,u),this.assertManager(u,await this.manager.observe()),await this.result(u,i)}catch{if(u){this.files.restore(r,u);try{await this.manager.execute(`daemon-reload`)}catch{Y(`systemd install failed; definition restored but manager reload remains unresolved`)}}Y(`systemd install failed; owned definition restored where possible, inspect manager discovery`)}})}enable(){return this.link(!0)}disable(){return this.link(!1)}link(e){return this.serialized(e,!1,async(t,n,r)=>{let i=await this.manager.observe();if(this.assertManager(t,i,!t.unit&&!e),!t.unit&&e&&Y(`service is not installed; run service install first`),t.link&&!t.link.owned)return e&&Y(`foreign autostart leaf prevents service enablement`),this.result(t,n,`Foreign autostart artifact remains; inspect it explicitly`);if(!r)return this.result(t,n,`Owned autostart cleanup remains; restore a safe local runtime before changing files`);if(!!t.link===e)return this.result(t,n);let a=this.files.setEnabled(t,e);try{await this.execute(`daemon-reload`,a),this.assertManager(a,await this.manager.observe(),!a.unit)}catch{e&&this.files.restore(t,a),Y(`systemd ${e?`enable`:`disable`} reload failed; inspect remaining manager state`)}return this.result(a,n)})}start(){return this.run(`start`)}restart(){return this.run(`restart`)}stop(){return this.run(`stop`)}uninstall(){return this.run(`uninstall`)}async stopped(e,t,n){let r=this.clock.now()+1e4;for(;this.clock.now()<r;){let i=await this.manager.observe();this.assertManager(e,i),i.mainPid!==null&&i.mainPid!==n&&Y(`service stop manager job changed; ownership unresolved`);let a=await this.local(e,t,{...i,mainPid:n},Math.min(500,r-this.clock.now()));a.kind===`foreign`&&Y(`service stop ownership changed; endpoint is foreign`);let o=await this.manager.observe();if(this.assertManager(e,o),(o.mainPid!==null&&o.mainPid!==n||J(i)&&!J(o))&&Y(`service stop manager job changed during local probe; ownership unresolved`),J(o)&&o.mainPid===null&&(!t.paths||a.kind===`absent`))return;await this.clock.sleep(Math.min(100,Math.max(0,r-this.clock.now())))}Y(`service stop timed out; stopped state remains unresolved`)}async stopOwned(e,t){let n=await this.manager.observe();this.assertManager(e,n);let r=await this.local(e,t,n);r.kind===`foreign`&&Y(`local endpoint ownership is foreign; refusing service stop`);let i=await this.manager.observe();this.assertManager(e,i),(i.mainPid!==n.mainPid||J(n)&&!J(i))&&Y(`service stop ownership changed during local probe`),(!J(i)||i.mainPid!==null||t.paths&&r.kind!==`absent`)&&(await this.execute(`stop`,e),await this.stopped(e,t,n.mainPid))}async ready(e,t,n={}){let r=this.clock.now()+1e4;for(;this.clock.now()<r;){let i=await this.manager.observe();this.assertManager(e,i),n.pid!==void 0&&i.mainPid!==n.pid&&Y(`service readiness manager job changed`),i.mainPid!==null&&(n.pid??=i.mainPid);let a=await this.local(e,t,i,Math.min(500,r-this.clock.now()));a.kind===`foreign`&&Y(`service readiness ownership is foreign`);let o=await this.manager.observe();if(this.assertManager(e,o),o.mainPid!==i.mainPid&&Y(`service readiness manager job changed`),o.activeState===`active`&&o.conditionResult&&o.mainPid!==null&&a.kind===`verified`)return a.local;await this.clock.sleep(Math.min(100,Math.max(0,r-this.clock.now())))}Y(`service readiness timed out`)}async cleanupStart(e,t,n){let r=await this.manager.observe();this.assertManager(e,r);let i=await this.local(e,t,r),a=await this.manager.observe();this.assertManager(e,a),(a.mainPid!==r.mainPid||J(r)&&!J(a))&&Y(`start ownership changed during local probe; cleanup unresolved`),!(J(a)&&a.mainPid===null&&i.kind===`absent`)&&((r.mainPid===null||n.pid!==void 0&&n.pid!==r.mainPid||![`verified`,`absent`].includes(i.kind))&&Y(`start ownership unresolved; no cleanup stop was attempted`),await this.execute(`stop`,e),await this.stopped(e,t,r.mainPid))}run(e){let t=e===`stop`||e===`uninstall`;return this.serialized(!t,!1,async(n,r,i)=>{let a=await this.manager.observe();if(this.assertManager(n,a,!n.unit&&t),!n.unit)return t||Y(`service is not installed; run service install first`),this.result(n,r);let o=await this.local(n,r,a);if(o.kind===`foreign`&&Y(`local endpoint ownership is foreign`),e!==`start`&&await this.stopOwned(n,r),t){let t=n;e===`uninstall`&&i&&((!t.link||t.link.owned)&&(t=this.files.setEnabled(t,!1)),t=this.files.remove(t),await this.execute(`daemon-reload`,t),this.assertManager(t,await this.manager.observe(),!0));let a=e===`uninstall`?i?`Service uninstalled; credentials remain unchanged`:`Service stopped; owned definition and autostart cleanup remain until runtime is safe`:`Service stopped; if enabled, it may start after a later user-manager restart`;return this.result(t,r,a,!0)}if(e===`start`&&a.activeState===`active`){await this.ready(n,r);let e=await this.result(n,r);return e.ready||Y(`service start readiness changed during final confirmation`),e}e===`start`&&(!J(a)||a.mainPid!==null||o.kind!==`absent`)&&Y(`service start ownership is unresolved; stop the foreground or pending owner first`);let s=await this.manager.observe();this.assertManager(n,s),(!J(s)||s.mainPid!==null)&&Y(`service start manager job changed before command; ownership unresolved`);let c={};try{await this.execute(`start`,n),await this.ready(n,r,c);let e=await this.result(n,r);return e.ready||Y(`service start readiness changed during final confirmation`),e}catch{try{await this.cleanupStart(n,r,c)}catch{Y(`service start failed; ownership or cleanup remains unresolved`)}Y(`service start failed; newly started owned job was stopped`)}})}};const ll=Xn(A);function ul(e){let t=/(\d+)\.(\d+)/.exec(e);return t?Number(t[1])+Number(t[2])/100:null}function dl(e){return+!!e.some(e=>e.severity===`error`)}function fl(e,t){return{name:e,ok:!0,severity:`pass`,detail:t}}function X(e,t,n){return{name:e,ok:!0,severity:`warning`,detail:t,...n?{fix:n}:{}}}function Z(e,t,n){return{name:e,ok:!1,severity:`error`,detail:t,...n?{fix:n}:{}}}function pl(e,t,n,r){return t?{...fl(e,`connected to the local agent`),...n?{required:n}:{}}:n?{...Z(e,`required backend is not connected; ${r.detail}`,r.fix),required:!0}:r}function ml(e,t){for(let n of t.PATH?.split(Tn)??[])if(n)try{return en(F(n,e),j.X_OK),!0}catch{}return!1}async function hl(e){return(await ll(`tmux`,[`-V`],{env:e,timeout:3e3,maxBuffer:65536})).stdout}async function gl(e){return bs({socketPath:eo(e),herdrOnPath:()=>ml(`herdr`,e)})}function _l(e,t){if(!e.installed||!e.definition)return{env:t,context:`current shell setup`};let n=e.definition.environment;return{env:{PATH:n.PATH,HERDR_SOCKET_PATH:n.HERDR_SOCKET_PATH,XDG_CONFIG_HOME:n.XDG_CONFIG_HOME},context:`installed service setup`}}function vl(e,t){return e.loaded&&!e.installed?Z(`service manager`,`loaded service has no installed definition`):e.installed?e.definition?e.loaded?e.definition.serviceInstance?t?t.process.serviceInstance===e.definition.serviceInstance?fl(`service manager`,`loaded job matches the local service instance`):Z(`service manager`,`loaded job does not match the local service instance`,`stop the foreground owner and restart the service`):X(`service manager`,`loaded job cannot be matched until local control responds`):X(`service manager`,`legacy service definition has no verifiable instance marker`,`reinstall the service to record a service instance`):X(`service manager`,`installed service is stopped`,"run `shellbell service start` if background operation is wanted"):Z(`service manager`,`installed service definition is unreadable`,`reinstall the service after checking its definition`):X(`service manager`,`no service definition installed; foreground agent can still run`,"run `shellbell service install` for autostart")}function yl(e){let t=`installed=${e.installed}; enabled=${e.enabled}; active=${e.activeState}; authenticated ready=${e.ready}; linger=${e.linger}; ownership=${e.ownership}${e.diagnostic?`; ${e.diagnostic}`:``}`;return e.activeState===`unknown`?X(`service manager`,t,`restore access to the current user's systemd manager; foreground readiness is independent`):e.ownership===`foreign`?Z(`service manager`,t,`inspect the exact unit and any drop-ins; Shellbell refuses foreign definitions`):e.ready?fl(`service manager`,t):X(`service manager`,t,`inspect shellbell service status; install, start, and enable are separate choices; foreground readiness is independent`)}function bl(e,t){let n=e=>t.includes(e)?{...Z(e,`required backend unavailable until service state is selected`),required:!0}:X(e,`unavailable until service state is selected`);return[X(`identity`,e),Z(`service manager`,e),X(`control`,`unavailable until service state is selected`),X(`relay`,`unavailable until service state is selected`),n(`iterm2`),n(`tmux`),n(`herdr`),X(`terminal readiness`,`unavailable until service state is selected`)]}async function xl(e,t={}){let n=(e.platform??process.platform)===`linux`,i=X(`service manager`,`Linux systemd user-manager inspection unavailable; foreground readiness is independent`,`inspect shellbell service status and the current user's systemd manager`),a=e.requiredBackends.filter(e=>e!==`tmux`).map(e=>({...Z(e,e===`herdr`?`Shellbell's Herdr backend is not yet qualified for Linux delivery (Herdr itself supports Linux)`:`iTerm2 is not supported on Linux`),required:!0})),o=null,s;if(n){let n,r={...e.env,SHELLBELL_DIR:e.requestedStateDir??e.env.SHELLBELL_DIR},o=e=>(r=e,n=(t.selectLinuxPaths??(e=>qt({env:e})))(e),n);try{i=yl(await(t.inspectLinuxService??(()=>new cl({env:r,selectPaths:o}).status()))(o))}catch{}let c;try{let e=n??o(r);s=e;let t=St(e);c=t.status===`ready`?fl(`host state`,`Linux host state admitted`):Z(`host state`,t.reason??`Linux host state is absent`,`initialize absent state with shellbell host init --new, or inspect existing state before recovery`)}catch{c=Z(`host state`,`Linux state or runtime selection is unsafe or unavailable`,`use a nonroot matching real/effective user, a valid machine ID, and a private 0700 local runtime directory`)}if(c.severity===`error`)return[c,i,X(`control`,`unavailable until host state is admitted`),X(`relay`,`unavailable until host state is admitted`),...a,e.requiredBackends.includes(`tmux`)?{...Z(`tmux`,`required backend unavailable until host state is admitted`),required:!0}:X(`tmux`,`unavailable until host state is admitted`)]}else{try{o=await(t.inspectManager??(()=>p().inspect()))()}catch{return bl(`service manager inspection failed; state unavailable`,e.requiredBackends)}try{s=Mt(o,e.requestedStateDir,e.defaultStateDir)}catch{return bl(`state selection unavailable; check SHELLBELL_DIR against installed service`,e.requiredBackends)}}let c,l=null;try{let e=r(s);e?(l=e.fp,c=fl(`identity`,n?`valid admitted Linux identity`:`valid identity at ${s.identity}`)):c=Z(`identity`,`identity missing at ${s.identity}`,`start Shellbell once to create an identity`)}catch{c=Z(`identity`,n?`Linux identity invalid or unreadable`:`identity invalid or unreadable at ${s.identity}`,`restore the original identity file; do not replace paired keys`)}let u=null,d;if(!l)d=Z(`control`,`cannot verify local process without a valid identity`);else try{let e=await(t.controlStatus??(e=>de(e,`status`,void 0,{timeoutMs:500,maxResponseBytes:65536})))(s.sock),n=be.safeParse(e);n.success?Pt(n.data,{computerFp:l,stateDir:s.dir})?(u=n.data,d=fl(`control`,`local agent identity and state verified`)):d=Z(`control`,`local endpoint belongs to a different identity or state directory`):d=Z(`control`,`local endpoint returned malformed or unsupported status`)}catch{d=Z(`control`,`local endpoint is absent or did not return bounded status`,`start Shellbell, or inspect the configured service`)}let f=n?i:vl(o,u),m=null,h=null;try{h=tt(s).relayUrl}catch{m=Z(`relay`,n?`Linux configuration invalid or unreadable`:`configuration invalid or unreadable at ${s.config}`,`repair the existing config without replacing identity files`)}if(!m){if(u?.relayOnline)m=fl(`relay`,`local agent reports relay connected`);else{let e=`configured relay`,n=!1;try{let r=new URL(h);[`ws:`,`wss:`,`http:`,`https:`].includes(r.protocol)&&(e=`${r.protocol===`ws:`?`http:`:r.protocol===`wss:`?`https:`:r.protocol}//${r.host}/healthz`,n=await(t.relayHealth??Fc)(h))}catch{}m=Z(`relay`,`local agent is not relay-connected; ${e} ${n?`is reachable`:`is not confirmed reachable`} (HTTP health does not prove WebSocket authorization)`,`check the relay URL, network, and running agent`)}}let{env:g,context:_}=n?{env:e.env,context:`current shell setup`}:_l(o,e.env),v=new Set(e.requiredBackends),y=e=>u?.backends.find(t=>t.name===e)?.connected===!0,ee=X(`iterm2`,`${_}: iTerm2 API socket unavailable`,`enable iTerm2 Python API, then start Shellbell to authorize access`);if(!n&&!y(`iterm2`))try{(t.itermSocketExists??(()=>nn(pc)))()&&(ee=X(`iterm2`,`${_}: API socket exists but agent is disconnected`,`start Shellbell to authorize iTerm2 API access`))}catch{ee=Z(`iterm2`,`iTerm2 API socket inspection failed`)}let b=pl(`iterm2`,y(`iterm2`),v.has(`iterm2`),ee),x=X(`tmux`,`${_}: tmux is unavailable`,`install tmux 3.2 or newer`);if(!y(`tmux`))try{let e=ul(await(t.tmuxVersion??hl)(g));x=e===null||e<3.02?Z(`tmux`,`${_}: tmux version is unsupported or unrecognizable`,`install tmux 3.2 or newer`):X(`tmux`,`${_}: tmux 3.2+ is installed but not connected`,`start a tmux session and Shellbell`)}catch(e){x=e.code===`ENOENT`?X(`tmux`,`${_}: tmux executable not found`,`install tmux 3.2 or newer`):Z(`tmux`,`${_}: tmux version probe failed`,`check installed tmux and the saved PATH`)}let S=pl(`tmux`,y(`tmux`),v.has(`tmux`),x),te=X(`herdr`,`${_}: Herdr is unavailable`,Ya);if(!n&&!y(`herdr`))try{let e=await(t.checkHerdr??gl)(g);te=e.ok?e.detail===`not installed (optional)`?X(`herdr`,`${_}: Herdr not found on PATH`,Ya):e.detail===`installed but not running (optional)`?X(`herdr`,`${_}: Herdr is installed but not running`,`start Herdr and Shellbell`):X(`herdr`,`${_}: Herdr API available but agent is disconnected`,`start Shellbell with Herdr enabled`):Z(`herdr`,`${_}: Herdr API is broken or unsupported`,Xa)}catch{te=Z(`herdr`,`${_}: Herdr API probe failed`,Xa)}let ne=pl(`herdr`,y(`herdr`),v.has(`herdr`),te),C=u?await(t.terminalSetup??Sl)(s.sock).catch(()=>null):null,w=(e,t)=>{let n=C?.find(e=>e.name===t);if(!n?.issue)return e;let{status:r,fix:i}=xr(n,`command-line`);return n.connected?{...X(t,r,i),...e.required?{required:!0}:{}}:pl(t,!1,v.has(t),X(t,r,i))},re=(n?y(`tmux`):u?.terminalReady)?fl(`terminal readiness`,`at least one backend connected to the verified local agent`):Z(`terminal readiness`,`no backend connected to a verified local agent`,`start Shellbell with a supported terminal backend`);return[...n?[fl(`host state`,`Linux host state admitted`)]:[],c,f,d,m,...n?a:[w(b,`iterm2`)],w(S,`tmux`),...n?[]:[w(ne,`herdr`)],re]}async function Sl(e){let t=await g(e);try{return await t.terminals()}finally{t.close()}}var Cl=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 wl(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&&Tl(e[r+1])&&Tl(e[r+2])&&Tl(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 Tl(e){return e!==void 0&&e>=48&&e<=55}const El=Buffer.from(`%output `),Dl=Buffer.from(`%extended-output `),Ol=Buffer.from(` : `);function kl(e){let t;if(e.subarray(0,El.length).equals(El))t=e.subarray(El.length);else if(e.subarray(0,Dl.length).equals(Dl))t=e.subarray(Dl.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]===El[1])return{pane:r,data:t.subarray(n+1)};let i=t.indexOf(Ol,n);if(i!==-1)return{pane:r,data:t.subarray(i+Ol.length)}}function Al(e){return`'${e.replace(/'/g,`'\\''`)}'`}function jl(e){return e.trim().split(/\s+/,1)[0]||`?`}const Ml=/^%(?:end|error) (\S+) (\S+) \S+$/;function Nl(e,t){let n=Ml.exec(e);return n!==null&&n[1]===t.time&&n[2]===t.num}var Pl=class extends Ln{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??$t)(this.opts.executable??`tmux`,e,{stdio:[`pipe`,`pipe`,`pipe`]});this.child=t,this.alive=!0;let n=new Cl,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&&!Nl(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:O(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=kl(t);if(!e)return!1;let n=++this.outputSeq;return this.emit(`output`,e.pane),this.listenerCount(`bytes`)>0&&this.emit(`bytes`,e.pane,wl(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: ${jl(n)}`)),this.stop()},this.opts.commandTimeoutMs??5e3);a.unref?.(),t.push({resolve:(e,t)=>r({lines:e,outputSeq:t}),reject:i,timer:a,verb:jl(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
32
+ `)}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 Fl={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 Il(e){let t=Fl[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 Ll=Rl();function Rl(){let e=new Map([[`\r`,`Enter`],[`
33
+ `,`Enter`],[` `,`Tab`]]);for(let[t,n]of Object.entries(Ze))e.has(n)||e.set(n,Il(t));return e}function zl(e){return e?Ll.get(e):void 0}const Bl=`#{session_id}\\t#{client_control_mode}\\t#{client_pid}`,Vl=e=>Al(e.replace(/\\t/g,` `)),Hl=Vl(`#{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}`),Ul=Vl(Bl),Wl=Vl(`#{cursor_x}\\t#{cursor_y}\\t#{history_size}\\t#{pane_width}\\t#{pane_height}\\t#{alternate_on}`),Gl=Vl(`#{cursor_x}\\t#{cursor_y}\\t#{history_size}\\t#{pane_width}\\t#{pane_height}\\t#{history_limit}\\t#{alternate_on}`),Q=e=>Number.parseInt(e??`0`,10)||0,Kl=/^%\d+$/,ql=/^\$\d+$/,Jl=/^@\d+$/;function Yl(e){let t=e.split(` `);return t.length!==18||!Kl.test(t[0]??``)||!ql.test(t[1]??``)||!Jl.test(t[3]??``)?null:{paneId:t[0]??``,sessionId:t[1]??``,sessionName:t[2]??``,windowId:t[3]??``,windowIndex:Q(t[4]),windowName:t[5]??``,paneIndex:Q(t[6]),paneTitle:t[7]??``,cwd:t[8]??``,width:Q(t[9]),height:Q(t[10]),paneActive:t[11]===`1`,windowActive:t[12]===`1`,historySize:Q(t[13]),cursorX:Q(t[14]),cursorY:Q(t[15]),dead:t[16]===`1`,currentCommand:t[17]??``}}const Xl=({sessionId:e,sessionName:t,windowIndex:n,windowActive:r,...i})=>JSON.stringify(i);function Zl(e){let t=e.map(Yl).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===Xl(e)?Xl(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 Ql(e){let t=e.split(` `),n=/^\d{1,10}$/.test(t[2]??``)?Number(t[2]):void 0;return{sessionId:t[0]??``,controlMode:t[1]===`1`,...n?{pid:n}:{}}}function $l(e){let t=e.split(` `);return{cursorX:Q(t[0]),cursorY:Q(t[1]),historySize:Q(t[2]),width:Q(t[3]),height:Q(t[4])}}function eu(e){let t=e.split(` `);if(!(t.length!==6||t[5]!==`0`&&t[5]!==`1`))return t[5]===`1`}function tu(e){let t=e.split(` `);if(t.length!==7||t[6]!==`0`&&t[6]!==`1`)return null;let n=t.slice(0,6).map(nu);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 nu(e){if(!/^(?:0|[1-9]\d*)$/.test(e))return null;let t=Number(e);return Number.isSafeInteger(t)?t:null}function ru(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 iu=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)}},au=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} ${Gl}`,`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=tu(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)>x.screenBytes||(e[6]?.reduce((e,t)=>e+Buffer.byteLength(t),0)??0)>x.screenBytes)return;let c=s===0?[]:_r(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(rt(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} ${Gl}`,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=tu(a[0]?.[0]??``),s=tu(a.at(-1)?.[0]??``);if(!ou(o,t.facts)||!ou(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:_r(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 ou(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 su=[`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 cu(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} '${su.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 lu={block:2,underline:4,bar:6};function uu(e){let t=``,n=``;return e.forEach((e,r)=>{r>0&&(n+=t?`\x1b[49m\r\n${t}`:`\r
34
+ `),n+=e;for(let[,n=``]of e.matchAll(/\x1b\[([\d;:]*)m/g))t=du(t,n)}),n}function du(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 fu(e,t=!1){let[n=[],r=[],i=[],a=[],o=[]]=e,s=(n[0]??``).split(` `);if(s.length!==su.length)throw Error(`unexpected tmux pane state`);let c=Object.fromEntries(su.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?`${Sr}\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+=uu(m),u&&(f+=`\x1b[0m\x1b[${l(`alternate_saved_y`)+1};${l(`alternate_saved_x`)+1}H`,f+=`\x1b[?1049h${uu(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=lu[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(`
35
+ `)}}var pu=class extends Ln{opts;control;history;log;generation=0;held=[];size;seeding=!1;reseedWanted=!1;resizeTimer=null;muting=null;ended=!1;historyLines;names=new iu;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 Pl({sessionId:t,socketName:e.socketName,executable:e.executable,log:e.log})))(e.tmuxSessionId),this.history=new au(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([...cu(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=fu(r);this.size={cols:s.cols,rows:s.rows},this.held=void 0,this.generation++,this.names=new iu;let c=Buffer.from(this.names.write(Buffer.from(s.data))).toString(),l=fu(r,!0),u={data:Buffer.from(new iu().write(Buffer.from(l.data))).toString(),reason:this.reason},d=n.length>0?this.history.capture(r,s,this.historyLines,a,Buffer.from(new iu().write(Buffer.from(fu(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 mu=Xn(A),hu=`brew install tmux (3.2+), then start a tmux session`,gu=5e3,_u=10485760;function vu(e,t){return Va({cwd:e.cwd||void 0,project:Ia(e.windowName,e.currentCommand),processName:e.currentCommand,title:e.paneTitle,ignore:[t]})}function yu(e){return O(e)}function bu(e){return`historySize`in e}function xu(e,t){return new Promise((n,r)=>{let i=setTimeout(()=>r(Error(`tmux exec timeout: ${t}`)),gu);i.unref?.(),e.then(e=>{clearTimeout(i),n(e)},e=>{clearTimeout(i),r(e instanceof Error?e:Error(String(e)))})})}var Su=class t{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;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 mu(this.program(),[...e.socketName?[`-L`,e.socketName]:[],...t],{timeout:gu,maxBuffer:_u})).stdout);this.exec=e=>xu(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 mu(n,e,{timeout:gu,maxBuffer:_u})).stdout),i=e=>xu(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=ul(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 e=this.closes,n=await t.detect(this.exec);if(e===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 C(n.reason??`tmux unavailable`,hu);this.watcher&&clearInterval(this.watcher),this.closed=!1,await this.syncControls(),await this.refreshPanes(),!(this.closed||e!==this.closes)&&(this.watcher=setInterval(()=>{this.syncControls().then(()=>this.refreshPanes()).catch(e=>this.log.warn(`tmux watcher failed`,{error:yu(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.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:yu(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(`
36
+ `).filter(Boolean)}catch(e){this.log.debug(`tmux list-sessions failed; keeping the existing clients`,{error:yu(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 Pl({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:yu(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.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=Zl(await this.channel().command(`list-panes -a -F ${Hl}`))}catch(e){this.log.warn(`list-panes failed`,{error:yu(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??Sn(),o=[...n.keys()].filter(e=>{let r=t.get(e);if(!r)return!1;let i=n.get(e);return ru(r,a)!==ru(i,a)||r.cwd!==i.cwd||!za(vu(r,a),vu(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 D(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} ${Gl}`))[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=tu(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 Or({sessionId:e,cwd:t.cwd,title:ru(t,this.opts.hostname??Sn()),sessionLabel:`tmux · ${t.sessionId} · Tab ${t.windowIndex+1} · Pane ${t.paneIndex+1}`},t.currentCommand,`local-process`)}async listSessions(){let e=new Set,t=new Map;try{let n=(await this.channel().command(`list-clients -F ${Ul}`)).map(Ql).filter(e=>!e.controlMode);e=new Set(n.map(e=>e.sessionId)),t=await this.hostApps(n)}catch(e){this.log.debug(`list-clients failed; no pane reported focused`,{error:yu(e)})}let n=this.opts.hostname??Sn(),r=e=>this.sessionIndex.get(e)??2**53-1;return[...this.panes.values()].sort((e,t)=>r(e.sessionId)-r(t.sessionId)||e.windowIndex-t.windowIndex||e.paneIndex-t.paneIndex).map(r=>({id:r.paneId,backend:`tmux`,title:ru(r,n),cwd:r.cwd||void 0,...vu(r,n),cols:Math.max(1,r.width),rows:Math.max(1,r.height),windowId:r.sessionId,windowNumber:this.sessionIndex.get(r.sessionId)??0,tabId:r.windowId,tabIndex:r.windowIndex,paneIndex:r.paneIndex,isFocusedOnMac:r.paneActive&&r.windowActive&&e.has(r.sessionId),state:`unknown`,...this.alternate.has(r.paneId)&&{alternateScreen:this.alternate.get(r.paneId)},...t.has(r.sessionId)&&{shownIn:t.get(r.sessionId)}}))}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??xo)().catch(()=>void 0)});let r=this.processes.table;if(!r)return t;for(let{sessionId:n,pid:i}of e){let e=i?So(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 pu({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&&!Ia(t.windowName,t.currentCommand))return La(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}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?Gl:Wl,o=await n.command(`display-message -p -t ${e} ${a}`),s=await n.command(`capture-pane -p -e -N -t ${e}`),c=$l(o[0]??``);this.observeAlternate(e,r?tu(o[0]??``)?.alternate:eu(o[0]??``));let l=Math.max(1,c.height),u=s.map(gr);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=tu(o[0]??``);if(!f||f.alternate||!this.panes.has(e)||this.channel(e)!==n||!n.alive)return d;let p;try{p=tu((await n.command(`display-message -p -t ${e} ${Gl}`))[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=$l((await i.command(`display-message -p -t ${e} ${Wl}`))[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(gr),oldestAvailable:o}}async getHistoryPage(e,t){if(rt(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(!bu(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)||(bu(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)||(bu(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)||(bu(d)?u.length===t.before-s?{status:`page`,from:s,to:t.before,oldestAvailable:o,lines:u.map(gr)}:{status:`unavailable`,reason:`changed`}:d)}async sendText(e,t){this.pane(e);let n=this.channel(e),r=zl(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 -- ${Al(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-${L()}`,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=e===void 0?void 0:Nt.parse(e),r=await t.detect(this.exec,{requireServer:!1});if(!r.ok)throw new C(r.reason??`tmux unavailable`,hu);let i=(await this.exec([`new-session`,`-d`,`-P`,`-F`,`#{pane_id}`,...n?[`-x`,String(n.cols),`-y`,String(n.rows)]:[]])).trim();if(!/^%\d+$/.test(i))throw Error(`tmux new-session returned an invalid pane id`);try{n&&await this.exec([`if-shell`,`-F`,`-t`,i,`#{==:#{default-size},${n.cols}x${n.rows}}`,`set-option -u -t ${i} default-size`]),await this.connect()}catch(e){throw await this.exec([`kill-pane`,`-t`,i]).catch(()=>void 0),e}return i}async hostedSessionTarget(e){if(!/^%\d+$/.test(e))throw new D(e);let t=(await this.exec([`display-message`,`-p`,`-t`,e,`#{session_id}`])).trim();if(!/^\$\d+$/.test(t))throw new D(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 D(e);this.scheduleRefresh()}async waitForVisibleClient(e,{timeoutMs:t=15e3,intervalMs:n=250}={}){if(!/^\$\d+$/.test(e))throw new D(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 D(e.windowId);t=e.windowId}else return!1;return this.hasDesktopClient(t)}async hasDesktopClient(e){let t=Bl.replace(/\\t/g,` `),n=(await this.exec([`list-clients`,`-t`,e,`-F`,t])).split(`
37
+ `).filter(Boolean).map(Ql).filter(e=>!e.controlMode);if(n.length===0)return!1;let r=await(this.opts.processTable??xo)().catch(()=>void 0);return r?n.some(e=>e.pid!==void 0&&So(e.pid,r)!==void 0):(this.opts.platform??process.platform)!==`darwin`}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 D(e.windowId);t=this.channelForSession(e.windowId),n=`new-window -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(t){throw new e(`focus`)}};function Cu(e){let t=e.log.child({unit:`tmux-start`}),n=e.terminalExecutable??(()=>Mo(`tmux`)),r=()=>n()??`tmux`,i=new Su({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`,Su.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)=>{if(c||r!==i)throw new C(`tmux was replaced`,`Try again after the service reconnects.`);let s=n();if(!s)throw new C(`tmux is not installed`,`Install tmux 3.2 or newer.`);let l=a??await i.createFirstSession(o),u=l;return await Nc(async()=>{let n=await i.hostedSessionTarget(l);if(u=n.sessionId,c)throw new C(`tmux stopped`,`Reconnect your computer.`);if(await t.launch({executable:s,...o?{initialSize:o}:{},args:[...n.socketName?[`-L`,n.socketName]:[],`attach-session`,`-t`,n.sessionId]}),!await i.waitForVisibleClient(n.sessionId,{timeoutMs:e.attachTimeoutMs}))throw new C(`terminal window did not attach`,`Unlock your computer and try again.`)},()=>i.discardHostedSession(u)),l}}))}).catch(e=>{f=`none`,t.debug(`tmux startup discovery failed`,{error:O(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:O(n)}),e.onUnavailable&&!u&&n instanceof C&&(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:O(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 wu(e){return new Promise(t=>{let n=zn(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 Tu(e,t,n){let r=F(N(t.runtimeDir),Fn(`sha256`).update(e).digest(`hex`).slice(0,32));for(let i of[e,r]){if(!f(i))continue;me(i,t.linuxHost.uid),i===r&&we(t,i);let e=F(i,`agent.pid`);if(f(e)){let r=ue(Ee(e,64,t.linuxHost.uid).toString(`utf8`).trim());if(!r||(n.processAlive??mt)(r))throw new k(`unsafe`)}let a=[`agent.sock.lock`,`init.sock.lock`,`service.lock`],o=un(i);try{for(let e=o.readSync();e;e=o.readSync())if(a.some(t=>e.name===t||e.name.startsWith(`${t}-candidate-`)))throw new k(`unsafe`)}finally{o.closeSync()}let s=F(i,`agent.sock`);if(Buffer.byteLength(s)>107)throw new k(`unsafe`);let c=f(s);if(c&&(!c.isSocket()||c.uid!==t.linuxHost.uid||(c.mode&4095)!=384)||await(n.probeSocket??wu)(s)!==`absent`)throw new k(`unsafe`)}}function Eu(e,t){let n=t===void 0?f(e):me(e,t),r=ln(e,j.O_RDONLY|j.O_DIRECTORY|j.O_NOFOLLOW);try{if(!n||!_t(n,rn(r)))throw new k(`unsafe`);an(r)}finally{tn(r)}}function Du(e,t){let n=f(e);if(n){if(!n.isDirectory()||n.isSymbolicLink())throw new k(`unsafe`);return}Du(N(e),t);try{cn(e,{mode:448})}catch(e){if(e.code!==`EEXIST`)throw e}me(e,t),Eu(N(e))}async function Ou(e,t,n,r={}){let i;try{if(h(e.dir)!==e.dir)throw new k(`unsafe`);let o=St(e);if(o.status===`ready`)return{status:`already-initialized`,stateDir:e.dir};if(o.status!==`absent`)throw new k(`unsafe`);let s,c,u;if(t.kind===`adopt`){if(t.confirmSourceInactive!==!0||!P(t.source)||(c=h(t.source),c===e.dir))throw new k(`unsafe`);s=lt(c,e.linuxHost.uid),await Tu(c,e,r)}else if(t.kind===`new`){if(u=Wt.parse(n),Buffer.byteLength(`${JSON.stringify(u,null,2)}\n`)>65536)throw new k(`invalid`)}else throw new k(`invalid`);Xe(e),i=a(F(e.runtimeDir,`init.sock`));let d=St(e);if(d.status===`ready`)return{status:`already-initialized`,stateDir:e.dir};if(d.status!==`absent`)throw new k(`unsafe`);if(c){await Tu(c,e,r);let t=lt(c,e.linuxHost.uid);if(!s||!t.identity.equals(s.identity)||!t.config.equals(s.config)||!t.pairings.equals(s.pairings))throw new k(`unsafe`)}if(Du(N(e.dir),e.linuxHost.uid),h(e.dir)!==e.dir)throw new k(`unsafe`);cn(e.dir,{mode:448});let p=me(e.dir,e.linuxHost.uid);Eu(N(e.dir));let m=()=>{if(!_t(p,me(e.dir,e.linuxHost.uid)))throw new k(`unsafe`)},g=s??{identity:Buffer.from(`${JSON.stringify(l(Ce()),null,2)}\n`),config:Buffer.from(`${JSON.stringify(u,null,2)}\n`),pairings:Buffer.from(`{"v":1,"phones":[]}
38
+ `)};for(let t of[`identity`,`config`,`pairings`]){r.checkpoint?.(`before-${t}`),m();let n=F(e.dir,`${t}.json`);if(f(n))throw new k(`unsafe`);kt(n,g[t],()=>{if(m(),f(n))throw new k(`unsafe`)}),r.checkpoint?.(`after-${t}`)}lt(e.dir,e.linuxHost.uid),Eu(e.dir,e.linuxHost.uid),r.checkpoint?.(`before-marker`),m();let _=F(e.dir,`host.json`);return kt(_,`${JSON.stringify({v:1,hostDigest:e.linuxHost.hostDigest,installationId:L()})}\n`,()=>{if(m(),f(_))throw new k(`unsafe`)}),r.checkpoint?.(`after-marker`),r.checkpoint?.(`before-directory-fsync`),Eu(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?.()}}function ku(e=process.platform,t){if(e!==`linux`)return Ht();let n=qt(t);return Ge(n),n}function Au(e,t={}){e.command(`host`).description(`manage explicit 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&&(!P(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 Ou((t.selectPaths??qt)(),n.new?{kind:`new`}:{kind:`adopt`,source:n.adopt,confirmSourceInactive:!0},{...dt(),computerName:(t.hostname??Sn)().replace(/\.local$/,``)||`Linux`}),i={status:e.status,next:`shellbell start`};console.log(r?JSON.stringify(i):` host state ${e.status}; run shellbell start for foreground operation`);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}`)})}const ju=`https://github.com/bilal-/shellbell`,Mu=`https://api.github.com/repos/bilal-/shellbell`,Nu=/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/,Pu=I.string().max(32).regex(Nu),Fu=I.string().regex(/^[a-f0-9]{64}$/),Iu=I.string().regex(/^[a-f0-9]{40}$/),Lu=I.object({asset:I.string().max(160),sha256:Fu}).strict(),Ru=Lu.extend({buildNumber:I.number().int().positive().max(2147483647),minimumOS:I.string().regex(/^\d{1,3}\.\d{1,3}(?:\.\d{1,3})?$/),signed:I.literal(!0),notarized:I.literal(!0)}).strict(),zu=Lu.extend({minimumGlibc:I.string().regex(/^[0-9]{1,6}\.[0-9]{1,6}$/)}).strict(),Bu=I.object({schemaVersion:I.literal(1),component:I.literal(`computer`),channel:I.literal(`stable`),version:Pu,tag:I.string().max(64),sourceCommit:Iu,platforms:I.object({macosArm64:Ru.optional(),macosHeadless:Lu.optional(),linuxArm64:zu.optional(),linuxX64:zu.optional()}).strict()}).strict(),Vu=I.object({tag_name:I.string(),draft:I.boolean(),prerelease:I.boolean(),assets:I.array(I.object({name:I.string(),digest:I.string().nullable(),size:I.number().int().nonnegative(),browser_download_url:I.string()})).max(100)});function Hu(e,t){Pu.parse(e),Pu.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 Uu(e,t){if(!e.startsWith(`shellbell@`)||!Nu.test(e.slice(10)))throw Error(`Invalid computer release tag`);if(!/^[A-Za-z0-9._-]+$/.test(t))throw Error(`Invalid release asset name`);return`${ju}/releases/download/${encodeURIComponent(e)}/${t}`}var Wu=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){Pu.parse(e);let n=AbortSignal.timeout(3e4),r;if(t){if(Pu.parse(t),r=Vu.parse(await this.json(`${Mu}/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=I.array(Vu).max(100).parse(await this.json(`${Mu}/releases?per_page=100&page=${r}`,n));if(e.push(...i.filter(e=>!e.draft&&!e.prerelease&&e.tag_name.startsWith(`shellbell@`)&&Nu.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)=>Hu(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=Bu.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(I.object({object:I.object({type:I.literal(`commit`),sha:Iu})}).parse(await this.json(`${Mu}/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:Hu(o.version,e)>0,releaseUrl:`${ju}/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!==Uu(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:${Fn(`sha256`).update(e).digest(`hex`)}`!==t.digest)throw Error(`Downloaded artifact does not match the published digest`)}};const Gu=Xn(A);function Ku(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 qu(e){let t=await R(e.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=F(await R(e.home),`.local/share/shellbell/installs`,`linux-${e.arch}`,e.version);return t!==F(n,`agent/dist/cli.js`)||await R(e.node)!==F(n,`runtime/bin/node`)?`other`:`linux-archive`}async function Ju(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=Fn(`sha256`);try{for(a=await Un(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 Yu(e){if(!process.stdin.isTTY)throw Error(`Use --yes to install an update without an interactive terminal, or --check to check only`);let t=nr({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 Xu(e,t){e.command(`update [version]`).description(`check for computer updates; manually install verified Linux archive updates`).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 Wu,{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 R(M()),l=await qu({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`){console.log(`This installation is managed outside the Linux archive 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=process.arch===`arm64`?s.linuxArm64:s.linuxX64;if(!u)throw Error(`This release has no archive for this computer's architecture`);let d=F(c,`.local/share/shellbell/installs`,`linux-${process.arch}`),f=process.arch===`arm64`?o.release.platforms.linuxArm64:o.release.platforms.linuxX64;if(!f)throw Error(`Missing platform compatibility information`);if(Ku((await Gu(`/usr/bin/getconf`,[`GNU_LIBC_VERSION`],{env:{PATH:`/usr/bin:/bin`,LC_ALL:`C`},timeout:5e3,maxBuffer:1024})).stdout,f.minimumGlibc),await Gn(F(d,`current`))!==t)throw Error(`A different version is already selected; run ~/.local/bin/shellbell update instead`);let p=F(d,t,`install.sh`),m=await Vn(p);if(!m.isFile()||m.isSymbolicLink()||m.uid!==process.getuid()||m.mode&3602)throw Error(`The installed archive's update bootstrap is unsafe; use the official manual installer`);if(!r.yes&&!await Yu(o.release.version)){console.log(`Update cancelled.`);return}let h=await Hn(F(Cn(),`shellbell-update-`));try{let e=F(h,u.name);console.log(`Downloading Shellbell ${o.release.version}…`),await Ju(a,u,e);let n=await Gu(`/bin/sh`,[p,`--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(n.stdout.trim()),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 Kn(h,{recursive:!0,force:!0})}})}const Zu=fe,$=new Nn().name(`shellbell`).version(Zu).option(`--relay <url>`,`override relay url`).option(`--json`,`machine output`).option(`--verbose`,`debug logging`).option(`--insecure`,`allow a ws:// relay url (LAN dev only)`);Xu($,Zu);function Qu(){let e=$.opts(),t=ku();return{opts:e,p:t,cfg:Qe(t),log:zt({file:t.log,verbose:e.verbose,stdout:process.stdout.isTTY&&!e.json})}}const $u=e=>`${e.slice(0,4)}-${e.slice(4,8)}`;function ed(e,t){return td(`\n Pair "${Gr(t)}"?\n Phone fingerprint ${Kt(e)}\n Check that your phone shows the same fingerprint. [y/N] (60 s) `,6e4)}function td(e,t){return new Promise(n=>{let r=An({input:process.stdin,output:process.stdout}),i=setTimeout(()=>{r.close(),console.log(`
39
+ (timed out — declined)`),n(!1)},t);r.question(e,e=>{clearTimeout(i),r.close(),n(/^y(es)?$/i.test(e.trim()))})})}function nd(e,t){console.log(`\n Computer ${e.computerName} (${$u(t)})\n Relay ${e.relayUrl}\n\n Scan this with the Shellbell app:\n`)}function rd(e,t){Pn.generate(e,{small:!0},e=>{console.log(e.split(`
36
40
  `).map(e=>` ${e}`).join(`
37
- `)),console.log(`\n Pairing window closes in ${Math.round((t-Date.now())/6e4)} min\n`)})}function tl(e,t,n){let r=Yt(e,`r`);try{let e=Wt(r).size,i=Math.max(0,e-t),a=e-i,o=Buffer.alloc(a);a>0&&Qt(r,o,0,a,i);let s=o.toString(`utf8`).replace(/\n$/,``);return s.length===0?``:s.split(`
41
+ `)),console.log(`\n Pairing window closes in ${Math.round((t-Date.now())/6e4)} min\n`)})}function id(e,t,n){let r=ln(e,`r`);try{let e=rn(r).size,i=Math.max(0,e-t),a=e-i,o=Buffer.alloc(a);a>0&&fn(r,o,0,a,i);let s=o.toString(`utf8`).replace(/\n$/,``);return s.length===0?``:s.split(`
38
42
  `).slice(-n).join(`
39
- `)}finally{Ht(r)}}async function nl(e){try{return await se(e,`status`),!0}catch(e){let t=e.code;return t!==`ECONNREFUSED`&&t!==`ENOENT`}}function rl(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 il(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 al(e,t){if(t===void 0)return{cfg:e};let n=we(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 ol(e,t,n=!1,r={}){let i=r.paths??Kc(),a=r.nativeService?void 0:()=>it({stateDir:i.dir,uid:i.linuxHost?.uid??process.getuid(),serviceInstance:r.serviceInstance});a?.(),i.linuxHost&&(Xe(i),kt(i));let o=pt(i);if(t!==void 0){let e=al(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}=tt(i),l=new ee(e),u=Wo({paths:o.terminalPlugins??[],registry:l,log:e}),d=i.linuxHost?null:new Ka({recordPath:L(i.dir,`iterm2-access.json`),assumeApproved:(()=>{try{return St(i).length>0}catch{return!1}})(),interactive:!r.nativeService&&!r.managedService&&process.stdin.isTTY===!0,socketPath:Mo}),f=i.linuxHost?null:r.itermBackend===void 0?new jo(new No({log:e,cookieProvider:()=>d.cookieProvider(Ha)}),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=Qn({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:M(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=f&&d?(()=>{let e=d.onChange(()=>l.notifySetupChanged()),t=Object.assign(e=>e?{}:{issue:d.connecting?`connecting`:d.issue??`not-running`},{connect:()=>d.connect(async()=>{await _,l.connected().some(e=>e.name===`iterm2`)||await x()})}),n=l.registerSetupReporter(`iterm2`,t);return()=>{e(),n()}})():()=>{},C=!i.linuxHost&&r.itermBackend===void 0?qo(`iterm2`):null,w=!i.linuxHost&&r.tmuxBackendOptions===void 0?$o():null,te=async()=>{await C?.start(),await x();let e=d?.issue;if(e&&!l.connected().some(e=>e.name===`iterm2`)&&Xn({name:`iterm2`,connected:!1,issue:e})){let{status:t,fix:n}=Qn({name:`iterm2`,connected:!1,issue:e},`phone`);throw new De(`${t} ${n??``}`.trim())}await Yo(l,`iterm2`)},ne=r.terminalWindows??[...w?[w]:[],...f&&C?[{id:`iterm2`,label:`iTerm2`,available:C.available,async launch(e){if(l.connected().some(e=>e.name===`iterm2`)||await te(),l.member(`iterm2`)!==f)throw new j(`iTerm2 was replaced`,`Reconnect your computer.`);await f.createCommandSession(Zo(e))}}]:[]],re=Bc({registry:l,log:e,onConnected:e=>m(` tmux connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>m(` tmux not running`),backendOptions:r.tmuxBackendOptions,terminalWindows:ne}),ie=i.linuxHost?null:(r.startHerdr??Ba)({registry:l,log:e,onConnected:e=>m(` herdr connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>m(` herdr not running (optional)`)}),ae=()=>{S(),u.stop(),v=!0,g&&clearTimeout(g),g=null},oe=[];f&&C&&oe.push(l.registerSessionLauncher(`iterm2`,{available:C.available,start:async()=>(await te(),{backend:f})}));let se=!i.linuxHost&&r.startHerdr===void 0?Jo():null;if(se){oe.push(l.registerSessionLauncher(`herdr`,{available:se.available,start:async()=>{await se.start(),await Yo(l,`herdr`);let e=l.member(`herdr`);if(!e)throw new j(`Herdr unavailable`,`Check Herdr's local API.`);return{backend:e}}}));for(let e of ne)oe.push(l.registerHostedLauncher({backend:`herdr`,host:e.id,label:e.label},{available:()=>{let t=l.member(`herdr`);return e.available()&&(t instanceof Fa&&t.isConnected?t.terminalAttachExecutable!==void 0:ra()!==void 0)},unavailableReason:()=>{let t=l.member(`herdr`);return e.available()&&t instanceof Fa?t.terminalAttachIssue:void 0},create:async t=>{let n=t instanceof Fa?t.terminalAttachExecutable:void 0;if(!n||!(t instanceof Fa))throw new j(`Herdr terminal attach is unavailable`,`Use matching Herdr CLI/server versions, 0.9.3 or newer.`);let{terminalId:r,workspaceId:i}=await t.createWorkspace();return await Qo(async()=>{if(l.member(`herdr`)!==t||t.terminalAttachExecutable!==n)throw new j(`Herdr was disconnected before the terminal could open`,`Reconnect Herdr and try again.`);await e.launch({executable:n,args:[`terminal`,`attach`,r],environment:{HERDR_SOCKET_PATH:t.terminalSocketPath}})},async()=>{if(!i)throw Error(`Herdr workspace id unknown`);await t.closeWorkspace(i)}),r}}))}let ce=()=>{for(let e of oe)e();ae(),re.stop(),ie?.stop()},le={server:null},T;return T=new vi({paths:i,config:o,identity:s,fp:c,registry:l,log:e,appVersion:Jc,serviceInstance:r.serviceInstance??null,confirm:rl(le,n,(e,t)=>Zc(e,t),!r.nativeService),onPairingClosed:()=>le.server?.notifyClosed(),onSuperseded:()=>{r.nativeService||console.log(` another shellbell agent took over; exiting`),le.server?il(T,le.server,()=>process.exit(0),ce).catch(()=>process.exit(1)):process.exit(0)}}),le.server=new $e(i.sock,T,e,i.pid,a,!r.nativeService&&!r.managedService?e=>Tt({stateDir:i.dir,uid:i.linuxHost?.uid??process.getuid()},e):void 0,r.nativeService?`native`:`terminal`),{agent:T,control:le.server,p:i,cfg:o,fp:c,releaseOutput:h,stopFirstConnect:ae,stopBackendDetectors:ce,herdr:ie}}$.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}=Yc(),{agent:a,control:o,cfg:s,fp:c,releaseOutput:l,stopBackendDetectors:u}=await ol(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${Jc}\n Computer ${s.computerName} (${Xc(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(),a.pairingList.length===0&&!e.service&&process.stdin.isTTY){console.log(`
43
+ `)}finally{tn(r)}}async function ad(e){try{return await de(e,`status`),!0}catch(e){let t=e.code;return t!==`ECONNREFUSED`&&t!==`ENOENT`}}function od(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 sd(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 cd(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 ld(e,t,n=!1,r={}){let i=r.paths??ku(),a=r.nativeService?void 0:()=>vt({stateDir:i.dir,uid:i.linuxHost?.uid??process.getuid(),serviceInstance:r.serviceInstance});a?.(),i.linuxHost&&(Ge(i),Xe(i));let o=Qe(i);if(t!==void 0){let e=cd(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}=ht(i),l=new ie(e),u=Tc({paths:o.terminalPlugins??[],registry:l,log:e}),d=i.linuxHost?null:new Os({recordPath:F(i.dir,`iterm2-access.json`),assumeApproved:(()=>{try{return bt(i).length>0}catch{return!1}})(),interactive:!r.nativeService&&!r.managedService&&process.stdin.isTTY===!0,socketPath:pc}),f=i.linuxHost?null:r.itermBackend===void 0?new fc(new mc({log:e,cookieProvider:()=>d.cookieProvider(ws)}),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,ee=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=xr({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:O(t)})}g=setTimeout(()=>void b(),1e4)}},b=()=>v?Promise.resolve():_||(g&&clearTimeout(g),g=null,_=ee().finally(()=>{_=null}),_);f?.isConnected===!1&&l.add(f),f&&b();let x=f&&d?(()=>{let e=d.onChange(()=>l.notifySetupChanged()),t=Object.assign(e=>e?{}:{issue:d.connecting?`connecting`:d.issue??`not-running`},{connect:()=>d.connect(async()=>{await _,l.connected().some(e=>e.name===`iterm2`)||await b()})}),n=l.registerSetupReporter(`iterm2`,t);return()=>{e(),n()}})():()=>{},S=!i.linuxHost&&r.itermBackend===void 0?Oc(`iterm2`):null,te=!i.linuxHost&&r.tmuxBackendOptions===void 0?Pc():null,ne=async()=>{await S?.start(),await b();let e=d?.issue;if(e&&!l.connected().some(e=>e.name===`iterm2`)&&yr({name:`iterm2`,connected:!1,issue:e})){let{status:t,fix:n}=xr({name:`iterm2`,connected:!1,issue:e},`phone`);throw new Ie(`${t} ${n??``}`.trim())}await Ac(l,`iterm2`)},w=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 C(`iTerm2 was replaced`,`Reconnect your computer.`);e.initialSize?await f.createCommandSession(Mc(e),e.initialSize):await f.createCommandSession(Mc(e))}}]:[]],re=Cu({registry:l,log:e,onConnected:e=>m(` tmux connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>m(` tmux not running`),backendOptions:r.tmuxBackendOptions,terminalWindows:w}),ae=i.linuxHost?null:(r.startHerdr??xs)({registry:l,log:e,onConnected:e=>m(` herdr connected · ${e} pane${e===1?``:`s`}`),onUnavailable:()=>m(` herdr not running (optional)`)}),oe=()=>{x(),u.stop(),v=!0,g&&clearTimeout(g),g=null},T=[];f&&S&&T.push(l.registerSessionLauncher(`iterm2`,{available:S.available,start:async()=>(await ne(),{backend:f})}));let se=!i.linuxHost&&r.startHerdr===void 0?kc():null;if(se){T.push(l.registerSessionLauncher(`herdr`,{available:se.available,start:async()=>{await se.start(),await Ac(l,`herdr`);let e=l.member(`herdr`);if(!e)throw new C(`Herdr unavailable`,`Check Herdr's local API.`);return{backend:e}}}));for(let e of w)T.push(l.registerHostedLauncher({backend:`herdr`,host:e.id,label:e.label},{available:()=>{let t=l.member(`herdr`);return e.available()&&(t instanceof gs&&t.isConnected?t.terminalAttachExecutable!==void 0:Po()!==void 0)},unavailableReason:()=>{let t=l.member(`herdr`);return e.available()&&t instanceof gs?t.terminalAttachIssue:void 0},create:async(t,n,r)=>{let i=t instanceof gs?t.terminalAttachExecutable:void 0;if(!i||!(t instanceof gs))throw new C(`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 Nc(async()=>{if(l.member(`herdr`)!==t||t.terminalAttachExecutable!==i)throw new C(`Herdr was disconnected before the terminal could open`,`Reconnect Herdr and try again.`);await e.launch({executable:i,...r?{initialSize:r}:{},args:[`terminal`,`attach`,a],environment:{HERDR_SOCKET_PATH:t.terminalSocketPath}})},async()=>{if(!o)throw Error(`Herdr workspace id unknown`);await t.closeWorkspace(o)}),a}}))}let ce=()=>{for(let e of T)e();oe(),re.stop(),ae?.stop()},le={server:null},ue;return ue=new qa({paths:i,config:o,identity:s,fp:c,registry:l,log:e,appVersion:Zu,serviceInstance:r.serviceInstance??null,confirm:od(le,n,(e,t)=>ed(e,t),!r.nativeService),onPairingClosed:()=>le.server?.notifyClosed(),onSuperseded:()=>{r.nativeService||console.log(` another shellbell agent took over; exiting`),le.server?sd(ue,le.server,()=>process.exit(0),ce).catch(()=>process.exit(1)):process.exit(0)}}),le.server=new ft(i.sock,ue,e,i.pid,a,!r.nativeService&&!r.managedService?e=>Bt({stateDir:i.dir,uid:i.linuxHost?.uid??process.getuid()},e):void 0,r.nativeService?`native`:`terminal`),{agent:ue,control:le.server,p:i,cfg:o,fp:c,releaseOutput:h,stopFirstConnect:oe,stopBackendDetectors:ce,herdr:ae}}$.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=Xt(e.service===!0)}catch(e){console.error(` ${e.message}`),process.exit(1)}let{opts:n,p:r,log:i}=Qu(),{agent:a,control:o,cfg:s,fp:c,releaseOutput:l,stopBackendDetectors:u}=await ld(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${Zu}\n Computer ${s.computerName} (${$u(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(),a.pairingList.length===0&&!e.service&&process.stdin.isTTY){console.log(`
40
44
  No phones paired yet. Scan this with the Shellbell app:
41
- `);let{qrText:e,expiresAt:t}=a.openPairing();el(e,t)}let d=!1,f=()=>{if(d){console.error(` forcing exit`),process.exit(130);return}d=!0,il(a,o,process.exit,u).catch(()=>process.exit(1))};process.on(`SIGINT`,f),process.on(`SIGTERM`,f)}),$.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}=Yc(),{fp:a}=tt(n),o=async()=>{let{agent:r,control:a,cfg:o,fp:s,releaseOutput:c,stopBackendDetectors:l}=await ol(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();$c(o,s),el(u,d),c(),setTimeout(()=>void il(r,a,()=>process.exit(0),l).catch(()=>process.exit(1)),301e3)};if(!await nl(n.sock)){await o();return}let s=ie(n.sock,{onOpen:(e,t)=>{$c(r,a),el(e,t)},onRequest:(t,n)=>e.yes?Promise.resolve(!0):Zc(t,n),onClose:()=>{console.log(` pairing window closed`),process.exit(0)},onError:e=>{console.error(` ${e.message}`),process.exit(1)}});setTimeout(()=>{s.close(),process.exit(0)},301e3)}),$.command(`status`).description(`show agent status`).action(async()=>{let{opts:e,p:t}=Yc();try{let n=await se(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 sl(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}$.command(`devices`).description(`list paired phones`).action(async()=>{let{opts:e,p:t}=Yc();try{let n=await se(t.sock,`devices`);console.log(e.json?JSON.stringify(n):JSON.stringify(n,null,2))}catch(e){sl(e)}});async function cl(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}=Qn(s,`command-line`);return r(` ${c}`),l&&r(` ${l}`),s.connected&&!s.issue?0:2}$.command(`connect <terminal>`).description(`connect a terminal that needs your approval, such as iterm2`).action(async e=>{let{p:t}=Yc(),n;try{n=await h(t.sock),process.exitCode=await cl(n,e)}catch(e){sl(e)}finally{n?.close()}}),$.command(`unpair <target>`).description(`remove a paired phone (fp prefix or name)`).action(async e=>{let{p:t}=Yc();try{let n=await se(t.sock,`unpair`,{target:e});console.log(n.removed?` removed`:` no such phone`)}catch(e){sl(e)}});function ll(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}try{if(o){let e=await(n.createLinuxLifecycle??(()=>new Ds({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(ul),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 lt?e:new lt(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 ul=`
45
+ `);let{qrText:e,expiresAt:t}=a.openPairing();rd(e,t)}let d=!1,f=()=>{if(d){console.error(` forcing exit`),process.exit(130);return}d=!0,sd(a,o,process.exit,u).catch(()=>process.exit(1))};process.on(`SIGINT`,f),process.on(`SIGTERM`,f)}),$.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}=Qu(),{fp:a}=ht(n),o=async()=>{let{agent:r,control:a,cfg:o,fp:s,releaseOutput:c,stopBackendDetectors:l}=await ld(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();nd(o,s),rd(u,d),c(),setTimeout(()=>void sd(r,a,()=>process.exit(0),l).catch(()=>process.exit(1)),301e3)};if(!await ad(n.sock)){await o();return}let s=ce(n.sock,{onOpen:(e,t)=>{nd(r,a),rd(e,t)},onRequest:(t,n)=>e.yes?Promise.resolve(!0):ed(t,n),onClose:()=>{console.log(` pairing window closed`),process.exit(0)},onError:e=>{console.error(` ${e.message}`),process.exit(1)}});setTimeout(()=>{s.close(),process.exit(0)},301e3)}),$.command(`status`).description(`show agent status`).action(async()=>{let{opts:e,p:t}=Qu();try{let n=await de(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 ud(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}$.command(`devices`).description(`list paired phones`).action(async()=>{let{opts:e,p:t}=Qu();try{let n=await de(t.sock,`devices`);console.log(e.json?JSON.stringify(n):JSON.stringify(n,null,2))}catch(e){ud(e)}});async function dd(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}=xr(s,`command-line`);return r(` ${c}`),l&&r(` ${l}`),s.connected&&!s.issue?0:2}$.command(`connect <terminal>`).description(`connect a terminal that needs your approval, such as iterm2`).action(async e=>{let{p:t}=Qu(),n;try{n=await g(t.sock),process.exitCode=await dd(n,e)}catch(e){ud(e)}finally{n?.close()}}),$.command(`unpair <target>`).description(`remove a paired phone (fp prefix or name)`).action(async e=>{let{p:t}=Qu();try{let n=await de(t.sock,`unpair`,{target:e});console.log(n.removed?` removed`:` no such phone`)}catch(e){ud(e)}});function fd(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}try{if(o){let e=await(n.createLinuxLifecycle??(()=>new cl({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(pd),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 Ct?e:new Ct(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 pd=`
42
46
  macOS may now ask a few questions. Each one is optional:
43
47
  - "Background Items Added: node" is this service. node is the runtime Shellbell runs on.
44
48
  - "node" or "osascript" wants to control "iTerm2" appears when you run
@@ -46,4 +50,4 @@ end if`,n)).trim()!==`yes`)throw new U(`iTerm2 is not running`,`not-running`);le
46
50
  Shellbell controls no other app.
47
51
  - "Find devices on your local network" lets your phone connect straight to this Mac on the
48
52
  same Wi-Fi. Without it, your phone may not connect while it is on the same Wi-Fi.
49
- Change any answer later in System Settings → Privacy & Security.`;ll($,()=>new Ct({manager:f(),requestedStateDir:process.env.SHELLBELL_DIR||void 0,defaultStateDir:L(P(),`.shellbell`),env:process.env})),$.command(`logs`).option(`-f, --follow`).description(`show the agent log`).action(e=>{let{p:t}=Yc();e.follow?Bt(`tail`,[`-f`,t.log],{stdio:`inherit`}):Ut(t.log)&&process.stdout.write(tl(t.log,65536,200))});function dl(e,t){process.exitCode=2,t?console.log(JSON.stringify({error:e})):console.error(` ${e}`)}$.command(`config`).description(`config set <${a.join(`|`)}> <value>`).argument(`<op>`).argument(`<key>`).argument(`<value>`).action((e,t,n)=>{let r=$.opts();if(e!==`set`){dl(`unknown config operation ${e} (expected set)`,r.json);return}let i=!!r.insecure||process.env.SHELLBELL_ALLOW_INSECURE_RELAY===`1`,a=ye(yt(),t,n,i);if(`error`in a){dl(a.error,r.json);return}try{let e=Kc();Qe(e,e=>{let r=ye(e,t,n,i);if(`error`in r)throw Error(r.error);return r.next})}catch(e){dl(e instanceof Error?e.message:String(e),r.json);return}r.json?console.log(JSON.stringify({saved:!0,restartRequired:!0})):console.log(` configuration saved; the running agent must be restarted`)});function fl(e,t,n=console.log,r=e=>{process.exitCode=e}){let i=As(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 pl(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??Bs)({requestedStateDir:o.SHELLBELL_DIR,defaultStateDir:t.defaultStateDir??L(P(),`.shellbell`),requiredBackends:a,env:o})}catch{s=[{name:`doctor`,ok:!1,severity:`error`,detail:`diagnostic inspection failed`}]}fl(s,r)})}pl($),qc($);function ml(e,t,n=tn){if(!e)return!1;let r;try{r=n(e)}catch{r=e}let i=gn(t),a;try{a=n(i)}catch{a=i}return a===r}ml(process.argv[1],import.meta.url)&&$.parseAsync().catch(e=>{console.error(e),process.exit(1)});export{a as CONFIG_KEYS,ul as MACOS_SERVICE_PROMPTS,pl as addDoctorCommand,ll as addServiceCommands,ol as buildAgent,rl as chooseConfirm,cl as connectTerminalCommand,ml as isEntryPoint,fl as printDoctorResult,$ as program,ye as resolveConfigSet,al as resolveRelayOverride,il as shutdown,nl as socketAlive,tl as tailFile,we as validateRelayUrl};
53
+ Change any answer later in System Settings → Privacy & Security.`;fd($,()=>new Lt({manager:p(),requestedStateDir:process.env.SHELLBELL_DIR||void 0,defaultStateDir:F(M(),`.shellbell`),env:process.env})),$.command(`logs`).option(`-f, --follow`).description(`show the agent log`).action(e=>{let{p:t}=Qu();e.follow?$t(`tail`,[`-f`,t.log],{stdio:`inherit`}):nn(t.log)&&process.stdout.write(id(t.log,65536,200))});function md(e,t){process.exitCode=2,t?console.log(JSON.stringify({error:e})):console.error(` ${e}`)}$.command(`config`).description(`config set <${o.join(`|`)}> <value>`).argument(`<op>`).argument(`<key>`).argument(`<value>`).action(async(e,t,n)=>{let r=$.opts();if(e!==`set`){md(`unknown config operation ${e} (expected set)`,r.json);return}let i=!!r.insecure||process.env.SHELLBELL_ALLOW_INSECURE_RELAY===`1`,a=De(dt(),t,n,i);if(`error`in a){md(a.error,r.json);return}let o=!1,s=!0;try{let e=ku(),r=Je(e,e=>{let r=De(e,t,n,i);if(`error`in r)throw Error(r.error);return r.next});if(t===`conversations`){let t;try{if(t=await g(e.sock),t.runtime.stateDir===hn(e.dir)){let e=await t.applyConversationSetting(Ae(r));o=e!==null,s=e!==Ae(r)}}catch{}finally{t?.close()}}}catch(e){md(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 hd(e,t,n=console.log,r=e=>{process.exitCode=e}){let i=dl(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 gd(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=>!y.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=y.filter(e=>i.has(e)),o=t.env??process.env,s;try{s=await(t.runDoctor??xl)({requestedStateDir:o.SHELLBELL_DIR,defaultStateDir:t.defaultStateDir??F(M(),`.shellbell`),requiredBackends:a,env:o})}catch{s=[{name:`doctor`,ok:!1,severity:`error`,detail:`diagnostic inspection failed`}]}hd(s,r)})}gd($),Au($);function _d(e,t,n=hn){if(!e)return!1;let r;try{r=n(e)}catch{r=e}let i=jn(t),a;try{a=n(i)}catch{a=i}return a===r}_d(process.argv[1],import.meta.url)&&$.parseAsync().catch(e=>{console.error(e),process.exit(1)});export{o as CONFIG_KEYS,pd as MACOS_SERVICE_PROMPTS,gd as addDoctorCommand,fd as addServiceCommands,ld as buildAgent,od as chooseConfirm,dd as connectTerminalCommand,_d as isEntryPoint,hd as printDoctorResult,$ as program,De as resolveConfigSet,cd as resolveRelayOverride,sd as shutdown,ad as socketAlive,id as tailFile,Ne as validateRelayUrl};