@sma1lboy/rove 0.9.251 → 0.9.252

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.
Files changed (105) hide show
  1. package/dist/cli/{chunk-84bmcqyz.js → chunk-07jq0271.js} +1 -1
  2. package/dist/cli/{chunk-8spmjwwz.js → chunk-0gxa04rx.js} +1 -1
  3. package/dist/cli/{chunk-d99385f2.js → chunk-17pg88dq.js} +2 -2
  4. package/dist/cli/chunk-1qge84t7.js +3 -0
  5. package/dist/cli/{chunk-crdyt04z.js → chunk-1v8y9xtk.js} +1 -1
  6. package/dist/cli/chunk-1zwp3ase.js +2 -0
  7. package/dist/cli/{chunk-8ja7jrhc.js → chunk-24dryfqb.js} +1 -1
  8. package/dist/cli/{chunk-719avf77.js → chunk-25867jnk.js} +1 -1
  9. package/dist/cli/{chunk-28wjmb9f.js → chunk-2bp01vf2.js} +1 -1
  10. package/dist/cli/{chunk-zcwgmz5p.js → chunk-2bxts9pp.js} +1 -1
  11. package/dist/cli/{chunk-dgbcpkr2.js → chunk-2ks86x2d.js} +1 -1
  12. package/dist/cli/{chunk-ga5f2pyc.js → chunk-2n1n70f2.js} +1 -1
  13. package/dist/cli/{chunk-ny12rama.js → chunk-2rfyjb3y.js} +1 -1
  14. package/dist/cli/{chunk-bvqwgrar.js → chunk-2s762g8n.js} +1 -1
  15. package/dist/cli/{chunk-g5rr5fpn.js → chunk-34468esa.js} +1 -1
  16. package/dist/cli/{chunk-g872swb8.js → chunk-36pkmg07.js} +4 -4
  17. package/dist/cli/{chunk-6h0n4b5t.js → chunk-4ays3krf.js} +1 -1
  18. package/dist/cli/{chunk-5456ttpr.js → chunk-4e1wcgw7.js} +3 -3
  19. package/dist/cli/{chunk-mf7fb92r.js → chunk-564jgrb3.js} +1 -1
  20. package/dist/cli/{chunk-mq06xpqr.js → chunk-57wm48dh.js} +1 -1
  21. package/dist/cli/{chunk-mv0hp5cv.js → chunk-5hhr44fc.js} +1 -1
  22. package/dist/cli/chunk-5qxp7xx3.js +2 -0
  23. package/dist/cli/{chunk-nsqsvgry.js → chunk-6a4xqzqf.js} +3 -3
  24. package/dist/cli/{chunk-qxzrdfh7.js → chunk-7h7270rz.js} +3 -3
  25. package/dist/cli/{chunk-76n3d9x3.js → chunk-7zxf47xb.js} +1 -1
  26. package/dist/cli/chunk-8e0nmegv.js +2 -0
  27. package/dist/cli/{chunk-9v568ape.js → chunk-952aedqm.js} +1 -1
  28. package/dist/cli/{chunk-x33sm4rp.js → chunk-9dregrj6.js} +1 -1
  29. package/dist/cli/{chunk-daw4mxq3.js → chunk-9e21z4gn.js} +1 -1
  30. package/dist/cli/chunk-9mcpqrx8.js +2 -0
  31. package/dist/cli/{chunk-7z9yfnjd.js → chunk-9sta3ak4.js} +1 -1
  32. package/dist/cli/chunk-a1wjg2cv.js +3 -0
  33. package/dist/cli/{chunk-v312167r.js → chunk-axmpjma9.js} +1 -1
  34. package/dist/cli/{chunk-963er0h4.js → chunk-ayhkcv0w.js} +3 -3
  35. package/dist/cli/{chunk-e003wm6d.js → chunk-b67pjyyg.js} +1 -1
  36. package/dist/cli/{chunk-2apszxn2.js → chunk-b7xjhgts.js} +1 -1
  37. package/dist/cli/{chunk-regtterm.js → chunk-bhm24ne6.js} +4 -4
  38. package/dist/cli/{chunk-t33z2kdv.js → chunk-c0ksxg3z.js} +1 -1
  39. package/dist/cli/{chunk-mre9g9vq.js → chunk-cbd6y9at.js} +1 -1
  40. package/dist/cli/{chunk-w4cpkhzj.js → chunk-ccn7pq03.js} +1 -1
  41. package/dist/cli/{chunk-mnm9n2vr.js → chunk-cpv1rpc7.js} +1 -1
  42. package/dist/cli/{chunk-8s0mz115.js → chunk-csdttpme.js} +4 -4
  43. package/dist/cli/{chunk-86chrjqr.js → chunk-cvrtapqt.js} +1 -1
  44. package/dist/cli/{chunk-8sbbzs5g.js → chunk-e8pv3b92.js} +1 -1
  45. package/dist/cli/{chunk-q5bhq11t.js → chunk-ebhbtvhd.js} +1 -1
  46. package/dist/cli/{chunk-1exaxwyv.js → chunk-fz0xfw86.js} +1 -1
  47. package/dist/cli/{chunk-4rx3nhvq.js → chunk-h3q3r1py.js} +1 -1
  48. package/dist/cli/{chunk-sqp33pwr.js → chunk-h89ghyex.js} +1 -1
  49. package/dist/cli/{chunk-cp5jp5mq.js → chunk-j6t7xvm3.js} +1 -1
  50. package/dist/cli/{chunk-vwg79maj.js → chunk-jn7vr075.js} +1 -1
  51. package/dist/cli/{chunk-964z8ccb.js → chunk-jnj2kk2h.js} +1 -1
  52. package/dist/cli/{chunk-2pen6b1t.js → chunk-jp31bpgp.js} +1 -1
  53. package/dist/cli/{chunk-ncrr0fa3.js → chunk-jwnhthx9.js} +1 -1
  54. package/dist/cli/{chunk-ayr5dpgc.js → chunk-kda565xs.js} +1 -1
  55. package/dist/cli/{chunk-6ms5chc3.js → chunk-ke3t032y.js} +1 -1
  56. package/dist/cli/{chunk-m4wy9ja5.js → chunk-kqv7t8jk.js} +1 -1
  57. package/dist/cli/chunk-kx0wzjj4.js +2 -0
  58. package/dist/cli/chunk-m2t2n474.js +6 -0
  59. package/dist/cli/{chunk-n52x0ehz.js → chunk-m3bz62v4.js} +1 -1
  60. package/dist/cli/chunk-my20q579.js +3 -0
  61. package/dist/cli/chunk-n2xemv4a.js +2 -0
  62. package/dist/cli/{chunk-v6d6kvmk.js → chunk-n92fz0hn.js} +1 -1
  63. package/dist/cli/{chunk-mdnrrj16.js → chunk-namxa4wy.js} +1 -1
  64. package/dist/cli/chunk-npb9xz3y.js +3 -0
  65. package/dist/cli/{chunk-gp991c3v.js → chunk-nqtvthqg.js} +1 -1
  66. package/dist/cli/{chunk-w7yg0bbz.js → chunk-nz9nmp4v.js} +1 -1
  67. package/dist/cli/{chunk-8ezc1ban.js → chunk-pgmv2hwf.js} +1 -1
  68. package/dist/cli/{chunk-6ahc8w4p.js → chunk-phpt1d3e.js} +1 -1
  69. package/dist/cli/{chunk-6rrzq5et.js → chunk-pj3gnkfr.js} +1 -1
  70. package/dist/cli/{chunk-e1xvz3sv.js → chunk-q2fnt7gm.js} +1 -1
  71. package/dist/cli/{chunk-7vv6160d.js → chunk-qh4y4e27.js} +1 -1
  72. package/dist/cli/{chunk-apfzdw7g.js → chunk-rc8baevh.js} +1 -1
  73. package/dist/cli/{chunk-y5dk90tw.js → chunk-resmnaxq.js} +1 -1
  74. package/dist/cli/{chunk-5r71q63g.js → chunk-rj7fwa30.js} +1 -1
  75. package/dist/cli/{chunk-kb3zvtkj.js → chunk-rxge7bh5.js} +1 -1
  76. package/dist/cli/{chunk-rqpwy31f.js → chunk-sbn5pbz9.js} +1 -1
  77. package/dist/cli/{chunk-mnpewdhd.js → chunk-t3v57v42.js} +2 -2
  78. package/dist/cli/chunk-t5qayy7m.js +9 -0
  79. package/dist/cli/chunk-tfqrc2v1.js +31 -0
  80. package/dist/cli/chunk-trjve2xz.js +3 -0
  81. package/dist/cli/{chunk-jrdwedn2.js → chunk-va0n5rwm.js} +1 -1
  82. package/dist/cli/chunk-va5am5n6.js +2 -0
  83. package/dist/cli/{chunk-rt4tg426.js → chunk-vwpcv7j1.js} +1 -1
  84. package/dist/cli/{chunk-nep425b6.js → chunk-x8pk5cyf.js} +1 -1
  85. package/dist/cli/{chunk-rkgnrfga.js → chunk-yt24rrvx.js} +1 -1
  86. package/dist/cli/{chunk-rhq87p4r.js → chunk-zb5d61xa.js} +1 -1
  87. package/dist/cli/{chunk-jfnr89qj.js → chunk-zzzm2cfx.js} +1 -1
  88. package/dist/cli/index.js +5 -5
  89. package/dist/cli/rove.js +1 -1
  90. package/dist/completions/rove.bash +1 -1
  91. package/dist/completions/rove.fish +1 -1
  92. package/dist/completions/rove.zsh +1 -1
  93. package/package.json +3 -3
  94. package/dist/cli/chunk-2dpr8gps.js +0 -2
  95. package/dist/cli/chunk-3msnqacf.js +0 -2
  96. package/dist/cli/chunk-88czbfqx.js +0 -3
  97. package/dist/cli/chunk-dcjxtwdb.js +0 -7
  98. package/dist/cli/chunk-e1x88j3k.js +0 -3
  99. package/dist/cli/chunk-f7rmd4zk.js +0 -6
  100. package/dist/cli/chunk-fsdh66fa.js +0 -2
  101. package/dist/cli/chunk-h9kzwj14.js +0 -2
  102. package/dist/cli/chunk-k9spgfmx.js +0 -3
  103. package/dist/cli/chunk-nxe45n7k.js +0 -17
  104. package/dist/cli/chunk-q6qhk171.js +0 -2
  105. package/dist/cli/chunk-qft75bkm.js +0 -2
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{embeddedTerminalEnv}from"./chunk-7bgbansg.js";import{ClientWriter,LineReceiver,clearTransientStatuses,createOscSignals,objectPayload,optionalBoolean,requireString,scanOscSignals}from"./chunk-k67vbszb.js";import{FREEZE_RESTORE_MAX_BYTES,FREEZE_TTL_MS,clearFrozenSessions,fileFreezeSink,freezeSession,freshModeTrack,loadFrozenSessions,scanTerminalModes,terminalModePreamble,thawSession}from"./chunk-0y4qgnby.js";import{writeTextAtomic}from"./chunk-5mhvjytn.js";import{installDaemonCrashHandlers,logDaemonError}from"./chunk-rxqdw6s5.js";import{DEFAULT_TERMINAL_COLORS,foldDefaultColorQueries,formatDefaultColorReply,parseTerminalDefaultColors}from"./chunk-4250pw6r.js";import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{recordPtyExit}from"./chunk-w2sp489k.js";import"./chunk-etfh8f4z.js";import{spawnDetachedDaemon,withoutPtyJob}from"./chunk-7j00hbq5.js";import{CURRENT_VERSION}from"./chunk-cp5jp5mq.js";import{listenOnUnixSocket}from"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import{ensureOwnerOnlyStateDir}from"./chunk-yt15y085.js";import{DAEMON_PROTOCOL_VERSION,frameToLine}from"./chunk-s5a5dyab.js";import"./chunk-md094j05.js";import{rotateLogIfNeeded}from"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import{defaultPtyFreezeDir,defaultPtyHostLogPath,defaultPtyHostPidPath,defaultPtyHostSocketPath,isWindowsPipePath,resolveDaemonHomeDir}from"./chunk-npwzmmv9.js";import{preRenameStateDir}from"./chunk-b39sdtt0.js";import{ROVE_STATE_DIR_BASENAME,readRoveHomeDirEnv}from"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";function formatPtyHostLine(event,message,now=new Date){return`[${now.toISOString()}] pty-host [${event}]: ${message}`}import{readFileSync}from"fs";import{mkdir,unlink}from"fs/promises";import{createServer}from"net";import{dirname}from"path";import{existsSync,lstatSync,mkdirSync,renameSync}from"fs";import{homedir}from"os";import{join}from"path";var PTY_HOST_DATA_ENTRIES=["pty-exits.json","pty-sessions"];function lstatIfExists(path){try{return lstatSync(path)}catch{return}}function migrateLegacyPtyHostData(homeDir=readRoveHomeDirEnv()??homedir()){let canonicalDir=join(homeDir,ROVE_STATE_DIR_BASENAME),legacyDir=preRenameStateDir(homeDir);if(canonicalDir===legacyDir)return[];let moved=[];for(let name of PTY_HOST_DATA_ENTRIES){let canonical=join(canonicalDir,name),legacy=join(legacyDir,name);try{if(existsSync(canonical))continue;let stat=lstatIfExists(legacy);if(!stat||stat.isSymbolicLink())continue;mkdirSync(canonicalDir,{recursive:!0}),renameSync(legacy,canonical),moved.push(name)}catch{}}return moved}import{randomUUID as randomUUID2}from"crypto";var TERMINAL_NAME="xterm-256color";function bunTerminalDriver(spawn){let spawnTerminal=spawn??((argv,options)=>Bun.spawn(argv,options));return(request)=>{let proc=spawnTerminal([...request.argv],{cwd:request.cwd,env:request.env,terminal:{cols:request.cols,rows:request.rows,name:TERMINAL_NAME,data:(_terminal,data)=>request.onData(data)}});return{pid:proc.pid,exited:proc.exited.then(()=>({code:proc.exitCode??null,signal:proc.signalCode??null}),()=>({code:null,signal:null})),write:(data)=>proc.terminal?.write(data),resize:(cols,rows)=>proc.terminal?.resize(cols,rows),close:()=>proc.terminal?.close(),kill:(signal)=>proc.kill(signal)}}}import{randomUUID}from"crypto";import{StringDecoder}from"string_decoder";function freshSessionState(key,spec,argv){return{key,generation:randomUUID(),cwd:spec.cwd,proc:null,alive:!0,chunks:[],bytes:0,totalBytes:0,cols:spec.cols??80,rows:spec.rows??24,command:argv,title:"",titleCarry:"",titleDecoder:new StringDecoder("utf8"),colorQueryCarry:"",defaultColors:parseTerminalDefaultColors(spec.defaultColors)??DEFAULT_TERMINAL_COLORS,modes:freshModeTrack(),ringModes:freshModeTrack(),sinks:new Map,emulatorSinks:new Set,parked:!1,parkedScreenBytes:0,exit:null,restored:!1,lastFreezeAtMs:0,frozenTotalBytes:0}}function sessionInfo(s){return{key:s.key,generation:s.generation,alive:s.alive,pid:s.proc?.pid??null,command:s.command,title:s.title,programStatusEvent:s.programStatusEvent,programStatus:s.oscSignals?.records.get(""),contexts:s.oscSignals?.contexts,totalBytes:s.totalBytes,parked:s.parked,parkedScreenBytes:s.parkedScreenBytes,exit:s.exit,restored:s.restored||void 0}}function describeExit(exit){if(exit?.signal)return` (signal ${exit.signal})`;if(exit&&exit.code!==null)return` (code ${exit.code})`;return" (cause unknown)"}function ringTail(chunks,bytes,maxBytes){let skip=Math.max(0,bytes-maxBytes),seen=0,parts=[];for(let chunk of chunks){if(seen+chunk.byteLength>skip)parts.push(seen>=skip?chunk:chunk.subarray(skip-seen));seen+=chunk.byteLength}return Buffer.concat(parts).toString("utf8")}function hostStats(sessions,perSessionCap,parkRestoreDeltas,parkRestoreFallbacks){let ringBytes=0,count=0,parkedSessions=0,parkedScreenBytes=0;for(let session of sessions)if(count++,ringBytes+=session.bytes,session.parked)parkedSessions++,parkedScreenBytes+=session.parkedScreenBytes;return{ringBytes,ringCapacityBytes:count*perSessionCap,parkedSessions,parkedScreenBytes,parkRestoreDeltas,parkRestoreFallbacks}}var OSC_TITLE_RE=/\x1b\][02];([^\x07\x1b]*)(?:\x07|\x1b\\)/g,TITLE_CARRY_CAP=1024;function titleCarryFrom(rest){let osc=rest.lastIndexOf("\x1B]");if(osc!==-1)return rest.slice(osc,osc+TITLE_CARRY_CAP);return rest.endsWith("\x1B")?"\x1B":""}function foldOscTitle(prevCarry,chunkText){let text=prevCarry+chunkText,title=null,end=0;OSC_TITLE_RE.lastIndex=0;for(let match=OSC_TITLE_RE.exec(text);match;match=OSC_TITLE_RE.exec(text))title=match[1]??"",end=match.index+match[0].length;return{title,carry:titleCarryFrom(text.slice(end))}}function scanOscTitle(session,buf){let{title,carry}=foldOscTitle(session.titleCarry,session.titleDecoder.write(buf));if(title!==null)session.title=title;session.titleCarry=carry}function peekRing(session,sinceOffset){if(!session)return{exists:!1,alive:!1,pid:null,offset:0,data:"",sinceValid:!1,exit:null};let windowStart=session.totalBytes-session.bytes,buf=Buffer.concat(session.chunks),sinceValid=!1;if(sinceOffset!==void 0&&sinceOffset>=windowStart&&sinceOffset<=session.totalBytes)buf=buf.subarray(sinceOffset-windowStart),sinceValid=!0;return{exists:!0,alive:session.alive,pid:session.proc?.pid??null,offset:session.totalBytes,data:buf.toString("base64"),sinceValid,exit:session.exit??null}}async function settledWithin(exited,ms){let timer,settled=await Promise.race([exited.then(()=>!0,()=>!0),new Promise((resolve)=>{timer=setTimeout(()=>resolve(!1),ms)})]);if(timer)clearTimeout(timer);return settled}function signalProcessGroup(pid,signal,fallback,platform=process.platform,onSignal){if(platform!=="win32"&&pid>1)try{process.kill(-pid,signal),onSignal?.(`sent ${signal} to process group -${pid}`);return}catch{}try{fallback(),onSignal?.(`sent ${signal} to pid ${pid} (per-process fallback)`)}catch{}}var TERMINATION_GRACE_MS=500;async function terminatePtyChild(proc,onSettled,onSignal){if(proc.endTree){onSignal?.(await proc.endTree()),signalProcessGroup(proc.pid,"SIGKILL",()=>proc.kill("SIGKILL"),process.platform,onSignal),await settledWithin(proc.exited,TERMINATION_GRACE_MS),onSettled();return}if(signalProcessGroup(proc.pid,"SIGTERM",()=>proc.kill("SIGTERM"),process.platform,onSignal),!await settledWithin(proc.exited,TERMINATION_GRACE_MS))signalProcessGroup(proc.pid,"SIGKILL",()=>proc.kill("SIGKILL"),process.platform,onSignal),await settledWithin(proc.exited,TERMINATION_GRACE_MS);onSettled()}class PtyChildController{deps;constructor(deps){this.deps=deps}spawn(key,spec,spare=!1){let argv=spec.command&&spec.command.length>0?[...spec.command]:[spec.shell??resolveLoginShell()],session=freshSessionState(key,spec,argv);if(this.startChild(session),session.alive)this.deps.log?.("pty",`spawned ${argv[0]} for ${key} (pid ${session.proc?.pid})`),this.deps.onSessionStart?.(spare);return session}startChild(session){session.generation=randomUUID2(),session.oscSignals=void 0,session.programStatusEvent=void 0,this.reportStatus(session,null);try{session.proc=(this.deps.driver??bunTerminalDriver())({argv:[...session.command],cwd:session.cwd,env:embeddedTerminalEnv(process.env,{TERM:"xterm-256color",COLUMNS:String(session.cols),LINES:String(session.rows),BASH_SILENCE_DEPRECATION_WARNING:"1",ROVE_TERMINAL_PTY:"1"}),cols:session.cols,rows:session.rows,onData:(data)=>this.onData(session,data)}),session.alive=!0,session.proc.exited.then((exit)=>this.markExited(session,exit),()=>this.markExited(session))}catch(err){session.alive=!1,this.deps.log?.("pty",`spawn failed for ${session.key}: ${err instanceof Error?err.message:String(err)}`)}}async endChild(session){if(!session.alive)return;let proc=session.proc;if(!proc){this.markExited(session);return}await terminatePtyChild(proc,()=>this.markExited(session),(line)=>this.deps.log?.("pty-signal",`${session.key}: ${line}`))}markExited(session,exit){if(!session.alive)return;if(session.alive=!1,session.oscSignals){let before=session.oscSignals.records.get("");if(clearTransientStatuses(session.oscSignals),before!==session.oscSignals.records.get(""))this.reportStatus(session,null)}let sessionExit={code:exit?.code??null,signal:exit?.signal??null,at:new Date().toISOString()};session.exit=sessionExit;try{session.proc?.close()}catch{}this.deps.onExit?.(session,sessionExit)}reportStatus(session,status){let event={key:session.key,generation:session.generation,revision:(session.programStatusEvent?.revision??0)+1,at:Date.now(),status};session.programStatusEvent=event,this.deps.onProgramStatus?.(event)}onData(session,data){let buf=typeof data==="string"?Buffer.from(data,"utf8"):Buffer.from(data),text=buf.toString("latin1");session.oscSignals??=createOscSignals();let queries=scanOscSignals(session.oscSignals,buf,Date.now(),(status)=>this.reportStatus(session,status)),colorQueries=foldDefaultColorQueries(session.colorQueryCarry,text);session.colorQueryCarry=colorQueries.carry;let replies=colorQueries.slots.map((slot)=>formatDefaultColorReply(slot,session.defaultColors));for(let i=0;i<Math.min(queries,16);i++)replies.push("\x1B]7501;?\x1B\\");let modeReplies=scanTerminalModes(session.modes,text);if(session.emulatorSinks.size===0)replies.push(...modeReplies);if(replies.length>0)try{session.proc?.write(replies.join(""))}catch{}scanOscTitle(session,buf),session.chunks.push(buf),session.bytes+=buf.byteLength,session.totalBytes+=buf.byteLength;while(session.bytes>this.deps.scrollbackCap&&session.chunks.length>1){let dropped=session.chunks.shift();if(!dropped)break;session.bytes-=dropped.byteLength,scanTerminalModes(session.ringModes,dropped.toString("latin1"))}this.deps.onOutput?.(session,buf)}}function shouldFreeze(session,now){let appended=session.totalBytes-(session.frozenTotalBytes??0);if(appended<=0)return!1;let since=now-session.lastFreezeAtMs;if(since<5000)return!1;return appended>=65536||since>=60000}class WarmSpare{deps;spare=null;constructor(deps){this.deps=deps}warm(cwd,shell,cols=80,rows=24){let argv0=shell??resolveLoginShell();if(this.spare?.alive&&this.spare.cwd===cwd&&this.spare.command[0]===argv0)return;let old=this.spare;if(this.spare=null,old)this.deps.endChild(old);let session=this.deps.spawn("::spare",{cwd,command:[argv0],cols,rows},!0);this.spare=session.alive?session:null}adopt(key,spec){let spare=this.spare;if(!spare?.alive||spare.cwd!==spec.cwd)return null;let want=spec.command&&spec.command.length>0?spec.command:[spec.shell??resolveLoginShell()];if(want.length!==1||want[0]!==spare.command[0])return null;this.spare=null,spare.key=key,spare.defaultColors=parseTerminalDefaultColors(spec.defaultColors)??spare.defaultColors;let cols=spec.cols??spare.cols,rows=spec.rows??spare.rows;if(spare.cols!==cols||spare.rows!==rows){spare.cols=cols,spare.rows=rows;try{spare.proc?.resize(cols,rows)}catch{return this.deps.markExited(spare),null}}return this.deps.log?.("pty",`adopted warm shell for ${key} (pid ${spare.proc?.pid})`),this.deps.onSessionStart?.(),this.warm(spec.cwd,spare.command[0],cols,rows),spare}async end(){let spare=this.spare;if(this.spare=null,spare)await this.deps.endChild(spare)}}var LOGGED_WRITE_BYTES=1024,DEFAULT_SCROLLBACK_CAP=524288,EXIT_TAIL_BYTES=16384;class PtyHost{sessions=new Map;opts;scrollbackCap;parkRestoreDeltas=0;parkRestoreFallbacks=0;childController;warmSpare;constructor(opts={}){this.opts=opts,this.scrollbackCap=opts.scrollbackCap??DEFAULT_SCROLLBACK_CAP,this.childController=new PtyChildController({driver:opts.driver,onProgramStatus:(event)=>this.opts.onProgramStatus?.(event),scrollbackCap:this.scrollbackCap,onSessionStart:(spare)=>{if(!spare)this.opts.onSessionStart?.()},onOutput:(session,data)=>{if(session.sinks.size===0){this.maybeFreeze(session);return}let frame={type:"event",name:"pty.data",payload:{key:session.key,data:data.toString("base64")}};for(let sink of session.sinks.values())sink(frame);this.maybeFreeze(session)},onExit:(session,exit)=>{let frame={type:"event",name:"pty.exit",payload:{key:session.key,pid:session.proc?.pid??null,...exit}};for(let sink of session.sinks.values())sink(frame);if(this.opts.log?.("pty",`session ${session.key} exited${describeExit(exit)}`),this.maybeFreeze(session,!0),!session.closedByRequest)try{this.opts.onSessionExit?.({key:session.key,pid:session.proc?.pid??null,exit,tail:ringTail(session.chunks,session.bytes,EXIT_TAIL_BYTES)})}catch{}this.opts.onSessionEnd?.()},log:(event,message)=>this.opts.log?.(event,message)}),this.warmSpare=new WarmSpare({spawn:(key,spec,spare)=>this.childController.spawn(key,spec,spare),endChild:(session)=>this.childController.endChild(session),markExited:(session)=>this.childController.markExited(session),log:(event,message)=>this.opts.log?.(event,message),onSessionStart:()=>this.opts.onSessionStart?.()})}open(key,spec,token,sink,sinceOffset,sincePid,answersQueries=!1){let session=this.sessions.get(key),created=!1,respawned=!1;if(!session)created=!0,session=this.warmSpare.adopt(key,spec)??this.childController.spawn(key,spec),this.sessions.set(key,session);else if(!session.alive&&session.restored)this.respawn(session,spec),respawned=session.alive;else if(session.alive&&spec.cols!==void 0&&spec.rows!==void 0&&(session.cols!==spec.cols||session.rows!==spec.rows))this.resize(key,spec.cols,spec.rows);let defaultColors=parseTerminalDefaultColors(spec.defaultColors);if(defaultColors)session.defaultColors=defaultColors;if(session.sinks.set(token,sink),answersQueries)session.emulatorSinks.add(token);else session.emulatorSinks.delete(token);session.parked=!1,session.parkedScreenBytes=0;let windowStart=session.totalBytes-session.bytes,replay=Buffer.concat(session.chunks),sinceValid=!1;if(!created&&sinceOffset!==void 0&&sinceOffset>=windowStart&&sinceOffset<=session.totalBytes&&sincePid!==void 0&&sincePid===session.proc?.pid)replay=replay.subarray(sinceOffset-windowStart),sinceValid=!0;if(sinceOffset!==void 0&&sincePid!==void 0)if(sinceValid)this.parkRestoreDeltas++;else this.parkRestoreFallbacks++;if(!sinceValid)replay=Buffer.concat([Buffer.from(terminalModePreamble(session.ringModes.modes),"latin1"),replay]);return{replay:replay.toString("base64"),alive:session.alive,pid:session.proc?.pid??null,created,respawned,offset:session.totalBytes,sinceValid}}warm(cwd,shell,cols=80,rows=24){this.warmSpare.warm(cwd,shell,cols,rows)}write(key,data){let session=this.sessions.get(key);if(!session?.alive||data.length===0)return;if(data.length>=LOGGED_WRITE_BYTES)this.opts.log?.("pty",`wrote ${data.length} bytes to ${key}`);try{session.proc?.write(data)}catch(error){this.opts.log?.("pty",`write failed on ${key} (${data.length} bytes): ${String(error)}`)}}resize(key,cols,rows){let session=this.sessions.get(key);if(!session?.alive)return;session.cols=cols,session.rows=rows;try{session.proc?.resize(cols,rows)}catch{}}killIfGeneration(key,expectedGeneration){let session=this.sessions.get(key);if(!session)return{accepted:!1,reason:"missing-session"};if(session.generation!==expectedGeneration)return{accepted:!1,reason:"generation-mismatch"};return this.kill(key).catch((err)=>logDaemonError("pty-kill",err)),{accepted:!0}}kill(key){let session=this.sessions.get(key);if(!session)return Promise.resolve();return this.sessions.delete(key),session.closedByRequest=!0,this.opts.freeze?.drop(key),this.childController.endChild(session)}rename(from,to){let session=this.sessions.get(from);if(!session||from===to||this.sessions.has(to))return!1;if(this.sessions.delete(from),session.key=to,session.programStatusEvent){let previous=session.programStatusEvent;this.opts.onProgramStatus?.({...previous,revision:previous.revision+1,at:Date.now(),status:null}),session.programStatusEvent={...previous,key:to,revision:previous.revision+1,at:Date.now()},this.opts.onProgramStatus?.(session.programStatusEvent)}return this.sessions.set(to,session),this.opts.freeze?.drop(from),this.maybeFreeze(session,!0),this.opts.log?.("pty",`renamed session ${from} \u2192 ${to}`),!0}detach(key,token,parked=!1,parkedScreenBytes=0){let session=this.sessions.get(key);if(!session)return;session.sinks.delete(token),session.emulatorSinks.delete(token),this.applyParkedOnDetach(session,parked,parkedScreenBytes)}detachClient(token){for(let session of this.sessions.values()){if(session.emulatorSinks.delete(token),!session.sinks.delete(token))continue;this.applyParkedOnDetach(session)}}applyParkedOnDetach(session,parked=!1,parkedScreenBytes=0){if(session.sinks.size!==0)return;session.parked=parked,session.parkedScreenBytes=parked?Math.max(0,parkedScreenBytes):0}list(){return Array.from(this.sessions.values(),(s)=>sessionInfo(s))}peek(key,sinceOffset){return peekRing(this.sessions.get(key),sinceOffset)}stats(){return hostStats(this.sessions.values(),this.scrollbackCap,this.parkRestoreDeltas,this.parkRestoreFallbacks)}async killAll(){let sessions=Array.from(this.sessions.keys(),(key)=>this.kill(key));sessions.push(this.warmSpare.end()),await Promise.all(sessions)}async shutdown(){this.flushFrozen();let endings=Array.from(this.sessions.values(),(session)=>this.childController.endChild(session));endings.push(this.warmSpare.end()),await Promise.all(endings)}flushFrozen(){for(let session of this.sessions.values())this.maybeFreeze(session,!0)}restoreFrozen(records){let restoredCount=0;for(let record of records){if(this.sessions.has(record.key))continue;let session=thawSession(record,this.scrollbackCap);if(!session)continue;this.sessions.set(record.key,session),restoredCount++}if(restoredCount>0)this.opts.log?.("pty",`restored ${restoredCount} frozen session(s) from disk`);return restoredCount}respawn(session,spec){if(session.restored=!1,session.exit=null,spec.command&&spec.command.length>0)session.command=[...spec.command];if(session.cols=spec.cols??session.cols,session.rows=spec.rows??session.rows,session.defaultColors=parseTerminalDefaultColors(spec.defaultColors)??session.defaultColors,this.childController.startChild(session),!session.alive)return;this.opts.log?.("pty",`respawned restored session ${session.key} (pid ${session.proc?.pid})`),this.opts.onSessionStart?.()}maybeFreeze(session,force=!1){let freeze=this.opts.freeze;if(!freeze||session.key.startsWith("::"))return;if(session.closedByRequest)return;let now=Date.now();if(!force&&!shouldFreeze(session,now))return;session.lastFreezeAtMs=now,session.frozenTotalBytes=session.totalBytes,freeze.save(freezeSession(session))}liveCount(){let n=0;for(let session of this.sessions.values())if(session.alive)n++;return n}}function dispatchPtyRequest(req,client,deps){let{ptys}=deps;switch(req.name){case"hello":return{protocolVersion:DAEMON_PROTOCOL_VERSION,ptyHost:!0,pid:process.pid};case"pty.openChecked":case"pty.open":{let payload=objectPayload(req.payload);if(req.name==="pty.openChecked"&&requireString(payload,"admissionToken")!==admissionToken(ptys))return{kind:"changed"};let open=ptys.open(requireString(payload,"key"),{cwd:requireString(payload,"cwd"),command:Array.isArray(payload.command)?payload.command.filter((c)=>typeof c==="string"):void 0,shell:typeof payload.shell==="string"?payload.shell:void 0,cols:typeof payload.cols==="number"?payload.cols:void 0,rows:typeof payload.rows==="number"?payload.rows:void 0,defaultColors:parseTerminalDefaultColors(payload.defaultColors)??void 0},client,(frame)=>deps.writeFrame(client,frame),typeof payload.sinceOffset==="number"?payload.sinceOffset:void 0,typeof payload.sincePid==="number"?payload.sincePid:void 0,payload.answersQueries===!0);return req.name==="pty.openChecked"?{kind:"opened",open}:open}case"pty.write":{let payload=objectPayload(req.payload);return ptys.write(requireString(payload,"key"),typeof payload.data==="string"?payload.data:""),{}}case"pty.resize":{let payload=objectPayload(req.payload);return ptys.resize(requireString(payload,"key"),typeof payload.cols==="number"?payload.cols:80,typeof payload.rows==="number"?payload.rows:24),{}}case"pty.kill":{let payload=objectPayload(req.payload),key=requireString(payload,"key");if("expectedGeneration"in payload)return ptys.killIfGeneration(key,requireString(payload,"expectedGeneration"));if(optionalBoolean(payload,"wait")===!0)return ptys.kill(key).then(()=>({accepted:!0,ended:!0}),(err)=>{return logDaemonError("pty-kill",err),{accepted:!0,ended:!1}});return ptys.kill(key).catch((err)=>logDaemonError("pty-kill",err)),{accepted:!0}}case"pty.rename":{let payload=objectPayload(req.payload);return{renamed:ptys.rename(requireString(payload,"from"),requireString(payload,"to"))}}case"pty.detach":{let payload=objectPayload(req.payload);ptys.detach(requireString(payload,"key"),client,payload.parked===!0,typeof payload.parkedScreenBytes==="number"?payload.parkedScreenBytes:0)}return{};case"pty.watchStatus":client.watchProgramStatus=!0;for(let session of ptys.list())if(session.programStatusEvent)deps.writeFrame(client,{type:"event",name:"pty.programStatus",payload:session.programStatusEvent});return{supported:!0};case"pty.list":return{pid:process.pid,rssBytes:process.memoryUsage().rss,sessions:ptys.list(),admissionToken:admissionToken(ptys),stats:ptys.stats(),...deps.version?{version:deps.version}:{}};case"pty.peek":{let payload=objectPayload(req.payload);return ptys.peek(requireString(payload,"key"),typeof payload.sinceOffset==="number"?payload.sinceOffset:void 0)}case"pty.warm":{let payload=objectPayload(req.payload);return ptys.warm(requireString(payload,"cwd"),typeof payload.shell==="string"?payload.shell:void 0,typeof payload.cols==="number"?payload.cols:void 0,typeof payload.rows==="number"?payload.rows:void 0),{}}case"spawn.detached":{if(process.platform!=="win32")throw Error("spawn.detached is Windows-only");let payload=objectPayload(req.payload),env=objectPayload(payload.env);return spawnDetachedDaemon(requireString(payload,"command"),Array.isArray(payload.args)?payload.args.filter((a)=>typeof a==="string"):[],withoutPtyJob(Object.fromEntries(Object.entries(env).filter((e)=>typeof e[1]==="string"))),requireString(payload,"logPath")),{}}case"daemon.stop":return deps.requestStop(),{};default:throw Error(`unknown pty-host request: ${req.name}`)}}function admissionToken(ptys){return JSON.stringify(ptys.list().map((s)=>[s.key,s.generation,s.pid,s.alive]))}var DEFAULT_IDLE_EXIT_MS=60000,DEFAULT_ORPHAN_CHECK_MS=30000;function resolveMaxLifetimeMs(){let raw=process.env.ROVE_PTY_MAX_LIFETIME_MS;if(raw===void 0)return null;let n=Number(raw);return Number.isFinite(n)&&n>0?n:null}function resolveIdleExitMs(){let raw=process.env.ROVE_PTY_IDLE_EXIT_MS;if(raw===void 0)return DEFAULT_IDLE_EXIT_MS;let n=Number(raw);return Number.isFinite(n)&&n>=0?n:DEFAULT_IDLE_EXIT_MS}async function startPtyHostServer(options={}){migrateLegacyPtyHostData();let socketPath=options.socketPath??defaultPtyHostSocketPath(),pidPath=options.pidPath??defaultPtyHostPidPath(),freezeDir=options.freezeDir??defaultPtyFreezeDir(),idleExitMs=options.idleExitMs||resolveIdleExitMs(),orphanCheckMs=options.orphanCheckMs||DEFAULT_ORPHAN_CHECK_MS,maxLifetimeMs=options.maxLifetimeMs??resolveMaxLifetimeMs(),bootedAtMs=Date.now(),log=options.log??(()=>{}),clients=new Set,stopping=!1,wipeFreezeOnStop=!1,idleTimer=null,cancelIdle=()=>{if(idleTimer)clearTimeout(idleTimer);idleTimer=null},armIdle=()=>{if(stopping)return;cancelIdle(),idleTimer=setTimeout(()=>{if(stopping||ptys.liveCount()>0)return;log("idle",`no live sessions for ${idleExitMs}ms \u2014 exiting`),stop()},idleExitMs)},orphaned=()=>{if(maxLifetimeMs!==null&&Date.now()-bootedAtMs>=maxLifetimeMs)return`exceeded its ${maxLifetimeMs}ms lifetime ceiling`;let owner;try{owner=readFileSync(pidPath,"utf8").trim()}catch{return`pidfile ${pidPath} is gone`}let pid=Number.parseInt(owner,10);if(pid===process.pid)return null;return Number.isInteger(pid)?`pidfile ${pidPath} now names pid ${pid}`:`pidfile ${pidPath} is unreadable`},orphanTimer=setInterval(()=>{if(stopping)return;let reason=orphaned();if(!reason)return;log("orphan",`${reason} \u2014 exiting rather than outliving my owner`),stop()},orphanCheckMs);orphanTimer.unref?.();let ptys=new PtyHost({onProgramStatus:(event)=>{for(let client of clients)if(client.watchProgramStatus)writeFrame(client,{type:"event",name:"pty.programStatus",payload:event})},onSessionStart:cancelIdle,onSessionEnd:()=>{if(ptys.liveCount()===0)armIdle()},onSessionExit:(info)=>{try{recordPtyExit(info)}catch(err){log("pty",`exit record write failed for ${info.key}: ${err instanceof Error?err.message:String(err)}`)}},freeze:fileFreezeSink(freezeDir),driver:options.driver,log});ptys.restoreFrozen(loadFrozenSessions(freezeDir,Date.now(),(s)=>{let mib=(bytes)=>`${Math.round(bytes/1048576)}MB`,notes=[`restored ${s.restored} (${mib(s.bytesRead)})`];if(s.deferred>0)notes.push(`${s.deferred} left unread past the ${mib(FREEZE_RESTORE_MAX_BYTES)} budget`);if(s.expired>0)notes.push(`${s.expired} deleted past the ${FREEZE_TTL_MS/86400000}-day TTL`);if(s.unreadable>0)notes.push(`${s.unreadable} unreadable`);log("freeze",notes.join(", "))}));let pipeSocket=isWindowsPipePath(socketPath);if(await ensureOwnerOnlyStateDir(resolveDaemonHomeDir()),!pipeSocket)await mkdir(dirname(socketPath),{recursive:!0});await mkdir(dirname(pidPath),{recursive:!0});let server=createServer((socket)=>{let client={socket,writer:new ClientWriter(socket,{onOverflow:()=>{log("backpressure","disconnecting PTY client whose critical queue exceeded 8MiB"),socket.destroy()}})};clients.add(client);let receiver=new LineReceiver;socket.on("data",(chunk)=>{if(!receiver.push(chunk,(line)=>handleLine(client,line)))log("framing","disconnecting PTY client whose request exceeded 8MiB"),socket.destroy()}),socket.on("error",()=>{}),socket.on("close",()=>{clients.delete(client),ptys.detachClient(client)})}),api={socketPath,pidPath,async close(){if(stopping)return;if(stopping=!0,cancelIdle(),clearInterval(orphanTimer),await ptys.shutdown(),wipeFreezeOnStop)clearFrozenSessions(freezeDir);for(let client of Array.from(clients))client.socket.destroy();if(await new Promise((resolve)=>server.close(()=>resolve())),!pipeSocket)await unlink(socketPath).catch(()=>{});await unlink(pidPath).catch(()=>{})}};async function stop(){await api.close().catch((err)=>logDaemonError("pty-host-shutdown",err)),options.onStop?.()}let verbDeps={ptys,writeFrame,requestStop:()=>{wipeFreezeOnStop=!0,setTimeout(()=>void stop(),0).unref()},...options.version?{version:options.version}:{}};function handleLine(client,line){if(line.trim().length>0){let frame=null;try{frame=JSON.parse(line)}catch{writeFrame(client,{type:"response",id:"parse-error",error:{message:"malformed frame"}})}if(frame)if(frame.type!=="request")writeFrame(client,{type:"response",id:"parse-error",error:{message:"requests only"}});else{let req=frame,reply=(payload)=>writeFrame(client,{type:"response",id:req.id,name:req.name,payload}),fail=(err)=>writeFrame(client,{type:"response",id:req.id,name:req.name,error:{message:err instanceof Error?err.message:String(err)}});try{let payload=dispatchPtyRequest(req,client,verbDeps);if(payload instanceof Promise)payload.then(reply,fail);else reply(payload)}catch(err){fail(err)}}}}return await listenOnUnixSocket(server,socketPath),await writeTextAtomic(pidPath,`${process.pid}
2
+ import{embeddedTerminalEnv}from"./chunk-7bgbansg.js";import{FREEZE_RESTORE_MAX_BYTES,FREEZE_TTL_MS,clearFrozenSessions,fileFreezeSink,freezeSession,freshModeTrack,loadFrozenSessions,scanTerminalModes,terminalModePreamble,thawSession}from"./chunk-0y4qgnby.js";import{ClientWriter,LineReceiver,clearTransientStatuses,createOscSignals,objectPayload,optionalBoolean,requireString,scanOscSignals}from"./chunk-k67vbszb.js";import{writeTextAtomic}from"./chunk-5mhvjytn.js";import{DEFAULT_TERMINAL_COLORS,foldDefaultColorQueries,formatDefaultColorReply,parseTerminalDefaultColors}from"./chunk-4250pw6r.js";import{installDaemonCrashHandlers,logDaemonError}from"./chunk-rxqdw6s5.js";import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{recordPtyExit}from"./chunk-w2sp489k.js";import"./chunk-etfh8f4z.js";import{spawnDetachedDaemon,withoutPtyJob}from"./chunk-7j00hbq5.js";import{CURRENT_VERSION}from"./chunk-j6t7xvm3.js";import{listenOnUnixSocket}from"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import{ensureOwnerOnlyStateDir}from"./chunk-yt15y085.js";import{DAEMON_PROTOCOL_VERSION,frameToLine}from"./chunk-s5a5dyab.js";import"./chunk-md094j05.js";import{rotateLogIfNeeded}from"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import{defaultPtyFreezeDir,defaultPtyHostLogPath,defaultPtyHostPidPath,defaultPtyHostSocketPath,isWindowsPipePath,resolveDaemonHomeDir}from"./chunk-npwzmmv9.js";import{preRenameStateDir}from"./chunk-b39sdtt0.js";import{ROVE_STATE_DIR_BASENAME,readRoveHomeDirEnv}from"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";function formatPtyHostLine(event,message,now=new Date){return`[${now.toISOString()}] pty-host [${event}]: ${message}`}import{readFileSync}from"fs";import{mkdir,unlink}from"fs/promises";import{createServer}from"net";import{dirname}from"path";import{existsSync,lstatSync,mkdirSync,renameSync}from"fs";import{homedir}from"os";import{join}from"path";var PTY_HOST_DATA_ENTRIES=["pty-exits.json","pty-sessions"];function lstatIfExists(path){try{return lstatSync(path)}catch{return}}function migrateLegacyPtyHostData(homeDir=readRoveHomeDirEnv()??homedir()){let canonicalDir=join(homeDir,ROVE_STATE_DIR_BASENAME),legacyDir=preRenameStateDir(homeDir);if(canonicalDir===legacyDir)return[];let moved=[];for(let name of PTY_HOST_DATA_ENTRIES){let canonical=join(canonicalDir,name),legacy=join(legacyDir,name);try{if(existsSync(canonical))continue;let stat=lstatIfExists(legacy);if(!stat||stat.isSymbolicLink())continue;mkdirSync(canonicalDir,{recursive:!0}),renameSync(legacy,canonical),moved.push(name)}catch{}}return moved}import{randomUUID as randomUUID2}from"crypto";var TERMINAL_NAME="xterm-256color";function bunTerminalDriver(spawn){let spawnTerminal=spawn??((argv,options)=>Bun.spawn(argv,options));return(request)=>{let proc=spawnTerminal([...request.argv],{cwd:request.cwd,env:request.env,terminal:{cols:request.cols,rows:request.rows,name:TERMINAL_NAME,data:(_terminal,data)=>request.onData(data)}});return{pid:proc.pid,exited:proc.exited.then(()=>({code:proc.exitCode??null,signal:proc.signalCode??null}),()=>({code:null,signal:null})),write:(data)=>proc.terminal?.write(data),resize:(cols,rows)=>proc.terminal?.resize(cols,rows),close:()=>proc.terminal?.close(),kill:(signal)=>proc.kill(signal)}}}import{randomUUID}from"crypto";import{StringDecoder}from"string_decoder";function freshSessionState(key,spec,argv){return{key,generation:randomUUID(),cwd:spec.cwd,proc:null,alive:!0,chunks:[],bytes:0,totalBytes:0,cols:spec.cols??80,rows:spec.rows??24,command:argv,title:"",titleCarry:"",titleDecoder:new StringDecoder("utf8"),colorQueryCarry:"",defaultColors:parseTerminalDefaultColors(spec.defaultColors)??DEFAULT_TERMINAL_COLORS,modes:freshModeTrack(),ringModes:freshModeTrack(),sinks:new Map,emulatorSinks:new Set,parked:!1,parkedScreenBytes:0,exit:null,restored:!1,lastFreezeAtMs:0,frozenTotalBytes:0}}function sessionInfo(s){return{key:s.key,generation:s.generation,alive:s.alive,pid:s.proc?.pid??null,command:s.command,title:s.title,programStatusEvent:s.programStatusEvent,programStatus:s.oscSignals?.records.get(""),contexts:s.oscSignals?.contexts,totalBytes:s.totalBytes,parked:s.parked,parkedScreenBytes:s.parkedScreenBytes,exit:s.exit,restored:s.restored||void 0}}function describeExit(exit){if(exit?.signal)return` (signal ${exit.signal})`;if(exit&&exit.code!==null)return` (code ${exit.code})`;return" (cause unknown)"}function ringTail(chunks,bytes,maxBytes){let skip=Math.max(0,bytes-maxBytes),seen=0,parts=[];for(let chunk of chunks){if(seen+chunk.byteLength>skip)parts.push(seen>=skip?chunk:chunk.subarray(skip-seen));seen+=chunk.byteLength}return Buffer.concat(parts).toString("utf8")}function hostStats(sessions,perSessionCap,parkRestoreDeltas,parkRestoreFallbacks){let ringBytes=0,count=0,parkedSessions=0,parkedScreenBytes=0;for(let session of sessions)if(count++,ringBytes+=session.bytes,session.parked)parkedSessions++,parkedScreenBytes+=session.parkedScreenBytes;return{ringBytes,ringCapacityBytes:count*perSessionCap,parkedSessions,parkedScreenBytes,parkRestoreDeltas,parkRestoreFallbacks}}var OSC_TITLE_RE=/\x1b\][02];([^\x07\x1b]*)(?:\x07|\x1b\\)/g,TITLE_CARRY_CAP=1024;function titleCarryFrom(rest){let osc=rest.lastIndexOf("\x1B]");if(osc!==-1)return rest.slice(osc,osc+TITLE_CARRY_CAP);return rest.endsWith("\x1B")?"\x1B":""}function foldOscTitle(prevCarry,chunkText){let text=prevCarry+chunkText,title=null,end=0;OSC_TITLE_RE.lastIndex=0;for(let match=OSC_TITLE_RE.exec(text);match;match=OSC_TITLE_RE.exec(text))title=match[1]??"",end=match.index+match[0].length;return{title,carry:titleCarryFrom(text.slice(end))}}function scanOscTitle(session,buf){let{title,carry}=foldOscTitle(session.titleCarry,session.titleDecoder.write(buf));if(title!==null)session.title=title;session.titleCarry=carry}function peekRing(session,sinceOffset){if(!session)return{exists:!1,alive:!1,pid:null,offset:0,data:"",sinceValid:!1,exit:null};let windowStart=session.totalBytes-session.bytes,buf=Buffer.concat(session.chunks),sinceValid=!1;if(sinceOffset!==void 0&&sinceOffset>=windowStart&&sinceOffset<=session.totalBytes)buf=buf.subarray(sinceOffset-windowStart),sinceValid=!0;return{exists:!0,alive:session.alive,pid:session.proc?.pid??null,offset:session.totalBytes,data:buf.toString("base64"),sinceValid,exit:session.exit??null}}async function settledWithin(exited,ms){let timer,settled=await Promise.race([exited.then(()=>!0,()=>!0),new Promise((resolve)=>{timer=setTimeout(()=>resolve(!1),ms)})]);if(timer)clearTimeout(timer);return settled}function signalProcessGroup(pid,signal,fallback,platform=process.platform,onSignal){if(platform!=="win32"&&pid>1)try{process.kill(-pid,signal),onSignal?.(`sent ${signal} to process group -${pid}`);return}catch{}try{fallback(),onSignal?.(`sent ${signal} to pid ${pid} (per-process fallback)`)}catch{}}var TERMINATION_GRACE_MS=500;async function terminatePtyChild(proc,onSettled,onSignal){if(proc.endTree){onSignal?.(await proc.endTree()),signalProcessGroup(proc.pid,"SIGKILL",()=>proc.kill("SIGKILL"),process.platform,onSignal),await settledWithin(proc.exited,TERMINATION_GRACE_MS),onSettled();return}if(signalProcessGroup(proc.pid,"SIGTERM",()=>proc.kill("SIGTERM"),process.platform,onSignal),!await settledWithin(proc.exited,TERMINATION_GRACE_MS))signalProcessGroup(proc.pid,"SIGKILL",()=>proc.kill("SIGKILL"),process.platform,onSignal),await settledWithin(proc.exited,TERMINATION_GRACE_MS);onSettled()}class PtyChildController{deps;constructor(deps){this.deps=deps}spawn(key,spec,spare=!1){let argv=spec.command&&spec.command.length>0?[...spec.command]:[spec.shell??resolveLoginShell()],session=freshSessionState(key,spec,argv);if(this.startChild(session),session.alive)this.deps.log?.("pty",`spawned ${argv[0]} for ${key} (pid ${session.proc?.pid})`),this.deps.onSessionStart?.(spare);return session}startChild(session){session.generation=randomUUID2(),session.oscSignals=void 0,session.programStatusEvent=void 0,this.reportStatus(session,null);try{session.proc=(this.deps.driver??bunTerminalDriver())({argv:[...session.command],cwd:session.cwd,env:embeddedTerminalEnv(process.env,{TERM:"xterm-256color",COLUMNS:String(session.cols),LINES:String(session.rows),BASH_SILENCE_DEPRECATION_WARNING:"1",ROVE_TERMINAL_PTY:"1"}),cols:session.cols,rows:session.rows,onData:(data)=>this.onData(session,data)}),session.alive=!0,session.proc.exited.then((exit)=>this.markExited(session,exit),()=>this.markExited(session))}catch(err){session.alive=!1,this.deps.log?.("pty",`spawn failed for ${session.key}: ${err instanceof Error?err.message:String(err)}`)}}async endChild(session){if(!session.alive)return;let proc=session.proc;if(!proc){this.markExited(session);return}await terminatePtyChild(proc,()=>this.markExited(session),(line)=>this.deps.log?.("pty-signal",`${session.key}: ${line}`))}markExited(session,exit){if(!session.alive)return;if(session.alive=!1,session.oscSignals){let before=session.oscSignals.records.get("");if(clearTransientStatuses(session.oscSignals),before!==session.oscSignals.records.get(""))this.reportStatus(session,null)}let sessionExit={code:exit?.code??null,signal:exit?.signal??null,at:new Date().toISOString()};session.exit=sessionExit;try{session.proc?.close()}catch{}this.deps.onExit?.(session,sessionExit)}reportStatus(session,status){let event={key:session.key,generation:session.generation,revision:(session.programStatusEvent?.revision??0)+1,at:Date.now(),status};session.programStatusEvent=event,this.deps.onProgramStatus?.(event)}onData(session,data){let buf=typeof data==="string"?Buffer.from(data,"utf8"):Buffer.from(data),text=buf.toString("latin1");session.oscSignals??=createOscSignals();let queries=scanOscSignals(session.oscSignals,buf,Date.now(),(status)=>this.reportStatus(session,status)),colorQueries=foldDefaultColorQueries(session.colorQueryCarry,text);session.colorQueryCarry=colorQueries.carry;let replies=colorQueries.slots.map((slot)=>formatDefaultColorReply(slot,session.defaultColors));for(let i=0;i<Math.min(queries,16);i++)replies.push("\x1B]7501;?\x1B\\");let modeReplies=scanTerminalModes(session.modes,text);if(session.emulatorSinks.size===0)replies.push(...modeReplies);if(replies.length>0)try{session.proc?.write(replies.join(""))}catch{}scanOscTitle(session,buf),session.chunks.push(buf),session.bytes+=buf.byteLength,session.totalBytes+=buf.byteLength;while(session.bytes>this.deps.scrollbackCap&&session.chunks.length>1){let dropped=session.chunks.shift();if(!dropped)break;session.bytes-=dropped.byteLength,scanTerminalModes(session.ringModes,dropped.toString("latin1"))}this.deps.onOutput?.(session,buf)}}function shouldFreeze(session,now){let appended=session.totalBytes-(session.frozenTotalBytes??0);if(appended<=0)return!1;let since=now-session.lastFreezeAtMs;if(since<5000)return!1;return appended>=65536||since>=60000}class WarmSpare{deps;spare=null;constructor(deps){this.deps=deps}warm(cwd,shell,cols=80,rows=24){let argv0=shell??resolveLoginShell();if(this.spare?.alive&&this.spare.cwd===cwd&&this.spare.command[0]===argv0)return;let old=this.spare;if(this.spare=null,old)this.deps.endChild(old);let session=this.deps.spawn("::spare",{cwd,command:[argv0],cols,rows},!0);this.spare=session.alive?session:null}adopt(key,spec){let spare=this.spare;if(!spare?.alive||spare.cwd!==spec.cwd)return null;let want=spec.command&&spec.command.length>0?spec.command:[spec.shell??resolveLoginShell()];if(want.length!==1||want[0]!==spare.command[0])return null;this.spare=null,spare.key=key,spare.defaultColors=parseTerminalDefaultColors(spec.defaultColors)??spare.defaultColors;let cols=spec.cols??spare.cols,rows=spec.rows??spare.rows;if(spare.cols!==cols||spare.rows!==rows){spare.cols=cols,spare.rows=rows;try{spare.proc?.resize(cols,rows)}catch{return this.deps.markExited(spare),null}}return this.deps.log?.("pty",`adopted warm shell for ${key} (pid ${spare.proc?.pid})`),this.deps.onSessionStart?.(),this.warm(spec.cwd,spare.command[0],cols,rows),spare}async end(){let spare=this.spare;if(this.spare=null,spare)await this.deps.endChild(spare)}}var LOGGED_WRITE_BYTES=1024,DEFAULT_SCROLLBACK_CAP=524288,EXIT_TAIL_BYTES=16384;class PtyHost{sessions=new Map;opts;scrollbackCap;parkRestoreDeltas=0;parkRestoreFallbacks=0;childController;warmSpare;constructor(opts={}){this.opts=opts,this.scrollbackCap=opts.scrollbackCap??DEFAULT_SCROLLBACK_CAP,this.childController=new PtyChildController({driver:opts.driver,onProgramStatus:(event)=>this.opts.onProgramStatus?.(event),scrollbackCap:this.scrollbackCap,onSessionStart:(spare)=>{if(!spare)this.opts.onSessionStart?.()},onOutput:(session,data)=>{if(session.sinks.size===0){this.maybeFreeze(session);return}let frame={type:"event",name:"pty.data",payload:{key:session.key,data:data.toString("base64")}};for(let sink of session.sinks.values())sink(frame);this.maybeFreeze(session)},onExit:(session,exit)=>{let frame={type:"event",name:"pty.exit",payload:{key:session.key,pid:session.proc?.pid??null,...exit}};for(let sink of session.sinks.values())sink(frame);if(this.opts.log?.("pty",`session ${session.key} exited${describeExit(exit)}`),this.maybeFreeze(session,!0),!session.closedByRequest)try{this.opts.onSessionExit?.({key:session.key,pid:session.proc?.pid??null,exit,tail:ringTail(session.chunks,session.bytes,EXIT_TAIL_BYTES)})}catch{}this.opts.onSessionEnd?.()},log:(event,message)=>this.opts.log?.(event,message)}),this.warmSpare=new WarmSpare({spawn:(key,spec,spare)=>this.childController.spawn(key,spec,spare),endChild:(session)=>this.childController.endChild(session),markExited:(session)=>this.childController.markExited(session),log:(event,message)=>this.opts.log?.(event,message),onSessionStart:()=>this.opts.onSessionStart?.()})}open(key,spec,token,sink,sinceOffset,sincePid,answersQueries=!1){let session=this.sessions.get(key),created=!1,respawned=!1;if(!session)created=!0,session=this.warmSpare.adopt(key,spec)??this.childController.spawn(key,spec),this.sessions.set(key,session);else if(!session.alive&&session.restored)this.respawn(session,spec),respawned=session.alive;else if(session.alive&&spec.cols!==void 0&&spec.rows!==void 0&&(session.cols!==spec.cols||session.rows!==spec.rows))this.resize(key,spec.cols,spec.rows);let defaultColors=parseTerminalDefaultColors(spec.defaultColors);if(defaultColors)session.defaultColors=defaultColors;if(session.sinks.set(token,sink),answersQueries)session.emulatorSinks.add(token);else session.emulatorSinks.delete(token);session.parked=!1,session.parkedScreenBytes=0;let windowStart=session.totalBytes-session.bytes,replay=Buffer.concat(session.chunks),sinceValid=!1;if(!created&&sinceOffset!==void 0&&sinceOffset>=windowStart&&sinceOffset<=session.totalBytes&&sincePid!==void 0&&sincePid===session.proc?.pid)replay=replay.subarray(sinceOffset-windowStart),sinceValid=!0;if(sinceOffset!==void 0&&sincePid!==void 0)if(sinceValid)this.parkRestoreDeltas++;else this.parkRestoreFallbacks++;if(!sinceValid)replay=Buffer.concat([Buffer.from(terminalModePreamble(session.ringModes.modes),"latin1"),replay]);return{replay:replay.toString("base64"),alive:session.alive,pid:session.proc?.pid??null,created,respawned,offset:session.totalBytes,sinceValid}}warm(cwd,shell,cols=80,rows=24){this.warmSpare.warm(cwd,shell,cols,rows)}write(key,data){let session=this.sessions.get(key);if(!session?.alive||data.length===0)return;if(data.length>=LOGGED_WRITE_BYTES)this.opts.log?.("pty",`wrote ${data.length} bytes to ${key}`);try{session.proc?.write(data)}catch(error){this.opts.log?.("pty",`write failed on ${key} (${data.length} bytes): ${String(error)}`)}}resize(key,cols,rows){let session=this.sessions.get(key);if(!session?.alive)return;session.cols=cols,session.rows=rows;try{session.proc?.resize(cols,rows)}catch{}}killIfGeneration(key,expectedGeneration){let session=this.sessions.get(key);if(!session)return{accepted:!1,reason:"missing-session"};if(session.generation!==expectedGeneration)return{accepted:!1,reason:"generation-mismatch"};return this.kill(key).catch((err)=>logDaemonError("pty-kill",err)),{accepted:!0}}kill(key){let session=this.sessions.get(key);if(!session)return Promise.resolve();return this.sessions.delete(key),session.closedByRequest=!0,this.opts.freeze?.drop(key),this.childController.endChild(session)}rename(from,to){let session=this.sessions.get(from);if(!session||from===to||this.sessions.has(to))return!1;if(this.sessions.delete(from),session.key=to,session.programStatusEvent){let previous=session.programStatusEvent;this.opts.onProgramStatus?.({...previous,revision:previous.revision+1,at:Date.now(),status:null}),session.programStatusEvent={...previous,key:to,revision:previous.revision+1,at:Date.now()},this.opts.onProgramStatus?.(session.programStatusEvent)}return this.sessions.set(to,session),this.opts.freeze?.drop(from),this.maybeFreeze(session,!0),this.opts.log?.("pty",`renamed session ${from} \u2192 ${to}`),!0}detach(key,token,parked=!1,parkedScreenBytes=0){let session=this.sessions.get(key);if(!session)return;session.sinks.delete(token),session.emulatorSinks.delete(token),this.applyParkedOnDetach(session,parked,parkedScreenBytes)}detachClient(token){for(let session of this.sessions.values()){if(session.emulatorSinks.delete(token),!session.sinks.delete(token))continue;this.applyParkedOnDetach(session)}}applyParkedOnDetach(session,parked=!1,parkedScreenBytes=0){if(session.sinks.size!==0)return;session.parked=parked,session.parkedScreenBytes=parked?Math.max(0,parkedScreenBytes):0}list(){return Array.from(this.sessions.values(),(s)=>sessionInfo(s))}peek(key,sinceOffset){return peekRing(this.sessions.get(key),sinceOffset)}stats(){return hostStats(this.sessions.values(),this.scrollbackCap,this.parkRestoreDeltas,this.parkRestoreFallbacks)}async killAll(){let sessions=Array.from(this.sessions.keys(),(key)=>this.kill(key));sessions.push(this.warmSpare.end()),await Promise.all(sessions)}async shutdown(){this.flushFrozen();let endings=Array.from(this.sessions.values(),(session)=>this.childController.endChild(session));endings.push(this.warmSpare.end()),await Promise.all(endings)}flushFrozen(){for(let session of this.sessions.values())this.maybeFreeze(session,!0)}restoreFrozen(records){let restoredCount=0;for(let record of records){if(this.sessions.has(record.key))continue;let session=thawSession(record,this.scrollbackCap);if(!session)continue;this.sessions.set(record.key,session),restoredCount++}if(restoredCount>0)this.opts.log?.("pty",`restored ${restoredCount} frozen session(s) from disk`);return restoredCount}respawn(session,spec){if(session.restored=!1,session.exit=null,spec.command&&spec.command.length>0)session.command=[...spec.command];if(session.cols=spec.cols??session.cols,session.rows=spec.rows??session.rows,session.defaultColors=parseTerminalDefaultColors(spec.defaultColors)??session.defaultColors,this.childController.startChild(session),!session.alive)return;this.opts.log?.("pty",`respawned restored session ${session.key} (pid ${session.proc?.pid})`),this.opts.onSessionStart?.()}maybeFreeze(session,force=!1){let freeze=this.opts.freeze;if(!freeze||session.key.startsWith("::"))return;if(session.closedByRequest)return;let now=Date.now();if(!force&&!shouldFreeze(session,now))return;session.lastFreezeAtMs=now,session.frozenTotalBytes=session.totalBytes,freeze.save(freezeSession(session))}liveCount(){let n=0;for(let session of this.sessions.values())if(session.alive)n++;return n}}function dispatchPtyRequest(req,client,deps){let{ptys}=deps;switch(req.name){case"hello":return{protocolVersion:DAEMON_PROTOCOL_VERSION,ptyHost:!0,pid:process.pid};case"pty.openChecked":case"pty.open":{let payload=objectPayload(req.payload);if(req.name==="pty.openChecked"&&requireString(payload,"admissionToken")!==admissionToken(ptys))return{kind:"changed"};let open=ptys.open(requireString(payload,"key"),{cwd:requireString(payload,"cwd"),command:Array.isArray(payload.command)?payload.command.filter((c)=>typeof c==="string"):void 0,shell:typeof payload.shell==="string"?payload.shell:void 0,cols:typeof payload.cols==="number"?payload.cols:void 0,rows:typeof payload.rows==="number"?payload.rows:void 0,defaultColors:parseTerminalDefaultColors(payload.defaultColors)??void 0},client,(frame)=>deps.writeFrame(client,frame),typeof payload.sinceOffset==="number"?payload.sinceOffset:void 0,typeof payload.sincePid==="number"?payload.sincePid:void 0,payload.answersQueries===!0);return req.name==="pty.openChecked"?{kind:"opened",open}:open}case"pty.write":{let payload=objectPayload(req.payload);return ptys.write(requireString(payload,"key"),typeof payload.data==="string"?payload.data:""),{}}case"pty.resize":{let payload=objectPayload(req.payload);return ptys.resize(requireString(payload,"key"),typeof payload.cols==="number"?payload.cols:80,typeof payload.rows==="number"?payload.rows:24),{}}case"pty.kill":{let payload=objectPayload(req.payload),key=requireString(payload,"key");if("expectedGeneration"in payload)return ptys.killIfGeneration(key,requireString(payload,"expectedGeneration"));if(optionalBoolean(payload,"wait")===!0)return ptys.kill(key).then(()=>({accepted:!0,ended:!0}),(err)=>{return logDaemonError("pty-kill",err),{accepted:!0,ended:!1}});return ptys.kill(key).catch((err)=>logDaemonError("pty-kill",err)),{accepted:!0}}case"pty.rename":{let payload=objectPayload(req.payload);return{renamed:ptys.rename(requireString(payload,"from"),requireString(payload,"to"))}}case"pty.detach":{let payload=objectPayload(req.payload);ptys.detach(requireString(payload,"key"),client,payload.parked===!0,typeof payload.parkedScreenBytes==="number"?payload.parkedScreenBytes:0)}return{};case"pty.watchStatus":client.watchProgramStatus=!0;for(let session of ptys.list())if(session.programStatusEvent)deps.writeFrame(client,{type:"event",name:"pty.programStatus",payload:session.programStatusEvent});return{supported:!0};case"pty.list":return{pid:process.pid,rssBytes:process.memoryUsage().rss,sessions:ptys.list(),admissionToken:admissionToken(ptys),stats:ptys.stats(),...deps.version?{version:deps.version}:{}};case"pty.peek":{let payload=objectPayload(req.payload);return ptys.peek(requireString(payload,"key"),typeof payload.sinceOffset==="number"?payload.sinceOffset:void 0)}case"pty.warm":{let payload=objectPayload(req.payload);return ptys.warm(requireString(payload,"cwd"),typeof payload.shell==="string"?payload.shell:void 0,typeof payload.cols==="number"?payload.cols:void 0,typeof payload.rows==="number"?payload.rows:void 0),{}}case"spawn.detached":{if(process.platform!=="win32")throw Error("spawn.detached is Windows-only");let payload=objectPayload(req.payload),env=objectPayload(payload.env);return spawnDetachedDaemon(requireString(payload,"command"),Array.isArray(payload.args)?payload.args.filter((a)=>typeof a==="string"):[],withoutPtyJob(Object.fromEntries(Object.entries(env).filter((e)=>typeof e[1]==="string"))),requireString(payload,"logPath")),{}}case"daemon.stop":return deps.requestStop(),{};default:throw Error(`unknown pty-host request: ${req.name}`)}}function admissionToken(ptys){return JSON.stringify(ptys.list().map((s)=>[s.key,s.generation,s.pid,s.alive]))}var DEFAULT_IDLE_EXIT_MS=60000,DEFAULT_ORPHAN_CHECK_MS=30000;function resolveMaxLifetimeMs(){let raw=process.env.ROVE_PTY_MAX_LIFETIME_MS;if(raw===void 0)return null;let n=Number(raw);return Number.isFinite(n)&&n>0?n:null}function resolveIdleExitMs(){let raw=process.env.ROVE_PTY_IDLE_EXIT_MS;if(raw===void 0)return DEFAULT_IDLE_EXIT_MS;let n=Number(raw);return Number.isFinite(n)&&n>=0?n:DEFAULT_IDLE_EXIT_MS}async function startPtyHostServer(options={}){migrateLegacyPtyHostData();let socketPath=options.socketPath??defaultPtyHostSocketPath(),pidPath=options.pidPath??defaultPtyHostPidPath(),freezeDir=options.freezeDir??defaultPtyFreezeDir(),idleExitMs=options.idleExitMs||resolveIdleExitMs(),orphanCheckMs=options.orphanCheckMs||DEFAULT_ORPHAN_CHECK_MS,maxLifetimeMs=options.maxLifetimeMs??resolveMaxLifetimeMs(),bootedAtMs=Date.now(),log=options.log??(()=>{}),clients=new Set,stopping=!1,wipeFreezeOnStop=!1,idleTimer=null,cancelIdle=()=>{if(idleTimer)clearTimeout(idleTimer);idleTimer=null},armIdle=()=>{if(stopping)return;cancelIdle(),idleTimer=setTimeout(()=>{if(stopping||ptys.liveCount()>0)return;log("idle",`no live sessions for ${idleExitMs}ms \u2014 exiting`),stop()},idleExitMs)},orphaned=()=>{if(maxLifetimeMs!==null&&Date.now()-bootedAtMs>=maxLifetimeMs)return`exceeded its ${maxLifetimeMs}ms lifetime ceiling`;let owner;try{owner=readFileSync(pidPath,"utf8").trim()}catch{return`pidfile ${pidPath} is gone`}let pid=Number.parseInt(owner,10);if(pid===process.pid)return null;return Number.isInteger(pid)?`pidfile ${pidPath} now names pid ${pid}`:`pidfile ${pidPath} is unreadable`},orphanTimer=setInterval(()=>{if(stopping)return;let reason=orphaned();if(!reason)return;log("orphan",`${reason} \u2014 exiting rather than outliving my owner`),stop()},orphanCheckMs);orphanTimer.unref?.();let ptys=new PtyHost({onProgramStatus:(event)=>{for(let client of clients)if(client.watchProgramStatus)writeFrame(client,{type:"event",name:"pty.programStatus",payload:event})},onSessionStart:cancelIdle,onSessionEnd:()=>{if(ptys.liveCount()===0)armIdle()},onSessionExit:(info)=>{try{recordPtyExit(info)}catch(err){log("pty",`exit record write failed for ${info.key}: ${err instanceof Error?err.message:String(err)}`)}},freeze:fileFreezeSink(freezeDir),driver:options.driver,log});ptys.restoreFrozen(loadFrozenSessions(freezeDir,Date.now(),(s)=>{let mib=(bytes)=>`${Math.round(bytes/1048576)}MB`,notes=[`restored ${s.restored} (${mib(s.bytesRead)})`];if(s.deferred>0)notes.push(`${s.deferred} left unread past the ${mib(FREEZE_RESTORE_MAX_BYTES)} budget`);if(s.expired>0)notes.push(`${s.expired} deleted past the ${FREEZE_TTL_MS/86400000}-day TTL`);if(s.unreadable>0)notes.push(`${s.unreadable} unreadable`);log("freeze",notes.join(", "))}));let pipeSocket=isWindowsPipePath(socketPath);if(await ensureOwnerOnlyStateDir(resolveDaemonHomeDir()),!pipeSocket)await mkdir(dirname(socketPath),{recursive:!0});await mkdir(dirname(pidPath),{recursive:!0});let server=createServer((socket)=>{let client={socket,writer:new ClientWriter(socket,{onOverflow:()=>{log("backpressure","disconnecting PTY client whose critical queue exceeded 8MiB"),socket.destroy()}})};clients.add(client);let receiver=new LineReceiver;socket.on("data",(chunk)=>{if(!receiver.push(chunk,(line)=>handleLine(client,line)))log("framing","disconnecting PTY client whose request exceeded 8MiB"),socket.destroy()}),socket.on("error",()=>{}),socket.on("close",()=>{clients.delete(client),ptys.detachClient(client)})}),api={socketPath,pidPath,async close(){if(stopping)return;if(stopping=!0,cancelIdle(),clearInterval(orphanTimer),await ptys.shutdown(),wipeFreezeOnStop)clearFrozenSessions(freezeDir);for(let client of Array.from(clients))client.socket.destroy();if(await new Promise((resolve)=>server.close(()=>resolve())),!pipeSocket)await unlink(socketPath).catch(()=>{});await unlink(pidPath).catch(()=>{})}};async function stop(){await api.close().catch((err)=>logDaemonError("pty-host-shutdown",err)),options.onStop?.()}let verbDeps={ptys,writeFrame,requestStop:()=>{wipeFreezeOnStop=!0,setTimeout(()=>void stop(),0).unref()},...options.version?{version:options.version}:{}};function handleLine(client,line){if(line.trim().length>0){let frame=null;try{frame=JSON.parse(line)}catch{writeFrame(client,{type:"response",id:"parse-error",error:{message:"malformed frame"}})}if(frame)if(frame.type!=="request")writeFrame(client,{type:"response",id:"parse-error",error:{message:"requests only"}});else{let req=frame,reply=(payload)=>writeFrame(client,{type:"response",id:req.id,name:req.name,payload}),fail=(err)=>writeFrame(client,{type:"response",id:req.id,name:req.name,error:{message:err instanceof Error?err.message:String(err)}});try{let payload=dispatchPtyRequest(req,client,verbDeps);if(payload instanceof Promise)payload.then(reply,fail);else reply(payload)}catch(err){fail(err)}}}}return await listenOnUnixSocket(server,socketPath),await writeTextAtomic(pidPath,`${process.pid}
3
3
  `),armIdle(),log("boot",`pty host listening on ${socketPath}`),api}function writeFrame(client,frame){client.writer.write(frameToLine(frame))}async function runPtyHostSubcommand(_argv){rotateLogIfNeeded(defaultPtyHostLogPath()),installDaemonCrashHandlers();let server=await startPtyHostServer({log:(event,message)=>console.log(formatPtyHostLine(event,message)),version:CURRENT_VERSION,onStop:()=>process.exit(0)});console.log(formatPtyHostLine("listen",`v${CURRENT_VERSION} listening on ${server.socketPath}`));let shutdown=async(signal)=>{console.log(formatPtyHostLine("signal",`${signal} received \u2014 closing host, frozen sessions kept`)),await server.close(),process.exit(0)};process.once("SIGINT",()=>void shutdown("SIGINT")),process.once("SIGTERM",()=>void shutdown("SIGTERM"))}export{runPtyHostSubcommand};
@@ -1,4 +1,4 @@
1
1
  // @bun
2
- import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{recommendedGlobalInstallCommand}from"./chunk-cp5jp5mq.js";function updaterShell(deps={}){let platform=deps.platform??process.platform;if(platform!=="win32")return"sh";return resolveLoginShell({fallback:"/bin/sh",platform,env:deps.env,exists:deps.exists})}function updaterShellFailureHint(deps={}){if((deps.platform??process.platform)!=="win32")return null;return["The update script is POSIX shell. Rove runs it through Git for Windows'","bash \u2014 the same shell every engine and terminal tab launches through.","Install Git for Windows (https://git-scm.com/download/win), or update","by hand:",` ${recommendedGlobalInstallCommand()}`,""].join(`
2
+ import{resolveLoginShell}from"./chunk-vjvkkrzc.js";import{recommendedGlobalInstallCommand}from"./chunk-j6t7xvm3.js";function updaterShell(deps={}){let platform=deps.platform??process.platform;if(platform!=="win32")return"sh";return resolveLoginShell({fallback:"/bin/sh",platform,env:deps.env,exists:deps.exists})}function updaterShellFailureHint(deps={}){if((deps.platform??process.platform)!=="win32")return null;return["The update script is POSIX shell. Rove runs it through Git for Windows'","bash \u2014 the same shell every engine and terminal tab launches through.","Install Git for Windows (https://git-scm.com/download/win), or update","by hand:",` ${recommendedGlobalInstallCommand()}`,""].join(`
3
3
  `)}
4
4
  export{updaterShell,updaterShellFailureHint};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{submitFeedback}from"./chunk-w7yg0bbz.js";import"./chunk-cp5jp5mq.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";import{readFileSync}from"fs";var CLI_NAME=ROVE_PRODUCT_NAME,FEEDBACK_USAGE=[`Usage: ${CLI_NAME} feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]`,"","Create a GitHub Discussion in the Rove repository using the GitHub CLI.","","Requires:"," gh auth login","","Options:"," --title <text> Discussion title"," --body <text> Discussion body"," --body-file <path> Read the Discussion body from a file; use - for stdin"," --category <slug> Discussion category slug (default: feedback)"," -h, --help Print this help",""].join(`
2
+ import{submitFeedback}from"./chunk-nz9nmp4v.js";import"./chunk-j6t7xvm3.js";import"./chunk-prqeddy7.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";import{readFileSync}from"fs";var CLI_NAME=ROVE_PRODUCT_NAME,FEEDBACK_USAGE=[`Usage: ${CLI_NAME} feedback --title <text> (--body <text> | --body-file <path>) [--category <slug>]`,"","Create a GitHub Discussion in the Rove repository using the GitHub CLI.","","Requires:"," gh auth login","","Options:"," --title <text> Discussion title"," --body <text> Discussion body"," --body-file <path> Read the Discussion body from a file; use - for stdin"," --category <slug> Discussion category slug (default: feedback)"," -h, --help Print this help",""].join(`
3
3
  `);function usageError(message){process.stderr.write(`${CLI_NAME} feedback: ${message}
4
4
 
5
5
  ${FEEDBACK_USAGE}
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{PS_PROBE_TIMEOUT_MS,engineProcessIn,foregroundEngine,foregroundEngineIn,hasAncestor,parsePsSnapshot,psSnapshot,psSnapshotWith,vendorFromArgv}from"./chunk-8ja7jrhc.js";import"./chunk-2pen6b1t.js";import"./chunk-2tfnscxk.js";import"./chunk-w4cpkhzj.js";import"./chunk-w7zv47mp.js";import"./chunk-2brn8e1y.js";import"./chunk-964z8ccb.js";import"./chunk-x33sm4rp.js";import"./chunk-7kysxgbq.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import"./chunk-21ek142k.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-zk5qkkb1.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import{PsProbeUnavailableError}from"./chunk-pxk2c2vj.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{vendorFromArgv,psSnapshotWith,psSnapshot,parsePsSnapshot,hasAncestor,foregroundEngineIn,foregroundEngine,engineProcessIn,PsProbeUnavailableError,PS_PROBE_TIMEOUT_MS};
2
+ import{PS_PROBE_TIMEOUT_MS,engineProcessIn,foregroundEngine,foregroundEngineIn,hasAncestor,parsePsSnapshot,psSnapshot,psSnapshotWith,vendorFromArgv}from"./chunk-24dryfqb.js";import"./chunk-jp31bpgp.js";import"./chunk-2tfnscxk.js";import"./chunk-ccn7pq03.js";import"./chunk-w7zv47mp.js";import"./chunk-2brn8e1y.js";import"./chunk-jnj2kk2h.js";import"./chunk-9dregrj6.js";import"./chunk-qzsahxd9.js";import"./chunk-xy8be792.js";import"./chunk-7kysxgbq.js";import"./chunk-h2m7em1e.js";import"./chunk-tdhk4dz8.js";import"./chunk-21ek142k.js";import"./chunk-40dgv828.js";import"./chunk-3342qzve.js";import"./chunk-zk5qkkb1.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import{PsProbeUnavailableError}from"./chunk-pxk2c2vj.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import"./chunk-91sykzqq.js";export{vendorFromArgv,psSnapshotWith,psSnapshot,parsePsSnapshot,hasAncestor,foregroundEngineIn,foregroundEngine,engineProcessIn,PsProbeUnavailableError,PS_PROBE_TIMEOUT_MS};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{activityHookAdapters}from"./chunk-2pen6b1t.js";import{readFileSync}from"fs";function hookConfigIssues(){let issues=[];for(let adapter of activityHookAdapters()){if(!adapter.hookConfigRefusal)continue;let file=adapter.globalSettingsPath();if(!file)continue;let raw;try{raw=readFileSync(file,"utf8")}catch{continue}let reason=adapter.hookConfigRefusal(raw);if(reason)issues.push({file,reason})}return issues}
2
+ import{activityHookAdapters}from"./chunk-jp31bpgp.js";import{readFileSync}from"fs";function hookConfigIssues(){let issues=[];for(let adapter of activityHookAdapters()){if(!adapter.hookConfigRefusal)continue;let file=adapter.globalSettingsPath();if(!file)continue;let raw;try{raw=readFileSync(file,"utf8")}catch{continue}let reason=adapter.hookConfigRefusal(raw);if(reason)issues.push({file,reason})}return issues}
3
3
  export{hookConfigIssues};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useT,useTheme}from"./chunk-vwg79maj.js";import"./chunk-yknavm97.js";import{$jsx,$jsxs,useRenderer}from"./chunk-29kvfqeh.js";import{require_react_production}from"./chunk-2wd4744g.js";import"./chunk-6rrzq5et.js";import"./chunk-764bsyb0.js";import"./chunk-8sbbzs5g.js";import"./chunk-atn06ncf.js";import"./chunk-zcadc92x.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-7z9yfnjd.js";import"./chunk-7j00hbq5.js";import"./chunk-gaf6n1ea.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import{BREAKING_VERSIONS,CURRENT_VERSION,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries,updateCommandFor}from"./chunk-cp5jp5mq.js";import"./chunk-40dgv828.js";import"./chunk-zk5qkkb1.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-032g0ahy.js";import"./chunk-q3xt0mqt.js";import"./chunk-cmp64q4j.js";import"./chunk-s5a5dyab.js";import"./chunk-md094j05.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-91sykzqq.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:updateCommandFor(selected.version)})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
2
+ import{ReleaseNotesBody,bootPaneHost,pageCloseBindings,runShellUpdater,useBindings,useT,useTheme}from"./chunk-jn7vr075.js";import"./chunk-yknavm97.js";import"./chunk-pj3gnkfr.js";import{$jsx,$jsxs,useRenderer}from"./chunk-29kvfqeh.js";import{require_react_production}from"./chunk-2wd4744g.js";import"./chunk-764bsyb0.js";import"./chunk-e8pv3b92.js";import"./chunk-atn06ncf.js";import"./chunk-zcadc92x.js";import"./chunk-vjvkkrzc.js";import"./chunk-pdvyfz3n.js";import"./chunk-55ajzrj6.js";import"./chunk-t7j8g9f6.js";import"./chunk-dmzg9zdc.js";import"./chunk-6xppe9bj.js";import"./chunk-9sta3ak4.js";import"./chunk-gaf6n1ea.js";import"./chunk-7j00hbq5.js";import"./chunk-ag3txfg2.js";import"./chunk-2brn8e1y.js";import"./chunk-xy8be792.js";import{BREAKING_VERSIONS,CURRENT_VERSION,breakingVersionsCrossed,fetchReleaseNotes,fetchReleaseSummaries,updateCommandFor}from"./chunk-j6t7xvm3.js";import"./chunk-40dgv828.js";import"./chunk-zk5qkkb1.js";import"./chunk-mw0ysrpd.js";import"./chunk-a7kq09ke.js";import"./chunk-prqeddy7.js";import"./chunk-zt7wfnva.js";import"./chunk-yt15y085.js";import"./chunk-032g0ahy.js";import"./chunk-q3xt0mqt.js";import"./chunk-cmp64q4j.js";import"./chunk-s5a5dyab.js";import"./chunk-md094j05.js";import"./chunk-hq9tbzqa.js";import"./chunk-pn5ygqn6.js";import"./chunk-npwzmmv9.js";import"./chunk-b39sdtt0.js";import"./chunk-nc46gddg.js";import{__toESM}from"./chunk-91sykzqq.js";import{TextAttributes}from"@opentui/core";var import_react2=__toESM(require_react_production(),1);var RELEASE_LIMIT=20;function VersionsPage(props){let{theme}=useTheme(),t=useT(),renderer=useRenderer(),[releases,setReleases]=import_react2.useState(null),[cursor,setCursor]=import_react2.useState(0),[notes,setNotes]=import_react2.useState({}),[status,setStatus]=import_react2.useState(null),selected=releases?.[cursor],crossings=selected?breakingVersionsCrossed(CURRENT_VERSION,selected.version):[],loadSummaries=props.fetchSummaries??fetchReleaseSummaries,loadNotes=props.fetchNotes??fetchReleaseNotes;import_react2.useEffect(()=>{loadSummaries(RELEASE_LIMIT).then((fetched)=>setReleases(fetched))},[loadSummaries]);let selectedVersion=selected?.version;import_react2.useEffect(()=>{if(selectedVersion===void 0||notes[selectedVersion]!==void 0)return;setNotes((cache)=>({...cache,[selectedVersion]:"loading"})),loadNotes(selectedVersion).then((fetched)=>{setNotes((cache)=>({...cache,[selectedVersion]:fetched??"missing"}))})},[selectedVersion,notes,loadNotes]);function move(delta){let count=releases?.length??0;if(count===0)return;setCursor((index)=>(index+delta+count)%count)}async function installSelected(){if(!selected)return;setStatus(t("update.statusRunningUpdater")),await new Promise((resolve)=>setTimeout(resolve,30)),await runShellUpdater({renderer,t,targetLabel:selected.version,command:updateCommandFor(selected.version)})}useBindings(()=>({bindings:[{key:"up",cmd:()=>move(-1)},{key:"down",cmd:()=>move(1)},{key:"k",cmd:()=>move(-1)},{key:"j",cmd:()=>move(1)},{key:"return",cmd:()=>void installSelected()},{key:"u",cmd:()=>void installSelected()},...pageCloseBindings(props.onClose)]}));let selectedNotes=selectedVersion===void 0?void 0:notes[selectedVersion];return $jsxs("box",{flexDirection:"column",flexGrow:1,paddingTop:1,paddingLeft:2,paddingRight:2,children:[$jsxs("box",{flexDirection:"row",justifyContent:"space-between",flexShrink:0,children:[$jsx("text",{fg:theme.text,attributes:TextAttributes.BOLD,wrapMode:"none",children:t("update.versions.pageTitle")}),$jsx("text",{fg:theme.textMuted,wrapMode:"none",onMouseUp:props.onClose,children:t("update.versions.closeHint")})]}),$jsxs("box",{flexDirection:"row",flexGrow:1,paddingTop:1,gap:2,children:[$jsxs("box",{flexDirection:"column",width:26,flexShrink:0,children:[releases===null?$jsx("text",{fg:theme.textMuted,children:t("update.versions.loading")}):null,releases!==null&&releases.length===0?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.versions.unavailable")}):null,(releases??[]).map((release,index)=>{let active=index===cursor,tags=[release.version===CURRENT_VERSION?t("update.versions.tagCurrent"):"",index===0?t("update.versions.tagLatest"):"",BREAKING_VERSIONS.includes(release.version)?t("update.versions.tagBreaking"):""].filter(Boolean).join(" ");return $jsxs("box",{flexDirection:"row",gap:1,paddingLeft:1,backgroundColor:active?theme.primary:void 0,onMouseUp:()=>setCursor(index),children:[$jsxs("text",{fg:active?theme.selectedListItemText:theme.text,attributes:release.version===CURRENT_VERSION?TextAttributes.BOLD:void 0,wrapMode:"none",children:["v",release.version]}),tags?$jsx("text",{fg:active?theme.selectedListItemText:theme.textMuted,wrapMode:"none",children:tags}):null]},release.version)})]}),$jsxs("box",{flexDirection:"column",flexGrow:1,flexShrink:1,children:[$jsx("scrollbox",{flexGrow:1,flexShrink:1,stickyScroll:!1,verticalScrollbarOptions:{trackOptions:{foregroundColor:"transparent"}},children:$jsxs("box",{flexDirection:"column",paddingRight:1,paddingBottom:1,gap:0,children:[selectedNotes==="loading"?$jsx("text",{fg:theme.textMuted,children:t("update.loadingNotes")}):null,selectedNotes==="missing"?$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t("update.notesUnavailable")}):null,selectedNotes!==void 0&&selectedNotes!=="loading"&&selectedNotes!=="missing"?$jsx(ReleaseNotesBody,{body:selectedNotes.body}):null]})}),crossings.length>0?$jsx("text",{fg:theme.warning,wrapMode:"word",children:t("update.versions.breakingWarning",{versions:crossings.join(", ")})}):null]})]}),status?$jsx("text",{fg:theme.info,wrapMode:"word",children:status}):null,$jsx("box",{flexShrink:0,paddingTop:1,children:$jsx("text",{fg:theme.textMuted,attributes:TextAttributes.DIM,wrapMode:"none",children:t("update.versions.footerHint")})})]})}var INLINE_ROWS=24;async function startVersionsHost(){await bootPaneHost({inlineRows:INLINE_ROWS,setup:()=>({root:()=>$jsx(VersionsPage,{onClose:()=>process.exit(0)})})})}export{startVersionsHost,VersionsPage};
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{isDev}from"./chunk-prqeddy7.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.251",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:mock":"ROVE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"ROVE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"ROVE_INCLUDE_SOCKET=1 ROVE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"ROVE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/rove-daemon":"0.7.22","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1","rove-bridge":"0.0.12","rove-weixin":"0.0.12",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var CURRENT_VERSION=package_default.version,PACKAGE_NAME=package_default.name;function repoSlug(){let url=package_default.repository?.url;if(!url)return null;let m=url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!m||!m[1]||!m[2])return null;return`${m[1]}/${m[2]}`}var UPDATE_SCRIPT_URL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",UPDATE_COMMAND=`curl -fsSL ${UPDATE_SCRIPT_URL} | sh`;function updateCommandFor(target){return target===void 0||target===DEFAULT_RELEASE_CHANNEL?UPDATE_COMMAND:`${UPDATE_COMMAND} -s -- ${target}`}function owningNpmPrefix(modulePath=fileURLToPath(import.meta.url)){let at=modulePath.indexOf("/lib/node_modules/");if(at<=0)return null;return modulePath.slice(0,at)}function recommendedGlobalInstallCommand(prefix=owningNpmPrefix()){let target=`${PACKAGE_NAME}@latest`;return prefix===null?`npm install -g ${target}`:`npm install -g --prefix ${prefix} ${target}`}var BREAKING_VERSIONS=[];function breakingVersionsCrossed(from,to,breaking=BREAKING_VERSIONS){let[lo,hi]=compareSemver(from,to)<=0?[from,to]:[to,from];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}var FETCH_TIMEOUT_MS=3000,RELEASE_CHANNELS=["latest","nightly"],DEFAULT_RELEASE_CHANNEL="latest";function channelOf(version=CURRENT_VERSION){return prereleaseOf(version)?.split(".")[0]==="nightly"?"nightly":DEFAULT_RELEASE_CHANNEL}async function fetchLatestFromRegistry(packageName,channel){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let encoded=packageName.replace("/","%2F"),res=await fetch(`https://registry.npmjs.org/${encoded}/${channel}`,{signal:ctrl.signal,headers:{accept:"application/json"}});if(!res.ok)return null;let body=await res.json();if(typeof body.version!=="string")return null;return body.version}catch{return null}finally{clearTimeout(timer)}}function isNewerSemver(latest,current){let core=compareSemver(latest,current);if(core!==0)return core>0;return comparePrerelease(prereleaseOf(latest),prereleaseOf(current))>0}function prereleaseOf(version){let dash=version.indexOf("-");return dash===-1?void 0:version.slice(dash+1)||void 0}function comparePrerelease(a,b){if(a===b)return 0;if(a===void 0)return 1;if(b===void 0)return-1;let aParts=a.split("."),bParts=b.split(".");for(let i=0;i<Math.max(aParts.length,bParts.length);i++){let av=aParts[i],bv=bParts[i];if(av===void 0)return-1;if(bv===void 0)return 1;if(av===bv)continue;let an=/^\d+$/.test(av)?Number.parseInt(av,10):null,bn=/^\d+$/.test(bv)?Number.parseInt(bv,10):null;if(an!==null&&bn!==null)return an>bn?1:-1;if(an!==null)return-1;if(bn!==null)return 1;return av>bv?1:-1}return 0}function compareSemver(aVersion,bVersion){let norm=(v)=>v.split("-")[0]??v,a=norm(aVersion).split(".").map((s)=>Number.parseInt(s,10)),b=norm(bVersion).split(".").map((s)=>Number.parseInt(s,10));for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(Number.isNaN(av)||Number.isNaN(bv))return 0;if(av>bv)return 1;if(av<bv)return-1}return 0}async function checkLatestVersion(opts={}){let channel=opts.channel??channelOf(),fake=process.env.ROVE_FAKE_UPDATE;if(fake)return{current:CURRENT_VERSION,latest:fake,hasUpdate:isNewerSemver(fake,CURRENT_VERSION),channel};if(isDev()&&!opts.force)return null;let latest=await fetchLatestFromRegistry(PACKAGE_NAME,channel);if(!latest)return null;return{current:CURRENT_VERSION,latest,hasUpdate:isNewerSemver(latest,CURRENT_VERSION),channel}}function versionFromTagName(tagName){if(typeof tagName!=="string")return null;return tagName.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fetchReleaseNotes(version){let slug=repoSlug();if(!slug)return null;let tag=`v${version}`,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases/tags/${tag}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return null;let body=await res.json();if(typeof body.body!=="string"||typeof body.html_url!=="string")return null;return{body:body.body,url:body.html_url,version}}catch{return null}finally{clearTimeout(timer)}}async function fetchReleaseNotesRange(args){let slug=repoSlug();if(!slug)return[];let limit=args.limit??100,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string"||typeof release.body!=="string")return null;if(compareSemver(version,args.current)<=0)return null;if(compareSemver(version,args.latest)>0)return null;return{version,url:release.html_url,body:release.body}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}async function fetchReleaseSummaries(limit=12){let slug=repoSlug();if(!slug)return[];let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string")return null;return{version,url:release.html_url}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}function releasePageUrl(version){let slug=repoSlug();if(!slug)return null;return`https://github.com/${slug}/releases/tag/v${version}`}
2
+ import{isDev}from"./chunk-prqeddy7.js";import{fileURLToPath}from"url";var package_default={$schema:"https://json.schemastore.org/package.json",name:"@sma1lboy/rove",version:"0.9.252",description:"Rove \u2014 the agent multiplexer for your terminal. Run coding agents on parallel tasks with isolated worktrees and persistent sessions.",keywords:["terminal","tui","cli","multiplexer","ai-agents","coding-agent","ai-coding-assistant","agentic-ai","parallel-agents","git-worktree","claude-code","codex","llm","developer-tools"],type:"module",packageManager:"bun@1.3.13",bin:{rove:"dist/cli/rove.js"},files:["dist/cli","dist/completions","dist/web","dist/web-ui","dist/skills","dist/*.wav","README.md","LICENSE"],publishConfig:{access:"public"},repository:{type:"git",url:"git+https://github.com/Sma1lboy/rove.git"},homepage:"https://rove.run",bugs:{url:"https://github.com/Sma1lboy/rove/issues"},engines:{bun:">=1.3.11"},scripts:{dev:"ROVE_DEV=1 bun --conditions=browser ./src/cli/rove.ts","dev:mock":"ROVE_DEV=1 bun ./src/tui-react/mock/host.tsx","dev:sandbox":"bun run scripts/dev-sandbox.ts run","dev:sandbox:reset":"bun run scripts/dev-sandbox.ts reset",build:"bun run scripts/build.ts","build:rubric":"bun run scripts/build-tier-rubric.ts",compile:"bun run scripts/compile.ts",typecheck:"tsc --noEmit","check-i18n":"bun run scripts/check-i18n.ts",test:"bun run test:fast && bun run test:socket","perf:golden":"bun scripts/perf-golden.ts","pty:soak":"bun scripts/pty-soak.ts","test:fast":"vitest run --passWithNoTests --minWorkers=1 --maxWorkers=8","test:socket":"ROVE_INCLUDE_SOCKET=1 vitest run test/daemon --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:socket:coverage":"ROVE_INCLUDE_SOCKET=1 ROVE_COVERAGE_DAEMON=1 vitest run test/daemon --coverage --pool forks --minWorkers=1 --maxWorkers=4 --passWithNoTests","test:behavior":"ROVE_INCLUDE_BEHAVIOR=1 vitest run test/behavior --pool forks --minWorkers=1 --maxWorkers=1 --retry=2 --passWithNoTests","test:render":"bun scripts/render-track.mjs",coverage:"vitest run --coverage --passWithNoTests",bench:"vitest bench --run",lint:"biome check .",knip:"knip-bun",postinstall:"bun run scripts/check-preview-deps.ts || true",prepublishOnly:"bun run typecheck && bun run build","plugin-sandbox":"bun run scripts/plugin-sandbox.ts"},"//":"biome.json + bunfig.toml live at the monorepo root since they apply repo-wide; bun.lock also lives at root (workspace-shared).",dependencies:{"@ansi-tools/parser":"^1.0.15","@opentui/core":"0.4.3","@opentui/react":"0.4.3","@xterm/addon-serialize":"^0.14.0","@xterm/addon-unicode11":"^0.9.0","@xterm/headless":"^6.0.0","node-pty":"^1.1.0",react:"^19.2.8","smol-toml":"^1.7.1",ws:"^8.21.3"},devDependencies:{"@biomejs/biome":"1.9.4","@sma1lboy/rove-daemon":"0.7.22","@tsconfig/bun":"1.0.11","@types/bun":"1.3.14","@types/node":"25.6.2","@types/react":"^19.2.0","@vitest/coverage-v8":"2.1.9",knip:"^6.14.2","react-devtools-core":"^7.0.1","rove-bridge":"0.0.13","rove-weixin":"0.0.13",typescript:"5.8.2",vitest:"2.1.9"},trustedDependencies:[]};var CURRENT_VERSION=package_default.version,PACKAGE_NAME=package_default.name;function repoSlug(){let url=package_default.repository?.url;if(!url)return null;let m=url.match(/github\.com[:/]([^/]+)\/([^/.]+)/);if(!m||!m[1]||!m[2])return null;return`${m[1]}/${m[2]}`}var UPDATE_SCRIPT_URL="https://raw.githubusercontent.com/Sma1lboy/rove/main/scripts/update.sh",UPDATE_COMMAND=`curl -fsSL ${UPDATE_SCRIPT_URL} | sh`;function updateCommandFor(target){return target===void 0||target===DEFAULT_RELEASE_CHANNEL?UPDATE_COMMAND:`${UPDATE_COMMAND} -s -- ${target}`}function owningNpmPrefix(modulePath=fileURLToPath(import.meta.url)){let at=modulePath.indexOf("/lib/node_modules/");if(at<=0)return null;return modulePath.slice(0,at)}function recommendedGlobalInstallCommand(prefix=owningNpmPrefix()){let target=`${PACKAGE_NAME}@latest`;return prefix===null?`npm install -g ${target}`:`npm install -g --prefix ${prefix} ${target}`}var BREAKING_VERSIONS=[];function breakingVersionsCrossed(from,to,breaking=BREAKING_VERSIONS){let[lo,hi]=compareSemver(from,to)<=0?[from,to]:[to,from];return breaking.filter((b)=>compareSemver(b,lo)>0&&compareSemver(b,hi)<=0)}var FETCH_TIMEOUT_MS=3000,RELEASE_CHANNELS=["latest","nightly"],DEFAULT_RELEASE_CHANNEL="latest";function channelOf(version=CURRENT_VERSION){return prereleaseOf(version)?.split(".")[0]==="nightly"?"nightly":DEFAULT_RELEASE_CHANNEL}async function fetchLatestFromRegistry(packageName,channel){let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let encoded=packageName.replace("/","%2F"),res=await fetch(`https://registry.npmjs.org/${encoded}/${channel}`,{signal:ctrl.signal,headers:{accept:"application/json"}});if(!res.ok)return null;let body=await res.json();if(typeof body.version!=="string")return null;return body.version}catch{return null}finally{clearTimeout(timer)}}function isNewerSemver(latest,current){let core=compareSemver(latest,current);if(core!==0)return core>0;return comparePrerelease(prereleaseOf(latest),prereleaseOf(current))>0}function prereleaseOf(version){let dash=version.indexOf("-");return dash===-1?void 0:version.slice(dash+1)||void 0}function comparePrerelease(a,b){if(a===b)return 0;if(a===void 0)return 1;if(b===void 0)return-1;let aParts=a.split("."),bParts=b.split(".");for(let i=0;i<Math.max(aParts.length,bParts.length);i++){let av=aParts[i],bv=bParts[i];if(av===void 0)return-1;if(bv===void 0)return 1;if(av===bv)continue;let an=/^\d+$/.test(av)?Number.parseInt(av,10):null,bn=/^\d+$/.test(bv)?Number.parseInt(bv,10):null;if(an!==null&&bn!==null)return an>bn?1:-1;if(an!==null)return-1;if(bn!==null)return 1;return av>bv?1:-1}return 0}function compareSemver(aVersion,bVersion){let norm=(v)=>v.split("-")[0]??v,a=norm(aVersion).split(".").map((s)=>Number.parseInt(s,10)),b=norm(bVersion).split(".").map((s)=>Number.parseInt(s,10));for(let i=0;i<3;i++){let av=a[i]??0,bv=b[i]??0;if(Number.isNaN(av)||Number.isNaN(bv))return 0;if(av>bv)return 1;if(av<bv)return-1}return 0}async function checkLatestVersion(opts={}){let channel=opts.channel??channelOf(),fake=process.env.ROVE_FAKE_UPDATE;if(fake)return{current:CURRENT_VERSION,latest:fake,hasUpdate:isNewerSemver(fake,CURRENT_VERSION),channel};if(isDev()&&!opts.force)return null;let latest=await fetchLatestFromRegistry(PACKAGE_NAME,channel);if(!latest)return null;return{current:CURRENT_VERSION,latest,hasUpdate:isNewerSemver(latest,CURRENT_VERSION),channel}}function versionFromTagName(tagName){if(typeof tagName!=="string")return null;return tagName.match(/^v(\d+\.\d+\.\d+)$/)?.[1]??null}async function fetchReleaseNotes(version){let slug=repoSlug();if(!slug)return null;let tag=`v${version}`,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases/tags/${tag}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return null;let body=await res.json();if(typeof body.body!=="string"||typeof body.html_url!=="string")return null;return{body:body.body,url:body.html_url,version}}catch{return null}finally{clearTimeout(timer)}}async function fetchReleaseNotesRange(args){let slug=repoSlug();if(!slug)return[];let limit=args.limit??100,ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string"||typeof release.body!=="string")return null;if(compareSemver(version,args.current)<=0)return null;if(compareSemver(version,args.latest)>0)return null;return{version,url:release.html_url,body:release.body}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}async function fetchReleaseSummaries(limit=12){let slug=repoSlug();if(!slug)return[];let ctrl=new AbortController,timer=setTimeout(()=>ctrl.abort(),FETCH_TIMEOUT_MS);try{let res=await fetch(`https://api.github.com/repos/${slug}/releases?per_page=${limit}`,{signal:ctrl.signal,headers:{accept:"application/vnd.github+json","x-github-api-version":"2022-11-28"}});if(!res.ok)return[];let body=await res.json();if(!Array.isArray(body))return[];return body.map((release)=>{let version=versionFromTagName(release.tag_name);if(!version||typeof release.html_url!=="string")return null;return{version,url:release.html_url}}).filter((release)=>release!==null)}catch{return[]}finally{clearTimeout(timer)}}function releasePageUrl(version){let slug=repoSlug();if(!slug)return null;return`https://github.com/${slug}/releases/tag/v${version}`}
3
3
  export{package_default,CURRENT_VERSION,PACKAGE_NAME,repoSlug,UPDATE_SCRIPT_URL,UPDATE_COMMAND,updateCommandFor,owningNpmPrefix,recommendedGlobalInstallCommand,BREAKING_VERSIONS,breakingVersionsCrossed,RELEASE_CHANNELS,DEFAULT_RELEASE_CHANNEL,channelOf,isNewerSemver,compareSemver,checkLatestVersion,fetchReleaseNotes,fetchReleaseNotesRange,fetchReleaseSummaries,releasePageUrl};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{RoveKeymap,armPrefixNow,bindingReachability,configurePrefix,currentPrefixConfiguration,dispatchKeyEvent,inputPassthroughReachable,insertRegistration,invokeArmedPrefixAction,isCtrlModifierKeyName,persistedSoundVolume,prefixHudHideDirect,prefixHudShowDirect,readKeybindingsFile,resetKeybindingsFileCache,resetPrefixConfiguration,resetPrefixState,resolveUserKeybindings}from"./chunk-yknavm97.js";import{$Fragment,$jsx,$jsxs,createRoot,flushSync,useRenderer}from"./chunk-29kvfqeh.js";import{require_react_production}from"./chunk-2wd4744g.js";import{RemoteOrchestrator}from"./chunk-6rrzq5et.js";import{updaterShell,updaterShellFailureHint}from"./chunk-8sbbzs5g.js";import{BUNDLED_THEMES,DEFAULT_THEME,DEFAULT_THEME_MODE,applyDisplayOverlay,readPersistedUiPrefs,resolveTheme,resolveThemeMode}from"./chunk-zcadc92x.js";import{loadUserThemes}from"./chunk-pdvyfz3n.js";import{connectIfRunning}from"./chunk-7z9yfnjd.js";import{tildify}from"./chunk-ag3txfg2.js";import{CURRENT_VERSION}from"./chunk-cp5jp5mq.js";import{loadStateFile,patchStateFile,readStateFileStrict,replaceStateFile}from"./chunk-zk5qkkb1.js";import{kvStatePath}from"./chunk-prqeddy7.js";import{localeState,setLocaleLang,t}from"./chunk-032g0ahy.js";import{isLocaleId}from"./chunk-q3xt0mqt.js";import{createStateCell,profileMark,profileTick,recentStateChangesForDiagnostics,renderProfileOn}from"./chunk-cmp64q4j.js";import{installClientCrashHandlers,logClient,logClientError,setClientLogContext}from"./chunk-hq9tbzqa.js";import{__toESM}from"./chunk-91sykzqq.js";import{RGBA}from"@opentui/core";var import_react3=__toESM(require_react_production(),1);var import_react=__toESM(require_react_production(),1);function useAccessor(state){return import_react.useSyncExternalStore(state.subscribe,state.get,state.get)}var store=createStateCell({themes:{...BUNDLED_THEMES},active:DEFAULT_THEME,mode:DEFAULT_THEME_MODE,transparentBackground:!0,focusAccent:"primary"});function listThemes(){return Object.keys(store.get().themes)}function hasTheme(name){return Boolean(store.get().themes[name])}function addTheme(name,theme){if(!name)return!1;if(!theme||typeof theme!=="object"||!theme.theme)return!1;return store.update((s)=>({...s,themes:{...s.themes,[name]:theme}})),!0}function selectedTheme(){return store.get().active}function setTheme(name){if(!hasTheme(name))return!1;return store.update((s)=>({...s,active:name})),!0}function transparentBackground(){return store.get().transparentBackground}function setTransparentBackground(v){store.update((s)=>({...s,transparentBackground:v}))}function focusAccent(){return store.get().focusAccent}function setFocusAccent(v){store.update((s)=>({...s,focusAccent:v}))}function themeMode(){return store.get().mode}function setThemeMode(mode){store.update((s)=>({...s,mode}))}var ThemeContext=import_react3.createContext(null),HOST_PALETTE_QUERY_TIMEOUT_MS=2000;function resolveActive(state,mode){let active=state.themes[state.active];if(active)return resolveTheme(active,mode);let fallback=state.themes[DEFAULT_THEME]??Object.values(state.themes)[0];if(!fallback)return resolveTheme({theme:{background:"#000000",text:"#ffffff"}},mode);return resolveTheme(fallback,mode)}function useHostThemeMode(renderer){let[mode,setMode]=import_react3.useState(()=>renderer?.themeMode??null);return import_react3.useEffect(()=>{if(!renderer)return;let onChange=(next)=>setMode(next);return renderer.on("theme_mode",onChange),setMode(renderer.themeMode),()=>{renderer.off("theme_mode",onChange)}},[renderer]),mode}function ThemeProvider(props){import_react3.useMemo(()=>{store.update((s)=>({...s,mode:props.mode??s.mode,active:props.theme&&s.themes[props.theme]?props.theme:s.active}))},[]);let state=useAccessor(store),renderer=useRenderer(),hostMode=useHostThemeMode(renderer),mode=resolveThemeMode(state.mode,hostMode),[hostBackground,setHostBackground]=import_react3.useState(null);import_react3.useEffect(()=>{if(!state.transparentBackground)return;if(renderer?.screenMode==="split-footer")return;if(!renderer)return;let cancelled=!1;return renderer.getPalette({timeout:HOST_PALETTE_QUERY_TIMEOUT_MS}).then((colors)=>{if(cancelled||!colors.defaultBackground)return;setHostBackground(RGBA.fromHex(colors.defaultBackground))}).catch(()=>{}),()=>{cancelled=!0}},[renderer,state.transparentBackground]);let theme=import_react3.useMemo(()=>applyDisplayOverlay(resolveActive(state,mode),state.focusAccent,state.transparentBackground,hostBackground??void 0),[state,mode,hostBackground]);import_react3.useEffect(()=>{if(renderer?.screenMode==="split-footer")return;renderer?.setBackgroundColor(theme.background??RGBA.fromInts(0,0,0))},[renderer,theme]);let value=import_react3.useMemo(()=>({theme,selected:state.active,transparentBackground:state.transparentBackground,focusAccent:state.focusAccent,modePreference:state.mode,mode:()=>mode,set(name){if(!hasTheme(name))return!1;return store.update((s)=>({...s,active:name})),!0},setMode(next){store.update((s)=>({...s,mode:next}))},setTransparentBackground(v){store.update((s)=>({...s,transparentBackground:v}))},setFocusAccent(v){store.update((s)=>({...s,focusAccent:v}))},preview:(options)=>applyDisplayOverlay(resolveActive({...state,active:options.themeName},resolveThemeMode(options.themeMode,hostMode)),options.focusAccent,options.transparentBackground,hostBackground??void 0),all:listThemes,has:hasTheme}),[theme,state,mode,hostMode,hostBackground]);return $jsx(ThemeContext.Provider,{value,children:props.children})}function useTheme(){let value=import_react3.useContext(ThemeContext);if(!value)throw Error("Theme context must be used within a context provider");return value}var import_react4=__toESM(require_react_production(),1);function useLang(){return useAccessor(localeState())}function useT(){let lang=useLang();return import_react4.useCallback((key,params)=>t(key,params),[lang])}var import_react7=__toESM(require_react_production(),1);var CTRL_HOLD_THRESHOLD_MS=400;function createCtrlHoldDetector(callbacks){let state={kind:"idle"},held=new Set,reset=()=>{if(state.kind==="pending")clearTimeout(state.timer);if(state.kind==="visible")callbacks.onHide();state={kind:"idle"}},cancel=()=>{reset(),held.clear()};return{keypress:(event)=>{if(!isCtrlModifierKeyName(event.name)){cancel();return}if(event.eventType==="repeat"&&held.has(event.name))return;if(event.eventType!=="press")return;if(held.add(event.name),state.kind!=="idle")return;state={kind:"pending",timer:setTimeout(()=>{state={kind:"visible"},callbacks.onReveal()},CTRL_HOLD_THRESHOLD_MS)}},keyrelease:(event)=>{if(!isCtrlModifierKeyName(event.name)||event.eventType!=="release")return;if(held.delete(event.name),held.size===0)reset()},cancel}}function availableActions(stack){let seen=new Set,actions=[],passthrough=inputPassthroughReachable(stack);for(let registration of[...stack].reverse()){let config=registration.config();if(config.enabled===!1)continue;for(let binding of config.bindings){if(binding.prefix&&currentPrefixConfiguration().key===null)continue;if(binding.yieldToPassthrough&&passthrough)continue;let chord=`${binding.prefix===!0}:${binding.key}`;if(seen.has(chord))continue;if(seen.add(chord),binding.id&&binding.action)actions.push({owner:registration.id,binding})}if(config.modal)break}return actions}function capturePaletteActions(stack){let seen=new Set;return availableActions(stack).flatMap(({owner,binding})=>{let id=binding.id;if(!id||id==="palette.open"||seen.has(id))return[];return seen.add(id),[{id,key:binding.key,prefix:binding.prefix===!0,run:()=>{let live=availableActions(stack).find((entry)=>entry.owner===owner&&entry.binding.id===id&&entry.binding.key===binding.key&&entry.binding.prefix===binding.prefix);if(!live?.binding.action)return!1;return live.binding.action.run(),!0}}]})}function bindByIds(handlers){let out=[];for(let id in handlers){let handler=handlers[id];if(!handler)continue;let action=typeof handler==="function"?void 0:handler,cmd=typeof handler==="function"?handler:()=>handler.run(),binding=findBinding(id),chords=binding?.keys??[],prefixChords=binding?.prefixKeys??[];if(chords.length===0&&prefixChords.length===0){console.warn(`[rove/keybindings] bindByIds: id="${id}" has no chords (or doesn't exist in RoveKeymap)`);continue}chords.forEach((key,slot)=>out.push({key,cmd,action,slot,id,yieldToPassthrough:binding?.yieldToPassthrough})),prefixChords.forEach((key,slot)=>out.push({key,prefix:!0,cmd,action,slot,id}))}return out}var KEYMAP_DEFAULTS=new Map(RoveKeymap.map((b)=>[b.id,{keys:[...b.keys],prefixKeys:b.prefixKeys&&[...b.prefixKeys],hint:b.hint?{...b.hint}:void 0}]));function defaultChordsOf(id){return KEYMAP_DEFAULTS.get(id)?.keys??[]}function resetKeymapToDefaults(){for(let row of RoveKeymap){let def=KEYMAP_DEFAULTS.get(row.id);if(!def)continue;let mutable=row;mutable.keys=[...def.keys],mutable.prefixKeys=def.prefixKeys&&[...def.prefixKeys],mutable.hint=def.hint?{...def.hint}:void 0}}var keymapVersionValue=0,keymapVersionListeners=new Set;function keymapVersion(){return keymapVersionValue}function subscribeKeymapVersion(listener){return keymapVersionListeners.add(listener),()=>{keymapVersionListeners.delete(listener)}}function bumpKeymapVersion(){keymapVersionValue+=1;for(let listener of[...keymapVersionListeners])listener()}var KEYMAP_BY_ID=new Map(RoveKeymap.map((b)=>[b.id,b]));function findBinding(id){return KEYMAP_BY_ID.get(id)}var MODIFIER_GLYPH={ctrl:"\u2303",control:"\u2303",alt:"\u2325",opt:"\u2325",option:"\u2325",shift:"\u21E7",cmd:"\u2318",command:"\u2318",meta:"\u2318",super:"\u2318"},KEY_GLYPH={enter:"\u23CE",return:"\u23CE",esc:"\u238B",escape:"\u238B",space:"\u2423",up:"\u2191",down:"\u2193",left:"\u2190",right:"\u2192",backspace:"\u232B",delete:"\u2326",del:"\u2326",pgup:"\u21DE",pageup:"\u21DE",pgdn:"\u21DF",pagedown:"\u21DF",home:"\u2196",end:"\u2198"};function formatKey(k,upper){if(k.includes("/"))return k.split("/").map((part)=>formatKey(part,upper)).join("/");let low=k.toLowerCase();if(low==="tab")return"tab";let named=KEY_GLYPH[low];if(named)return named;if(/^f\d{1,2}$/.test(low))return low.toUpperCase();if(!upper)return k;if(/^[a-z]$/.test(low))return k.toUpperCase();return k.replace(/[a-z]+/gi,(run)=>run.toUpperCase())}function formatChord(chord,prefixGlyph="\u2303A"){let s=chord.trim();if(!s)return s;let pm=/^prefix\s+(.+)$/i.exec(s);if(pm){let suffix=pm[1]??"";return`${prefixGlyph} ${suffix.includes("+")?formatChord(suffix,prefixGlyph):formatKey(suffix,!0)}`}let parts=s.split("+");if(parts.length===1)return formatKey(parts[0]??"",!1);let key=parts[parts.length-1]??"";return`${parts.slice(0,-1).map((p)=>MODIFIER_GLYPH[p.toLowerCase().trim()]??p).join("")} ${formatKey(key,!0)}`}var DIRECT_GUIDE_PREFIX_ACTION_ID="prefix.moreCommands",CTRL_FOLLOW_UP_CHORD=/^ctrl\+[^+]+$/;function ctrlFollowUpKey(chord){return CTRL_FOLLOW_UP_CHORD.test(chord)?chord.slice(5):null}function shortcutCaption(input){let binding=findBinding(input.bindingId);if(!binding)return null;if(input.reachability.direct.has(input.bindingId)){let direct=binding.keys[0];if(direct)return formatChord(direct)}if(input.prefixKey&&input.reachability.prefix.has(input.bindingId)){let stroke=binding.prefixKeys?.[0];if(stroke)return`${formatChord(input.prefixKey)} ${formatChord(stroke)}`}return null}function directGuideOptions(reachability,prefixKey){let options=RoveKeymap.filter((binding)=>reachability.direct.has(binding.id)).flatMap((binding)=>{let strokes=binding.keys.flatMap((chord)=>ctrlFollowUpKey(chord)??[]);if(strokes.length>2)return[{stroke:`${strokes[0]}-${strokes.at(-1)}`,action:binding.id}];return strokes.map((stroke)=>({stroke,action:binding.id}))}),prefixStroke=prefixKey?ctrlFollowUpKey(prefixKey):null;if(prefixStroke&&reachability.prefix.size>0)options.push({stroke:prefixStroke,action:DIRECT_GUIDE_PREFIX_ACTION_ID});return options}var import_react5=__toESM(require_react_production(),1);function useLatest(value){let ref=import_react5.useRef(value);return ref.current=value,ref}var ModalScopeContext=import_react7.createContext(null),nextId=1,stack=[],installedRenderer=null,installed=null,listener=null,releaseListener=null,ctrlHoldDetector=null,supersededRenderers=new WeakSet;function ensureInstalled(renderer){if(!renderer)throw Error("useBindings: no renderer in scope; call inside a component rendered by @opentui/react.");if(installedRenderer===renderer)return;if(supersededRenderers.has(renderer))return;if(installed&&listener)installed.off("keypress",listener);if(installed&&releaseListener)installed.off("keyrelease",releaseListener);if(ctrlHoldDetector?.cancel(),installedRenderer)supersededRenderers.add(installedRenderer);stack.length=0,resetPrefixState(),installedRenderer=renderer,installed=renderer.keyInput,ctrlHoldDetector=createCtrlHoldDetector({onReveal:()=>{resetPrefixState();let options=directGuideOptions(bindingReachability(stack),currentPrefixConfiguration().key);if(options.length>0)prefixHudShowDirect(options)},onHide:prefixHudHideDirect}),listener=(evt)=>{profileTick("key"),ctrlHoldDetector?.keypress(evt),dispatchKeyEvent(stack,evt,Date.now(),{flushSync})},releaseListener=(evt)=>ctrlHoldDetector?.keyrelease(evt),installed.on("keypress",listener),installed.on("keyrelease",releaseListener)}function modalActive(){return stack.some((r)=>r.modalOwner!==void 0)}function currentBindingReachability(){return bindingReachability(stack)}function armPrefixFromCurrentStack(){return armPrefixNow(stack)}function invokeArmedPrefixActionFromCurrentStack(actionId,stroke){return invokeArmedPrefixAction(stack,actionId,stroke)}var stackVersion=0,stackListeners=new Set;function bumpStackVersion(){prefixHudHideDirect(),stackVersion++;for(let listener2 of stackListeners)listener2()}function bindingReachabilitySignature(config){let bindings=config.bindings.map((binding)=>[binding.id??"",binding.key,binding.prefix===!0?"p":"d",binding.passthrough===!0?"i":"u"].join(":")).join("|");return`${config.enabled===!1?"off":"on"};${config.modal===!0?"modal":"plain"};${bindings}`}function useBindingStackVersion(){return import_react7.useSyncExternalStore((onChange)=>{return stackListeners.add(onChange),()=>stackListeners.delete(onChange)},()=>stackVersion)}function useBindings(config,opts){let renderer=useRenderer();ensureInstalled(renderer);let configRef=useLatest(config),scope=import_react7.useContext(ModalScopeContext),reachabilitySignature=bindingReachabilitySignature(config()),previousReachabilitySignature=import_react7.useRef(reachabilitySignature);import_react7.useEffect(()=>{if(previousReachabilitySignature.current===reachabilitySignature)return;previousReachabilitySignature.current=reachabilitySignature,bumpStackVersion()},[reachabilitySignature]),import_react7.useEffect(()=>{if(supersededRenderers.has(renderer))return;if(opts?.modalOwner!==void 0)resetPrefixState();let reg={config:()=>configRef.current(),id:nextId++,modalOwner:opts?.modalOwner,modalMember:opts?.modalOwner===void 0?scope??void 0:void 0};return insertRegistration(stack,reg),bumpStackVersion(),()=>{let i=stack.findIndex((r)=>r.id===reg.id);if(i>=0)stack.splice(i,1);bumpStackVersion()}},[])}function pageCloseBindings(cmd){return[{key:"escape",cmd},{key:"q",cmd},{key:"ctrl+c",cmd}]}function currentPaletteActions(){return capturePaletteActions(stack)}import{createCliRenderer}from"@opentui/core";var import_react21=__toESM(require_react_production(),1);async function connectPaneOrchestrator(options={}){let tag=options.logTag??"orch-connect",connect=options.connect??connectIfRunning,remote=null;try{let client=await connect();if(!client)return logClient(tag,"no daemon running \u2014 caller degrades"),null;return remote=new RemoteOrchestrator(client,{...options.orchestratorOptions,channels:options.channels}),await remote.init(),remote}catch(err){return logClientError(tag,err),remote?.dispose(),null}}var cached=null;function applyUserKeybindings(){if(cached)return cached;let{report,prefix}=resolveUserKeybindings(readKeybindingsFile(),RoveKeymap,process.platform);if(report.exists)configurePrefix(prefix);for(let w of report.warnings)console.warn(`[rove/keybindings] ${w}`);return cached=report,cached}function pluginKeybindings(){return userKeybindingsReport().plugins}function userKeybindingsReport(){return cached??applyUserKeybindings()}function reloadUserKeybindings(){cached=null,resetKeybindingsFileCache(),resetKeymapToDefaults(),resetPrefixConfiguration();let report=applyUserKeybindings();return bumpKeymapVersion(),report}var UI_PREFS_FOCUS_ACCENT_SLOTS=["primary","success","info"];var UI_PREFS_THEME_MODES=["dark","light","auto"];function applyUiPrefs(target,prefs){if(typeof prefs.theme==="string"&&prefs.theme.length>0&&prefs.theme!==target.selectedTheme()){if(!target.hasTheme(prefs.theme))target.reloadUserThemes();if(target.hasTheme(prefs.theme))target.setTheme(prefs.theme)}if(prefs.themeMode===null||typeof prefs.themeMode==="string"){let mode=normalizeThemeMode(prefs.themeMode);if(mode&&mode!==target.themeMode())target.setThemeMode(mode)}if(typeof prefs.transparentBackground==="boolean"&&prefs.transparentBackground!==target.transparentBackground())target.setTransparentBackground(prefs.transparentBackground);if(prefs.focusAccent===null||typeof prefs.focusAccent==="string"){let slot=normalizeFocusAccent(prefs.focusAccent);if(slot&&slot!==target.focusAccent())target.setFocusAccent(slot)}}function normalizeFocusAccent(value){if(value===null)return"primary";return UI_PREFS_FOCUS_ACCENT_SLOTS.includes(value)?value:null}function normalizeThemeMode(value){if(value===null)return"dark";return UI_PREFS_THEME_MODES.includes(value)?value:null}var STALL_HEARTBEAT_MS=1000,STALL_THRESHOLD_MS=2000;function stallReport(gapMs,mem,heartbeatMs=STALL_HEARTBEAT_MS,thresholdMs=STALL_THRESHOLD_MS){let stallMs=gapMs-heartbeatMs;if(stallMs<thresholdMs)return null;let mb=(n)=>Math.round(n/1048576);return`event loop stalled ~${stallMs}ms \u2014 rss=${mb(mem.rss)}MB heapUsed=${mb(mem.heapUsed)}MB`}function installEventLoopStallTelemetry(){let last=Date.now(),timer=setInterval(()=>{let now=Date.now(),gap=now-last;last=now;let report=stallReport(gap,process.memoryUsage());if(report)logClient("stall",report)},STALL_HEARTBEAT_MS);return timer.unref?.(),()=>clearInterval(timer)}var KITTY_KEYBOARD={};function hostTargetFps(){return 60}function hostRenderOptions(onDestroy){let base={backgroundColor:"transparent",externalOutputMode:"passthrough",exitOnCtrlC:!1,screenMode:"alternate-screen",useKittyKeyboard:KITTY_KEYBOARD,targetFps:hostTargetFps()};return onDestroy?{...base,onDestroy}:base}function inlineRenderOptions(heightRows,onDestroy){let base={backgroundColor:"transparent",exitOnCtrlC:!1,screenMode:"split-footer",footerHeight:heightRows,useKittyKeyboard:KITTY_KEYBOARD};return onDestroy?{...base,onDestroy}:base}function installExitRestoreBackstop(renderer){process.on("exit",()=>renderer.destroy())}var BRACKETED_PASTE_ON="\x1B[?2004h",BRACKETED_PASTE_OFF="\x1B[?2004l";function installBracketedPasteMode(stdout=process.stdout){if(!stdout.isTTY)return()=>{};let write=(seq)=>{try{stdout.write(seq)}catch{}};write(BRACKETED_PASTE_ON);let restored=!1,restore=()=>{if(restored)return;restored=!0,write(BRACKETED_PASTE_OFF)};return process.on("exit",restore),restore}var exitCriticalWork=new Set;async function whenExitReady(){while(exitCriticalWork.size>0)await Promise.allSettled([...exitCriticalWork])}function installPaneExitBackstop(opts={}){let ceilingMs=opts.ceilingMs??5000,exit=opts.exit??((code)=>process.exit(code)),exitScheduled=!1,exited=!1,exitOnce=()=>{if(exited)return;exited=!0,exit(0)},scheduleExit=()=>{if(exitScheduled)return;exitScheduled=!0;let ceiling=setTimeout(()=>{console.error(`[rove] exit backstop: ${exitCriticalWork.size} task(s) still in flight after ${ceilingMs}ms \u2014 exiting anyway`),exitOnce()},ceilingMs);ceiling.unref?.(),whenExitReady().then(()=>{clearTimeout(ceiling),exitOnce()})};for(let signal of["SIGHUP","SIGTERM","SIGINT"])process.on(signal,scheduleExit)}function installOrphanExitWatchdog(intervalMs=5000){let timer=setInterval(()=>{if(process.ppid===1)process.exit(0)},intervalMs);return timer.unref?.(),()=>clearInterval(timer)}var SYNC_START=Buffer.from("\x1B[?2026h"),SYNC_END=Buffer.from("\x1B[?2026l");class ImeAnchorController{owner=null;anchor=null;claim(owner,anchor){this.owner=owner,this.anchor={x:Math.max(0,Math.trunc(anchor.x)),y:Math.max(0,Math.trunc(anchor.y))}}release(owner){if(this.owner!==owner)return!1;return this.owner=null,this.anchor=null,!0}current(){return this.anchor}}var imeAnchorController=new ImeAnchorController;class ImeAnchorFrameTransformer{controller;pending=Buffer.alloc(0);frame=Buffer.alloc(0);constructor(controller){this.controller=controller}push(chunk){let data=this.pending.length>0?Buffer.concat([this.pending,chunk]):chunk;this.pending=Buffer.alloc(0);let output=[],offset=0;while(offset<data.length){if(this.frame.length===0){let start=data.indexOf(SYNC_START,offset);if(start<0){let tail2=data.subarray(offset),pendingLength2=longestMarkerPrefixSuffix(tail2,[SYNC_START]),safeLength2=tail2.length-pendingLength2;if(safeLength2>0)output.push(tail2.subarray(0,safeLength2));if(pendingLength2>0)this.pending=Buffer.from(tail2.subarray(safeLength2));break}if(start>offset)output.push(data.subarray(offset,start));this.frame=Buffer.from(SYNC_START),offset=start+SYNC_START.length;continue}let end=data.indexOf(SYNC_END,offset),restart=data.indexOf(SYNC_START,offset);if(restart>=0&&(end<0||restart<end)){this.frame=Buffer.from(SYNC_START),offset=restart+SYNC_START.length;continue}if(end>=0){if(end>offset)this.frame=Buffer.concat([this.frame,data.subarray(offset,end)]);output.push(this.frame);let anchor=this.controller.current();if(anchor)output.push(Buffer.from(`\x1B[${anchor.y+1};${anchor.x+1}H\x1B[?25l`));output.push(SYNC_END),this.frame=Buffer.alloc(0),offset=end+SYNC_END.length;continue}let tail=data.subarray(offset),pendingLength=longestMarkerPrefixSuffix(tail,[SYNC_START,SYNC_END]),safeLength=tail.length-pendingLength;if(safeLength>0)this.frame=Buffer.concat([this.frame,tail.subarray(0,safeLength)]);if(pendingLength>0)this.pending=Buffer.from(tail.subarray(safeLength));break}return output.length>0?Buffer.concat(output):Buffer.alloc(0)}flush(){if(this.frame.length>0)return this.frame=Buffer.alloc(0),this.pending=Buffer.alloc(0),Buffer.alloc(0);let pending=this.pending;return this.pending=Buffer.alloc(0),pending}}function longestMarkerPrefixSuffix(bytes,markers){let max=Math.min(bytes.length,Math.max(...markers.map((marker)=>marker.length-1)));for(let length=max;length>0;length-=1){let suffix=bytes.subarray(bytes.length-length);if(markers.some((marker)=>length<marker.length&&suffix.equals(marker.subarray(0,length))))return length}return 0}function asBuffer(chunk,encodingOrCallback){if(typeof chunk!=="string")return Buffer.from(chunk);let encoding=typeof encodingOrCallback==="string"?encodingOrCallback:void 0;return Buffer.from(chunk,encoding)}function writeCallback(encodingOrCallback,maybeCallback){return typeof encodingOrCallback==="function"?encodingOrCallback:maybeCallback}function createImeAnchoredOutput(target,controller=imeAnchorController){let transformer=new ImeAnchorFrameTransformer(controller),exposedWrite=(chunk,encodingOrCallback,maybeCallback)=>{let transformed=transformer.push(asBuffer(chunk,encodingOrCallback)),callback=writeCallback(encodingOrCallback,maybeCallback);if(transformed.length===0){if(callback)queueMicrotask(()=>callback(null));return!0}return callback?target.write(transformed,callback):target.write(transformed)};return{stdout:new Proxy(target,{get(stream,property){if(property==="write")return exposedWrite;let value=Reflect.get(stream,property,stream);return typeof value==="function"?value.bind(stream):value},set(stream,property,value){if(property==="write")return exposedWrite=value,!0;return Reflect.set(stream,property,value,stream)}}),flush(){let pending=transformer.flush();if(pending.length>0)target.write(pending)}}}var IME_ANCHOR_PLATFORMS=new Set(["darwin","win32"]);function createHostImeOutput(opts){if(!IME_ANCHOR_PLATFORMS.has(opts.platform)||!opts.fullscreen)return{active:!1,rendererOptions:{},attach:()=>()=>{},flush:()=>{}};let output=createImeAnchoredOutput(opts.stdout,opts.controller);return{active:!0,rendererOptions:{stdout:output.stdout,remote:!1},attach:(renderer)=>installRendererResizeForwarder(renderer,opts.stdout),flush:()=>output.flush()}}function installRendererResizeForwarder(renderer,terminal,signals=process){let onResize=()=>{let{columns:width,rows:height}=terminal;if(!width||!height)return;renderer.resize(width,height)};return signals.on("SIGWINCH",onResize),()=>signals.removeListener("SIGWINCH",onResize)}function needsScreenSelfHeal(platform){return platform==="win32"}function requestFullRepaint(renderer){if(renderer.screenMode!=="alternate-screen")return!1;let internals=renderer;return internals.forceFullRepaintRequested=!0,renderer.requestRender(),!0}function writeThroughRenderer(renderer,chunk,fallback=process.stdout){let writeOut=renderer?.writeOut;try{if(typeof writeOut==="function")writeOut.call(renderer,chunk);else fallback.write(chunk)}catch{}}function redrawScreen(renderer){if(renderer.screenMode!=="alternate-screen")return!1;return writeThroughRenderer(renderer,"\x1B[H\x1B[2J"),requestFullRepaint(renderer)}function installScreenSelfHeal(opts){let platform=opts.platform??process.platform;if(!needsScreenSelfHeal(platform))return()=>{};let{renderer}=opts,repaint=()=>{requestFullRepaint(renderer)};return renderer.on("resize",repaint),renderer.on("focus",repaint),()=>{renderer.off("resize",repaint),renderer.off("focus",repaint)}}var import_react9=__toESM(require_react_production(),1);var PANE_ORDER=["sidebar","workspace","files","terminal"],FocusContext=import_react9.createContext(null);function FocusProvider(props){let[focused,setFocusedState]=import_react9.useState(props.initial??"sidebar"),renderer=useRenderer(),focusedRef=useLatest(focused),setFocused=import_react9.useCallback((pane)=>{if(focusedRef.current===pane)return;let current=renderer?.currentFocusedRenderable;if(current&&!current.isDestroyed)try{current.blur()}catch{}setFocusedState(pane)},[renderer]),cycle=import_react9.useCallback((delta)=>{let next=(PANE_ORDER.indexOf(focusedRef.current)+delta+PANE_ORDER.length)%PANE_ORDER.length;setFocused(PANE_ORDER[next])},[setFocused]),value=import_react9.useMemo(()=>({focused,is:(pane)=>focused===pane,setFocused,cycle}),[focused,setFocused,cycle]);return $jsx(FocusContext.Provider,{value,children:props.children})}function useFocus(){let ctx=import_react9.useContext(FocusContext);if(!ctx)throw Error("useFocus: must be called inside <FocusProvider>. See src/tui-react/context/focus.tsx.");return ctx}function useOptionalFocus(){return import_react9.useContext(FocusContext)}var import_react10=__toESM(require_react_production(),1);var WRITE_DEBOUNCE_MS=250;function createKvCore(){let store2=createStateCell(loadStateFile(),"kv.snapshot"),dirtyKeys=new Set,quiet=new Map,seeded=new Map,writeTimer=null,errorListeners=new Set,reportedKeys=new Set;function reportWriteError(err){let fresh=[...dirtyKeys].filter((key)=>!reportedKeys.has(key));if(fresh.length===0)return;for(let key of fresh)reportedKeys.add(key);let failure={keys:fresh,file:kvStatePath(),error:err};for(let listener2 of errorListeners)listener2(failure)}function writeNow(label){if(dirtyKeys.size===0)return!0;try{let patch={},snap=store2.get();for(let key of dirtyKeys)patch[key]=quiet.has(key)?quiet.get(key):snap[key];return patchStateFile(patch,"strict"),dirtyKeys.clear(),reportedKeys.clear(),!0}catch(err){return console.error(`[rove] kv ${label} failed:`,err),reportWriteError(err),!1}}function cancelTimer(){if(writeTimer)clearTimeout(writeTimer),writeTimer=null}function scheduleWrite(){cancelTimer(),writeTimer=setTimeout(()=>{writeTimer=null,writeNow("write")},WRITE_DEBOUNCE_MS)}return{snapshot:store2.get,subscribe:store2.subscribe,get(key,defaultValue){return(quiet.has(key)?quiet.get(key):store2.get()[key])??defaultValue},set(key,value){quiet.delete(key),store2.update((s)=>{if(value!==void 0)return{...s,[key]:value};if(!(key in s))return s;let next={...s};return delete next[key],next}),dirtyKeys.add(key),scheduleWrite()},setQuiet(key,value){quiet.set(key,value),dirtyKeys.add(key),scheduleWrite()},seed(key,value){if(!seeded.has(key))seeded.set(key,value);if(quiet.has(key)||store2.get()[key]!==void 0)return;store2.update((s)=>({...s,[key]:value}))},flush(){return cancelTimer(),writeNow("flush")},clear(){try{replaceStateFile({})}catch(err){return console.error("[rove] kv clear write failed:",err),!1}return cancelTimer(),dirtyKeys.clear(),reportedKeys.clear(),quiet.clear(),store2.set({}),!0},reload(){try{readStateFileStrict(),cancelTimer(),writeNow("reload flush");let fresh=readStateFileStrict(),before=store2.get(),next={...fresh};for(let[key,value]of seeded)if(next[key]===void 0)next[key]=value;for(let key of dirtyKeys)if(before[key]===void 0)delete next[key];else next[key]=before[key];for(let key of[...quiet.keys()])if(!dirtyKeys.has(key))quiet.delete(key);if(dirtyKeys.size>0)scheduleWrite();let changed=0;for(let key of new Set([...Object.keys(before),...Object.keys(next)]))if(JSON.stringify(before[key])!==JSON.stringify(next[key]))changed++;if(changed>0)store2.set(next);return{ok:!0,changed}}catch(error){return{ok:!1,error}}},onWriteError(listener2){return errorListeners.add(listener2),()=>{errorListeners.delete(listener2)}}}}var Ctx=import_react10.createContext(null);function KVProvider(props){let[core]=import_react10.useState(createKvCore),snapshot=import_react10.useSyncExternalStore(core.subscribe,core.snapshot,core.snapshot);import_react10.useEffect(()=>{let flush=()=>{core.flush()};return process.on("exit",flush),()=>{process.off("exit",flush)}},[core]);let value=import_react10.useMemo(()=>({ready:!0,store:snapshot,signal(name,defaultValue){return core.seed(name,defaultValue),[()=>core.get(name)??defaultValue,(next)=>core.set(name,next)]},get:core.get,set:core.set,setQuiet:core.setQuiet,flush:core.flush,clear:core.clear,reload:core.reload,onWriteError:core.onWriteError}),[core,snapshot]);return $jsx(Ctx.Provider,{value,children:props.children})}function useKV(){let value=import_react10.useContext(Ctx);if(!value)throw Error("KV context must be used within a context provider");return value}function useOptionalKV(){return import_react10.useContext(Ctx)??null}var import_react13=__toESM(require_react_production(),1);var import_react12=__toESM(require_react_production(),1);var TOAST_DURATION_MS=4500;function unreadKey(taskId,tabId){return`${taskId}:${tabId}`}function addUnread(prev,input){let key=unreadKey(input.taskId,input.tabId),existing=prev.get(key);if(existing==="needs_input"||existing==="error")return prev;let next=new Map(prev);return next.set(key,input.kind),next}function removeUnread(prev,taskId,tabId){let key=unreadKey(taskId,tabId);if(!prev.has(key))return prev;let next=new Map(prev);return next.delete(key),next}function shouldShowToast(kind,toastEnabled){return kind==="error"||toastEnabled}function shouldPlaySound(input,soundEnabled){return soundEnabled&&input.silent!==!0}function attentionKindFor(state){if(state==="permission_needed")return"needs_input";if(state==="error"||state==="rate_limited"||state==="dead")return"error";if(state==="turn_complete")return"done";return null}function chipAttentionKind(turn){if(turn==="done")return"done";if(turn==="error"||turn==="rate_limited"||turn==="dead")return"error";if(turn==="needs_input")return"needs_input";return null}function attentionEdges(prev,next,skip,kindFor){if(prev===null)return[];let out=[];for(let[key,state]of next){if(key===skip)continue;if(prev.get(key)===state)continue;let kind=kindFor(state);if(kind)out.push({key,kind})}return out}function sanitizeOscBody(body){let out="",segmentStart=0;for(let i=0;i<body.length;i++){let code=body.charCodeAt(i);if(code>31&&(code<127||code>159))continue;out+=`${body.slice(segmentStart,i)} `,segmentStart=i+1}return segmentStart===0?body:out+body.slice(segmentStart)}function osc9(body){return`\x1B]9;${sanitizeOscBody(body)}\x07`}import{existsSync,mkdirSync}from"fs";import{tmpdir}from"os";import{basename,delimiter,extname,isAbsolute,join,resolve}from"path";var pulse_default="../pulse-ynhb2ave.wav";function scaleWavVolume(wav,volume){let gain=Math.min(1,Math.max(0,volume));if(wav.length<12)return null;if(wav.readUInt32BE(0)!==1380533830||wav.readUInt32BE(8)!==1463899717)return null;let bitsPerSample,format,data;for(let offset=12;offset+8<=wav.length;){let id=wav.readUInt32BE(offset),size=wav.readUInt32LE(offset+4),start=offset+8,end=start+size;if(size<0||end>wav.length)return null;if(id===1718449184){if(size<16)return null;format=wav.readUInt16LE(start),bitsPerSample=wav.readUInt16LE(start+14)}else if(id===1684108385)data={start,end};offset=end+size%2}if(format!==1||bitsPerSample!==16||!data)return null;if((data.end-data.start)%2!==0)return null;let out=Buffer.from(wav);if(gain===1)return out;for(let i=data.start;i<data.end;i+=2){let scaled=Math.round(out.readInt16LE(i)*gain);out.writeInt16LE(Math.min(32767,Math.max(-32768,scaled)),i)}return out}var pulseAsset=isAbsolute(pulse_default)?pulse_default:resolve(import.meta.dir,pulse_default),DIR=join(tmpdir(),"rove-sfx"),PLAYERS=["ffplay","mpv","mpg123","mpg321","mplayer","afplay","play","omxplayer","aplay","cmdmp3","cvlc","powershell.exe"];function args(player,file){if(player==="ffplay")return[player,"-autoexit","-nodisp",file];if(player==="mpv")return[player,"--no-video","--audio-display=no",file];if(player==="mplayer")return[player,"-vo","null",file];if(player==="cvlc")return[player,"--play-and-exit",file];if(player==="powershell.exe")return[player,"-c",`(New-Object Media.SoundPlayer '${file.replace(/'/g,"''")}').PlaySync()`];return[player,file]}var cachedPlayer,cachedPaths=new Map;function pathDirs(rawPath,delim=delimiter){return rawPath.split(delim).filter(Boolean)}function pickPlayer(){if(cachedPlayer!==void 0)return cachedPlayer;let segments=pathDirs(process.env.PATH??"");return cachedPlayer=PLAYERS.find((p)=>segments.some((dir)=>existsSync(join(dir,p))))??null,cachedPlayer}function assetNameFor(assetPath,volume){let name=basename(assetPath),ext=extname(name);return`${name.slice(0,name.length-ext.length)}@${Math.round(volume*100)}${ext}`}async function ensureAsset(volume){let cached2=cachedPaths.get(volume);if(cached2)return cached2;let pending=(async()=>{mkdirSync(DIR,{recursive:!0});let dest=join(DIR,assetNameFor(pulseAsset,volume)),out=Bun.file(dest);if(await out.exists())return dest;let source=Buffer.from(await Bun.file(pulseAsset).arrayBuffer());return await Bun.write(out,scaleWavVolume(source,volume)??source),dest})();return cachedPaths.set(volume,pending),pending}function pulse(volume=persistedSoundVolume()){if(!(volume>0))return;let player=pickPlayer();if(!player)return;ensureAsset(volume).then((path)=>{try{Bun.spawn(args(player,path),{stdin:"ignore",stdout:"ignore",stderr:"ignore"}).unref?.()}catch{}}).catch(()=>{return})}var ctx=import_react12.createContext(null);function NotificationsProvider(props){let[toasts,setToasts]=import_react12.useState([]),[unread,setUnread]=import_react12.useState(new Map),kv=useOptionalKV(),renderer=useRenderer(),snapshot=import_react12.useMemo(()=>loadStateFile(),[]),prefs=import_react12.useMemo(()=>({"notifications.sound.enabled":kv?.get("notifications.sound.enabled")??snapshot["notifications.sound.enabled"],"notifications.toast.enabled":kv?.get("notifications.toast.enabled")??snapshot["notifications.toast.enabled"]}),[kv,snapshot]),counter=import_react12.useRef(0),timers=import_react12.useRef(new Set);import_react12.useEffect(()=>()=>{for(let id of timers.current)clearTimeout(id);timers.current.clear()},[]);let dismiss=import_react12.useCallback((id)=>{setToasts((prev)=>prev.filter((t2)=>t2.id!==id))},[]),notify=import_react12.useCallback((input)=>{setUnread((prev)=>addUnread(prev,input));let soundEnabled=prefs["notifications.sound.enabled"]!==!1;if(shouldPlaySound(input,soundEnabled))writeThroughRenderer(renderer,`\x07${osc9(`Rove \u2014 ${input.title}`)}`),pulse();let toastEnabled=prefs["notifications.toast.enabled"]!==!1;if(shouldShowToast(input.kind,toastEnabled)){let id=++counter.current;setToasts((prev)=>[...prev,{id,...input}]);let timer=setTimeout(()=>{timers.current.delete(timer),dismiss(id)},TOAST_DURATION_MS);timers.current.add(timer)}},[prefs,dismiss,renderer]),markRead=import_react12.useCallback((taskId,tabId)=>{setUnread((prev)=>removeUnread(prev,taskId,tabId))},[]),value=import_react12.useMemo(()=>({toasts,unread,notify,dismiss,markRead}),[toasts,unread,notify,dismiss,markRead]);return $jsx(ctx.Provider,{value,children:props.children})}function useNotifications(){let value=import_react12.useContext(ctx);if(!value)throw Error("useNotifications must be used within a NotificationsProvider");return value}function useOptionalNotifications(){return import_react12.useContext(ctx)}function KvWriteErrorToasts(){let kv=useOptionalKV(),notifications=useOptionalNotifications();return import_react13.useEffect(()=>{if(!kv||!notifications)return;return kv.onWriteError((failure)=>{notifications.notify({taskId:"",tabId:"",kind:"error",title:t("settings.stateWrite.failedTitle"),body:t("settings.stateWrite.failedBody",{file:tildify(failure.file),keys:failure.keys.join(", ")})})})},[kv,notifications]),null}var import_react17=__toESM(require_react_production(),1);function isNarrowWidth(cols){return cols<70}function narrowSurface(args2){if(args2.focusedPane==="sidebar")return"sidebar";return args2.hasSelection||args2.hasOpenPage?"content":"sidebar"}var import_react15=__toESM(require_react_production(),1);var stores=new WeakMap;function terminalSizeStore(source){let existing=stores.get(source);if(existing)return existing;let listeners=new Set,size={width:source.width,height:source.height},notify=()=>{for(let listener2 of listeners)listener2()},store2={subscribe(listener2){if(listeners.add(listener2),listeners.size===1)source.on("resize",notify);return()=>{if(listeners.delete(listener2),listeners.size===0)source.off("resize",notify)}},snapshot(){if(size.width!==source.width||size.height!==source.height)size={width:source.width,height:source.height};return size}};return stores.set(source,store2),store2}function useTerminalSize(){let store2=terminalSizeStore(useRenderer());return import_react15.useSyncExternalStore(store2.subscribe,store2.snapshot)}function useDialogPaddingX(){let dims=useTerminalSize();return isNarrowWidth(dims.width)?1:2}var DIALOG_CONTENT_OPACITY=0.5,TRANSPARENT_DIALOG_CONTENT_OPACITY=0.75;function Dialog(props){let dimensions=useTerminalSize(),{theme}=useTheme(),renderer=useRenderer(),dismissRef=import_react17.useRef(!1),width=props.size==="xlarge"?140:props.size==="large"?110:props.size==="small"?50:80,VERTICAL_MARGIN=2,upperFifth=props.placement==="upper-fifth"&&!isNarrowWidth(dimensions.width),headerTop=Math.max(2,Math.floor(dimensions.height/5)),cardTop=upperFifth?Math.max(2,headerTop-1):0,maxCardHeight=Math.max(8,upperFifth?dimensions.height-cardTop-2:dimensions.height-4);return $jsx("box",{onMouseDown:()=>{dismissRef.current=!!renderer?.getSelection()},onMouseUp:()=>{if(dismissRef.current){dismissRef.current=!1;return}props.onClose?.()},width:dimensions.width,height:dimensions.height,alignItems:"center",justifyContent:upperFifth?"flex-start":"center",paddingTop:cardTop,position:"absolute",zIndex:3000,left:0,top:0,shouldFill:!1,children:$jsx("box",{onMouseUp:(e)=>{dismissRef.current=!1,e.stopPropagation()},width,maxWidth:dimensions.width-2,maxHeight:maxCardHeight,flexShrink:1,flexGrow:0,backgroundColor:theme.backgroundDialog,paddingTop:1,children:props.children})})}var entrySeq=0,ctx2=import_react17.createContext(null);function DialogProvider(props){let[stack2,setStack]=import_react17.useState([]),[size,setSize]=import_react17.useState("medium"),[placement,setPlacement]=import_react17.useState("center"),renderer=useRenderer(),{transparentBackground:transparentBackground2}=useTheme(),focusRef=import_react17.useRef(null),refocusTimer=import_react17.useRef(null);import_react17.useEffect(()=>()=>{if(refocusTimer.current)clearTimeout(refocusTimer.current)},[]);let refocus=import_react17.useCallback(()=>{if(refocusTimer.current)clearTimeout(refocusTimer.current);refocusTimer.current=setTimeout(()=>{let focus=focusRef.current;if(!focus||focus.isDestroyed)return;function find(item){for(let child of item.getChildren()){if(child===focus)return!0;if(find(child))return!0}return!1}let root=renderer?.root;if(!root)return;if(!find(root))return;focus.focus()},1)},[renderer]),stackRef=useLatest(stack2),captureFocusIfFirst=import_react17.useCallback(()=>{if(refocusTimer.current)clearTimeout(refocusTimer.current);if(stackRef.current.length===0)focusRef.current=renderer?.currentFocusedRenderable??null,focusRef.current?.blur()},[renderer]),dismissTop=import_react17.useCallback(()=>{let selection=renderer?.getSelection();if(selection){if(renderer?.clearSelection(),selection.getSelectedText())return}stackRef.current.at(-1)?.onClose?.(),setStack((s)=>s.slice(0,-1)),refocus()},[renderer,refocus]),value=import_react17.useMemo(()=>({clear(options){for(let item of stackRef.current)item.onClose?.();if(setSize("medium"),setPlacement("center"),setStack([]),options?.refocus===!1)focusRef.current=null;else refocus()},replace(thunk,onClose){captureFocusIfFirst();for(let item of stackRef.current)item.onClose?.();setSize("medium"),setPlacement("center"),setStack([{key:++entrySeq,element:thunk,onClose}])},push(thunk,onClose){captureFocusIfFirst(),setStack((s)=>[...s,{key:++entrySeq,element:thunk,onClose}])},pop(){if(stackRef.current.at(-1)?.onClose?.(),setStack((s)=>s.slice(0,-1)),stackRef.current.length<=1)refocus()},get stack(){return stackRef.current},get size(){return size},setSize,get placement(){return placement},setPlacement}),[stack2,size,placement,refocus,captureFocusIfFirst]),top=stack2.at(-1),contentOpacity=top?transparentBackground2?TRANSPARENT_DIALOG_CONTENT_OPACITY:DIALOG_CONTENT_OPACITY:1;return $jsxs(ctx2.Provider,{value,children:[$jsx("box",{flexGrow:1,backgroundColor:top&&!transparentBackground2?"black":"transparent",children:$jsx("box",{flexGrow:1,opacity:contentOpacity,children:props.children})}),$jsx("box",{position:"absolute",zIndex:3000,children:top?$jsxs(ModalScopeContext,{value:MODAL_SCOPE,children:[$jsx(ModalBarrier,{dismissTop}),$jsx(Dialog,{onClose:()=>value.clear(),size,placement,children:top.element()},top.key)]}):null})]})}var MODAL_SCOPE=Symbol("rove.dialog.modal");function ModalBarrier(props){return useBindings(()=>({modal:!0,bindings:[{key:"escape",cmd:props.dismissTop},{key:"ctrl+c",cmd:props.dismissTop}]}),{modalOwner:MODAL_SCOPE}),null}function useDialog(){let value=import_react17.useContext(ctx2);if(!value)throw Error("useDialog must be used within a DialogProvider");return value}function useOptionalDialog(){return import_react17.useContext(ctx2)}function showDialog(dialog,body,opts){return new Promise((resolve2)=>{if(dialog.replace(()=>body(resolve2),()=>resolve2(void 0)),opts?.size)dialog.setSize(opts.size)})}var import_react18=__toESM(require_react_production(),1);function PaneCrashFallback(props){let{theme}=useTheme(),t2=useT(),sizing=props.width===void 0?{flexGrow:1}:{width:props.width,flexShrink:0};return $jsxs("box",{...sizing,flexDirection:"column",backgroundColor:theme.background,paddingLeft:1,paddingTop:1,gap:1,children:[$jsx("text",{fg:theme.error,wrapMode:"word",children:props.region?t2("common.paneCrash.regionTitle",{region:t2(`common.paneCrash.region.${props.region}`)}):t2("common.paneCrash.title")}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t2(props.region?"common.paneCrash.regionHint":"common.paneCrash.hint")}),$jsx("text",{fg:theme.focusAccent,onMouseUp:props.onRetry,children:t2("common.paneCrash.retry")})]})}function formatPaneCrashDiagnostic(region,error,info){let base=error instanceof Error?error.stack??error.message:String(error),componentStack=info.componentStack?.trim()||"(unavailable)",stateChanges=recentStateChangesForDiagnostics();return`region: ${region??"root"}
2
+ import{RoveKeymap,armPrefixNow,bindingReachability,configurePrefix,currentPrefixConfiguration,dispatchKeyEvent,inputPassthroughReachable,insertRegistration,invokeArmedPrefixAction,isCtrlModifierKeyName,persistedSoundVolume,prefixHudHideDirect,prefixHudShowDirect,readKeybindingsFile,resetKeybindingsFileCache,resetPrefixConfiguration,resetPrefixState,resolveUserKeybindings}from"./chunk-yknavm97.js";import{RemoteOrchestrator}from"./chunk-pj3gnkfr.js";import{$Fragment,$jsx,$jsxs,createRoot,flushSync,useRenderer}from"./chunk-29kvfqeh.js";import{require_react_production}from"./chunk-2wd4744g.js";import{updaterShell,updaterShellFailureHint}from"./chunk-e8pv3b92.js";import{BUNDLED_THEMES,DEFAULT_THEME,DEFAULT_THEME_MODE,applyDisplayOverlay,readPersistedUiPrefs,resolveTheme,resolveThemeMode}from"./chunk-zcadc92x.js";import{loadUserThemes}from"./chunk-pdvyfz3n.js";import{connectIfRunning}from"./chunk-9sta3ak4.js";import{tildify}from"./chunk-ag3txfg2.js";import{CURRENT_VERSION}from"./chunk-j6t7xvm3.js";import{loadStateFile,patchStateFile,readStateFileStrict,replaceStateFile}from"./chunk-zk5qkkb1.js";import{kvStatePath}from"./chunk-prqeddy7.js";import{localeState,setLocaleLang,t}from"./chunk-032g0ahy.js";import{isLocaleId}from"./chunk-q3xt0mqt.js";import{createStateCell,profileMark,profileTick,recentStateChangesForDiagnostics,renderProfileOn}from"./chunk-cmp64q4j.js";import{installClientCrashHandlers,logClient,logClientError,setClientLogContext}from"./chunk-hq9tbzqa.js";import{__toESM}from"./chunk-91sykzqq.js";import{RGBA}from"@opentui/core";var import_react3=__toESM(require_react_production(),1);var import_react=__toESM(require_react_production(),1);function useAccessor(state){return import_react.useSyncExternalStore(state.subscribe,state.get,state.get)}var store=createStateCell({themes:{...BUNDLED_THEMES},active:DEFAULT_THEME,mode:DEFAULT_THEME_MODE,transparentBackground:!0,focusAccent:"primary"});function listThemes(){return Object.keys(store.get().themes)}function hasTheme(name){return Boolean(store.get().themes[name])}function addTheme(name,theme){if(!name)return!1;if(!theme||typeof theme!=="object"||!theme.theme)return!1;return store.update((s)=>({...s,themes:{...s.themes,[name]:theme}})),!0}function selectedTheme(){return store.get().active}function setTheme(name){if(!hasTheme(name))return!1;return store.update((s)=>({...s,active:name})),!0}function transparentBackground(){return store.get().transparentBackground}function setTransparentBackground(v){store.update((s)=>({...s,transparentBackground:v}))}function focusAccent(){return store.get().focusAccent}function setFocusAccent(v){store.update((s)=>({...s,focusAccent:v}))}function themeMode(){return store.get().mode}function setThemeMode(mode){store.update((s)=>({...s,mode}))}var ThemeContext=import_react3.createContext(null),HOST_PALETTE_QUERY_TIMEOUT_MS=2000;function resolveActive(state,mode){let active=state.themes[state.active];if(active)return resolveTheme(active,mode);let fallback=state.themes[DEFAULT_THEME]??Object.values(state.themes)[0];if(!fallback)return resolveTheme({theme:{background:"#000000",text:"#ffffff"}},mode);return resolveTheme(fallback,mode)}function useHostThemeMode(renderer){let[mode,setMode]=import_react3.useState(()=>renderer?.themeMode??null);return import_react3.useEffect(()=>{if(!renderer)return;let onChange=(next)=>setMode(next);return renderer.on("theme_mode",onChange),setMode(renderer.themeMode),()=>{renderer.off("theme_mode",onChange)}},[renderer]),mode}function ThemeProvider(props){import_react3.useMemo(()=>{store.update((s)=>({...s,mode:props.mode??s.mode,active:props.theme&&s.themes[props.theme]?props.theme:s.active}))},[]);let state=useAccessor(store),renderer=useRenderer(),hostMode=useHostThemeMode(renderer),mode=resolveThemeMode(state.mode,hostMode),[hostBackground,setHostBackground]=import_react3.useState(null);import_react3.useEffect(()=>{if(!state.transparentBackground)return;if(renderer?.screenMode==="split-footer")return;if(!renderer)return;let cancelled=!1;return renderer.getPalette({timeout:HOST_PALETTE_QUERY_TIMEOUT_MS}).then((colors)=>{if(cancelled||!colors.defaultBackground)return;setHostBackground(RGBA.fromHex(colors.defaultBackground))}).catch(()=>{}),()=>{cancelled=!0}},[renderer,state.transparentBackground]);let theme=import_react3.useMemo(()=>applyDisplayOverlay(resolveActive(state,mode),state.focusAccent,state.transparentBackground,hostBackground??void 0),[state,mode,hostBackground]);import_react3.useEffect(()=>{if(renderer?.screenMode==="split-footer")return;renderer?.setBackgroundColor(theme.background??RGBA.fromInts(0,0,0))},[renderer,theme]);let value=import_react3.useMemo(()=>({theme,selected:state.active,transparentBackground:state.transparentBackground,focusAccent:state.focusAccent,modePreference:state.mode,mode:()=>mode,set(name){if(!hasTheme(name))return!1;return store.update((s)=>({...s,active:name})),!0},setMode(next){store.update((s)=>({...s,mode:next}))},setTransparentBackground(v){store.update((s)=>({...s,transparentBackground:v}))},setFocusAccent(v){store.update((s)=>({...s,focusAccent:v}))},preview:(options)=>applyDisplayOverlay(resolveActive({...state,active:options.themeName},resolveThemeMode(options.themeMode,hostMode)),options.focusAccent,options.transparentBackground,hostBackground??void 0),all:listThemes,has:hasTheme}),[theme,state,mode,hostMode,hostBackground]);return $jsx(ThemeContext.Provider,{value,children:props.children})}function useTheme(){let value=import_react3.useContext(ThemeContext);if(!value)throw Error("Theme context must be used within a context provider");return value}var import_react4=__toESM(require_react_production(),1);function useLang(){return useAccessor(localeState())}function useT(){let lang=useLang();return import_react4.useCallback((key,params)=>t(key,params),[lang])}var import_react7=__toESM(require_react_production(),1);var CTRL_HOLD_THRESHOLD_MS=400;function createCtrlHoldDetector(callbacks){let state={kind:"idle"},held=new Set,reset=()=>{if(state.kind==="pending")clearTimeout(state.timer);if(state.kind==="visible")callbacks.onHide();state={kind:"idle"}},cancel=()=>{reset(),held.clear()};return{keypress:(event)=>{if(!isCtrlModifierKeyName(event.name)){cancel();return}if(event.eventType==="repeat"&&held.has(event.name))return;if(event.eventType!=="press")return;if(held.add(event.name),state.kind!=="idle")return;state={kind:"pending",timer:setTimeout(()=>{state={kind:"visible"},callbacks.onReveal()},CTRL_HOLD_THRESHOLD_MS)}},keyrelease:(event)=>{if(!isCtrlModifierKeyName(event.name)||event.eventType!=="release")return;if(held.delete(event.name),held.size===0)reset()},cancel}}function availableActions(stack){let seen=new Set,actions=[],passthrough=inputPassthroughReachable(stack);for(let registration of[...stack].reverse()){let config=registration.config();if(config.enabled===!1)continue;for(let binding of config.bindings){if(binding.prefix&&currentPrefixConfiguration().key===null)continue;if(binding.yieldToPassthrough&&passthrough)continue;let chord=`${binding.prefix===!0}:${binding.key}`;if(seen.has(chord))continue;if(seen.add(chord),binding.id&&binding.action)actions.push({owner:registration.id,binding})}if(config.modal)break}return actions}function capturePaletteActions(stack){let seen=new Set;return availableActions(stack).flatMap(({owner,binding})=>{let id=binding.id;if(!id||id==="palette.open"||seen.has(id))return[];return seen.add(id),[{id,key:binding.key,prefix:binding.prefix===!0,run:()=>{let live=availableActions(stack).find((entry)=>entry.owner===owner&&entry.binding.id===id&&entry.binding.key===binding.key&&entry.binding.prefix===binding.prefix);if(!live?.binding.action)return!1;return live.binding.action.run(),!0}}]})}function bindByIds(handlers){let out=[];for(let id in handlers){let handler=handlers[id];if(!handler)continue;let action=typeof handler==="function"?void 0:handler,cmd=typeof handler==="function"?handler:()=>handler.run(),binding=findBinding(id),chords=binding?.keys??[],prefixChords=binding?.prefixKeys??[];if(chords.length===0&&prefixChords.length===0){console.warn(`[rove/keybindings] bindByIds: id="${id}" has no chords (or doesn't exist in RoveKeymap)`);continue}chords.forEach((key,slot)=>out.push({key,cmd,action,slot,id,yieldToPassthrough:binding?.yieldToPassthrough})),prefixChords.forEach((key,slot)=>out.push({key,prefix:!0,cmd,action,slot,id}))}return out}var KEYMAP_DEFAULTS=new Map(RoveKeymap.map((b)=>[b.id,{keys:[...b.keys],prefixKeys:b.prefixKeys&&[...b.prefixKeys],hint:b.hint?{...b.hint}:void 0}]));function defaultChordsOf(id){return KEYMAP_DEFAULTS.get(id)?.keys??[]}function resetKeymapToDefaults(){for(let row of RoveKeymap){let def=KEYMAP_DEFAULTS.get(row.id);if(!def)continue;let mutable=row;mutable.keys=[...def.keys],mutable.prefixKeys=def.prefixKeys&&[...def.prefixKeys],mutable.hint=def.hint?{...def.hint}:void 0}}var keymapVersionValue=0,keymapVersionListeners=new Set;function keymapVersion(){return keymapVersionValue}function subscribeKeymapVersion(listener){return keymapVersionListeners.add(listener),()=>{keymapVersionListeners.delete(listener)}}function bumpKeymapVersion(){keymapVersionValue+=1;for(let listener of[...keymapVersionListeners])listener()}var KEYMAP_BY_ID=new Map(RoveKeymap.map((b)=>[b.id,b]));function findBinding(id){return KEYMAP_BY_ID.get(id)}var MODIFIER_GLYPH={ctrl:"\u2303",control:"\u2303",alt:"\u2325",opt:"\u2325",option:"\u2325",shift:"\u21E7",cmd:"\u2318",command:"\u2318",meta:"\u2318",super:"\u2318"},KEY_GLYPH={enter:"\u23CE",return:"\u23CE",esc:"\u238B",escape:"\u238B",space:"\u2423",up:"\u2191",down:"\u2193",left:"\u2190",right:"\u2192",backspace:"\u232B",delete:"\u2326",del:"\u2326",pgup:"\u21DE",pageup:"\u21DE",pgdn:"\u21DF",pagedown:"\u21DF",home:"\u2196",end:"\u2198"};function formatKey(k,upper){if(k.includes("/"))return k.split("/").map((part)=>formatKey(part,upper)).join("/");let low=k.toLowerCase();if(low==="tab")return"tab";let named=KEY_GLYPH[low];if(named)return named;if(/^f\d{1,2}$/.test(low))return low.toUpperCase();if(!upper)return k;if(/^[a-z]$/.test(low))return k.toUpperCase();return k.replace(/[a-z]+/gi,(run)=>run.toUpperCase())}function formatChord(chord,prefixGlyph="\u2303A"){let s=chord.trim();if(!s)return s;let pm=/^prefix\s+(.+)$/i.exec(s);if(pm){let suffix=pm[1]??"";return`${prefixGlyph} ${suffix.includes("+")?formatChord(suffix,prefixGlyph):formatKey(suffix,!0)}`}let parts=s.split("+");if(parts.length===1)return formatKey(parts[0]??"",!1);let key=parts[parts.length-1]??"";return`${parts.slice(0,-1).map((p)=>MODIFIER_GLYPH[p.toLowerCase().trim()]??p).join("")} ${formatKey(key,!0)}`}var DIRECT_GUIDE_PREFIX_ACTION_ID="prefix.moreCommands",CTRL_FOLLOW_UP_CHORD=/^ctrl\+[^+]+$/;function ctrlFollowUpKey(chord){return CTRL_FOLLOW_UP_CHORD.test(chord)?chord.slice(5):null}function shortcutCaption(input){let binding=findBinding(input.bindingId);if(!binding)return null;if(input.reachability.direct.has(input.bindingId)){let direct=binding.keys[0];if(direct)return formatChord(direct)}if(input.prefixKey&&input.reachability.prefix.has(input.bindingId)){let stroke=binding.prefixKeys?.[0];if(stroke)return`${formatChord(input.prefixKey)} ${formatChord(stroke)}`}return null}function directGuideOptions(reachability,prefixKey){let options=RoveKeymap.filter((binding)=>reachability.direct.has(binding.id)).flatMap((binding)=>{let strokes=binding.keys.flatMap((chord)=>ctrlFollowUpKey(chord)??[]);if(strokes.length>2)return[{stroke:`${strokes[0]}-${strokes.at(-1)}`,action:binding.id}];return strokes.map((stroke)=>({stroke,action:binding.id}))}),prefixStroke=prefixKey?ctrlFollowUpKey(prefixKey):null;if(prefixStroke&&reachability.prefix.size>0)options.push({stroke:prefixStroke,action:DIRECT_GUIDE_PREFIX_ACTION_ID});return options}var import_react5=__toESM(require_react_production(),1);function useLatest(value){let ref=import_react5.useRef(value);return ref.current=value,ref}var ModalScopeContext=import_react7.createContext(null),nextId=1,stack=[],installedRenderer=null,installed=null,listener=null,releaseListener=null,ctrlHoldDetector=null,supersededRenderers=new WeakSet;function ensureInstalled(renderer){if(!renderer)throw Error("useBindings: no renderer in scope; call inside a component rendered by @opentui/react.");if(installedRenderer===renderer)return;if(supersededRenderers.has(renderer))return;if(installed&&listener)installed.off("keypress",listener);if(installed&&releaseListener)installed.off("keyrelease",releaseListener);if(ctrlHoldDetector?.cancel(),installedRenderer)supersededRenderers.add(installedRenderer);stack.length=0,resetPrefixState(),installedRenderer=renderer,installed=renderer.keyInput,ctrlHoldDetector=createCtrlHoldDetector({onReveal:()=>{resetPrefixState();let options=directGuideOptions(bindingReachability(stack),currentPrefixConfiguration().key);if(options.length>0)prefixHudShowDirect(options)},onHide:prefixHudHideDirect}),listener=(evt)=>{profileTick("key"),ctrlHoldDetector?.keypress(evt),dispatchKeyEvent(stack,evt,Date.now(),{flushSync})},releaseListener=(evt)=>ctrlHoldDetector?.keyrelease(evt),installed.on("keypress",listener),installed.on("keyrelease",releaseListener)}function modalActive(){return stack.some((r)=>r.modalOwner!==void 0)}function currentBindingReachability(){return bindingReachability(stack)}function armPrefixFromCurrentStack(){return armPrefixNow(stack)}function invokeArmedPrefixActionFromCurrentStack(actionId,stroke){return invokeArmedPrefixAction(stack,actionId,stroke)}var stackVersion=0,stackListeners=new Set;function bumpStackVersion(){prefixHudHideDirect(),stackVersion++;for(let listener2 of stackListeners)listener2()}function bindingReachabilitySignature(config){let bindings=config.bindings.map((binding)=>[binding.id??"",binding.key,binding.prefix===!0?"p":"d",binding.passthrough===!0?"i":"u"].join(":")).join("|");return`${config.enabled===!1?"off":"on"};${config.modal===!0?"modal":"plain"};${bindings}`}function useBindingStackVersion(){return import_react7.useSyncExternalStore((onChange)=>{return stackListeners.add(onChange),()=>stackListeners.delete(onChange)},()=>stackVersion)}function useBindings(config,opts){let renderer=useRenderer();ensureInstalled(renderer);let configRef=useLatest(config),scope=import_react7.useContext(ModalScopeContext),reachabilitySignature=bindingReachabilitySignature(config()),previousReachabilitySignature=import_react7.useRef(reachabilitySignature);import_react7.useEffect(()=>{if(previousReachabilitySignature.current===reachabilitySignature)return;previousReachabilitySignature.current=reachabilitySignature,bumpStackVersion()},[reachabilitySignature]),import_react7.useEffect(()=>{if(supersededRenderers.has(renderer))return;if(opts?.modalOwner!==void 0)resetPrefixState();let reg={config:()=>configRef.current(),id:nextId++,modalOwner:opts?.modalOwner,modalMember:opts?.modalOwner===void 0?scope??void 0:void 0};return insertRegistration(stack,reg),bumpStackVersion(),()=>{let i=stack.findIndex((r)=>r.id===reg.id);if(i>=0)stack.splice(i,1);bumpStackVersion()}},[])}function pageCloseBindings(cmd){return[{key:"escape",cmd},{key:"q",cmd},{key:"ctrl+c",cmd}]}function currentPaletteActions(){return capturePaletteActions(stack)}import{createCliRenderer}from"@opentui/core";var import_react21=__toESM(require_react_production(),1);async function connectPaneOrchestrator(options={}){let tag=options.logTag??"orch-connect",connect=options.connect??connectIfRunning,remote=null;try{let client=await connect();if(!client)return logClient(tag,"no daemon running \u2014 caller degrades"),null;return remote=new RemoteOrchestrator(client,{...options.orchestratorOptions,channels:options.channels}),await remote.init(),remote}catch(err){return logClientError(tag,err),remote?.dispose(),null}}var cached=null;function applyUserKeybindings(){if(cached)return cached;let{report,prefix}=resolveUserKeybindings(readKeybindingsFile(),RoveKeymap,process.platform);if(report.exists)configurePrefix(prefix);for(let w of report.warnings)console.warn(`[rove/keybindings] ${w}`);return cached=report,cached}function pluginKeybindings(){return userKeybindingsReport().plugins}function userKeybindingsReport(){return cached??applyUserKeybindings()}function reloadUserKeybindings(){cached=null,resetKeybindingsFileCache(),resetKeymapToDefaults(),resetPrefixConfiguration();let report=applyUserKeybindings();return bumpKeymapVersion(),report}var UI_PREFS_FOCUS_ACCENT_SLOTS=["primary","success","info"];var UI_PREFS_THEME_MODES=["dark","light","auto"];function applyUiPrefs(target,prefs){if(typeof prefs.theme==="string"&&prefs.theme.length>0&&prefs.theme!==target.selectedTheme()){if(!target.hasTheme(prefs.theme))target.reloadUserThemes();if(target.hasTheme(prefs.theme))target.setTheme(prefs.theme)}if(prefs.themeMode===null||typeof prefs.themeMode==="string"){let mode=normalizeThemeMode(prefs.themeMode);if(mode&&mode!==target.themeMode())target.setThemeMode(mode)}if(typeof prefs.transparentBackground==="boolean"&&prefs.transparentBackground!==target.transparentBackground())target.setTransparentBackground(prefs.transparentBackground);if(prefs.focusAccent===null||typeof prefs.focusAccent==="string"){let slot=normalizeFocusAccent(prefs.focusAccent);if(slot&&slot!==target.focusAccent())target.setFocusAccent(slot)}}function normalizeFocusAccent(value){if(value===null)return"primary";return UI_PREFS_FOCUS_ACCENT_SLOTS.includes(value)?value:null}function normalizeThemeMode(value){if(value===null)return"dark";return UI_PREFS_THEME_MODES.includes(value)?value:null}var STALL_HEARTBEAT_MS=1000,STALL_THRESHOLD_MS=2000;function stallReport(gapMs,mem,heartbeatMs=STALL_HEARTBEAT_MS,thresholdMs=STALL_THRESHOLD_MS){let stallMs=gapMs-heartbeatMs;if(stallMs<thresholdMs)return null;let mb=(n)=>Math.round(n/1048576);return`event loop stalled ~${stallMs}ms \u2014 rss=${mb(mem.rss)}MB heapUsed=${mb(mem.heapUsed)}MB`}function installEventLoopStallTelemetry(){let last=Date.now(),timer=setInterval(()=>{let now=Date.now(),gap=now-last;last=now;let report=stallReport(gap,process.memoryUsage());if(report)logClient("stall",report)},STALL_HEARTBEAT_MS);return timer.unref?.(),()=>clearInterval(timer)}var KITTY_KEYBOARD={};function hostTargetFps(){return 60}function hostRenderOptions(onDestroy){let base={backgroundColor:"transparent",externalOutputMode:"passthrough",exitOnCtrlC:!1,screenMode:"alternate-screen",useKittyKeyboard:KITTY_KEYBOARD,targetFps:hostTargetFps()};return onDestroy?{...base,onDestroy}:base}function inlineRenderOptions(heightRows,onDestroy){let base={backgroundColor:"transparent",exitOnCtrlC:!1,screenMode:"split-footer",footerHeight:heightRows,useKittyKeyboard:KITTY_KEYBOARD};return onDestroy?{...base,onDestroy}:base}function installExitRestoreBackstop(renderer){process.on("exit",()=>renderer.destroy())}var BRACKETED_PASTE_ON="\x1B[?2004h",BRACKETED_PASTE_OFF="\x1B[?2004l";function installBracketedPasteMode(stdout=process.stdout){if(!stdout.isTTY)return()=>{};let write=(seq)=>{try{stdout.write(seq)}catch{}};write(BRACKETED_PASTE_ON);let restored=!1,restore=()=>{if(restored)return;restored=!0,write(BRACKETED_PASTE_OFF)};return process.on("exit",restore),restore}var exitCriticalWork=new Set;async function whenExitReady(){while(exitCriticalWork.size>0)await Promise.allSettled([...exitCriticalWork])}function installPaneExitBackstop(opts={}){let ceilingMs=opts.ceilingMs??5000,exit=opts.exit??((code)=>process.exit(code)),exitScheduled=!1,exited=!1,exitOnce=()=>{if(exited)return;exited=!0,exit(0)},scheduleExit=()=>{if(exitScheduled)return;exitScheduled=!0;let ceiling=setTimeout(()=>{console.error(`[rove] exit backstop: ${exitCriticalWork.size} task(s) still in flight after ${ceilingMs}ms \u2014 exiting anyway`),exitOnce()},ceilingMs);ceiling.unref?.(),whenExitReady().then(()=>{clearTimeout(ceiling),exitOnce()})};for(let signal of["SIGHUP","SIGTERM","SIGINT"])process.on(signal,scheduleExit)}function installOrphanExitWatchdog(intervalMs=5000){let timer=setInterval(()=>{if(process.ppid===1)process.exit(0)},intervalMs);return timer.unref?.(),()=>clearInterval(timer)}var SYNC_START=Buffer.from("\x1B[?2026h"),SYNC_END=Buffer.from("\x1B[?2026l");class ImeAnchorController{owner=null;anchor=null;claim(owner,anchor){this.owner=owner,this.anchor={x:Math.max(0,Math.trunc(anchor.x)),y:Math.max(0,Math.trunc(anchor.y))}}release(owner){if(this.owner!==owner)return!1;return this.owner=null,this.anchor=null,!0}current(){return this.anchor}}var imeAnchorController=new ImeAnchorController;class ImeAnchorFrameTransformer{controller;pending=Buffer.alloc(0);frame=Buffer.alloc(0);constructor(controller){this.controller=controller}push(chunk){let data=this.pending.length>0?Buffer.concat([this.pending,chunk]):chunk;this.pending=Buffer.alloc(0);let output=[],offset=0;while(offset<data.length){if(this.frame.length===0){let start=data.indexOf(SYNC_START,offset);if(start<0){let tail2=data.subarray(offset),pendingLength2=longestMarkerPrefixSuffix(tail2,[SYNC_START]),safeLength2=tail2.length-pendingLength2;if(safeLength2>0)output.push(tail2.subarray(0,safeLength2));if(pendingLength2>0)this.pending=Buffer.from(tail2.subarray(safeLength2));break}if(start>offset)output.push(data.subarray(offset,start));this.frame=Buffer.from(SYNC_START),offset=start+SYNC_START.length;continue}let end=data.indexOf(SYNC_END,offset),restart=data.indexOf(SYNC_START,offset);if(restart>=0&&(end<0||restart<end)){this.frame=Buffer.from(SYNC_START),offset=restart+SYNC_START.length;continue}if(end>=0){if(end>offset)this.frame=Buffer.concat([this.frame,data.subarray(offset,end)]);output.push(this.frame);let anchor=this.controller.current();if(anchor)output.push(Buffer.from(`\x1B[${anchor.y+1};${anchor.x+1}H\x1B[?25l`));output.push(SYNC_END),this.frame=Buffer.alloc(0),offset=end+SYNC_END.length;continue}let tail=data.subarray(offset),pendingLength=longestMarkerPrefixSuffix(tail,[SYNC_START,SYNC_END]),safeLength=tail.length-pendingLength;if(safeLength>0)this.frame=Buffer.concat([this.frame,tail.subarray(0,safeLength)]);if(pendingLength>0)this.pending=Buffer.from(tail.subarray(safeLength));break}return output.length>0?Buffer.concat(output):Buffer.alloc(0)}flush(){if(this.frame.length>0)return this.frame=Buffer.alloc(0),this.pending=Buffer.alloc(0),Buffer.alloc(0);let pending=this.pending;return this.pending=Buffer.alloc(0),pending}}function longestMarkerPrefixSuffix(bytes,markers){let max=Math.min(bytes.length,Math.max(...markers.map((marker)=>marker.length-1)));for(let length=max;length>0;length-=1){let suffix=bytes.subarray(bytes.length-length);if(markers.some((marker)=>length<marker.length&&suffix.equals(marker.subarray(0,length))))return length}return 0}function asBuffer(chunk,encodingOrCallback){if(typeof chunk!=="string")return Buffer.from(chunk);let encoding=typeof encodingOrCallback==="string"?encodingOrCallback:void 0;return Buffer.from(chunk,encoding)}function writeCallback(encodingOrCallback,maybeCallback){return typeof encodingOrCallback==="function"?encodingOrCallback:maybeCallback}function createImeAnchoredOutput(target,controller=imeAnchorController){let transformer=new ImeAnchorFrameTransformer(controller),exposedWrite=(chunk,encodingOrCallback,maybeCallback)=>{let transformed=transformer.push(asBuffer(chunk,encodingOrCallback)),callback=writeCallback(encodingOrCallback,maybeCallback);if(transformed.length===0){if(callback)queueMicrotask(()=>callback(null));return!0}return callback?target.write(transformed,callback):target.write(transformed)};return{stdout:new Proxy(target,{get(stream,property){if(property==="write")return exposedWrite;let value=Reflect.get(stream,property,stream);return typeof value==="function"?value.bind(stream):value},set(stream,property,value){if(property==="write")return exposedWrite=value,!0;return Reflect.set(stream,property,value,stream)}}),flush(){let pending=transformer.flush();if(pending.length>0)target.write(pending)}}}var IME_ANCHOR_PLATFORMS=new Set(["darwin","win32"]);function createHostImeOutput(opts){if(!IME_ANCHOR_PLATFORMS.has(opts.platform)||!opts.fullscreen)return{active:!1,rendererOptions:{},attach:()=>()=>{},flush:()=>{}};let output=createImeAnchoredOutput(opts.stdout,opts.controller);return{active:!0,rendererOptions:{stdout:output.stdout,remote:!1},attach:(renderer)=>installRendererResizeForwarder(renderer,opts.stdout),flush:()=>output.flush()}}function installRendererResizeForwarder(renderer,terminal,signals=process){let onResize=()=>{let{columns:width,rows:height}=terminal;if(!width||!height)return;renderer.resize(width,height)};return signals.on("SIGWINCH",onResize),()=>signals.removeListener("SIGWINCH",onResize)}function needsScreenSelfHeal(platform){return platform==="win32"}function requestFullRepaint(renderer){if(renderer.screenMode!=="alternate-screen")return!1;let internals=renderer;return internals.forceFullRepaintRequested=!0,renderer.requestRender(),!0}function writeThroughRenderer(renderer,chunk,fallback=process.stdout){let writeOut=renderer?.writeOut;try{if(typeof writeOut==="function")writeOut.call(renderer,chunk);else fallback.write(chunk)}catch{}}function redrawScreen(renderer){if(renderer.screenMode!=="alternate-screen")return!1;return writeThroughRenderer(renderer,"\x1B[H\x1B[2J"),requestFullRepaint(renderer)}function installScreenSelfHeal(opts){let platform=opts.platform??process.platform;if(!needsScreenSelfHeal(platform))return()=>{};let{renderer}=opts,repaint=()=>{requestFullRepaint(renderer)};return renderer.on("resize",repaint),renderer.on("focus",repaint),()=>{renderer.off("resize",repaint),renderer.off("focus",repaint)}}var import_react9=__toESM(require_react_production(),1);var PANE_ORDER=["sidebar","workspace","files","terminal"],FocusContext=import_react9.createContext(null);function FocusProvider(props){let[focused,setFocusedState]=import_react9.useState(props.initial??"sidebar"),renderer=useRenderer(),focusedRef=useLatest(focused),setFocused=import_react9.useCallback((pane)=>{if(focusedRef.current===pane)return;let current=renderer?.currentFocusedRenderable;if(current&&!current.isDestroyed)try{current.blur()}catch{}setFocusedState(pane)},[renderer]),cycle=import_react9.useCallback((delta)=>{let next=(PANE_ORDER.indexOf(focusedRef.current)+delta+PANE_ORDER.length)%PANE_ORDER.length;setFocused(PANE_ORDER[next])},[setFocused]),value=import_react9.useMemo(()=>({focused,is:(pane)=>focused===pane,setFocused,cycle}),[focused,setFocused,cycle]);return $jsx(FocusContext.Provider,{value,children:props.children})}function useFocus(){let ctx=import_react9.useContext(FocusContext);if(!ctx)throw Error("useFocus: must be called inside <FocusProvider>. See src/tui-react/context/focus.tsx.");return ctx}function useOptionalFocus(){return import_react9.useContext(FocusContext)}var import_react10=__toESM(require_react_production(),1);var WRITE_DEBOUNCE_MS=250;function createKvCore(){let store2=createStateCell(loadStateFile(),"kv.snapshot"),dirtyKeys=new Set,quiet=new Map,seeded=new Map,writeTimer=null,errorListeners=new Set,reportedKeys=new Set;function reportWriteError(err){let fresh=[...dirtyKeys].filter((key)=>!reportedKeys.has(key));if(fresh.length===0)return;for(let key of fresh)reportedKeys.add(key);let failure={keys:fresh,file:kvStatePath(),error:err};for(let listener2 of errorListeners)listener2(failure)}function writeNow(label){if(dirtyKeys.size===0)return!0;try{let patch={},snap=store2.get();for(let key of dirtyKeys)patch[key]=quiet.has(key)?quiet.get(key):snap[key];return patchStateFile(patch,"strict"),dirtyKeys.clear(),reportedKeys.clear(),!0}catch(err){return console.error(`[rove] kv ${label} failed:`,err),reportWriteError(err),!1}}function cancelTimer(){if(writeTimer)clearTimeout(writeTimer),writeTimer=null}function scheduleWrite(){cancelTimer(),writeTimer=setTimeout(()=>{writeTimer=null,writeNow("write")},WRITE_DEBOUNCE_MS)}return{snapshot:store2.get,subscribe:store2.subscribe,get(key,defaultValue){return(quiet.has(key)?quiet.get(key):store2.get()[key])??defaultValue},set(key,value){quiet.delete(key),store2.update((s)=>{if(value!==void 0)return{...s,[key]:value};if(!(key in s))return s;let next={...s};return delete next[key],next}),dirtyKeys.add(key),scheduleWrite()},setQuiet(key,value){quiet.set(key,value),dirtyKeys.add(key),scheduleWrite()},seed(key,value){if(!seeded.has(key))seeded.set(key,value);if(quiet.has(key)||store2.get()[key]!==void 0)return;store2.update((s)=>({...s,[key]:value}))},flush(){return cancelTimer(),writeNow("flush")},clear(){try{replaceStateFile({})}catch(err){return console.error("[rove] kv clear write failed:",err),!1}return cancelTimer(),dirtyKeys.clear(),reportedKeys.clear(),quiet.clear(),store2.set({}),!0},reload(){try{readStateFileStrict(),cancelTimer(),writeNow("reload flush");let fresh=readStateFileStrict(),before=store2.get(),next={...fresh};for(let[key,value]of seeded)if(next[key]===void 0)next[key]=value;for(let key of dirtyKeys)if(before[key]===void 0)delete next[key];else next[key]=before[key];for(let key of[...quiet.keys()])if(!dirtyKeys.has(key))quiet.delete(key);if(dirtyKeys.size>0)scheduleWrite();let changed=0;for(let key of new Set([...Object.keys(before),...Object.keys(next)]))if(JSON.stringify(before[key])!==JSON.stringify(next[key]))changed++;if(changed>0)store2.set(next);return{ok:!0,changed}}catch(error){return{ok:!1,error}}},onWriteError(listener2){return errorListeners.add(listener2),()=>{errorListeners.delete(listener2)}}}}var Ctx=import_react10.createContext(null);function KVProvider(props){let[core]=import_react10.useState(createKvCore),snapshot=import_react10.useSyncExternalStore(core.subscribe,core.snapshot,core.snapshot);import_react10.useEffect(()=>{let flush=()=>{core.flush()};return process.on("exit",flush),()=>{process.off("exit",flush)}},[core]);let value=import_react10.useMemo(()=>({ready:!0,store:snapshot,signal(name,defaultValue){return core.seed(name,defaultValue),[()=>core.get(name)??defaultValue,(next)=>core.set(name,next)]},get:core.get,set:core.set,setQuiet:core.setQuiet,flush:core.flush,clear:core.clear,reload:core.reload,onWriteError:core.onWriteError}),[core,snapshot]);return $jsx(Ctx.Provider,{value,children:props.children})}function useKV(){let value=import_react10.useContext(Ctx);if(!value)throw Error("KV context must be used within a context provider");return value}function useOptionalKV(){return import_react10.useContext(Ctx)??null}var import_react13=__toESM(require_react_production(),1);var import_react12=__toESM(require_react_production(),1);var TOAST_DURATION_MS=4500;function unreadKey(taskId,tabId){return`${taskId}:${tabId}`}function addUnread(prev,input){let key=unreadKey(input.taskId,input.tabId),existing=prev.get(key);if(existing==="needs_input"||existing==="error")return prev;let next=new Map(prev);return next.set(key,input.kind),next}function removeUnread(prev,taskId,tabId){let key=unreadKey(taskId,tabId);if(!prev.has(key))return prev;let next=new Map(prev);return next.delete(key),next}function shouldShowToast(kind,toastEnabled){return kind==="error"||toastEnabled}function shouldPlaySound(input,soundEnabled){return soundEnabled&&input.silent!==!0}function attentionKindFor(state){if(state==="permission_needed")return"needs_input";if(state==="error"||state==="rate_limited"||state==="dead")return"error";if(state==="turn_complete")return"done";return null}function chipAttentionKind(turn){if(turn==="done")return"done";if(turn==="error"||turn==="rate_limited"||turn==="dead")return"error";if(turn==="needs_input")return"needs_input";return null}function attentionEdges(prev,next,skip,kindFor){if(prev===null)return[];let out=[];for(let[key,state]of next){if(key===skip)continue;if(prev.get(key)===state)continue;let kind=kindFor(state);if(kind)out.push({key,kind})}return out}function sanitizeOscBody(body){let out="",segmentStart=0;for(let i=0;i<body.length;i++){let code=body.charCodeAt(i);if(code>31&&(code<127||code>159))continue;out+=`${body.slice(segmentStart,i)} `,segmentStart=i+1}return segmentStart===0?body:out+body.slice(segmentStart)}function osc9(body){return`\x1B]9;${sanitizeOscBody(body)}\x07`}import{existsSync,mkdirSync}from"fs";import{tmpdir}from"os";import{basename,delimiter,extname,isAbsolute,join,resolve}from"path";var pulse_default="../pulse-ynhb2ave.wav";function scaleWavVolume(wav,volume){let gain=Math.min(1,Math.max(0,volume));if(wav.length<12)return null;if(wav.readUInt32BE(0)!==1380533830||wav.readUInt32BE(8)!==1463899717)return null;let bitsPerSample,format,data;for(let offset=12;offset+8<=wav.length;){let id=wav.readUInt32BE(offset),size=wav.readUInt32LE(offset+4),start=offset+8,end=start+size;if(size<0||end>wav.length)return null;if(id===1718449184){if(size<16)return null;format=wav.readUInt16LE(start),bitsPerSample=wav.readUInt16LE(start+14)}else if(id===1684108385)data={start,end};offset=end+size%2}if(format!==1||bitsPerSample!==16||!data)return null;if((data.end-data.start)%2!==0)return null;let out=Buffer.from(wav);if(gain===1)return out;for(let i=data.start;i<data.end;i+=2){let scaled=Math.round(out.readInt16LE(i)*gain);out.writeInt16LE(Math.min(32767,Math.max(-32768,scaled)),i)}return out}var pulseAsset=isAbsolute(pulse_default)?pulse_default:resolve(import.meta.dir,pulse_default),DIR=join(tmpdir(),"rove-sfx"),PLAYERS=["ffplay","mpv","mpg123","mpg321","mplayer","afplay","play","omxplayer","aplay","cmdmp3","cvlc","powershell.exe"];function args(player,file){if(player==="ffplay")return[player,"-autoexit","-nodisp",file];if(player==="mpv")return[player,"--no-video","--audio-display=no",file];if(player==="mplayer")return[player,"-vo","null",file];if(player==="cvlc")return[player,"--play-and-exit",file];if(player==="powershell.exe")return[player,"-c",`(New-Object Media.SoundPlayer '${file.replace(/'/g,"''")}').PlaySync()`];return[player,file]}var cachedPlayer,cachedPaths=new Map;function pathDirs(rawPath,delim=delimiter){return rawPath.split(delim).filter(Boolean)}function pickPlayer(){if(cachedPlayer!==void 0)return cachedPlayer;let segments=pathDirs(process.env.PATH??"");return cachedPlayer=PLAYERS.find((p)=>segments.some((dir)=>existsSync(join(dir,p))))??null,cachedPlayer}function assetNameFor(assetPath,volume){let name=basename(assetPath),ext=extname(name);return`${name.slice(0,name.length-ext.length)}@${Math.round(volume*100)}${ext}`}async function ensureAsset(volume){let cached2=cachedPaths.get(volume);if(cached2)return cached2;let pending=(async()=>{mkdirSync(DIR,{recursive:!0});let dest=join(DIR,assetNameFor(pulseAsset,volume)),out=Bun.file(dest);if(await out.exists())return dest;let source=Buffer.from(await Bun.file(pulseAsset).arrayBuffer());return await Bun.write(out,scaleWavVolume(source,volume)??source),dest})();return cachedPaths.set(volume,pending),pending}function pulse(volume=persistedSoundVolume()){if(!(volume>0))return;let player=pickPlayer();if(!player)return;ensureAsset(volume).then((path)=>{try{Bun.spawn(args(player,path),{stdin:"ignore",stdout:"ignore",stderr:"ignore"}).unref?.()}catch{}}).catch(()=>{return})}var ctx=import_react12.createContext(null);function NotificationsProvider(props){let[toasts,setToasts]=import_react12.useState([]),[unread,setUnread]=import_react12.useState(new Map),kv=useOptionalKV(),renderer=useRenderer(),snapshot=import_react12.useMemo(()=>loadStateFile(),[]),prefs=import_react12.useMemo(()=>({"notifications.sound.enabled":kv?.get("notifications.sound.enabled")??snapshot["notifications.sound.enabled"],"notifications.toast.enabled":kv?.get("notifications.toast.enabled")??snapshot["notifications.toast.enabled"]}),[kv,snapshot]),counter=import_react12.useRef(0),timers=import_react12.useRef(new Set);import_react12.useEffect(()=>()=>{for(let id of timers.current)clearTimeout(id);timers.current.clear()},[]);let dismiss=import_react12.useCallback((id)=>{setToasts((prev)=>prev.filter((t2)=>t2.id!==id))},[]),notify=import_react12.useCallback((input)=>{setUnread((prev)=>addUnread(prev,input));let soundEnabled=prefs["notifications.sound.enabled"]!==!1;if(shouldPlaySound(input,soundEnabled))writeThroughRenderer(renderer,`\x07${osc9(`Rove \u2014 ${input.title}`)}`),pulse();let toastEnabled=prefs["notifications.toast.enabled"]!==!1;if(shouldShowToast(input.kind,toastEnabled)){let id=++counter.current;setToasts((prev)=>[...prev,{id,...input}]);let timer=setTimeout(()=>{timers.current.delete(timer),dismiss(id)},TOAST_DURATION_MS);timers.current.add(timer)}},[prefs,dismiss,renderer]),markRead=import_react12.useCallback((taskId,tabId)=>{setUnread((prev)=>removeUnread(prev,taskId,tabId))},[]),value=import_react12.useMemo(()=>({toasts,unread,notify,dismiss,markRead}),[toasts,unread,notify,dismiss,markRead]);return $jsx(ctx.Provider,{value,children:props.children})}function useNotifications(){let value=import_react12.useContext(ctx);if(!value)throw Error("useNotifications must be used within a NotificationsProvider");return value}function useOptionalNotifications(){return import_react12.useContext(ctx)}function KvWriteErrorToasts(){let kv=useOptionalKV(),notifications=useOptionalNotifications();return import_react13.useEffect(()=>{if(!kv||!notifications)return;return kv.onWriteError((failure)=>{notifications.notify({taskId:"",tabId:"",kind:"error",title:t("settings.stateWrite.failedTitle"),body:t("settings.stateWrite.failedBody",{file:tildify(failure.file),keys:failure.keys.join(", ")})})})},[kv,notifications]),null}var import_react17=__toESM(require_react_production(),1);function isNarrowWidth(cols){return cols<70}function narrowSurface(args2){if(args2.focusedPane==="sidebar")return"sidebar";return args2.hasSelection||args2.hasOpenPage?"content":"sidebar"}var import_react15=__toESM(require_react_production(),1);var stores=new WeakMap;function terminalSizeStore(source){let existing=stores.get(source);if(existing)return existing;let listeners=new Set,size={width:source.width,height:source.height},notify=()=>{for(let listener2 of listeners)listener2()},store2={subscribe(listener2){if(listeners.add(listener2),listeners.size===1)source.on("resize",notify);return()=>{if(listeners.delete(listener2),listeners.size===0)source.off("resize",notify)}},snapshot(){if(size.width!==source.width||size.height!==source.height)size={width:source.width,height:source.height};return size}};return stores.set(source,store2),store2}function useTerminalSize(){let store2=terminalSizeStore(useRenderer());return import_react15.useSyncExternalStore(store2.subscribe,store2.snapshot)}function useDialogPaddingX(){let dims=useTerminalSize();return isNarrowWidth(dims.width)?1:2}var DIALOG_CONTENT_OPACITY=0.5,TRANSPARENT_DIALOG_CONTENT_OPACITY=0.75;function Dialog(props){let dimensions=useTerminalSize(),{theme}=useTheme(),renderer=useRenderer(),dismissRef=import_react17.useRef(!1),width=props.size==="xlarge"?140:props.size==="large"?110:props.size==="small"?50:80,VERTICAL_MARGIN=2,upperFifth=props.placement==="upper-fifth"&&!isNarrowWidth(dimensions.width),headerTop=Math.max(2,Math.floor(dimensions.height/5)),cardTop=upperFifth?Math.max(2,headerTop-1):0,maxCardHeight=Math.max(8,upperFifth?dimensions.height-cardTop-2:dimensions.height-4);return $jsx("box",{onMouseDown:()=>{dismissRef.current=!!renderer?.getSelection()},onMouseUp:()=>{if(dismissRef.current){dismissRef.current=!1;return}props.onClose?.()},width:dimensions.width,height:dimensions.height,alignItems:"center",justifyContent:upperFifth?"flex-start":"center",paddingTop:cardTop,position:"absolute",zIndex:3000,left:0,top:0,shouldFill:!1,children:$jsx("box",{onMouseUp:(e)=>{dismissRef.current=!1,e.stopPropagation()},width,maxWidth:dimensions.width-2,maxHeight:maxCardHeight,flexShrink:1,flexGrow:0,backgroundColor:theme.backgroundDialog,paddingTop:1,children:props.children})})}var entrySeq=0,ctx2=import_react17.createContext(null);function DialogProvider(props){let[stack2,setStack]=import_react17.useState([]),[size,setSize]=import_react17.useState("medium"),[placement,setPlacement]=import_react17.useState("center"),renderer=useRenderer(),{transparentBackground:transparentBackground2}=useTheme(),focusRef=import_react17.useRef(null),refocusTimer=import_react17.useRef(null);import_react17.useEffect(()=>()=>{if(refocusTimer.current)clearTimeout(refocusTimer.current)},[]);let refocus=import_react17.useCallback(()=>{if(refocusTimer.current)clearTimeout(refocusTimer.current);refocusTimer.current=setTimeout(()=>{let focus=focusRef.current;if(!focus||focus.isDestroyed)return;function find(item){for(let child of item.getChildren()){if(child===focus)return!0;if(find(child))return!0}return!1}let root=renderer?.root;if(!root)return;if(!find(root))return;focus.focus()},1)},[renderer]),stackRef=useLatest(stack2),captureFocusIfFirst=import_react17.useCallback(()=>{if(refocusTimer.current)clearTimeout(refocusTimer.current);if(stackRef.current.length===0)focusRef.current=renderer?.currentFocusedRenderable??null,focusRef.current?.blur()},[renderer]),dismissTop=import_react17.useCallback(()=>{let selection=renderer?.getSelection();if(selection){if(renderer?.clearSelection(),selection.getSelectedText())return}stackRef.current.at(-1)?.onClose?.(),setStack((s)=>s.slice(0,-1)),refocus()},[renderer,refocus]),value=import_react17.useMemo(()=>({clear(options){for(let item of stackRef.current)item.onClose?.();if(setSize("medium"),setPlacement("center"),setStack([]),options?.refocus===!1)focusRef.current=null;else refocus()},replace(thunk,onClose){captureFocusIfFirst();for(let item of stackRef.current)item.onClose?.();setSize("medium"),setPlacement("center"),setStack([{key:++entrySeq,element:thunk,onClose}])},push(thunk,onClose){captureFocusIfFirst(),setStack((s)=>[...s,{key:++entrySeq,element:thunk,onClose}])},pop(){if(stackRef.current.at(-1)?.onClose?.(),setStack((s)=>s.slice(0,-1)),stackRef.current.length<=1)refocus()},get stack(){return stackRef.current},get size(){return size},setSize,get placement(){return placement},setPlacement}),[stack2,size,placement,refocus,captureFocusIfFirst]),top=stack2.at(-1),contentOpacity=top?transparentBackground2?TRANSPARENT_DIALOG_CONTENT_OPACITY:DIALOG_CONTENT_OPACITY:1;return $jsxs(ctx2.Provider,{value,children:[$jsx("box",{flexGrow:1,backgroundColor:top&&!transparentBackground2?"black":"transparent",children:$jsx("box",{flexGrow:1,opacity:contentOpacity,children:props.children})}),$jsx("box",{position:"absolute",zIndex:3000,children:top?$jsxs(ModalScopeContext,{value:MODAL_SCOPE,children:[$jsx(ModalBarrier,{dismissTop}),$jsx(Dialog,{onClose:()=>value.clear(),size,placement,children:top.element()},top.key)]}):null})]})}var MODAL_SCOPE=Symbol("rove.dialog.modal");function ModalBarrier(props){return useBindings(()=>({modal:!0,bindings:[{key:"escape",cmd:props.dismissTop},{key:"ctrl+c",cmd:props.dismissTop}]}),{modalOwner:MODAL_SCOPE}),null}function useDialog(){let value=import_react17.useContext(ctx2);if(!value)throw Error("useDialog must be used within a DialogProvider");return value}function useOptionalDialog(){return import_react17.useContext(ctx2)}function showDialog(dialog,body,opts){return new Promise((resolve2)=>{if(dialog.replace(()=>body(resolve2),()=>resolve2(void 0)),opts?.size)dialog.setSize(opts.size)})}var import_react18=__toESM(require_react_production(),1);function PaneCrashFallback(props){let{theme}=useTheme(),t2=useT(),sizing=props.width===void 0?{flexGrow:1}:{width:props.width,flexShrink:0};return $jsxs("box",{...sizing,flexDirection:"column",backgroundColor:theme.background,paddingLeft:1,paddingTop:1,gap:1,children:[$jsx("text",{fg:theme.error,wrapMode:"word",children:props.region?t2("common.paneCrash.regionTitle",{region:t2(`common.paneCrash.region.${props.region}`)}):t2("common.paneCrash.title")}),$jsx("text",{fg:theme.textMuted,wrapMode:"word",children:t2(props.region?"common.paneCrash.regionHint":"common.paneCrash.hint")}),$jsx("text",{fg:theme.focusAccent,onMouseUp:props.onRetry,children:t2("common.paneCrash.retry")})]})}function formatPaneCrashDiagnostic(region,error,info){let base=error instanceof Error?error.stack??error.message:String(error),componentStack=info.componentStack?.trim()||"(unavailable)",stateChanges=recentStateChangesForDiagnostics();return`region: ${region??"root"}
3
3
  ${base}
4
4
  React component stack:
5
5
  ${componentStack}
@@ -1,3 +1,3 @@
1
1
  // @bun
2
- import{JsonHookAdapter,editJsonSettings,isObject,removeRoveHooks,vendorConfigHome}from"./chunk-x33sm4rp.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import{__require}from"./chunk-91sykzqq.js";import{join}from"path";var CLAUDE_HOOK_EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"Stop",verb:"turn-complete"},{event:"StopFailure",verb:"turn-failed"},{event:"Notification",matcher:"permission_prompt",verb:"awaiting-input"},{event:"Notification",matcher:"elicitation_dialog",verb:"awaiting-input"},{event:"SessionEnd",verb:"session-end"},{event:"PreCompact",verb:"pre-compact"},{event:"PostCompact",verb:"post-compact"},{event:"SubagentStart",verb:"subagent-start"},{event:"SubagentStop",verb:"subagent-stop"},{event:"PreToolUse",verb:"tool-pre"},{event:"PostToolUse",verb:"tool-post"},{event:"PostToolUseFailure",verb:"tool-failed"}],ROVE_HOOK_EVENTS=[...new Set(CLAUDE_HOOK_EVENT_MAP.map((e)=>e.event))];function failureFromErrorType(errorType){if(typeof errorType!=="string")return"other";if(errorType==="rate_limit"||errorType==="overloaded")return"rate_limit";if(errorType==="billing_error")return"billing";return"other"}function claudeSettingsPath(){return join(vendorConfigHome("claude"),"settings.json")}var WORKTREE_SYNC_VERB="worktree-created";function mergeWorktreeSyncHook(current,command){let{hooks:rawHooks,...restSettings}=current,{WorktreeCreate,...otherHooks}=isObject(rawHooks)?rawHooks:{},prior=Array.isArray(WorktreeCreate)?WorktreeCreate:[],kept=removeRoveHooks(prior,[WORKTREE_SYNC_VERB]);if(command!==null)kept.push({hooks:[{type:"command",command}]});let nextHooks={...otherHooks};if(kept.length>0)nextHooks.WorktreeCreate=kept;return Object.keys(nextHooks).length>0?{...restSettings,hooks:nextHooks}:{...restSettings}}class ClaudeHookAdapter extends JsonHookAdapter{vendor="claude";eventMap=CLAUDE_HOOK_EVENT_MAP;globalSettingsPath(){return claudeSettingsPath()}activityDetailFromPayload(kind,payload){if(kind==="turn-failed")return{failure:failureFromErrorType(payload.error_type)};if(kind==="awaiting-input")return{waiting:payload.notification_type==="elicitation_dialog"?"input":"permission"};if(kind==="tool-pre"||kind==="tool-post"||kind==="tool-failed")return{tool:{...typeof payload.tool_name==="string"?{name:payload.tool_name}:{},...typeof payload.tool_use_id==="string"?{id:payload.tool_use_id}:{}}};if(kind==="pre-compact"||kind==="post-compact")return{compact:{trigger:payload.trigger==="manual"?"manual":"auto"}};if(kind==="subagent-start"||kind==="subagent-stop")return{subagent:{...typeof payload.agent_type==="string"?{type:payload.agent_type}:{},...typeof payload.agent_id==="string"?{id:payload.agent_id}:{}}};return}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}isUnattendedSession(env){return env.CLAUDE_CODE_SESSION_ATTENDED==="0"}async externallyManagedHooks(){let{isRovePluginEnabled,detectLegacyInstalls,migrationHint}=await import("./chunk-rt4tg426.js");if(!isRovePluginEnabled())return;let notice=migrationHint(detectLegacyInstalls(),ROVE_PRODUCT_NAME);return notice?{notice}:{}}supportsWorktreeSync(){return!0}async removeWorktreeSyncHook(settingsFilePath){await editJsonSettings(settingsFilePath,(cur)=>mergeWorktreeSyncHook(cur,null))}}
2
+ import{JsonHookAdapter,editJsonSettings,isObject,removeRoveHooks,vendorConfigHome}from"./chunk-9dregrj6.js";import{ROVE_PRODUCT_NAME}from"./chunk-zt7wfnva.js";import{__require}from"./chunk-91sykzqq.js";import{join}from"path";var CLAUDE_HOOK_EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"Stop",verb:"turn-complete"},{event:"StopFailure",verb:"turn-failed"},{event:"Notification",matcher:"permission_prompt",verb:"awaiting-input"},{event:"Notification",matcher:"elicitation_dialog",verb:"awaiting-input"},{event:"SessionEnd",verb:"session-end"},{event:"PreCompact",verb:"pre-compact"},{event:"PostCompact",verb:"post-compact"},{event:"SubagentStart",verb:"subagent-start"},{event:"SubagentStop",verb:"subagent-stop"},{event:"PreToolUse",verb:"tool-pre"},{event:"PostToolUse",verb:"tool-post"},{event:"PostToolUseFailure",verb:"tool-failed"}],ROVE_HOOK_EVENTS=[...new Set(CLAUDE_HOOK_EVENT_MAP.map((e)=>e.event))];function failureFromErrorType(errorType){if(typeof errorType!=="string")return"other";if(errorType==="rate_limit"||errorType==="overloaded")return"rate_limit";if(errorType==="billing_error")return"billing";return"other"}function claudeSettingsPath(){return join(vendorConfigHome("claude"),"settings.json")}var WORKTREE_SYNC_VERB="worktree-created";function mergeWorktreeSyncHook(current,command){let{hooks:rawHooks,...restSettings}=current,{WorktreeCreate,...otherHooks}=isObject(rawHooks)?rawHooks:{},prior=Array.isArray(WorktreeCreate)?WorktreeCreate:[],kept=removeRoveHooks(prior,[WORKTREE_SYNC_VERB]);if(command!==null)kept.push({hooks:[{type:"command",command}]});let nextHooks={...otherHooks};if(kept.length>0)nextHooks.WorktreeCreate=kept;return Object.keys(nextHooks).length>0?{...restSettings,hooks:nextHooks}:{...restSettings}}class ClaudeHookAdapter extends JsonHookAdapter{vendor="claude";eventMap=CLAUDE_HOOK_EVENT_MAP;globalSettingsPath(){return claudeSettingsPath()}activityDetailFromPayload(kind,payload){if(kind==="turn-failed")return{failure:failureFromErrorType(payload.error_type)};if(kind==="awaiting-input")return{waiting:payload.notification_type==="elicitation_dialog"?"input":"permission"};if(kind==="tool-pre"||kind==="tool-post"||kind==="tool-failed")return{tool:{...typeof payload.tool_name==="string"?{name:payload.tool_name}:{},...typeof payload.tool_use_id==="string"?{id:payload.tool_use_id}:{}}};if(kind==="pre-compact"||kind==="post-compact")return{compact:{trigger:payload.trigger==="manual"?"manual":"auto"}};if(kind==="subagent-start"||kind==="subagent-stop")return{subagent:{...typeof payload.agent_type==="string"?{type:payload.agent_type}:{},...typeof payload.agent_id==="string"?{id:payload.agent_id}:{}}};return}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}isUnattendedSession(env){return env.CLAUDE_CODE_SESSION_ATTENDED==="0"}async externallyManagedHooks(){let{isRovePluginEnabled,detectLegacyInstalls,migrationHint}=await import("./chunk-vwpcv7j1.js");if(!isRovePluginEnabled())return;let notice=migrationHint(detectLegacyInstalls(),ROVE_PRODUCT_NAME);return notice?{notice}:{}}supportsWorktreeSync(){return!0}async removeWorktreeSyncHook(settingsFilePath){await editJsonSettings(settingsFilePath,(cur)=>mergeWorktreeSyncHook(cur,null))}}
3
3
  export{CLAUDE_HOOK_EVENT_MAP,claudeSettingsPath,ClaudeHookAdapter};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{spawnCapture}from"./chunk-2tfnscxk.js";import{CONTRIB_ENGINE_IDS,contribEngineEntry,detectBobAccount,detectClaudeAccount,detectCodexAccount,detectCopilotAccount,detectKimiAccount,isContribEngine,mergeFlatHooks,parseFlatHooks,pluginEngineIds}from"./chunk-w4cpkhzj.js";import{TomlError,parse}from"./chunk-w7zv47mp.js";import{ClaudeHookAdapter}from"./chunk-964z8ccb.js";import{GATED_TOOL_VERBS,JsonHookAdapter,ROVE_HOOK_VERSION,bobDbPath,bobTrustPath,claudeGlobalConfigPath,copilotConfigPath,editJsonSettings,hookCommandQuoting,isJsonlLineWithinBound,isObject,readFirstLineBounded,readSharedConfigSync,readTextFileBounded,readTextFileIfRegular,roveHookArgs,roveHookInvocation,updateSharedJsonSync,vendorAgentDir,vendorConfigHome,vendorWriteHomeDeps}from"./chunk-x33sm4rp.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{samePath}from"./chunk-pn5ygqn6.js";import{__require}from"./chunk-91sykzqq.js";var BOB_SCREEN_MANIFEST={rules:[{state:"blocked",any:["complete sign-in in your browser"]},{state:"blocked",all:["do you trust this folder?"],any:["trust folder","don't trust"]},{state:"blocked",all:["approve once"],any:["reject","always allow"]},{state:"working",any:["enter to steer","tab to queue"]},{state:"idle",lineRegex:["^\\s*\\w[\\w ]* mode( \xB7|\\s*$)"]}]};import{homedir}from"os";var TRUSTED="TRUST_FOLDER";function trustBobWorktree(worktreePath,home=homedir()){updateSharedJsonSync(bobTrustPath(home),(raw)=>{if(raw===void 0)return{};try{return JSON.parse(raw)}catch{return{}}},(doc)=>{let folders=doc.folders&&typeof doc.folders==="object"&&!Array.isArray(doc.folders)?doc.folders:{};if(folders[worktreePath]===TRUSTED)return;let merged={...doc,version:doc.version??1,folders:{...folders,[worktreePath]:TRUSTED}};return`${JSON.stringify(merged,null,2)}
2
+ import{spawnCapture}from"./chunk-2tfnscxk.js";import{CONTRIB_ENGINE_IDS,contribEngineEntry,detectBobAccount,detectClaudeAccount,detectCodexAccount,detectCopilotAccount,detectKimiAccount,isContribEngine,mergeFlatHooks,parseFlatHooks,pluginEngineIds}from"./chunk-ccn7pq03.js";import{TomlError,parse}from"./chunk-w7zv47mp.js";import{ClaudeHookAdapter}from"./chunk-jnj2kk2h.js";import{GATED_TOOL_VERBS,JsonHookAdapter,ROVE_HOOK_VERSION,bobDbPath,bobTrustPath,claudeGlobalConfigPath,copilotConfigPath,editJsonSettings,hookCommandQuoting,isJsonlLineWithinBound,isObject,readFirstLineBounded,readSharedConfigSync,readTextFileBounded,readTextFileIfRegular,roveHookArgs,roveHookInvocation,updateSharedJsonSync,vendorAgentDir,vendorConfigHome,vendorWriteHomeDeps}from"./chunk-9dregrj6.js";import{quoteShellArgv}from"./chunk-7kysxgbq.js";import{BUILTIN_VENDORS,isBuiltinVendor}from"./chunk-h2m7em1e.js";import{samePath}from"./chunk-pn5ygqn6.js";import{__require}from"./chunk-91sykzqq.js";var BOB_SCREEN_MANIFEST={rules:[{state:"blocked",any:["complete sign-in in your browser"]},{state:"blocked",all:["do you trust this folder?"],any:["trust folder","don't trust"]},{state:"blocked",all:["approve once"],any:["reject","always allow"]},{state:"working",any:["enter to steer","tab to queue"]},{state:"idle",lineRegex:["^\\s*\\w[\\w ]* mode( \xB7|\\s*$)"]}]};import{homedir}from"os";var TRUSTED="TRUST_FOLDER";function trustBobWorktree(worktreePath,home=homedir()){updateSharedJsonSync(bobTrustPath(home),(raw)=>{if(raw===void 0)return{};try{return JSON.parse(raw)}catch{return{}}},(doc)=>{let folders=doc.folders&&typeof doc.folders==="object"&&!Array.isArray(doc.folders)?doc.folders:{};if(folders[worktreePath]===TRUSTED)return;let merged={...doc,version:doc.version??1,folders:{...folders,[worktreePath]:TRUSTED}};return`${JSON.stringify(merged,null,2)}
3
3
  `})}var claudeCapabilities={interruptSequence:"\x1B"},claudeIdentity={shortName:"Claude"};import{homedir as homedir2,userInfo}from"os";import path from"path";var OAUTH_USAGE_URL="https://api.anthropic.com/api/oauth/usage",OAUTH_BETA_HEADER="oauth-2025-04-20",OAUTH_USER_AGENT="claude-cli/2.1.198 (external, cli)",USAGE_TIMEOUT_MS=1e4,KEYCHAIN_SERVICE="Claude Code-credentials";function parseResetsAtMs(value){if(value==null)return null;let numeric=typeof value==="number"?value:/^\d+(?:\.\d+)?$/.test(value.trim())?Number(value):null;if(numeric!=null){if(!Number.isFinite(numeric)||numeric<=0)return null;return numeric<1000000000000?numeric*1000:numeric}let parsed=Date.parse(String(value));return Number.isNaN(parsed)?null:parsed}var clampPercent=(value)=>Math.min(100,Math.max(0,Math.round(value)));function windowLabel(kind,scopeModel){if(kind==="weekly_scoped"&&scopeModel)return scopeModel;return kind.startsWith("weekly")||kind.startsWith("seven_day")?"7d":"5h"}function usageFromClaudePayload(payload,capturedAt){let windows=[];if(payload.limits?.length)for(let limit of payload.limits){if(typeof limit.kind!=="string"||typeof limit.percent!=="number")continue;windows.push({kind:limit.kind,label:windowLabel(limit.kind,limit.scope?.model?.display_name),percent:clampPercent(limit.percent),resetsAt:parseResetsAtMs(limit.resets_at)})}else{if(typeof payload.five_hour?.utilization==="number")windows.push({kind:"session",label:"5h",percent:clampPercent(payload.five_hour.utilization),resetsAt:parseResetsAtMs(payload.five_hour.resets_at)});if(typeof payload.seven_day?.utilization==="number")windows.push({kind:"weekly_all",label:"7d",percent:clampPercent(payload.seven_day.utilization),resetsAt:parseResetsAtMs(payload.seven_day.resets_at)})}return{windows,capturedAt}}function parseCredentials(raw){try{let oauth=JSON.parse(raw)?.claudeAiOauth;if(!oauth||typeof oauth.accessToken!=="string"||!oauth.accessToken)return null;return{accessToken:oauth.accessToken,...typeof oauth.expiresAt==="number"&&Number.isFinite(oauth.expiresAt)?{expiresAt:oauth.expiresAt}:{}}}catch{return null}}var isFresh=(c)=>c.expiresAt===void 0||c.expiresAt>Date.now();async function readFileCredentials(dir){try{return parseCredentials(await readTextFileBounded(path.join(dir,".credentials.json")))}catch{return null}}async function readKeychainCredentials(){if(process.platform!=="darwin")return null;let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),3000);try{let result=await spawnCapture("security",["find-generic-password","-a",userInfo().username,"-w","-s",KEYCHAIN_SERVICE],{cwd:homedir2(),signal:controller.signal});return result.status===0?parseCredentials(result.stdout.trim()):null}finally{clearTimeout(timeout)}}async function readAccessToken(){let configDir=process.env.CLAUDE_CONFIG_DIR?.trim();if(configDir){let fromFile=await readFileCredentials(configDir);return fromFile&&isFresh(fromFile)?fromFile.accessToken:null}return[await readKeychainCredentials(),await readFileCredentials(vendorConfigHome("claude"))].find((c)=>c!=null&&isFresh(c))?.accessToken??null}async function fetchClaudeQuotaUsage(now=Date.now){let token=await readAccessToken().catch(()=>null);if(!token)return null;let controller=new AbortController,timeout=setTimeout(()=>controller.abort(),USAGE_TIMEOUT_MS);try{let response=await fetch(OAUTH_USAGE_URL,{headers:{Authorization:`Bearer ${token}`,"Content-Type":"application/json","User-Agent":OAUTH_USER_AGENT,"anthropic-beta":OAUTH_BETA_HEADER},signal:controller.signal});if(!response.ok)return null;return usageFromClaudePayload(await response.json(),now())}catch{return null}finally{clearTimeout(timeout)}}function trustClaudeWorktree(worktreePath,home){let deps=vendorWriteHomeDeps(home);updateSharedJsonSync(claudeGlobalConfigPath(deps.env,deps.home()),(raw)=>{if(raw===void 0)return{};let doc=JSON.parse(raw);if(!isObject(doc))throw Error("Claude trust config must be a JSON object");return doc},(doc)=>{if(doc.projects!==void 0&&!isObject(doc.projects))throw Error("Claude trust projects must be an object");let projects={...doc.projects},existing=Object.hasOwn(projects,worktreePath)?projects[worktreePath]:{};if(!isObject(existing))throw Error("Claude trust project must be an object");if(existing.hasTrustDialogAccepted===!0)return;return projects[worktreePath]={...existing,hasTrustDialogAccepted:!0,hasCompletedProjectOnboarding:!0},JSON.stringify({...doc,projects},null,2)})}function isSyntheticClaudeRecord(record){return record.isMeta===!0||record.isCompactSummary===!0}function isClaudeCommandBreadcrumb(blocks){if(blocks.length===0)return!1;for(let b of blocks){if(b.type!=="text")return!1;let t=b.text.trim();if(!t.startsWith("<command-name>")&&!t.startsWith("<command-message>")&&!t.startsWith("<local-command"))return!1}return!0}function opensTurn(content){if(typeof content==="string")return content.trim().length>0;if(!Array.isArray(content))return!1;return content.some((b)=>!isObject(b)||b.type!=="tool_result")}function num(v){return typeof v==="number"&&Number.isFinite(v)?v:0}function readUsage(v){if(!isObject(v))return;return{input_tokens:num(v.input_tokens),output_tokens:num(v.output_tokens),cache_read_input_tokens:num(v.cache_read_input_tokens),cache_creation_input_tokens:num(v.cache_creation_input_tokens)}}function finish(draft){if(!draft.id)return null;let totals={input_tokens:0,output_tokens:0,cache_read_input_tokens:0,cache_creation_input_tokens:0};for(let u of draft.usageByMessage.values())totals.input_tokens+=u.input_tokens,totals.output_tokens+=u.output_tokens,totals.cache_read_input_tokens+=u.cache_read_input_tokens,totals.cache_creation_input_tokens+=u.cache_creation_input_tokens;return{id:draft.id,sessionId:draft.sessionId,...draft.model?{model:draft.model}:{},startedAt:draft.startedAt,endedAt:draft.endedAt,...draft.usageByMessage.size>0?{usage:totals}:{}}}function parseClaudeTurns(raw,fallbackSessionId=""){let out=[],draft=null;for(let line of raw.split(`
4
4
  `)){let trimmed=line.trim();if(!trimmed||!isJsonlLineWithinBound(trimmed))continue;let record;try{record=JSON.parse(trimmed)}catch{continue}if(!isObject(record)||isSyntheticClaudeRecord(record))continue;let inner=isObject(record.message)?record.message:record,at=typeof record.timestamp==="string"?Date.parse(record.timestamp):Number.NaN;if(!Number.isFinite(at))continue;let sessionId=typeof record.sessionId==="string"?record.sessionId:fallbackSessionId;if(inner.role==="user"){if(!opensTurn(inner.content))continue;if(draft){let done=finish(draft);if(done)out.push(done)}draft={id:"",sessionId,startedAt:at,endedAt:at,usageByMessage:new Map};continue}if(inner.role!=="assistant"||!draft)continue;if(draft.endedAt=at,typeof inner.model==="string")draft.model=inner.model;let messageId=typeof inner.id==="string"?inner.id:"";if(messageId)draft.id=messageId;let usage=readUsage(inner.usage);if(usage&&messageId)draft.usageByMessage.set(messageId,usage)}if(draft){let done=finish(draft);if(done)out.push(done)}return out}async function readClaudeTurns(transcriptPath){try{let raw=await readTextFileBounded(transcriptPath);return parseClaudeTurns(raw)}catch{return[]}}var HEX_RE=/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i;function parseHex(value){let match=HEX_RE.exec(value);if(!match)return[0,0,0];return[Number.parseInt(match[1],16),Number.parseInt(match[2],16),Number.parseInt(match[3],16)]}function luminance([red,green,blue]){return(red*0.2126+green*0.7152+blue*0.0722)/255}function blend(from,to,amount){return[Math.round(from[0]+(to[0]-from[0])*amount),Math.round(from[1]+(to[1]-from[1])*amount),Math.round(from[2]+(to[2]-from[2])*amount)]}function codexUserMessageBackground(background){return luminance(background)>0.5?blend(background,[0,0,0],0.04):blend(background,[255,255,255],0.12)}function transcriptRewrite(palette){let foreground=parseHex(palette.foreground),background=parseHex(palette.background),backgroundIsLight=luminance(background)>0.5;return{matchBackground:codexUserMessageBackground(background),foreground:backgroundIsLight?foreground:background,background:backgroundIsLight?background:foreground}}var codexTerminalPresentation={alternateScreenStyleRewrites:(palette)=>[transcriptRewrite(palette)]};var codexCapabilities={preparePromptSubmission:(prompt)=>{return/^[\/!]/.test(prompt.trimStart())?prompt:`${prompt} `},beforePromptSubmit:"\x1B[F",terminalPresentation:codexTerminalPresentation,interruptSequence:"\x1B"},codexIdentity={shortName:"Codex"};import{join}from"path";var EVENT_MAP=[{event:"SessionStart",verb:"session-start"},{event:"UserPromptSubmit",verb:"turn-start"},{event:"Stop",verb:"turn-complete"},{event:"SessionEnd",verb:"session-end"},{event:"PreCompact",verb:"pre-compact"},{event:"PostCompact",verb:"post-compact"},{event:"SubagentStart",verb:"subagent-start"},{event:"SubagentStop",verb:"subagent-stop"},{event:"PreToolUse",verb:"tool-pre"},{event:"PostToolUse",verb:"tool-post"}],ROVE_CODEX_HOOK_EVENTS=EVENT_MAP.map((e)=>e.event);function codexHooksPath(){return join(vendorConfigHome("codex"),"hooks.json")}class CodexHookAdapter extends JsonHookAdapter{vendor="codex";setupCommand="/hooks";eventMap=EVENT_MAP;globalSettingsPath(){return codexHooksPath()}activityDetailFromPayload(kind,payload){if(kind==="tool-pre"||kind==="tool-post")return{tool:{...typeof payload.tool_name==="string"?{name:payload.tool_name}:{}}};if(kind==="pre-compact"||kind==="post-compact")return{compact:{trigger:payload.trigger==="manual"?"manual":"auto"}};return}sessionFromPayload(payload){if(typeof payload.session_id!=="string"||!payload.session_id)return;return{sessionId:payload.session_id,...typeof payload.transcript_path==="string"&&payload.transcript_path?{transcriptPath:payload.transcript_path}:{}}}}import{createHash}from"crypto";function createAppendParseCache(opts){let maxFiles=opts.maxFiles??8,cache=new Map;function remember(filePath,entry){if(cache.delete(filePath),cache.set(filePath,entry),cache.size>maxFiles){let oldest=cache.keys().next().value;if(oldest!==void 0)cache.delete(oldest)}}return function(filePath,raw,ctx){let stableLength=raw.lastIndexOf(`
5
5
  `)+1,entry=cache.get(filePath),verifiedLength=Math.min(entry?.prefixLength??0,stableLength),hash=createHash("sha256").update(raw.slice(0,verifiedLength)),unchanged=entry!==void 0&&Object.is(entry.context,ctx)&&entry.prefixLength<=stableLength&&hash.copy().digest("hex")===entry.prefixHash,prefixState;if(unchanged)prefixState=entry.prefixLength<stableLength?opts.parseChunk(raw.slice(entry.prefixLength,stableLength),entry.state,ctx):entry.state;else prefixState=opts.parseChunk(raw.slice(0,stableLength),opts.initial(ctx),ctx);if(!unchanged||entry.prefixLength!==stableLength||entry.state!==prefixState)remember(filePath,{context:ctx,prefixLength:stableLength,prefixHash:hash.update(raw.slice(verifiedLength,stableLength)).digest("hex"),state:prefixState});let tail=raw.slice(stableLength);return tail.trim().length>0?opts.parseChunk(tail,prefixState,ctx):prefixState}}var sortedMessages=new WeakMap;function sortByTimestamp(messages){let hit=sortedMessages.get(messages);if(hit)return hit;let sorted=[...messages].sort((a,b)=>a.timestamp<b.timestamp?-1:a.timestamp>b.timestamp?1:0);return sortedMessages.set(messages,sorted),sorted}function normalizeCodexContent(raw){if(typeof raw==="string")return raw.length>0?[{type:"text",text:raw}]:[];if(!Array.isArray(raw))return[];let blocks=[];for(let item of raw){if(typeof item==="string"){if(item.length>0)blocks.push({type:"text",text:item});continue}if(!isObject(item))continue;let t=typeof item.type==="string"?item.type:void 0;if(t==="input_text"||t==="output_text"){let text=typeof item.text==="string"?item.text:"";if(text.length>0)blocks.push({type:"text",text});continue}if(t)blocks.push({type:"text",text:`[codex: ${t}]`})}return blocks}function isSyntheticCodexUserRow(blocks){if(blocks.length===0)return!1;for(let b of blocks){if(b.type!=="text")return!1;let t=(b.text??"").trim();if(!isTagEnvelope(t)&&!isInstructionsEnvelope(t))return!1}return!0}var ENVELOPE_TAGS=["environment_context","recommended_plugins","user_instructions"];function isTagEnvelope(text){return ENVELOPE_TAGS.some((tag)=>text.startsWith(`<${tag}>`)&&text.endsWith(`</${tag}>`))}function isInstructionsEnvelope(text){return text.startsWith("# AGENTS.md instructions")&&text.includes("<INSTRUCTIONS>")}function codexUsageToSnapshot(usage,opts={}){let totalInput=numberOr(usage.input_tokens,0),cachedInput=numberOr(usage.cached_input_tokens,0),output=numberOr(usage.output_tokens,0),nonCachedInput=Math.max(0,totalInput-cachedInput);if(totalInput<=0&&output<=0&&cachedInput<=0)return;return{input_tokens:nonCachedInput,output_tokens:output,...cachedInput>0?{cache_read_input_tokens:cachedInput}:{},...validPositive(opts.contextWindowTokens)?{context_window_tokens:opts.contextWindowTokens}:{}}}function numberOr(v,fallback){return typeof v==="number"&&Number.isFinite(v)?v:fallback}function validPositive(v){return typeof v==="number"&&Number.isFinite(v)&&v>0}var emptyState={messages:[],latestUsage:void 0,latestUsageTimestampMs:null},cache=createAppendParseCache({initial:()=>emptyState,parseChunk:foldRolloutChunk});function parseRolloutRaw(filePath,raw,sessionId){let state=cache(filePath,raw,sessionId);return{messages:sortByTimestamp(state.messages),...state.latestUsage?{usageMetrics:state.latestUsage}:{}}}function foldRolloutChunk(chunk,prev,sessionId){let updatedMessages,writableMessages=()=>{return updatedMessages??=[...prev.messages],updatedMessages},latestUsage=prev.latestUsage,latestUsageTimestampMs=prev.latestUsageTimestampMs;for(let line of chunk.split(`