vibelet 0.1.22 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/vibelet.mjs CHANGED
@@ -25,6 +25,7 @@ const stdoutLogPath = join(logDir, 'daemon.stdout.log');
25
25
  const stderrLogPath = join(logDir, 'daemon.stderr.log');
26
26
  const pidFilePath = join(vibeletDir, 'daemon.pid');
27
27
  const relayConfigPath = join(vibeletDir, 'relay.json');
28
+ const tunnelStatePath = join(vibeletDir, 'tunnel.json');
28
29
  const updateCheckPath = join(vibeletDir, 'update-check.json');
29
30
  const OFFICIAL_SITE_URL = 'https://vibelet.icu';
30
31
  const UPDATE_CHECK_INTERVAL_MS = 4 * 60 * 60 * 1000; // 4 hours
@@ -595,7 +596,9 @@ function printHelp() {
595
596
  process.stdout.write(`Usage:\n`);
596
597
  process.stdout.write(` npx ${packageJson.name} Install/start the daemon and print a pairing QR code\n`);
597
598
  process.stdout.write(` npx ${packageJson.name} start Same as above\n`);
598
- process.stdout.write(` npx ${packageJson.name} --relay <url> Use a tunnel URL for remote access\n`);
599
+ process.stdout.write(` npx ${packageJson.name} --tunnel Auto-start a Cloudflare Tunnel for remote access\n`);
600
+ process.stdout.write(` npx ${packageJson.name} --tunnel --force Force a new tunnel (discard existing)\n`);
601
+ process.stdout.write(` npx ${packageJson.name} --relay <url> Use a custom tunnel URL for remote access\n`);
599
602
  process.stdout.write(` npx ${packageJson.name} --host <ip> Set the primary host/IP address\n`);
600
603
  process.stdout.write(` npx ${packageJson.name} --fallback-hosts <ips> Comma-separated fallback IPs\n`);
601
604
  process.stdout.write(` npx ${packageJson.name} stop Stop the daemon\n`);
@@ -609,20 +612,29 @@ function printHelp() {
609
612
  process.stdout.write(`You can also invoke the published alias with:\n`);
610
613
  process.stdout.write(` npx ${packageJson.name === 'vibelet' ? '@vibelet/cli' : 'vibelet'}\n`);
611
614
  process.stdout.write(` vibelet\n\n`);
612
- process.stdout.write(`Remote access (relay):\n`);
613
- process.stdout.write(` Start a tunnel with one of these tools, then copy the generated URL:\n\n`);
614
- process.stdout.write(` # Cloudflare Tunnel (free, no account needed)\n`);
615
- process.stdout.write(` npx cloudflared tunnel --protocol http2 --url http://localhost:${port}\n\n`);
616
- process.stdout.write(` # ngrok (free, requires sign-up)\n`);
617
- process.stdout.write(` ngrok http ${port}\n\n`);
618
- process.stdout.write(` Then start vibelet with the tunnel URL:\n`);
615
+ process.stdout.write(`Remote access:\n`);
616
+ process.stdout.write(` # Easiest one command, powered by Cloudflare Tunnel (free, no account)\n`);
617
+ process.stdout.write(` npx ${packageJson.name} --tunnel\n\n`);
618
+ process.stdout.write(` # Or bring your own tunnel and pass the URL manually:\n`);
619
+ process.stdout.write(` npx cloudflared tunnel --protocol http2 --url http://localhost:${port}\n`);
620
+ process.stdout.write(` ngrok http ${port}\n`);
619
621
  process.stdout.write(` npx ${packageJson.name} --relay=https://<your-tunnel-url>\n\n`);
620
622
  process.stdout.write(` # Tailscale (P2P VPN, no tunnel needed)\n`);
621
- process.stdout.write(` Install Tailscale on both your computer and phone, then use your\n`);
622
- process.stdout.write(` Tailscale IP directly — no relay required:\n`);
623
623
  process.stdout.write(` npx ${packageJson.name} --host=<tailscale-ip>\n`);
624
624
  }
625
625
 
626
+ function consumeFlag(name) {
627
+ const idx = process.argv.indexOf(`--${name}`);
628
+ if (idx === -1) return false;
629
+ process.argv.splice(idx, 1);
630
+ return true;
631
+ }
632
+
633
+ function readNpmConfigFlag(name) {
634
+ const value = process.env[`npm_config_${name.replace(/-/g, '_')}`];
635
+ return value === '' || value === 'true';
636
+ }
637
+
626
638
  function parseNamedArg(name, errorHint) {
627
639
  const inlinePrefix = `--${name}=`;
628
640
  const inlineArg = process.argv.find((arg) => arg.startsWith(inlinePrefix));
@@ -664,15 +676,153 @@ function clearRelayConfig() {
664
676
  rmSync(relayConfigPath, { force: true });
665
677
  }
666
678
 
679
+ // ─── Tunnel management ──────────────────────────────────────────────────────────
680
+
681
+ function loadTunnelState() {
682
+ try {
683
+ return JSON.parse(readFileSync(tunnelStatePath, 'utf8'));
684
+ } catch {
685
+ return null;
686
+ }
687
+ }
688
+
689
+ function saveTunnelState(pid, url) {
690
+ mkdirSync(vibeletDir, { recursive: true });
691
+ writeFileSync(tunnelStatePath, JSON.stringify({ pid, url }, null, 2) + '\n', 'utf8');
692
+ }
693
+
694
+ function clearTunnelState() {
695
+ rmSync(tunnelStatePath, { force: true });
696
+ }
697
+
698
+ function stopTunnel() {
699
+ const state = loadTunnelState();
700
+ if (state?.pid && isProcessAlive(state.pid)) {
701
+ try { process.kill(state.pid, 'SIGTERM'); } catch { /* already dead */ }
702
+ }
703
+ clearTunnelState();
704
+ }
705
+
706
+ function getAliveTunnel() {
707
+ const state = loadTunnelState();
708
+ if (state?.pid && state?.url && isProcessAlive(state.pid)) {
709
+ return state;
710
+ }
711
+ return null;
712
+ }
713
+
714
+ function resolveCloudflaredBin() {
715
+ // 1. Check if cloudflared is in PATH
716
+ const which = spawnSync('which', ['cloudflared'], { encoding: 'utf8' });
717
+ if (which.status === 0 && which.stdout.trim()) {
718
+ return which.stdout.trim();
719
+ }
720
+
721
+ // 2. Ensure npx has it installed (this downloads if needed, but is fast if cached)
722
+ const result = spawnSync('npx', ['--yes', '--package=cloudflared', 'node', '-e',
723
+ "console.log(require('path').join(require('path').dirname(require.resolve('cloudflared')), 'bin', 'cloudflared'))"],
724
+ { encoding: 'utf8', timeout: 30_000 });
725
+ if (result.status === 0 && result.stdout.trim()) {
726
+ const binPath = result.stdout.trim();
727
+ if (existsSync(binPath)) return binPath;
728
+ }
729
+
730
+ return null;
731
+ }
732
+
733
+ function startTunnel() {
734
+ return new Promise((resolve, reject) => {
735
+ const logPath = join(logDir, 'tunnel.stderr.log');
736
+ mkdirSync(logDir, { recursive: true });
737
+
738
+ const cfBin = resolveCloudflaredBin();
739
+ if (!cfBin) {
740
+ reject(new Error('cloudflared not found. Install it with: brew install cloudflared'));
741
+ return;
742
+ }
743
+
744
+ // Strategy: start cloudflared with output to log files (so it survives detach),
745
+ // then tail the log to capture the URL.
746
+ // Truncate log so we don't match a stale URL from a previous run.
747
+ writeFileSync(logPath, '', 'utf8');
748
+ const logFd = openSync(logPath, 'a');
749
+ const child = spawn(cfBin, ['tunnel', '--protocol', 'http2', '--url', `http://localhost:${port}`], {
750
+ detached: true,
751
+ stdio: ['ignore', logFd, logFd],
752
+ });
753
+ child.unref();
754
+
755
+ const pid = child.pid;
756
+ let url = null;
757
+
758
+ const timeout = setTimeout(() => {
759
+ if (!url) {
760
+ try { process.kill(pid, 'SIGTERM'); } catch { /* */ }
761
+ reject(new Error('Timed out waiting for tunnel URL (30s). Check network/proxy settings.'));
762
+ }
763
+ }, 30_000);
764
+
765
+ // Poll the log file for the tunnel URL
766
+ const poll = setInterval(() => {
767
+ try {
768
+ const content = readFileSync(logPath, 'utf8');
769
+ const match = content.match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/);
770
+ if (match) {
771
+ url = match[0];
772
+ clearInterval(poll);
773
+ clearTimeout(timeout);
774
+ saveTunnelState(pid, url);
775
+ resolve({ pid, url });
776
+ return;
777
+ }
778
+ // Check if process died before producing URL
779
+ if (!isProcessAlive(pid)) {
780
+ clearInterval(poll);
781
+ clearTimeout(timeout);
782
+ reject(new Error('cloudflared exited before producing a tunnel URL. Check ~/.vibelet/logs/tunnel.stderr.log'));
783
+ }
784
+ } catch { /* file not ready yet */ }
785
+ }, 300);
786
+
787
+ child.on('error', (err) => {
788
+ clearInterval(poll);
789
+ clearTimeout(timeout);
790
+ reject(new Error(`Failed to start cloudflared: ${err.message}\nInstall it with: brew install cloudflared`));
791
+ });
792
+ });
793
+ }
794
+
667
795
  async function main() {
668
796
  // Update check: read cached result (sync, instant) and spawn background fetch.
669
797
  checkForUpdateFromCache();
670
798
  fetchLatestVersionInBackground();
671
799
 
800
+ const tunnelFlag = consumeFlag('tunnel') || readNpmConfigFlag('tunnel');
801
+ const forceFlag = consumeFlag('force') || readNpmConfigFlag('force');
672
802
  const relayArg = parseRelayArg();
673
803
  const hostArg = parseNamedArg('host', '100.x.x.x');
674
804
  const fallbackHostsArg = parseNamedArg('fallback-hosts', '100.x.x.x,192.168.1.x');
675
- const hasExplicitConfigOverrides = relayArg !== null || Boolean(hostArg) || Boolean(fallbackHostsArg);
805
+ const hasExplicitConfigOverrides = relayArg !== null || Boolean(hostArg) || Boolean(fallbackHostsArg) || tunnelFlag;
806
+
807
+ // --tunnel: auto-start or reuse a Cloudflare Tunnel
808
+ if (tunnelFlag) {
809
+ const existing = forceFlag ? null : getAliveTunnel();
810
+ if (existing) {
811
+ process.stdout.write(`Reusing tunnel: ${existing.url} (pid ${existing.pid})\n`);
812
+ saveRelayConfig(existing.url);
813
+ } else {
814
+ if (forceFlag) stopTunnel();
815
+ process.stdout.write('Starting Cloudflare Tunnel...\n');
816
+ try {
817
+ const tunnel = await startTunnel();
818
+ process.stdout.write(`Tunnel ready: ${tunnel.url}\n`);
819
+ saveRelayConfig(tunnel.url);
820
+ } catch (err) {
821
+ fail(err.message);
822
+ }
823
+ }
824
+ }
825
+
676
826
  // --relay "" clears saved relay; --relay <url> saves it; omitted uses saved value
677
827
  if (relayArg !== null) {
678
828
  if (relayArg) {
@@ -722,6 +872,12 @@ async function main() {
722
872
  if (stillAlive) {
723
873
  fail('Daemon did not stop in time.');
724
874
  }
875
+ // Also stop tunnel if running
876
+ const tunnelState = getAliveTunnel();
877
+ if (tunnelState) {
878
+ stopTunnel();
879
+ process.stdout.write('Tunnel stopped.\n');
880
+ }
725
881
  process.stdout.write('Daemon stopped.\n');
726
882
  return;
727
883
  }
@@ -729,6 +885,10 @@ async function main() {
729
885
  if (command === 'status') {
730
886
  process.stdout.write(`Service (${backend.name}): ${backend.statusLabel()}\n`);
731
887
  process.stdout.write(`Runtime: ${existsSync(runtimeDaemonEntryPath) ? runtimeDaemonEntryPath : 'not installed'}\n`);
888
+ const tunnelState = getAliveTunnel();
889
+ if (tunnelState) {
890
+ process.stdout.write(`Tunnel: ${tunnelState.url} (pid ${tunnelState.pid})\n`);
891
+ }
732
892
  const savedRelay = loadRelayConfig();
733
893
  if (savedRelay) {
734
894
  process.stdout.write(`Relay: ${savedRelay}\n`);
package/dist/index.cjs CHANGED
@@ -83,7 +83,7 @@ process.stdin.resume();
83
83
  `)}function ng(t){return Array.isArray(t)?t.map(e=>!e||typeof e!="object"?"":typeof e.text=="string"?e.text:typeof e.content=="string"?e.content:"").filter(Boolean).join(`
84
84
  `):""}function rg(t){return Array.isArray(t)&&t.length>0&&t.every(e=>e&&typeof e=="object"&&e.type==="tool_reference")}function sg(t){if(typeof t=="string")return t;let e=ng(t);return e||(rg(t)?"":JSON.stringify(t))}function ig(t){return/requested permissions|haven't granted/i.test(t)}function dc(t){return t.replace(eg,"").replace(/\s+/g," ").trim()}function og(t){let e=t.toLowerCase();return e==="error"||e==="failed"||e==="unknown error"}function ag(t){return/\brate limit\b/i.test(t)||/\busage limit\b/i.test(t)||/\bquota\b/i.test(t)||/\btoo many requests\b/i.test(t)||/\bcredit balance\b/i.test(t)||/\bcredits? remaining\b/i.test(t)||/\bmax(?:imum)? usage\b/i.test(t)}function lg(t){return t.toLowerCase().startsWith("claude ")?t:`Claude usage limit reached. ${t}`}function fc(t){let e=dc(t.resultText??""),n=(t.stderrLines??[]).map(dc).filter(Boolean).slice(-3),r=[e,...n].find(i=>!!i&&ag(i));if(r)return lg(r);let s=[e,...n].find(i=>!!i&&!og(i));return s?t.exitCode!=null&&s!==e?`Claude exited with code ${t.exitCode}: ${s}`:s:t.exitCode!=null?`Claude exited with code ${t.exitCode}`:"Claude returned an error result."}function or(t){return t.startsWith(gc)}var on=class{proc=null;handler=null;sessionId="";buffer="";cwd="";approvalMode;sawFinalResult=!1;interrupted=!1;exitHandler=null;lastStderr=[];pendingPermissionDescriptions=new Map;emittedToolCallIds=new Set;replayPhase=!1;hookPort=null;hookSecret=null;hookFiles=null;buildClaudeEnv(){let e=v.buildSanitizedEnv();for(let n of Object.keys(e))n.startsWith("CMUX_")&&delete e[n];return e}async start(e,n,r){return this.cwd=e,this.approvalMode=r,n&&(this.sessionId=n),this.sessionId||(this.sessionId=`pending_${Date.now()}`),te.info({sessionId:this.sessionId,cwd:e},"session initialized"),_.emit("driver.spawn",{agent:"claude",sessionId:this.sessionId,cwd:e}),this.sessionId}configureHookBridge(e,n){this.hookPort=e,this.hookSecret=n}sendPrompt(e){let n=["-p",e,"--output-format","stream-json","--verbose","--include-partial-messages"];this.sessionId&&!this.sessionId.startsWith("pending_")&&n.push("--resume",this.sessionId),ir(this.hookFiles),this.hookFiles=null,this.approvalMode!=="acceptEdits"&&this.approvalMode!=="autoApprove"&&this.hookPort&&this.hookSecret&&(this.hookFiles=uc(this.hookPort,this.hookSecret),n.push("--settings",this.hookFiles.settingsPath)),this.approvalMode==="acceptEdits"&&n.push("--permission-mode","acceptEdits"),this.approvalMode==="autoApprove"&&n.push("--dangerously-skip-permissions");let r=this.sessionId.startsWith("pending_")?"(new)":`(resume ${this.sessionId.slice(0,8)})`;te.info({sessionId:this.sessionId,label:r,promptPreview:e.slice(0,50)},"running claude"),Ys(`New message: ${e.slice(0,60)}`),this.sawFinalResult=!1,this.interrupted=!1,this.lastStderr=[],this.pendingPermissionDescriptions.clear(),this.emittedToolCallIds.clear(),this.replayPhase=!0,this.proc=(0,pc.spawn)(v.claudePath,n,{cwd:this.cwd||void 0,stdio:["ignore","pipe","pipe"],env:this.buildClaudeEnv()}),this.proc.on("error",s=>{let i=s.message;s.code==="ENOENT"&&this.cwd&&!(0,hc.existsSync)(this.cwd)&&(i=`Working directory does not exist: ${this.cwd}`),te.error({sessionId:this.sessionId,error:i,cwd:this.cwd},"spawn error"),_.emit("driver.error",{agent:"claude",sessionId:this.sessionId,error:i}),this.handler?.({type:"error",sessionId:this.sessionId,message:i})}),this.buffer="",this.proc.stdout.on("data",s=>{this.buffer+=s.toString();let i=this.buffer.split(`
85
85
  `);this.buffer=i.pop();for(let o of i)if(o.trim())try{this.handleRaw(JSON.parse(o))}catch{te.warn({sessionId:this.sessionId,linePreview:o.slice(0,100)},"failed to parse stdout line")}}),this.proc.stderr.on("data",s=>{let i=s.toString().trim();i&&(te.debug({sessionId:this.sessionId,stderr:i},"stderr"),this.lastStderr.push(i),this.lastStderr.length>10&&this.lastStderr.shift())}),this.proc.on("exit",(s,i)=>{te.info({sessionId:this.sessionId,exitCode:s,signal:i},"process exited");let o=this.interrupted;this.proc=null,ir(this.hookFiles),this.hookFiles=null,this.interrupted=!1,o&&!this.sawFinalResult?this.handler?.({type:"session.interrupted",sessionId:this.sessionId}):s&&s!==0&&!this.sawFinalResult&&(te.error({sessionId:this.sessionId,exitCode:s,lastStderr:this.lastStderr.slice(-3)},"abnormal exit"),this.handler?.({type:"error",sessionId:this.sessionId,message:fc({stderrLines:this.lastStderr,exitCode:s})})),this.exitHandler?.(s)})}respondApproval(e,n){if(te.info({sessionId:this.sessionId,requestId:e,approved:n},"approval response"),!this.proc?.stdin?.writable)return te.error({sessionId:this.sessionId},"cannot send approval: stdin not writable"),!1;let r=JSON.stringify({type:"control_response",request_id:e,permission_granted:n});return this.proc.stdin.write(r+`
86
- `),!0}setApprovalMode(e){this.approvalMode=e,te.info({sessionId:this.sessionId,approvalMode:e},"approval mode updated")}interrupt(){this.proc&&!this.proc.killed&&(this.interrupted=!0,this.proc.kill("SIGTERM"),te.info({sessionId:this.sessionId},"interrupted"))}stop(){if(!this.proc)return;this.proc.kill("SIGTERM");let e=this.proc;setTimeout(()=>{e.killed||e.kill("SIGKILL")},5e3).unref(),this.proc=null,ir(this.hookFiles),this.hookFiles=null}onMessage(e){this.handler=e}onExit(e){this.exitHandler=e}handleRaw(e){let n=e.type;if(n==="system"&&e.subtype==="init"){let r=e.session_id??"";r&&r!==this.sessionId&&(te.info({oldSessionId:this.sessionId,newSessionId:r},"session ID resolved"),_.emit("driver.init",{agent:"claude",sessionId:r}),this.sessionId=r);return}if(this.handler)switch(n){case"assistant":{if(this.replayPhase)break;let r=e.message?.content;if(!Array.isArray(r))break;for(let s of r)s.type==="tool_use"&&!this.emittedToolCallIds.has(s.id)&&(this.emittedToolCallIds.add(s.id),this.handler({type:"tool.call",sessionId:this.sessionId,toolName:s.name,input:s.input??{},toolCallId:s.id}));break}case"user":{if(this.replayPhase)break;let r=e.message?.content;if(!Array.isArray(r))break;for(let s of r)if(s.type==="tool_result"){let i=sg(s.content);if(!i)continue;if(s.is_error===!0&&typeof s.tool_use_id=="string"&&ig(i)){this.pendingPermissionDescriptions.set(s.tool_use_id,i);continue}this.handler({type:"tool.result",sessionId:this.sessionId,toolCallId:s.tool_use_id,output:i})}break}case"control_request":{this.replayPhase=!1;let r=e.request;r?.subtype==="can_use_tool"&&(_.emit("approval.request",{agent:"claude",sessionId:this.sessionId,toolName:r.tool_name}),this.handler({type:"approval.request",sessionId:this.sessionId,requestId:e.request_id,toolName:r.tool_name??"unknown",input:r.input??{},description:r.description??r.title??""}));break}case"stream_event":{this.replayPhase=!1;let r=e.event;r?.type==="content_block_delta"&&r?.delta?.type==="text_delta"&&r?.delta?.text&&this.handler({type:"text.delta",sessionId:this.sessionId,content:r.delta.text});break}case"result":{this.replayPhase=!1,this.sawFinalResult=!0;let r=typeof e.result=="string"?e.result:"";if(e.is_error){Ys("Claude failed."),this.handler({type:"error",sessionId:this.sessionId,message:fc({resultText:r,stderrLines:this.lastStderr})});break}let s=Array.isArray(e.permission_denials)?e.permission_denials:[];if(s.length>0){let a=s[0]??{},l=typeof a.tool_use_id=="string"?a.tool_use_id:`missing_${Date.now()}`,c=typeof a.tool_name=="string"?a.tool_name:"unknown",u=a.tool_input&&typeof a.tool_input=="object"?a.tool_input:{},d=this.pendingPermissionDescriptions.get(l)??`Claude requested permissions to use ${c}.`;_.emit("approval.request",{agent:"claude",sessionId:this.sessionId,toolName:c}),this.handler({type:"approval.request",sessionId:this.sessionId,requestId:`${gc}${l}`,toolName:c,input:u,description:d})}this.pendingPermissionDescriptions.clear();let i=e.total_cost_usd,o=e.usage?{inputTokens:e.usage.input_tokens,outputTokens:e.usage.output_tokens}:void 0;Ys("Claude finished. Run `claude --continue` to continue on desktop."),_.emit("session.done",{agent:"claude",sessionId:this.sessionId,cost:i,usage:o}),this.handler({type:"session.done",sessionId:this.sessionId,cost:i,usage:o});break}}}};var vc=require("child_process"),_c=require("fs");var Js=class{counters=new Map;timers=new Map;gauges=new Map;startTime=Date.now();logInterval=null;increment(e,n={}){this.counters.has(e)||this.counters.set(e,[]);let r=this.counters.get(e),s=JSON.stringify(n),i=r.find(o=>JSON.stringify(o.labels)===s);i?i.value++:r.push({value:1,labels:n})}gauge(e,n){this.gauges.set(e,n)}startTimer(e){let n=performance.now();return()=>{let r=Math.round(performance.now()-n),s=this.timers.get(e)??{count:0,totalMs:0,minMs:1/0,maxMs:0,lastMs:0};return s.count++,s.totalMs+=r,s.minMs=Math.min(s.minMs,r),s.maxMs=Math.max(s.maxMs,r),s.lastMs=r,this.timers.set(e,s),r}}snapshot(){let e={};for(let[s,i]of this.counters)e[s]=i.map(o=>({...o}));let n={};for(let[s,i]of this.timers)n[s]={...i,minMs:i.minMs===1/0?0:i.minMs};let r={};for(let[s,i]of this.gauges)r[s]=i;return{uptimeMs:Date.now()-this.startTime,counters:e,timers:n,gauges:r}}startPeriodicLog(e=6e4){this.logInterval||(this.logInterval=setInterval(()=>{let n=this.snapshot();P.info({metrics:n},"periodic metrics snapshot")},e),this.logInterval.unref())}stopPeriodicLog(){this.logInterval&&(clearInterval(this.logInterval),this.logInterval=null)}},w=new Js;var mc=require("node:fs"),Ks=require("node:path"),cg="@vibelet/cli";function ug(t){try{let e=JSON.parse((0,mc.readFileSync)(t,"utf8"));if(e.name===cg&&typeof e.version=="string"&&e.version.length>0)return e.version}catch{}return null}function dg(){return"0.1.22"}var yt=dg();var x=P.child({module:"codex"});function fg(t){switch(t.kind){case"request-user-input-approval":return{provider:"codex",kind:t.kind,rpcId:t.rpcId,questionId:t.questionId,approveLabel:t.approveLabel,denyLabel:t.denyLabel};default:return{provider:"codex",kind:t.kind,rpcId:t.rpcId}}}function pg(t){let e=t.approvalContext;if(!e||e.provider!=="codex")return null;switch(e.kind){case"command-execution":return{kind:e.kind,responseKind:"v2",rpcId:e.rpcId,toolName:t.toolName,input:t.input};case"file-change":return{kind:e.kind,responseKind:"v2",rpcId:e.rpcId,toolName:t.toolName,input:t.input};case"request-user-input-approval":return!e.questionId||!e.approveLabel||!e.denyLabel?null:{kind:e.kind,rpcId:e.rpcId,questionId:e.questionId,approveLabel:e.approveLabel,denyLabel:e.denyLabel,toolName:t.toolName,input:t.input};case"exec-command-legacy":return{kind:e.kind,rpcId:e.rpcId,toolName:t.toolName,input:t.input};case"apply-patch-legacy":return{kind:e.kind,rpcId:e.rpcId,toolName:t.toolName,input:t.input};default:return null}}function $(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function k(t){return typeof t=="string"&&t.trim().length>0?t.trim():null}var hg=new Set(["aborted","interrupted","cancelled","canceled"]);function gg(t){let e=k(t);return e?e.toLowerCase():null}function mg(t){let e=k(t);return e?e.replace(/[^a-z0-9]/gi,"").toLowerCase():null}function Xs(t){return t?k(t.itemId)??k(t.id)??k(t.callId)??k(t.call_id):null}function Zs(t,e){let n={};for(let[r,s]of Object.entries(t))e.includes(r)||(n[r]=s);return n}function bc(t){return/\bapprove\b|\ballow\b|\baccept\b|\byes\b|\bcontinue\b|\bproceed\b|\brun\b|\bapply\b/i.test(t)}function wc(t){return/\bdeny\b|\breject\b|\bdecline\b|\bno\b|\bcancel\b|\babort\b|\bstop\b/i.test(t)}function yg(t){if(!Array.isArray(t))return null;for(let e of t){let n=$(e);if(!n)continue;let r=k(n.id),s=Array.isArray(n.options)?n.options.map(l=>$(l)).filter(l=>!!l):[];if(!r||s.length===0)continue;let i=s.map(l=>k(l.label)).filter(l=>!!l);if(i.length<2)continue;let o=i.find(l=>bc(l))??i[0],a=i.find(l=>wc(l))??i[i.length-1];if(!(!o||!a||o===a))return{questionId:r,approveLabel:o,denyLabel:a}}return null}function Sg(t){if(!Array.isArray(t)||t.length===0)return!1;let e=t.map(s=>$(s)).filter(s=>!!s).flatMap(s=>(Array.isArray(s.options)?s.options:[]).map(o=>$(o)).filter(o=>!!o).map(o=>k(o.label)).filter(o=>!!o)),n=e.some(s=>bc(s)),r=e.some(s=>wc(s));return n&&r}function yc(t){let e=mg(t.type??t.itemType);if(e==="commandexecution")return{toolName:"Bash",input:Zs(t,["id","itemId","type","itemType","stdout","stderr","exitCode","exit_code","status","success","error"])};if(e==="filechange")return{toolName:"Patch",input:Zs(t,["id","itemId","type","itemType","stdout","stderr","exitCode","exit_code","status","success","error"])};if(e==="mcptoolcall"){let n=k(t.server),r=k(t.tool)??k(t.name);return r?{toolName:n?`mcp__${n}__${r}`:r,input:$(t.arguments)??$(t.input)??{}}:null}return null}function vg(t){if(!Array.isArray(t))return"";for(let e of t){let n=$(e);if(!n)continue;let r=k(n.question)??k(n.header);if(r)return r}return""}function Sc(t,e){return t==="autoApprove"?{approvalPolicy:"never",sandbox:"danger-full-access",sandboxPolicy:{type:"dangerFullAccess"}}:{approvalPolicy:"on-request",sandbox:"workspace-write",sandboxPolicy:{type:"workspaceWrite",writableRoots:[e],readOnlyAccess:{type:"fullAccess"},networkAccess:!0,excludeTmpdirEnvVar:!1,excludeSlashTmp:!1}}}var ar=class{proc=null;handler=null;exitHandler=null;buffer="";rpcId=0;pending=new Map;threadId="";lastStderr=[];approvalRequests=new Map;toolContextByCallId=new Map;turnStartInFlight=!1;interruptRequestedDuringTurnStart=!1;approvalMode;cwd="";async start(e,n,r){this.approvalMode=r,this.cwd=e,this.approvalRequests.clear(),this.toolContextByCallId.clear(),this.turnStartInFlight=!1,this.interruptRequestedDuringTurnStart=!1;let s=v.codexPath,i,o=this.buildSpawnArgs();if(v.isTransientPath(s)){let c=v.execViaLoginShell("codex",o);i=c.command,o=c.args,x.info({spawnCmd:i,argsPreview:o.slice(0,2)},"spawning via login shell")}else i=s,x.info({spawnCmd:i,args:o},"spawning");_.emit("driver.spawn",{agent:"codex",cwd:e,resumeSessionId:n}),this.lastStderr=[],this.proc=(0,vc.spawn)(i,o,{cwd:e||void 0,stdio:["pipe","pipe","pipe"],env:v.buildSanitizedEnv()}),this.proc.on("error",c=>{let u=c.message;c.code==="ENOENT"&&e&&!(0,_c.existsSync)(e)&&(u=`Working directory does not exist: ${e}`),x.error({error:u,cwd:e},"spawn error"),_.emit("driver.error",{agent:"codex",error:u})}),this.proc.stdout.on("data",c=>{this.buffer+=c.toString();let u=this.buffer.split(`
86
+ `),!0}setApprovalMode(e){this.approvalMode=e,te.info({sessionId:this.sessionId,approvalMode:e},"approval mode updated")}interrupt(){this.proc&&!this.proc.killed&&(this.interrupted=!0,this.proc.kill("SIGTERM"),te.info({sessionId:this.sessionId},"interrupted"))}stop(){if(!this.proc)return;this.proc.kill("SIGTERM");let e=this.proc;setTimeout(()=>{e.killed||e.kill("SIGKILL")},5e3).unref(),this.proc=null,ir(this.hookFiles),this.hookFiles=null}onMessage(e){this.handler=e}onExit(e){this.exitHandler=e}handleRaw(e){let n=e.type;if(n==="system"&&e.subtype==="init"){let r=e.session_id??"";r&&r!==this.sessionId&&(te.info({oldSessionId:this.sessionId,newSessionId:r},"session ID resolved"),_.emit("driver.init",{agent:"claude",sessionId:r}),this.sessionId=r);return}if(this.handler)switch(n){case"assistant":{if(this.replayPhase)break;let r=e.message?.content;if(!Array.isArray(r))break;for(let s of r)s.type==="tool_use"&&!this.emittedToolCallIds.has(s.id)&&(this.emittedToolCallIds.add(s.id),this.handler({type:"tool.call",sessionId:this.sessionId,toolName:s.name,input:s.input??{},toolCallId:s.id}));break}case"user":{if(this.replayPhase)break;let r=e.message?.content;if(!Array.isArray(r))break;for(let s of r)if(s.type==="tool_result"){let i=sg(s.content);if(!i)continue;if(s.is_error===!0&&typeof s.tool_use_id=="string"&&ig(i)){this.pendingPermissionDescriptions.set(s.tool_use_id,i);continue}this.handler({type:"tool.result",sessionId:this.sessionId,toolCallId:s.tool_use_id,output:i})}break}case"control_request":{this.replayPhase=!1;let r=e.request;r?.subtype==="can_use_tool"&&(_.emit("approval.request",{agent:"claude",sessionId:this.sessionId,toolName:r.tool_name}),this.handler({type:"approval.request",sessionId:this.sessionId,requestId:e.request_id,toolName:r.tool_name??"unknown",input:r.input??{},description:r.description??r.title??""}));break}case"stream_event":{this.replayPhase=!1;let r=e.event;r?.type==="content_block_delta"&&r?.delta?.type==="text_delta"&&r?.delta?.text&&this.handler({type:"text.delta",sessionId:this.sessionId,content:r.delta.text});break}case"result":{this.replayPhase=!1,this.sawFinalResult=!0;let r=typeof e.result=="string"?e.result:"";if(e.is_error){Ys("Claude failed."),this.handler({type:"error",sessionId:this.sessionId,message:fc({resultText:r,stderrLines:this.lastStderr})});break}let s=Array.isArray(e.permission_denials)?e.permission_denials:[];if(s.length>0){let a=s[0]??{},l=typeof a.tool_use_id=="string"?a.tool_use_id:`missing_${Date.now()}`,c=typeof a.tool_name=="string"?a.tool_name:"unknown",u=a.tool_input&&typeof a.tool_input=="object"?a.tool_input:{},d=this.pendingPermissionDescriptions.get(l)??`Claude requested permissions to use ${c}.`;_.emit("approval.request",{agent:"claude",sessionId:this.sessionId,toolName:c}),this.handler({type:"approval.request",sessionId:this.sessionId,requestId:`${gc}${l}`,toolName:c,input:u,description:d})}this.pendingPermissionDescriptions.clear();let i=e.total_cost_usd,o=e.usage?{inputTokens:e.usage.input_tokens,outputTokens:e.usage.output_tokens}:void 0;Ys("Claude finished. Run `claude --continue` to continue on desktop."),_.emit("session.done",{agent:"claude",sessionId:this.sessionId,cost:i,usage:o}),this.handler({type:"session.done",sessionId:this.sessionId,cost:i,usage:o});break}}}};var vc=require("child_process"),_c=require("fs");var Js=class{counters=new Map;timers=new Map;gauges=new Map;startTime=Date.now();logInterval=null;increment(e,n={}){this.counters.has(e)||this.counters.set(e,[]);let r=this.counters.get(e),s=JSON.stringify(n),i=r.find(o=>JSON.stringify(o.labels)===s);i?i.value++:r.push({value:1,labels:n})}gauge(e,n){this.gauges.set(e,n)}startTimer(e){let n=performance.now();return()=>{let r=Math.round(performance.now()-n),s=this.timers.get(e)??{count:0,totalMs:0,minMs:1/0,maxMs:0,lastMs:0};return s.count++,s.totalMs+=r,s.minMs=Math.min(s.minMs,r),s.maxMs=Math.max(s.maxMs,r),s.lastMs=r,this.timers.set(e,s),r}}snapshot(){let e={};for(let[s,i]of this.counters)e[s]=i.map(o=>({...o}));let n={};for(let[s,i]of this.timers)n[s]={...i,minMs:i.minMs===1/0?0:i.minMs};let r={};for(let[s,i]of this.gauges)r[s]=i;return{uptimeMs:Date.now()-this.startTime,counters:e,timers:n,gauges:r}}startPeriodicLog(e=6e4){this.logInterval||(this.logInterval=setInterval(()=>{let n=this.snapshot();P.info({metrics:n},"periodic metrics snapshot")},e),this.logInterval.unref())}stopPeriodicLog(){this.logInterval&&(clearInterval(this.logInterval),this.logInterval=null)}},w=new Js;var mc=require("node:fs"),Ks=require("node:path"),cg="@vibelet/cli";function ug(t){try{let e=JSON.parse((0,mc.readFileSync)(t,"utf8"));if(e.name===cg&&typeof e.version=="string"&&e.version.length>0)return e.version}catch{}return null}function dg(){return"0.1.24"}var yt=dg();var x=P.child({module:"codex"});function fg(t){switch(t.kind){case"request-user-input-approval":return{provider:"codex",kind:t.kind,rpcId:t.rpcId,questionId:t.questionId,approveLabel:t.approveLabel,denyLabel:t.denyLabel};default:return{provider:"codex",kind:t.kind,rpcId:t.rpcId}}}function pg(t){let e=t.approvalContext;if(!e||e.provider!=="codex")return null;switch(e.kind){case"command-execution":return{kind:e.kind,responseKind:"v2",rpcId:e.rpcId,toolName:t.toolName,input:t.input};case"file-change":return{kind:e.kind,responseKind:"v2",rpcId:e.rpcId,toolName:t.toolName,input:t.input};case"request-user-input-approval":return!e.questionId||!e.approveLabel||!e.denyLabel?null:{kind:e.kind,rpcId:e.rpcId,questionId:e.questionId,approveLabel:e.approveLabel,denyLabel:e.denyLabel,toolName:t.toolName,input:t.input};case"exec-command-legacy":return{kind:e.kind,rpcId:e.rpcId,toolName:t.toolName,input:t.input};case"apply-patch-legacy":return{kind:e.kind,rpcId:e.rpcId,toolName:t.toolName,input:t.input};default:return null}}function $(t){return!t||typeof t!="object"||Array.isArray(t)?null:t}function k(t){return typeof t=="string"&&t.trim().length>0?t.trim():null}var hg=new Set(["aborted","interrupted","cancelled","canceled"]);function gg(t){let e=k(t);return e?e.toLowerCase():null}function mg(t){let e=k(t);return e?e.replace(/[^a-z0-9]/gi,"").toLowerCase():null}function Xs(t){return t?k(t.itemId)??k(t.id)??k(t.callId)??k(t.call_id):null}function Zs(t,e){let n={};for(let[r,s]of Object.entries(t))e.includes(r)||(n[r]=s);return n}function bc(t){return/\bapprove\b|\ballow\b|\baccept\b|\byes\b|\bcontinue\b|\bproceed\b|\brun\b|\bapply\b/i.test(t)}function wc(t){return/\bdeny\b|\breject\b|\bdecline\b|\bno\b|\bcancel\b|\babort\b|\bstop\b/i.test(t)}function yg(t){if(!Array.isArray(t))return null;for(let e of t){let n=$(e);if(!n)continue;let r=k(n.id),s=Array.isArray(n.options)?n.options.map(l=>$(l)).filter(l=>!!l):[];if(!r||s.length===0)continue;let i=s.map(l=>k(l.label)).filter(l=>!!l);if(i.length<2)continue;let o=i.find(l=>bc(l))??i[0],a=i.find(l=>wc(l))??i[i.length-1];if(!(!o||!a||o===a))return{questionId:r,approveLabel:o,denyLabel:a}}return null}function Sg(t){if(!Array.isArray(t)||t.length===0)return!1;let e=t.map(s=>$(s)).filter(s=>!!s).flatMap(s=>(Array.isArray(s.options)?s.options:[]).map(o=>$(o)).filter(o=>!!o).map(o=>k(o.label)).filter(o=>!!o)),n=e.some(s=>bc(s)),r=e.some(s=>wc(s));return n&&r}function yc(t){let e=mg(t.type??t.itemType);if(e==="commandexecution")return{toolName:"Bash",input:Zs(t,["id","itemId","type","itemType","stdout","stderr","exitCode","exit_code","status","success","error"])};if(e==="filechange")return{toolName:"Patch",input:Zs(t,["id","itemId","type","itemType","stdout","stderr","exitCode","exit_code","status","success","error"])};if(e==="mcptoolcall"){let n=k(t.server),r=k(t.tool)??k(t.name);return r?{toolName:n?`mcp__${n}__${r}`:r,input:$(t.arguments)??$(t.input)??{}}:null}return null}function vg(t){if(!Array.isArray(t))return"";for(let e of t){let n=$(e);if(!n)continue;let r=k(n.question)??k(n.header);if(r)return r}return""}function Sc(t,e){return t==="autoApprove"?{approvalPolicy:"never",sandbox:"danger-full-access",sandboxPolicy:{type:"dangerFullAccess"}}:{approvalPolicy:"on-request",sandbox:"workspace-write",sandboxPolicy:{type:"workspaceWrite",writableRoots:[e],readOnlyAccess:{type:"fullAccess"},networkAccess:!0,excludeTmpdirEnvVar:!1,excludeSlashTmp:!1}}}var ar=class{proc=null;handler=null;exitHandler=null;buffer="";rpcId=0;pending=new Map;threadId="";lastStderr=[];approvalRequests=new Map;toolContextByCallId=new Map;turnStartInFlight=!1;interruptRequestedDuringTurnStart=!1;approvalMode;cwd="";async start(e,n,r){this.approvalMode=r,this.cwd=e,this.approvalRequests.clear(),this.toolContextByCallId.clear(),this.turnStartInFlight=!1,this.interruptRequestedDuringTurnStart=!1;let s=v.codexPath,i,o=this.buildSpawnArgs();if(v.isTransientPath(s)){let c=v.execViaLoginShell("codex",o);i=c.command,o=c.args,x.info({spawnCmd:i,argsPreview:o.slice(0,2)},"spawning via login shell")}else i=s,x.info({spawnCmd:i,args:o},"spawning");_.emit("driver.spawn",{agent:"codex",cwd:e,resumeSessionId:n}),this.lastStderr=[],this.proc=(0,vc.spawn)(i,o,{cwd:e||void 0,stdio:["pipe","pipe","pipe"],env:v.buildSanitizedEnv()}),this.proc.on("error",c=>{let u=c.message;c.code==="ENOENT"&&e&&!(0,_c.existsSync)(e)&&(u=`Working directory does not exist: ${e}`),x.error({error:u,cwd:e},"spawn error"),_.emit("driver.error",{agent:"codex",error:u})}),this.proc.stdout.on("data",c=>{this.buffer+=c.toString();let u=this.buffer.split(`
87
87
  `);this.buffer=u.pop();for(let d of u)if(d.trim())try{this.handleRaw(JSON.parse(d))}catch{x.warn({linePreview:d.slice(0,200)},"failed to parse stdout line")}}),this.proc.stderr.on("data",c=>{let u=c.toString().trim();u&&(x.debug({stderr:u},"stderr"),this.lastStderr.push(u),this.lastStderr.length>10&&this.lastStderr.shift())}),this.proc.on("exit",c=>{x.info({threadId:this.threadId,exitCode:c},"process exited"),c&&c!==0&&x.error({threadId:this.threadId,exitCode:c,lastStderr:this.lastStderr.slice(-3)},"abnormal exit"),this.proc=null,this.approvalRequests.clear(),this.toolContextByCallId.clear(),this.turnStartInFlight=!1,this.interruptRequestedDuringTurnStart=!1;for(let[,{reject:u}]of this.pending)u(new Error(`Codex process exited with code ${c}`));this.pending.clear(),this.exitHandler?.(c),c&&this.handler&&this.threadId&&this.handler({type:"error",sessionId:this.threadId,message:`Codex process exited with code ${c}`})});let a=w.startTimer("rpc.duration");await this.rpc("initialize",{clientInfo:{name:"@vibelet/cli",version:yt},capabilities:{experimentalApi:!0}}),a(),this.rpcNotify("initialized",{});let l=Sc(this.approvalMode,e);if(n){let c=await this.rpc("thread/resume",{threadId:n,approvalPolicy:l.approvalPolicy,sandbox:l.sandbox,persistExtendedHistory:!0});this.threadId=c?.thread?.id??n,x.info({threadId:this.threadId},"thread resumed"),_.emit("driver.init",{agent:"codex",sessionId:this.threadId})}else{let c=await this.rpc("thread/start",{cwd:e,approvalPolicy:l.approvalPolicy,sandbox:l.sandbox,experimentalRawEvents:!0,persistExtendedHistory:!0});this.threadId=c?.thread?.id??c?.threadId??"",x.info({threadId:this.threadId},"thread created"),_.emit("driver.init",{agent:"codex",sessionId:this.threadId})}return this.threadId}buildSpawnArgs(){return["app-server","--listen","stdio://"]}sendPrompt(e){let n=Sc(this.approvalMode,this.cwd||process.cwd());this.turnStartInFlight=!0,this.interruptRequestedDuringTurnStart=!1,x.info({threadId:this.threadId,promptPreview:e.slice(0,50)},"turn/start"),this.rpc("turn/start",{threadId:this.threadId,input:[{type:"text",text:e}],approvalPolicy:n.approvalPolicy,sandboxPolicy:n.sandboxPolicy}).then(r=>{x.debug({resultPreview:JSON.stringify(r).slice(0,200)},"turn/start result"),this.turnStartInFlight=!1,this.interruptRequestedDuringTurnStart&&(this.interruptRequestedDuringTurnStart=!1,this.requestTurnInterrupt())}).catch(r=>{this.turnStartInFlight=!1,this.interruptRequestedDuringTurnStart=!1,x.error({threadId:this.threadId,error:r.message},"sendPrompt error"),this.handler?.({type:"error",sessionId:this.threadId,message:r.message})})}respondApproval(e,n){if(!this.proc?.stdin?.writable)return!1;let r=this.approvalRequests.get(e),s=r?.rpcId??Number(e);if(!Number.isFinite(s))return!1;let i;if(!r)i=n?{decision:"approve"}:{decision:"deny",reason:"User denied from Vibelet"};else{switch(r.kind){case"command-execution":case"file-change":i={decision:n?"accept":"decline"};break;case"request-user-input-approval":i={answers:{[r.questionId]:{answers:[n?r.approveLabel:r.denyLabel]}}};break;case"exec-command-legacy":case"apply-patch-legacy":i={decision:n?"approved":"denied"};break;default:i={decision:n?"accept":"decline"};break}this.approvalRequests.delete(e)}return x.info({threadId:this.threadId,rpcId:s,approved:n},"approval response"),this.proc.stdin.write(JSON.stringify({jsonrpc:"2.0",id:s,result:i})+`
88
88
  `),!0}restorePendingApproval(e){let n=pg(e);n&&this.approvalRequests.set(e.requestId,n)}interrupt(){this.turnStartInFlight&&(this.interruptRequestedDuringTurnStart=!0),this.requestTurnInterrupt()}setApprovalMode(e){this.approvalMode=e,x.info({approvalMode:e},"approval mode updated (takes effect on subsequent turns)")}stop(){if(!this.proc)return;this.proc.kill("SIGTERM");let e=this.proc;setTimeout(()=>{e.killed||e.kill("SIGKILL")},5e3).unref(),this.proc=null,this.approvalRequests.clear(),this.toolContextByCallId.clear(),this.turnStartInFlight=!1,this.interruptRequestedDuringTurnStart=!1;for(let[,{reject:n}]of this.pending)n(new Error("Process stopped"));this.pending.clear()}onMessage(e){this.handler=e}onExit(e){this.exitHandler=e}rpc(e,n){let r=++this.rpcId,s=w.startTimer("rpc.duration");return new Promise((i,o)=>{if(this.pending.set(r,{resolve:a=>{s(),i(a)},reject:a=>{s(),o(a)}}),!this.proc?.stdin?.writable){this.pending.delete(r),s(),o(new Error("Process not available"));return}this.proc.stdin.write(JSON.stringify({jsonrpc:"2.0",method:e,id:r,params:n})+`
89
89
  `),setTimeout(()=>{this.pending.has(r)&&(this.pending.delete(r),x.error({method:e,rpcId:r,threadId:this.threadId},"RPC timeout"),s(),o(new Error(`RPC timeout: ${e}`)))},3e4).unref()})}requestTurnInterrupt(){this.rpc("turn/interrupt",{threadId:this.threadId}).catch(()=>{})}rpcNotify(e,n){this.proc?.stdin?.writable&&this.proc.stdin.write(JSON.stringify({jsonrpc:"2.0",method:e,params:n})+`
@@ -93,7 +93,7 @@ process.stdin.resume();
93
93
  `).find(r=>r.startsWith("n"))?.slice(1).trim()??""}async function Wg(t){let n=(await ti("lsof",["-p",String(t),"-Fn"])).split(`
94
94
  `).filter(r=>r.startsWith("n")).map(r=>r.slice(1).trim()).filter(r=>r.endsWith(".jsonl")?r.includes("/.claude/projects/")||r.includes("/.codex/sessions/"):!1);return[...new Set(n)]}async function Gg(){return(await ti("pgrep",["-fal",Eg])).split(`
95
95
  `).map(e=>e.trim()).filter(Boolean).map(e=>{let n=e.match(/^(\d+)\s+(.*)$/);if(!n)return null;let r=Number(n[1]),s=n[2];if(!Ng(s))return null;let i=dr(s);return!Number.isFinite(r)||!i?null:{pid:r,command:s,agent:i.agent}}).filter(e=>!!e)}async function Vg(){let e=(await Gg()).filter(n=>qg(n.pid));return Promise.all(e.map(async n=>({pid:n.pid,agent:n.agent,command:n.command,cwd:await jg(n.pid),sessionFiles:await Wg(n.pid)})))}function $g(t){return t.replace(/[^a-zA-Z0-9]/g,"-")}async function zg(t,e){if(!e)return null;try{if(t==="claude"){let o=(0,Pe.join)((0,ei.homedir)(),".claude","projects",$g(e)),l=(await(0,vt.readdir)(o).catch(()=>[])).filter(f=>f.endsWith(".jsonl"));if(l.length===0)return null;let c=null;if(await Promise.all(l.map(async f=>{let p=await(0,vt.stat)((0,Pe.join)(o,f)).catch(()=>null);p&&(!c||p.mtimeMs>c.mtimeMs)&&(c={name:f,mtimeMs:p.mtimeMs})})),!c)return null;let u=(0,Pe.join)(o,c.name),d=_t(t,u);return d?{sessionId:d,filePath:u}:null}let n=(0,Pe.join)((0,ei.homedir)(),".codex","sessions"),r=null;async function s(o){let a=await(0,vt.readdir)(o,{withFileTypes:!0}).catch(()=>[]);for(let l of a){let c=(0,Pe.join)(o,l.name);if(l.isDirectory())await s(c);else if(l.name.endsWith(".jsonl")){let u=await(0,vt.stat)(c).catch(()=>null);if(!u||r&&u.mtimeMs<=r.mtimeMs)continue;let d=await cn(c,t);if(!d||d.cwd!==e)continue;r={path:c,mtimeMs:u.mtimeMs,sessionId:d.sessionId}}}}await s(n);let i=r;return i?{sessionId:i.sessionId,filePath:i.path}:null}catch{return null}}async function Yg(){let t=await Vg(),e=await Promise.all(t.map(async r=>{let s=Hg(r);if(s)return Tc(s);if(Dg(r.agent,r.command))return null;let i=await zg(r.agent,r.cwd);return i?Tc({agent:r.agent,pid:r.pid,cwd:r.cwd,command:r.command,sessionId:i.sessionId,confidence:"low",sessionFilePath:i.filePath}):null})),n=Ug(e.filter(r=>r!==null));return ln={value:n,expiresAt:Date.now()+Rg},n}async function Cc(){return ln&&Date.now()<ln.expiresAt?ln.value:an||(an=Yg().finally(()=>{an=null}),an)}var ze=P.child({module:"inventory"}),Jg=6e3,Kg=1e4,Xg={listScannedSessions:pn,scanRunningSessions:Cc,searchSessionContent:Bc},se=Zg(),dn=null,fr=0,hr=0,pr=0,ri=0,si=new Set;function Zg(){return{scannedSessions:[],runningSessions:[],scannedAt:"",refreshedAt:0}}function Qg(t){return JSON.stringify({sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,title:t.title,createdAt:t.createdAt,lastActivityAt:t.lastActivityAt,sources:[...t.sources].sort(),runtime:{state:t.runtime.state,confidence:t.runtime.confidence,resumeMode:t.runtime.resumeMode,pid:t.runtime.pid,command:t.runtime.command,isResponding:t.runtime.isResponding,needsAttention:t.runtime.needsAttention},managed:t.managed,approvalMode:t.approvalMode})}function em(t){return JSON.stringify({sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,title:t.title,pid:t.pid,command:t.command,confidence:t.confidence,isResponding:t.isResponding})}function Rc(t){return JSON.stringify({scannedSessions:t.scannedSessions.map(Qg).sort(),runningSessions:t.runningSessions.map(em).sort()})}function tm(){for(let t of si)try{t()}catch(e){ze.warn({error:String(e)},"session inventory backfill listener failed")}}function un(){w.gauge("session.inventory.external_cached_sessions",se.scannedSessions.length),w.gauge("session.inventory.external_running_sessions",se.runningSessions.length),w.gauge("session.inventory.backfill_inflight",dn?1:0)}function Mc(t){return si.add(t),()=>{si.delete(t)}}function Nc(){return{cachedSessions:se.scannedSessions.length,runningSessions:se.runningSessions.length,cacheAgeMs:se.refreshedAt?Math.max(0,Date.now()-se.refreshedAt):void 0,backfillInFlight:!!dn,lastBackfillDurationMs:pr||void 0,lastBackfillCompletedAt:hr?new Date(hr).toISOString():void 0,lastBackfillAppliedAt:ri?new Date(ri).toISOString():void 0}}un();var bt={daemonActive:3,externalRunning:2,idle:1},Pc={high:3,medium:2,low:1};function Oc(t,e){return e.lastActivityAt.localeCompare(t.lastActivityAt)||t.sessionId.localeCompare(e.sessionId)}function nm(t,e){let n=t.runtime.needsAttention?1:0,r=e.runtime.needsAttention?1:0,s=t.runtime.isResponding?1:0,i=e.runtime.isResponding?1:0;return r-n||i-s||bt[e.runtime.state]-bt[t.runtime.state]||Oc(t,e)}function rm(t,e){return bt[e.state]>bt[t.state]?e:bt[e.state]<bt[t.state]?t:Pc[e.confidence]>Pc[t.confidence]?e:t}function sm(t,e){return t?e?t.localeCompare(e)<=0?t:e:t:e}function im(t,e){return t?e?t.localeCompare(e)>=0?t:e:t:e}function om(t,e){return e?t?!(St(e)&&!St(t)):!0:!1}function ii(t="high",e="resumeSession"){return{state:"idle",confidence:t,resumeMode:e}}function am(t){return{sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,title:t.title,createdAt:t.createdAt,lastActivityAt:t.lastActivityAt,sources:["record"],runtime:{...ii()},managed:t.managed,approvalMode:t.approvalMode}}function lm(t,e){return{sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,title:t.title,createdAt:e,lastActivityAt:e,sources:["process"],runtime:{state:"externalRunning",confidence:t.confidence,resumeMode:"resumeSession",pid:t.pid,command:t.command,isResponding:t.isResponding}}}function cm(t){return{sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,title:t.title,createdAt:t.createdAt,lastActivityAt:t.lastActivityAt,sources:["daemon"],runtime:{state:"daemonActive",confidence:"high",resumeMode:"reuseDriver",needsAttention:t.needsAttention||void 0,isResponding:t.isResponding||void 0},managed:t.managed,approvalMode:t.approvalMode}}function um(t,e){for(let n of e){let r=`${n.agent}:${n.sessionId}`,s=t.get(r);if(!s){t.set(r,{...n,sources:[...n.sources],runtime:{...n.runtime}});continue}let i=om(s.title,n.title)?n.title:s.title,o=n.cwd||s.cwd,a=rm(s.runtime,n.runtime),l=s.sources.slice();for(let f of n.sources)l.includes(f)||l.push(f);let c=n.sources.includes("process"),u=s.sources.includes("process")&&!s.sources.includes("daemon"),d=c?s.lastActivityAt:u?n.lastActivityAt:im(s.lastActivityAt,n.lastActivityAt);t.set(r,{...s,cwd:o,title:i,createdAt:sm(s.createdAt,n.createdAt),lastActivityAt:d,sources:l,runtime:a,managed:s.managed||n.managed,approvalMode:n.approvalMode??s.approvalMode})}}function dm(...t){let e=new Map;for(let n of t)um(e,n);return[...e.values()]}function fm(t,e,n,r,s){let i=r?.toLowerCase(),o=t.filter(a=>{if(e&&a.agent!==e||n&&a.cwd!==n)return!1;if(i){let l=(a.title??"").toLowerCase(),c=(a.cwd??"").toLowerCase(),u=l.includes(i)||c.includes(i),d=s?.has(a.sessionId)??!1;if(!u&&!d)return!1}return!0});return r&&ze.info({total:t.length,filtered:o.length,search:r,contentMatchIds:s?.size??0},"filter applied"),o}function pm(t,e){if(!e)return 0;let n=0,r=t.length;for(;n<r;){let s=n+r>>1,i=t[s];(e.lastActivityAt.localeCompare(i.lastActivityAt)||i.sessionId.localeCompare(e.sessionId))>0?r=s:n=s+1}if(n>0){let s=t[n-1];if(s.lastActivityAt===e.lastActivityAt&&s.sessionId===e.sessionId)return n}return 0}function Lc(t,e,n,r,s,i,o){let a=i?1/0:Math.max(1,e||50),l=dm(t.sessionRecords.map(am),t.scannedSessions,t.runningSessions.map(m=>lm(m,t.scannedAt)),t.activeSessions.map(cm)),c=t.deletedSessionIds?.size?l.filter(m=>!t.deletedSessionIds?.has(m.sessionId)):l,u=fm(c,r,s,i,o),d=u.filter(m=>m.runtime.state!=="idle"||m.managed).sort(nm),f=u.filter(m=>m.runtime.state==="idle"&&!m.managed).sort(Oc),p=pm(f,n),g=f.slice(p,p+a),y=p+g.length<f.length&&g.length>0?{lastActivityAt:g[g.length-1].lastActivityAt,sessionId:g[g.length-1].sessionId}:void 0;return{sessions:n?g:[...d,...g],nextCursor:y}}function fn(t,e,n,r,s){return new Promise(i=>{let o=Date.now(),a=!1,l=null,c=u=>{a||(a=!0,l&&(clearTimeout(l),l=null),i(u))};l=setTimeout(()=>{if(a)return;let u=Array.isArray(s)&&s.length>0;ze.warn({source:t,timeoutMs:r,durationMs:Date.now()-o,partial:u?s.length:0},u?"session inventory source timed out, using partial results":"session inventory source timed out, using fallback"),c(u?s:n)},r),typeof l=="object"&&"unref"in l&&l.unref(),e().then(u=>{c(u)}).catch(u=>{a||ze.warn({source:t,error:String(u)},"session inventory source failed, using fallback"),c(n)})})}function hm(t=Date.now()){return se.refreshedAt===0||t-se.refreshedAt>=Kg}async function gm(t,e){let n=new Date().toISOString(),r=[],[s,i]=await Promise.all([fn("scanner.sessions",()=>t.listScannedSessions(void 0,void 0,r),[],e,r),fn("process.running_sessions",()=>t.scanRunningSessions(),[],e)]);return{scannedSessions:s,runningSessions:i,scannedAt:n,refreshedAt:Date.now()}}function mm(t,e){if(dn)return;let n=fr,r=w.startTimer("session.inventory.backfill_latency_ms");dn=gm(t,e).then(s=>{if(n!==fr)return;let i=Rc(se);se=s;let o=Rc(s),a=r();pr=a,hr=Date.now(),un(),i!==o&&(ri=Date.now(),w.increment("session.inventory.backfill_applied"),ze.info({durationMs:a,scanned:s.scannedSessions.length,running:s.runningSessions.length},"session inventory external backfill applied"),tm())}).catch(s=>{n===fr&&(pr=r(),hr=Date.now(),un(),ze.warn({error:String(s),durationMs:pr},"session inventory external backfill failed"))}).finally(()=>{n===fr&&(dn=null,un())}),un()}async function gr(t){let e={...Xg,...t.loaders??{}},n=Math.max(250,t.sourceTimeoutMs??Jg);if(!t.search){let c=w.startTimer("session.inventory.fast_path_latency_ms");hm()&&mm(e,n);let u=se,d=Lc({activeSessions:t.activeSessions,sessionRecords:t.sessionRecords,scannedSessions:u.scannedSessions,runningSessions:u.runningSessions,scannedAt:u.scannedAt||new Date().toISOString(),deletedSessionIds:t.deletedSessionIds},t.limit,t.cursor,t.agent,t.cwd);return c(),d}let r=[],s=new Date().toISOString(),i=t.search,[o,a,l]=await Promise.all([fn("scanner.sessions",()=>e.listScannedSessions(t.agent,t.cwd,r),[],n,r),fn("process.running_sessions",()=>e.scanRunningSessions(),[],n),fn("scanner.search_content",()=>e.searchSessionContent(i,t.agent),void 0,n)]);return ze.info({search:t.search,contentMatches:l?.size??0,scanned:o.length,records:t.sessionRecords.length,active:t.activeSessions.length},"search results"),Lc({activeSessions:t.activeSessions,sessionRecords:t.sessionRecords,scannedSessions:o,runningSessions:a,scannedAt:s,deletedSessionIds:t.deletedSessionIds},t.limit,t.cursor,t.agent,t.cwd,i,l)}var Le=P.child({module:"scanner"});function Uc(t){let e=new Map;return{get(n){let r=e.get(n);if(r){if(Date.now()>r.expiresAt){e.delete(n);return}return r.value}},set(n,r){e.set(n,{value:r,expiresAt:Date.now()+t})},clear(){e.clear()}}}var qc=3e4,ci=Uc(qc),ui=Uc(qc),oi=new Map,ai=new Map,wt=24;function yr(){ci.clear(),ui.clear()}function jc(t){return t.replace(/[^a-zA-Z0-9]/g,"-")}async function It(t,e,n){if(t.length===0)return[];let r=Math.max(1,Math.min(e,t.length)),s=new Array(t.length),i=0;return await Promise.all(Array.from({length:r},async()=>{for(;;){let o=i;if(i+=1,o>=t.length)return;s[o]=await n(t[o],o)}})),s}function*Wc(t,e){let n=0,r=0;for(;n<t.length&&r<e;){let s=t.indexOf(`
96
- `,n);s===-1&&(s=t.length);let i=t.substring(n,s);n=s+1,!(i.length===0||i.trim().length===0)&&(yield i,r+=1)}}var li=512*1024;async function Gc(t,e){if(e<=li)return(0,L.readFile)(t,"utf-8");let n=await(0,L.open)(t,"r");try{let r=Buffer.alloc(li),{bytesRead:s}=await n.read(r,0,li,0);return r.toString("utf-8",0,s)}finally{await n.close()}}function hi(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>!e||typeof e!="object"?"":typeof e.text=="string"?e.text:typeof e.content=="string"?e.content:"").join(""):""}function Vc(t){return t?.type==="response_item"&&t.payload?.type==="message"&&t.payload.role==="user"?hi(t.payload.content):t?.type==="event_msg"&&t.payload?.type==="user_message"&&typeof t.payload.message=="string"?t.payload.message:""}function Sr(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>!e||typeof e!="object"||e.type!=="text"?"":typeof e.text=="string"?e.text:"").join(""):""}var ym=["<task-notification>","<local-command-caveat>","<local-command-stdout>","<local-command-stderr>","<command-name>","<command-message>","<command-args>","<system-reminder>","<environment_context>","# AGENTS.md instructions for "];function Sm(t,e){if(t?.isMeta===!0)return!0;let n=e.trim();return n?ym.some(r=>n.startsWith(r)):!1}function vr(t){if(t?.type!=="user"||t.message?.role!=="user")return"";let e=Sr(t.message.content);return Sm(t,e)?"":e}function vm(t){return Array.isArray(t)&&t.some(e=>e&&typeof e=="object"&&e.type==="tool_result")}function $c(t){let e=t.trim();return e.startsWith("# AGENTS.md instructions for ")||e.startsWith("<environment_context>")}function mr(t,e="scanner"){return{sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,title:t.title,createdAt:t.createdAt,lastActivityAt:t.lastActivityAt,sources:[e],runtime:ii()}}function _t(t,e){let n=(0,R.basename)(e,".jsonl");return t==="claude"?n||null:n.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i)?.[1]??null}async function _m(t,e){let n=await Gc(t,e),r=Wc(n,64),s="",i="",o,a,l;for(let c of r){let u;try{u=JSON.parse(c)}catch{continue}if(!s&&typeof u.cwd=="string"&&(s=u.cwd),!i&&typeof u.sessionId=="string"&&(i=u.sessionId),o||(o=$e([u.customTitle,u.summary])),!l){let d=vr(u),f=$e([],d);f&&(a=d,l=f)}if(s&&(o||l))break}return s?{sessionId:i||_t("claude",t)||(0,R.basename)(t,".jsonl"),cwd:s,title:o??l??$e([],a)}:null}async function bm(t,e){let n=await Gc(t,e),r=Wc(n,96),s="",i="",o,a,l;for(let c of r){let u;try{u=JSON.parse(c)}catch{continue}if(s||(s=u.payload?.cwd??u.cwd??""),i||(i=u.payload?.id??u.id??""),o||(o=$e([u.payload?.title,u.title])),!l){let d=Vc(u),f=d&&!$c(d)?$e([],d):void 0;f&&(a=d,l=f)}if(s&&(o||l))break}return s?{sessionId:i||_t("codex",t)||(0,R.basename)(t,".jsonl"),cwd:s,title:o??l??$e([],a)}:null}async function cn(t,e){let n=await(0,L.stat)(t).catch(()=>null);if(!n)return null;try{let r=n.size;if(e==="claude"){let i=await _m(t,r);return i?{sessionId:i.sessionId,agent:e,cwd:i.cwd,title:i.title,createdAt:new Date(n.birthtimeMs).toISOString(),lastActivityAt:new Date(n.mtimeMs).toISOString(),filePath:t}:null}let s=await bm(t,r);return s?{sessionId:s.sessionId,agent:e,cwd:s.cwd,title:s.title,createdAt:new Date(n.birthtimeMs).toISOString(),lastActivityAt:new Date(n.mtimeMs).toISOString(),filePath:t}:null}catch{return null}}async function Dc(t,e){let n=(0,R.join)((0,Se.homedir)(),".claude","projects");try{let r;t?r=[jc(t)]:r=(await(0,L.readdir)(n,{withFileTypes:!0})).filter(c=>c.isDirectory()).map(c=>c.name);let s=[];for(let l of r){let c=(0,R.join)(n,l),u=await(0,L.readdir)(c).catch(()=>[]);for(let d of u)d.endsWith(".jsonl")&&s.push((0,R.join)(c,d))}let i=await It(s,wt,async l=>{let c=await(0,L.stat)(l).catch(()=>null);return{path:l,mtimeMs:c?.mtimeMs??0}});return i.sort((l,c)=>c.mtimeMs-l.mtimeMs),(await It(i,wt,async l=>{let c=await cn(l.path,"claude");return c&&e&&e.push(mr(c)),c})).filter(l=>l!==null).map(l=>mr(l)).sort((l,c)=>c.lastActivityAt.localeCompare(l.lastActivityAt))}catch(r){return Le.warn({error:String(r)},"failed to list claude sessions"),[]}}async function Hc(t,e){let n=(0,R.join)((0,Se.homedir)(),".codex","sessions");try{let r=await(0,L.readdir)(n).catch(()=>[]),s=[];for(let l of r){let c=(0,R.join)(n,l),u=await(0,L.readdir)(c).catch(()=>[]);for(let d of u){let f=(0,R.join)(c,d),p=await(0,L.readdir)(f).catch(()=>[]);for(let g of p){let h=(0,R.join)(f,g),y=await(0,L.readdir)(h).catch(()=>[]);for(let m of y)m.endsWith(".jsonl")&&s.push((0,R.join)(h,m))}}}let i=await It(s,wt,async l=>{let c=await(0,L.stat)(l).catch(()=>null);return{path:l,mtimeMs:c?.mtimeMs??0}});return i.sort((l,c)=>c.mtimeMs-l.mtimeMs),(await It(i,wt,async l=>{let c=await cn(l.path,"codex");return c&&e&&(!t||c.cwd===t)&&e.push(mr(c)),c})).filter(l=>l!==null).filter(l=>!t||l.cwd===t).map(l=>mr(l)).sort((l,c)=>c.lastActivityAt.localeCompare(l.lastActivityAt))}catch(r){return Le.warn({error:String(r)},"failed to list codex sessions"),[]}}async function pn(t,e,n){let s=`list:${(0,Se.homedir)()}:${t??"all"}:${e??""}`,i=ci.get(s);if(i)return i;let o=oi.get(s);if(o)return o;let a=(async()=>{let l;if(t==="claude")l=await Dc(e,n);else if(t==="codex")l=await Hc(e,n);else{let[c,u]=await Promise.all([Dc(e,n),Hc(e,n)]);l=[...c,...u].sort((d,f)=>f.lastActivityAt.localeCompare(d.lastActivityAt))}return ci.set(s,l),l})();return oi.set(s,a),a.finally(()=>oi.delete(s)),a}async function Bc(t,e){let r=`search:${(0,Se.homedir)()}:${t}:${e??"all"}`,s=ui.get(r);if(s)return s;let i=ai.get(r);if(i)return i;let o=(async()=>{let a=new Set,l=t.toLowerCase();async function c(){let d=(0,R.join)((0,Se.homedir)(),".claude","projects");try{let f=await(0,L.readdir)(d,{withFileTypes:!0}),p=[];for(let h of f){if(!h.isDirectory())continue;let y=(0,R.join)(d,h.name),m=await(0,L.readdir)(y).catch(()=>[]);for(let E of m)E.endsWith(".jsonl")&&p.push((0,R.join)(y,E))}let g=await It(p,wt,h=>Fc(h,l,"claude"));for(let h of g)h&&a.add(h)}catch(f){Le.warn({error:String(f)},"failed to search claude files")}}async function u(){let d=(0,R.join)((0,Se.homedir)(),".codex","sessions");try{let f=[];async function p(h){let y=await(0,L.readdir)(h,{withFileTypes:!0}).catch(()=>[]);for(let m of y){let E=(0,R.join)(h,m.name);m.isDirectory()?await p(E):m.name.endsWith(".jsonl")&&f.push(E)}}await p(d);let g=await It(f,wt,h=>Fc(h,l,"codex"));for(let h of g)h&&a.add(h)}catch(f){Le.warn({error:String(f)},"failed to search codex files")}}return e==="claude"?await c():e==="codex"?await u():await Promise.all([c(),u()]),ui.set(r,a),a})();return ai.set(r,o),o.finally(()=>ai.delete(r)),o}async function Fc(t,e,n){let r=(0,fi.createReadStream)(t,{encoding:"utf-8"}),s=(0,pi.createInterface)({input:r,crlfDelay:1/0}),i=n==="claude"?wm:Im,o="",a=!1;try{for await(let l of s){if(!l.trim())continue;let c;try{c=JSON.parse(l)}catch{continue}if(o||(n==="claude"?typeof c.sessionId=="string"&&(o=c.sessionId):o=c.payload?.id??c.id??""),!a){let u=i(c);u&&u.toLowerCase().includes(e)&&(a=!0)}if(o&&a)break}}finally{s.close(),r.destroy()}return a?o||_t(n,t):null}function wm(t){return t?.type==="user"&&t.message?.role==="user"?vr(t):t?.type==="assistant"&&t.message?.role==="assistant"?Sr(t.message.content):""}function Im(t){if(t?.type==="response_item"&&t.payload?.type==="message"){let n=t.payload.role;if(n==="user"||n==="assistant")return hi(t.payload.content)}let e=Vc(t);return e||""}async function di(t,e){let n=(0,fi.createReadStream)(t,{encoding:"utf-8"}),r=(0,pi.createInterface)({input:n,crlfDelay:1/0});try{for await(let s of r){if(!s.trim())continue;let i;try{i=JSON.parse(s)}catch{continue}if(e(i))break}}finally{r.close(),n.destroy()}}async function zc(t,e){let n=(0,R.join)((0,Se.homedir)(),".claude","projects"),r=e?jc(e):null,s=await(0,L.readdir)(n).catch(()=>[]),i=r?[r,...s.filter(o=>o!==r)]:s;for(let o of i){let a=(0,R.join)(n,o,`${t}.jsonl`);if((await(0,L.stat)(a).catch(()=>null))?.isFile())return a}return null}async function Yc(t,e,n){if(e==="claude")return zc(t,n);let r=(0,R.join)((0,Se.homedir)(),".codex","sessions");return Jc(r,t)}function Am(t){if(t?.type==="user"&&t.message?.role==="user")return vm(t.message.content)?{kind:"toolResult"}:vr(t)?{kind:"userPrompt"}:null;if(t?.type==="assistant"&&t.message?.role==="assistant"){let e=Sr(t.message.content),n=t.message?.stop_reason;return{kind:"assistant",stopReason:typeof n=="string"?n:n??null,...e?{text:e}:{}}}return null}function xm(t){if(!t)return{};if(t.kind==="assistant"){let e=t.stopReason==null||t.stopReason==="tool_use";return{...e?{isResponding:!0}:{},...e&&t.text?{partialReplyText:t.text}:{}}}return{isResponding:!0}}async function ni(t,e){if(e!=="claude")return{};let n=null;try{await di(t,r=>{let s=Am(r);s&&(n=s)})}catch(r){return r.code!=="ENOENT"&&Le.warn({filePath:t,error:String(r)},"failed to read session runtime hints"),{}}return xm(n)}async function gi(t,e,n){let r=await Yc(t,e,n);return r?ni(r,e):{}}async function hn(t,e,n){let r=[],s=(i,o)=>{if(o?.coalesceConsecutiveAssistant&&i.role==="assistant"&&r[r.length-1]?.role==="assistant"){r[r.length-1]=i;return}r.push(i)};if(e==="claude")try{let i=await zc(t,n);i&&await di(i,o=>{if(o.type==="user"&&o.message?.role==="user"){let a=vr(o);a&&s({role:"user",content:a})}else if(o.type==="assistant"&&o.message?.role==="assistant"){let a=Sr(o.message.content);a&&s({role:"assistant",content:a})}})}catch(i){Le.warn({error:String(i)},"failed to read claude session history")}else if(e==="codex")try{let i=await Yc(t,e,n);i&&await di(i,o=>{if(o.type!=="response_item"||o.payload?.type!=="message")return;let a=o.payload.role;if(a!=="user"&&a!=="assistant")return;let l=hi(o.payload.content);l&&(a==="user"&&$c(l)||s({role:a,content:l},{coalesceConsecutiveAssistant:!0}))})}catch(i){Le.warn({error:String(i)},"failed to read codex session history")}return r}async function Jc(t,e){try{let n=await(0,L.readdir)(t,{withFileTypes:!0});for(let r of n){let s=(0,R.join)(t,r.name);if(r.isDirectory()){let i=await Jc(s,e);if(i)return i}else if(r.name.includes(e)&&r.name.endsWith(".jsonl"))return s}}catch(n){Le.warn({error:String(n)},"failed to walk codex sessions dir")}return null}var At=require("fs"),Zc=require("path");var Tm=500,Kc=200;function km(t){if(!Array.isArray(t))return[];let e=t.filter(n=>typeof n=="string"&&n.length>0);return e.length<=Kc?e:e.slice(-Kc)}function Em(t){if(!Array.isArray(t))return[];let e=[];for(let n of t)typeof n!="string"||n.length===0||e.includes(n)||e.push(n);return e}function Cm(t){if(!t||typeof t!="object"||Array.isArray(t))return;let e=t,n=typeof e.requestId=="string"?e.requestId:"",r=typeof e.toolName=="string"?e.toolName:"",s=typeof e.description=="string"?e.description:"",i=e.input&&typeof e.input=="object"&&!Array.isArray(e.input)?e.input:{};if(!n||!r||!s)return;let o=e.approvalContext;return o&&typeof o=="object"&&!Array.isArray(o)&&o.provider==="codex"&&typeof o.kind=="string"&&typeof o.rpcId=="number"?{requestId:n,toolName:r,input:i,description:s,approvalContext:{provider:"codex",kind:o.kind,rpcId:o.rpcId,...typeof o.questionId=="string"?{questionId:o.questionId}:{},...typeof o.approveLabel=="string"?{approveLabel:o.approveLabel}:{},...typeof o.denyLabel=="string"?{denyLabel:o.denyLabel}:{}}}:{requestId:n,toolName:r,input:i,description:s}}function Xc(t){return{...t,lastActivityAt:t.lastActivityAt??t.createdAt,acceptedClientMessageIds:km(t.acceptedClientMessageIds),pendingApproval:Cm(t.pendingApproval)}}function Rm(t){if(Array.isArray(t))return{records:t.map(Xc),deletedSessionIds:[]};if(t&&typeof t=="object"){let e=t;return{records:Array.isArray(e.records)?e.records.map(Xc):[],deletedSessionIds:Em(e.deletedSessionIds)}}return{records:[],deletedSessionIds:[]}}var _r=class{records;deletedSessionIds;debounceTimer=null;constructor(){let e=this.loadFromDisk();this.records=e.records,this.deletedSessionIds=new Set(e.deletedSessionIds)}getAll(){return this.records}getDeletedSessionIds(){return[...this.deletedSessionIds]}find(e){return this.records.find(n=>n.sessionId===e)}isDeleted(e){return this.deletedSessionIds.has(e)}upsert(e){this.deletedSessionIds.delete(e.sessionId);let n=this.records.findIndex(r=>r.sessionId===e.sessionId);n>=0?this.records[n]=e:this.records.unshift(e),this.scheduleSave()}remove(e){this.records=this.records.filter(n=>n.sessionId!==e),this.deletedSessionIds.add(e),this.scheduleSave()}flushSync(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.saveToDisk()}scheduleSave(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.saveToDisk()},Tm)}loadFromDisk(){try{let e=(0,At.readFileSync)(Xn,"utf-8");return Rm(JSON.parse(e))}catch{}return{records:[],deletedSessionIds:[]}}saveToDisk(){(0,At.mkdirSync)((0,Zc.dirname)(Xn),{recursive:!0}),(0,At.writeFileSync)(Xn,JSON.stringify({records:this.records,deletedSessionIds:[...this.deletedSessionIds]},null,2))}};var xt=require("path"),Qc=require("os");function br(t){return t=t.replace(/^~/,"~"),t.startsWith("~/")||t==="~"?(0,xt.join)((0,Qc.homedir)(),t.slice(2)):t}function Pm(t){let e=t.trim();if(!e)return"";let n=e.indexOf("#");n>0&&(e=e.slice(0,n));let r=e.match(/^(.*?)(:\d+(?::\d+)?)$/);return r&&(e=r[1]??e),e}function mi(t,e){let n=br(Pm(t));if(!n||(0,xt.isAbsolute)(n))return n;let r=br(e??"");return r?(0,xt.resolve)(r,n):n}var eu={approvalRequestV1:"vibelet.approvalRequest.v1"};var Tt=require("fs"),tu=require("path");function Lm(t){return!!(t&&typeof t=="object"&&typeof t.deviceId=="string"&&typeof t.pushToken=="string"&&t.platform==="expo"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"&&(typeof t.lastSentAt=="string"||typeof t.lastSentAt>"u"))}function Mm(t){try{let e=(0,Tt.readFileSync)(t,"utf8"),n=JSON.parse(e);return Array.isArray(n)?n.filter(Lm):[]}catch{return[]}}function gn(t,e){(0,Tt.mkdirSync)((0,tu.dirname)(t),{recursive:!0}),(0,Tt.writeFileSync)(t,JSON.stringify(e,null,2)+`
96
+ `,n);s===-1&&(s=t.length);let i=t.substring(n,s);n=s+1,!(i.length===0||i.trim().length===0)&&(yield i,r+=1)}}var li=512*1024;async function Gc(t,e){if(e<=li)return(0,L.readFile)(t,"utf-8");let n=await(0,L.open)(t,"r");try{let r=Buffer.alloc(li),{bytesRead:s}=await n.read(r,0,li,0);return r.toString("utf-8",0,s)}finally{await n.close()}}function hi(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>!e||typeof e!="object"?"":typeof e.text=="string"?e.text:typeof e.content=="string"?e.content:"").join(""):""}function Vc(t){return t?.type==="response_item"&&t.payload?.type==="message"&&t.payload.role==="user"?hi(t.payload.content):t?.type==="event_msg"&&t.payload?.type==="user_message"&&typeof t.payload.message=="string"?t.payload.message:""}function Sr(t){return typeof t=="string"?t:Array.isArray(t)?t.map(e=>!e||typeof e!="object"||e.type!=="text"?"":typeof e.text=="string"?e.text:"").join(""):""}var ym=["<task-notification>","<local-command-caveat>","<local-command-stdout>","<local-command-stderr>","<command-name>","<command-message>","<command-args>","<system-reminder>","<environment_context>","# AGENTS.md instructions for "];function Sm(t,e){if(t?.isMeta===!0)return!0;let n=e.trim();return n?ym.some(r=>n.startsWith(r)):!1}function vr(t){if(t?.type!=="user"||t.message?.role!=="user")return"";let e=Sr(t.message.content);return Sm(t,e)?"":e}function vm(t){return Array.isArray(t)&&t.some(e=>e&&typeof e=="object"&&e.type==="tool_result")}function $c(t){let e=t.trim();return e.startsWith("# AGENTS.md instructions for ")||e.startsWith("<environment_context>")}function mr(t,e="scanner"){return{sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,title:t.title,createdAt:t.createdAt,lastActivityAt:t.lastActivityAt,sources:[e],runtime:ii()}}function _t(t,e){let n=(0,R.basename)(e,".jsonl");return t==="claude"?n||null:n.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$/i)?.[1]??null}async function _m(t,e){let n=await Gc(t,e),r=Wc(n,64),s="",i="",o,a,l;for(let c of r){let u;try{u=JSON.parse(c)}catch{continue}if(!s&&typeof u.cwd=="string"&&(s=u.cwd),!i&&typeof u.sessionId=="string"&&(i=u.sessionId),o||(o=$e([u.customTitle,u.summary])),!l){let d=vr(u),f=$e([],d);f&&(a=d,l=f)}if(s&&(o||l))break}return s?{sessionId:i||_t("claude",t)||(0,R.basename)(t,".jsonl"),cwd:s,title:o??l??$e([],a)}:null}async function bm(t,e){let n=await Gc(t,e),r=Wc(n,96),s="",i="",o,a,l;for(let c of r){let u;try{u=JSON.parse(c)}catch{continue}if(s||(s=u.payload?.cwd??u.cwd??""),i||(i=u.payload?.id??u.id??""),o||(o=$e([u.payload?.title,u.title])),!l){let d=Vc(u),f=d&&!$c(d)?$e([],d):void 0;f&&(a=d,l=f)}if(s&&(o||l))break}return s?{sessionId:i||_t("codex",t)||(0,R.basename)(t,".jsonl"),cwd:s,title:o??l??$e([],a)}:null}async function cn(t,e){let n=await(0,L.stat)(t).catch(()=>null);if(!n)return null;try{let r=n.size;if(e==="claude"){let i=await _m(t,r);return i?{sessionId:i.sessionId,agent:e,cwd:i.cwd,title:i.title,createdAt:new Date(n.birthtimeMs).toISOString(),lastActivityAt:new Date(n.mtimeMs).toISOString(),filePath:t}:null}let s=await bm(t,r);return s?{sessionId:s.sessionId,agent:e,cwd:s.cwd,title:s.title,createdAt:new Date(n.birthtimeMs).toISOString(),lastActivityAt:new Date(n.mtimeMs).toISOString(),filePath:t}:null}catch{return null}}async function Dc(t,e){let n=(0,R.join)((0,Se.homedir)(),".claude","projects");try{let r;t?r=[jc(t)]:r=(await(0,L.readdir)(n,{withFileTypes:!0})).filter(c=>c.isDirectory()).map(c=>c.name);let s=[];for(let l of r){let c=(0,R.join)(n,l),u=await(0,L.readdir)(c).catch(()=>[]);for(let d of u)d.endsWith(".jsonl")&&s.push((0,R.join)(c,d))}let i=await It(s,wt,async l=>{let c=await(0,L.stat)(l).catch(()=>null);return{path:l,mtimeMs:c?.mtimeMs??0}});return i.sort((l,c)=>c.mtimeMs-l.mtimeMs),(await It(i,wt,async l=>{let c=await cn(l.path,"claude");return c&&e&&e.push(mr(c)),c})).filter(l=>l!==null).map(l=>mr(l)).sort((l,c)=>c.lastActivityAt.localeCompare(l.lastActivityAt))}catch(r){return Le.warn({error:String(r)},"failed to list claude sessions"),[]}}async function Hc(t,e){let n=(0,R.join)((0,Se.homedir)(),".codex","sessions");try{let r=await(0,L.readdir)(n).catch(()=>[]),s=[];for(let l of r){let c=(0,R.join)(n,l),u=await(0,L.readdir)(c).catch(()=>[]);for(let d of u){let f=(0,R.join)(c,d),p=await(0,L.readdir)(f).catch(()=>[]);for(let g of p){let h=(0,R.join)(f,g),y=await(0,L.readdir)(h).catch(()=>[]);for(let m of y)m.endsWith(".jsonl")&&s.push((0,R.join)(h,m))}}}let i=await It(s,wt,async l=>{let c=await(0,L.stat)(l).catch(()=>null);return{path:l,mtimeMs:c?.mtimeMs??0}});return i.sort((l,c)=>c.mtimeMs-l.mtimeMs),(await It(i,wt,async l=>{let c=await cn(l.path,"codex");return c&&e&&(!t||c.cwd===t)&&e.push(mr(c)),c})).filter(l=>l!==null).filter(l=>!t||l.cwd===t).map(l=>mr(l)).sort((l,c)=>c.lastActivityAt.localeCompare(l.lastActivityAt))}catch(r){return Le.warn({error:String(r)},"failed to list codex sessions"),[]}}async function pn(t,e,n){let s=`list:${(0,Se.homedir)()}:${t??"all"}:${e??""}`,i=ci.get(s);if(i)return i;let o=oi.get(s);if(o)return o;let a=(async()=>{let l;if(t==="claude")l=await Dc(e,n);else if(t==="codex")l=await Hc(e,n);else{let[c,u]=await Promise.all([Dc(e,n),Hc(e,n)]);l=[...c,...u].sort((d,f)=>f.lastActivityAt.localeCompare(d.lastActivityAt))}return ci.set(s,l),l})();return oi.set(s,a),a.finally(()=>oi.delete(s)),a}async function Bc(t,e){let r=`search:${(0,Se.homedir)()}:${t}:${e??"all"}`,s=ui.get(r);if(s)return s;let i=ai.get(r);if(i)return i;let o=(async()=>{let a=new Set,l=t.toLowerCase();async function c(){let d=(0,R.join)((0,Se.homedir)(),".claude","projects");try{let f=await(0,L.readdir)(d,{withFileTypes:!0}),p=[];for(let h of f){if(!h.isDirectory())continue;let y=(0,R.join)(d,h.name),m=await(0,L.readdir)(y).catch(()=>[]);for(let E of m)E.endsWith(".jsonl")&&p.push((0,R.join)(y,E))}let g=await It(p,wt,h=>Fc(h,l,"claude"));for(let h of g)h&&a.add(h)}catch(f){Le.warn({error:String(f)},"failed to search claude files")}}async function u(){let d=(0,R.join)((0,Se.homedir)(),".codex","sessions");try{let f=[];async function p(h){let y=await(0,L.readdir)(h,{withFileTypes:!0}).catch(()=>[]);for(let m of y){let E=(0,R.join)(h,m.name);m.isDirectory()?await p(E):m.name.endsWith(".jsonl")&&f.push(E)}}await p(d);let g=await It(f,wt,h=>Fc(h,l,"codex"));for(let h of g)h&&a.add(h)}catch(f){Le.warn({error:String(f)},"failed to search codex files")}}return e==="claude"?await c():e==="codex"?await u():await Promise.all([c(),u()]),ui.set(r,a),a})();return ai.set(r,o),o.finally(()=>ai.delete(r)),o}async function Fc(t,e,n){let r=(0,fi.createReadStream)(t,{encoding:"utf-8"}),s=(0,pi.createInterface)({input:r,crlfDelay:1/0}),i=n==="claude"?wm:Im,o="",a=!1;try{for await(let l of s){if(!l.trim())continue;let c;try{c=JSON.parse(l)}catch{continue}if(o||(n==="claude"?typeof c.sessionId=="string"&&(o=c.sessionId):o=c.payload?.id??c.id??""),!a){let u=i(c);u&&u.toLowerCase().includes(e)&&(a=!0)}if(o&&a)break}}finally{s.close(),r.destroy()}return a?o||_t(n,t):null}function wm(t){return t?.type==="user"&&t.message?.role==="user"?vr(t):t?.type==="assistant"&&t.message?.role==="assistant"?Sr(t.message.content):""}function Im(t){if(t?.type==="response_item"&&t.payload?.type==="message"){let n=t.payload.role;if(n==="user"||n==="assistant")return hi(t.payload.content)}let e=Vc(t);return e||""}async function di(t,e){let n=(0,fi.createReadStream)(t,{encoding:"utf-8"}),r=(0,pi.createInterface)({input:n,crlfDelay:1/0});try{for await(let s of r){if(!s.trim())continue;let i;try{i=JSON.parse(s)}catch{continue}if(e(i))break}}finally{r.close(),n.destroy()}}async function zc(t,e){let n=(0,R.join)((0,Se.homedir)(),".claude","projects"),r=e?jc(e):null,s=await(0,L.readdir)(n).catch(()=>[]),i=r?[r,...s.filter(o=>o!==r)]:s;for(let o of i){let a=(0,R.join)(n,o,`${t}.jsonl`);if((await(0,L.stat)(a).catch(()=>null))?.isFile())return a}return null}async function Yc(t,e,n){if(e==="claude")return zc(t,n);let r=(0,R.join)((0,Se.homedir)(),".codex","sessions");return Jc(r,t)}function Am(t){if(t?.type==="user"&&t.message?.role==="user")return vm(t.message.content)?{kind:"toolResult"}:vr(t)?{kind:"userPrompt"}:null;if(t?.type==="assistant"&&t.message?.role==="assistant"){let e=Sr(t.message.content),n=t.message?.stop_reason;return{kind:"assistant",stopReason:typeof n=="string"?n:n??null,...e?{text:e}:{}}}return t?.type==="system"&&t.subtype==="stop_hook_summary"?{kind:"stopHook"}:null}function xm(t){if(!t)return{};if(t.kind==="stopHook")return{};if(t.kind==="assistant"){let e=t.stopReason==null||t.stopReason==="tool_use";return{...e?{isResponding:!0}:{},...e&&t.text?{partialReplyText:t.text}:{}}}return{isResponding:!0}}async function ni(t,e){if(e!=="claude")return{};let n=null;try{await di(t,r=>{let s=Am(r);s&&(n=s)})}catch(r){return r.code!=="ENOENT"&&Le.warn({filePath:t,error:String(r)},"failed to read session runtime hints"),{}}return xm(n)}async function gi(t,e,n){let r=await Yc(t,e,n);return r?ni(r,e):{}}async function hn(t,e,n){let r=[],s=(i,o)=>{if(o?.coalesceConsecutiveAssistant&&i.role==="assistant"&&r[r.length-1]?.role==="assistant"){r[r.length-1]=i;return}r.push(i)};if(e==="claude")try{let i=await zc(t,n);i&&await di(i,o=>{if(o.type==="user"&&o.message?.role==="user"){let a=vr(o);a&&s({role:"user",content:a})}else if(o.type==="assistant"&&o.message?.role==="assistant"){let a=Sr(o.message.content);a&&s({role:"assistant",content:a})}})}catch(i){Le.warn({error:String(i)},"failed to read claude session history")}else if(e==="codex")try{let i=await Yc(t,e,n);i&&await di(i,o=>{if(o.type!=="response_item"||o.payload?.type!=="message")return;let a=o.payload.role;if(a!=="user"&&a!=="assistant")return;let l=hi(o.payload.content);l&&(a==="user"&&$c(l)||s({role:a,content:l},{coalesceConsecutiveAssistant:!0}))})}catch(i){Le.warn({error:String(i)},"failed to read codex session history")}return r}async function Jc(t,e){try{let n=await(0,L.readdir)(t,{withFileTypes:!0});for(let r of n){let s=(0,R.join)(t,r.name);if(r.isDirectory()){let i=await Jc(s,e);if(i)return i}else if(r.name.includes(e)&&r.name.endsWith(".jsonl"))return s}}catch(n){Le.warn({error:String(n)},"failed to walk codex sessions dir")}return null}var At=require("fs"),Zc=require("path");var Tm=500,Kc=200;function km(t){if(!Array.isArray(t))return[];let e=t.filter(n=>typeof n=="string"&&n.length>0);return e.length<=Kc?e:e.slice(-Kc)}function Em(t){if(!Array.isArray(t))return[];let e=[];for(let n of t)typeof n!="string"||n.length===0||e.includes(n)||e.push(n);return e}function Cm(t){if(!t||typeof t!="object"||Array.isArray(t))return;let e=t,n=typeof e.requestId=="string"?e.requestId:"",r=typeof e.toolName=="string"?e.toolName:"",s=typeof e.description=="string"?e.description:"",i=e.input&&typeof e.input=="object"&&!Array.isArray(e.input)?e.input:{};if(!n||!r||!s)return;let o=e.approvalContext;return o&&typeof o=="object"&&!Array.isArray(o)&&o.provider==="codex"&&typeof o.kind=="string"&&typeof o.rpcId=="number"?{requestId:n,toolName:r,input:i,description:s,approvalContext:{provider:"codex",kind:o.kind,rpcId:o.rpcId,...typeof o.questionId=="string"?{questionId:o.questionId}:{},...typeof o.approveLabel=="string"?{approveLabel:o.approveLabel}:{},...typeof o.denyLabel=="string"?{denyLabel:o.denyLabel}:{}}}:{requestId:n,toolName:r,input:i,description:s}}function Xc(t){return{...t,lastActivityAt:t.lastActivityAt??t.createdAt,acceptedClientMessageIds:km(t.acceptedClientMessageIds),pendingApproval:Cm(t.pendingApproval)}}function Rm(t){if(Array.isArray(t))return{records:t.map(Xc),deletedSessionIds:[]};if(t&&typeof t=="object"){let e=t;return{records:Array.isArray(e.records)?e.records.map(Xc):[],deletedSessionIds:Em(e.deletedSessionIds)}}return{records:[],deletedSessionIds:[]}}var _r=class{records;deletedSessionIds;debounceTimer=null;constructor(){let e=this.loadFromDisk();this.records=e.records,this.deletedSessionIds=new Set(e.deletedSessionIds)}getAll(){return this.records}getDeletedSessionIds(){return[...this.deletedSessionIds]}find(e){return this.records.find(n=>n.sessionId===e)}isDeleted(e){return this.deletedSessionIds.has(e)}upsert(e){this.deletedSessionIds.delete(e.sessionId);let n=this.records.findIndex(r=>r.sessionId===e.sessionId);n>=0?this.records[n]=e:this.records.unshift(e),this.scheduleSave()}remove(e){this.records=this.records.filter(n=>n.sessionId!==e),this.deletedSessionIds.add(e),this.scheduleSave()}flushSync(){this.debounceTimer&&(clearTimeout(this.debounceTimer),this.debounceTimer=null),this.saveToDisk()}scheduleSave(){this.debounceTimer&&clearTimeout(this.debounceTimer),this.debounceTimer=setTimeout(()=>{this.debounceTimer=null,this.saveToDisk()},Tm)}loadFromDisk(){try{let e=(0,At.readFileSync)(Xn,"utf-8");return Rm(JSON.parse(e))}catch{}return{records:[],deletedSessionIds:[]}}saveToDisk(){(0,At.mkdirSync)((0,Zc.dirname)(Xn),{recursive:!0}),(0,At.writeFileSync)(Xn,JSON.stringify({records:this.records,deletedSessionIds:[...this.deletedSessionIds]},null,2))}};var xt=require("path"),Qc=require("os");function br(t){return t=t.replace(/^~/,"~"),t.startsWith("~/")||t==="~"?(0,xt.join)((0,Qc.homedir)(),t.slice(2)):t}function Pm(t){let e=t.trim();if(!e)return"";let n=e.indexOf("#");n>0&&(e=e.slice(0,n));let r=e.match(/^(.*?)(:\d+(?::\d+)?)$/);return r&&(e=r[1]??e),e}function mi(t,e){let n=br(Pm(t));if(!n||(0,xt.isAbsolute)(n))return n;let r=br(e??"");return r?(0,xt.resolve)(r,n):n}var eu={approvalRequestV1:"vibelet.approvalRequest.v1"};var Tt=require("fs"),tu=require("path");function Lm(t){return!!(t&&typeof t=="object"&&typeof t.deviceId=="string"&&typeof t.pushToken=="string"&&t.platform==="expo"&&typeof t.createdAt=="string"&&typeof t.updatedAt=="string"&&(typeof t.lastSentAt=="string"||typeof t.lastSentAt>"u"))}function Mm(t){try{let e=(0,Tt.readFileSync)(t,"utf8"),n=JSON.parse(e);return Array.isArray(n)?n.filter(Lm):[]}catch{return[]}}function gn(t,e){(0,Tt.mkdirSync)((0,tu.dirname)(t),{recursive:!0}),(0,Tt.writeFileSync)(t,JSON.stringify(e,null,2)+`
97
97
  `,"utf8")}var wr=class{constructor(e=$l){this.pushSubscriptionsPath=e;this.records=Mm(e)}records;list(){return this.records.map(e=>({...e}))}listTokens(){return this.records.map(e=>e.pushToken)}count(){return this.records.length}register(e,n){let r=new Date().toISOString(),s=this.records.find(o=>o.deviceId===e),i={deviceId:e,pushToken:n,platform:"expo",createdAt:s?.createdAt??r,updatedAt:r,...s?.lastSentAt?{lastSentAt:s.lastSentAt}:{}};this.records=[i,...this.records.filter(o=>o.deviceId!==e&&o.pushToken!==n)],gn(this.pushSubscriptionsPath,this.records)}unregister(e,n){let r=this.records.filter(s=>!(s.deviceId===e&&s.pushToken===n));return r.length===this.records.length?!1:(this.records=r,gn(this.pushSubscriptionsPath,this.records),!0)}unregisterToken(e){let n=this.records.filter(r=>r.pushToken!==e);return n.length===this.records.length?!1:(this.records=n,gn(this.pushSubscriptionsPath,this.records),!0)}markSent(e){if(e.length===0)return;let n=new Set(e),r=new Date().toISOString(),s=!1;for(let i of this.records)n.has(i.pushToken)&&(i.lastSentAt=r,s=!0);s&&gn(this.pushSubscriptionsPath,this.records)}reset(){this.records=[],gn(this.pushSubscriptionsPath,this.records)}};var z=P.child({module:"push"}),Nm="https://exp.host/--/api/v2/push/send",Om="https://exp.host/--/api/v2/push/getReceipts",Bm=[0,1e3,3e3],mn=new wr;function Dm(t){return!!(t&&typeof t=="object"&&typeof t.daemonId=="string"&&typeof t.canonicalHost=="string"&&typeof t.sessionId=="string"&&(t.agent==="claude"||t.agent==="codex")&&(t.eventType==="reply_ready"||t.eventType==="approval_request")&&(typeof t.requestId>"u"||typeof t.requestId=="string"))}function Hm(t){return new Promise(e=>{setTimeout(e,t)})}function nu(t){return t==="DeviceNotRegistered"}function Fm(t,e){if(!Array.isArray(t.data))return{successfulTokens:[],ticketErrors:[]};let n=[],r=[];for(let[s,i]of t.data.entries()){let o=e[s];if(!(!o||!i||typeof i!="object")){if(i.status==="ok"){n.push(o);continue}r.push({token:o,ticket:i})}}return{successfulTokens:n,ticketErrors:r}}function Um(t,e){let n=new Map;if(!Array.isArray(t.data))return n;for(let[r,s]of t.data.entries()){let i=e[r];!i||!s||s.status!=="ok"||typeof s.id!="string"||s.id.length===0||n.set(s.id,i)}return n}function qm(t,e){let n=[],r=[],s=t.data;for(let[i,o]of e.entries()){let a=s?.[i];if(!a||typeof a!="object"){n.push(i);continue}a.status==="error"&&r.push({token:o,receipt:a})}return{pendingTicketIds:n,receiptErrors:r}}async function jm(t,e,n,r){let s=new Map(t);for(let i of Bm){if(s.size===0)return;i>0&&await n(i);let o;try{o=await e(Om,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({ids:[...s.keys()]})})}catch(u){z.error({error:String(u),count:s.size},"push receipt request failed");return}if(!o.ok){z.error({status:o.status,statusText:o.statusText,count:s.size},"push receipt request returned error status");return}let a=await o.json().catch(()=>null);if(!a){z.error({count:s.size},"push receipt response was unreadable");return}let{pendingTicketIds:l,receiptErrors:c}=qm(a,s);for(let{token:u,receipt:d}of c){let f=d.details?.error;if(z.error({token:u,message:d.message,details:d.details,receiptStatus:d.status},"push receipt rejected"),nu(f)){let p=r.unregisterToken(u);z.info({token:u,errorCode:f,removed:p},"push token removed after receipt rejection")}}s=new Map(l.map(u=>[u,s.get(u)]))}s.size>0&&z.warn({pendingReceipts:s.size},"push receipts still pending after polling")}function Wm(t){let e=t?.pushStore??mn,n=t?.fetchImpl??globalThis.fetch,r=t?.sleepImpl??Hm;return async function(i,o,a){let l=e.listTokens();if(l.length===0)return;let c=l.map(u=>({to:u,sound:"default",title:i,body:o,data:a,badge:1,...Dm(a)&&a.eventType==="approval_request"?{categoryId:eu.approvalRequestV1}:{}}));try{let u=await n(Nm,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(c)});if(!u.ok){z.error({status:u.status,statusText:u.statusText},"push send failed");return}let d=await u.json().catch(()=>null);if(!d){z.error({count:c.length},"push send returned unreadable response");return}let{successfulTokens:f,ticketErrors:p}=Fm(d,l),g=Um(d,l);for(let{token:h,ticket:y}of p){let m=y.details?.error;if(z.error({token:h,message:y.message,details:y.details,ticketStatus:y.status},"push ticket rejected"),nu(m)){let E=e.unregisterToken(h);z.info({token:h,errorCode:m,removed:E},"push token removed after ticket rejection")}}f.length>0&&(z.debug({count:f.length},"push sent"),e.markSent(f)),g.size>0&&await jm(g,n,r,e)}catch(u){z.error({error:String(u)},"push send error")}}}function yi(t,e){mn.register(t,e),z.info({deviceId:t,token:e,total:mn.count()},"push token registered")}function Si(t,e){let n=mn.unregister(t,e);z.info({deviceId:t,token:e,total:mn.count(),removed:n},"push token unregistered")}var Ir=Wm();var b=P.child({module:"manager"}),Gm="Done.",Vm="Approval required",ru=180,xr=200;function yn(...t){let e=[];for(let n of t)if(n?.length)for(let r of n)!r||e.includes(r)||(e.push(r),e.length>xr&&e.splice(0,e.length-xr));return e}function Ar(t){return t?.length?{acceptedClientMessageIds:yn(t)}:{}}function fe(t){return{sessionId:t.sessionId,agent:t.agent,cwd:t.cwd,approvalMode:t.approvalMode,acceptedClientMessageIds:yn(t.acceptedClientMessageIds),pendingApproval:t.agent==="codex"?t.pendingApproval:void 0,title:t.title,createdAt:t.createdAt,lastActivityAt:t.lastActivityAt,managed:t.managed,isResponding:t.isResponding||void 0}}function su(t){let e=t.pendingApproval?.requestId;return typeof e=="string"&&or(e)}function iu(t,e,n){return{sessionId:t,agent:e,...n}}function $m(t){return t.startsWith(zs)}function ou(t){return t?{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow"}}:{continue:!0,suppressOutput:!0,hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:"Denied from Vibelet"}}}var Tr=class{constructor(e=Ir){this.pushSender=e;this.removeInventoryBackfillListener=Mc(()=>{this.noteInventoryChanged("inventory_backfilled")}),this.startIdleSweep()}sessions=new Map;claudeHookSessions=new Map;store=new _r;idleSweepInterval=null;globalClients=new Set;inventoryVersion=0;removeInventoryBackfillListener;startIdleSweep(){v.idleTimeoutMs<=0&&v.turnStallTimeoutMs<=0||(this.idleSweepInterval=setInterval(()=>this.sweepIdleSessions(),6e4),this.idleSweepInterval.unref())}stopIdleSweep(){this.idleSweepInterval&&(clearInterval(this.idleSweepInterval),this.idleSweepInterval=null)}sweepIdleSessions(){let e=Date.now(),n=v.idleTimeoutMs,r=v.turnStallTimeoutMs;if(n<=0&&r<=0)return;let s=3600*1e3;for(let[i,o]of this.sessions){if(!o.active&&!o.driver){if(o.clients.size===0){let l=e-o.lastActivityTs;l>=s&&(b.info({sessionId:o.sessionId,inactiveMs:l},"removing inactive session from memory"),w.increment("session.cleanup",{reason:"inactive"}),this.unregisterClaudeHookSession(o),this.sessions.delete(i))}continue}if(!o.active||!o.driver)continue;let a=e-o.lastActivityTs;if(o.isResponding){if(r<=0||o.pendingApproval||a<r)continue;b.warn({sessionId:o.sessionId,agent:o.agent,inactiveMs:a,turnStallTimeoutMs:r},"stopping stalled driver"),w.increment("driver.stall_timeout",{agent:o.agent}),_.emit("driver.stall_timeout",{sessionId:o.sessionId,agent:o.agent,idleMs:a}),this.resolvePendingClaudeHookApprovals(o),o.driver.stop(),o.active=!1,o.driver=null,o.isResponding=!1,o.currentReplyText="",this.updateGauges(),this.broadcast(o.sessionId,{type:"error",sessionId:o.sessionId,message:`Agent stopped responding for over ${Math.ceil(r/1e3)}s. Send a new message to continue.`}),this.touchSession(o.sessionId),this.noteInventoryChanged("session_updated");continue}o.pendingApproval||n<=0||a<n||(b.info({sessionId:o.sessionId,agent:o.agent,idleMs:a,timeoutMs:n},"stopping idle driver"),w.increment("driver.idle_timeout",{agent:o.agent}),_.emit("driver.idle_timeout",{sessionId:o.sessionId,agent:o.agent,idleMs:a}),o.driver.stop(),o.active=!1,o.driver=null,this.updateGauges(),this.touchSession(o.sessionId),this.noteInventoryChanged("session_updated"))}}bindDriverLifecycle(e,n,r,s){e.driver?.onMessage(i=>{if(b.debug({agent:n,context:r,msgType:i.type,sessionId:e.sessionId},"driver message received"),i.type!=="response"&&"sessionId"in i&&i.sessionId&&i.sessionId!==e.sessionId&&!this.sessions.has(i.sessionId)&&this.remapSessionId(e,i.sessionId,s),(i.type==="session.done"||i.type==="session.interrupted")&&(e.isResponding=!1,(i.type==="session.interrupted"||!su(e))&&(e.pendingApproval=void 0)),i.type==="approval.request"){if(n==="codex"&&e.approvalMode==="autoApprove"){if(e.driver?.respondApproval(i.requestId,!0)??!1){_.emit("approval.response",{sessionId:e.sessionId,requestId:i.requestId,approved:!0}),e.pendingApproval=void 0,e.isResponding=!0,this.touchSession(e.sessionId),this.noteInventoryChanged("session_updated");return}b.warn({sessionId:e.sessionId,requestId:i.requestId},"failed to auto-approve codex request; falling back to pending approval flow")}e.isResponding=!1,e.pendingApproval={requestId:i.requestId,toolName:i.toolName,input:i.input,description:i.description,...i.approvalContext?{approvalContext:i.approvalContext}:{}},this.pushSender(Vm,this.buildPushBody(`${e.title||e.sessionId}: ${i.description||i.toolName}`),{sessionId:e.sessionId,agent:e.agent,requestId:i.requestId,eventType:"approval_request"})}n==="claude"&&i.type==="approval.request"&&or(i.requestId)&&(e.lastUserMessage?e.syntheticApprovalRetries[i.requestId]={message:e.lastUserMessage,toolName:i.toolName}:b.warn({sessionId:e.sessionId,requestId:i.requestId},"missing lastUserMessage for synthetic approval retry")),this.touchSession(e.sessionId,i.type!=="text.delta"),(i.type==="approval.request"||i.type==="session.done"||i.type==="session.interrupted")&&this.noteInventoryChanged("session_updated"),this.broadcast(e.sessionId,i),(i.type==="session.done"||i.type==="session.interrupted")&&e.bufferedPrompts.length>0&&this.flushBufferedPrompt(e)}),e.driver?.onExit?.(i=>{b.info({agent:n,context:r,exitCode:i,sessionId:e.sessionId},"driver exited"),_.emit("driver.exit",{sessionId:e.sessionId,agent:n,exitCode:i}),w.increment("driver.exit",{agent:n,abnormal:i&&i!==0?"true":"false"});let o=!!(e.pendingApproval&&(e.agent==="codex"||i===0&&su(e)));this.resolvePendingClaudeHookApprovals(e),e.active=!1,e.driver=null,e.isResponding=!1,e.currentReplyText="",o||(e.pendingApproval=void 0),this.updateGauges(),this.touchSession(e.sessionId),this.noteInventoryChanged("session_updated")})}remapSessionId(e,n,r){if(!n||n===e.sessionId)return;let s=this.sessions.get(n);if(s&&s!==e){b.warn({oldSessionId:e.sessionId,newSessionId:n},"skipping session ID remap because target already exists");return}let i=e.sessionId;b.info({oldSessionId:i,newSessionId:n},"session ID updated"),this.store.remove(i),this.sessions.delete(i),e.sessionId=n,this.sessions.set(n,e),this.store.upsert(fe(e)),this.noteInventoryChanged("session_remapped"),r&&this.reply(r,`id_update_${Date.now()}`,!0,{sessionId:n,oldSessionId:i})}flushBufferedPrompt(e,n=!1){if(!e.driver||!e.active||e.startupInProgress||e.pendingApproval||!n&&e.isResponding)return!1;let r=e.bufferedPrompts.shift();return r?(e.isResponding=!0,e.currentReplyText="",e.lastUserMessage=r,this.touchSession(e.sessionId),this.noteInventoryChanged("session_updated"),e.driver.sendPrompt(r),!0):!1}startPendingCodexSession(e,n){if(e.agent!=="codex"||!e.driver)return;let r=e.driver,s=e.sessionId,i=e.startupToken,o=w.startTimer("driver.spawn");(async()=>{try{let a=await r.start(e.cwd,void 0,e.approvalMode),l=o();if(this.sessions.get(s)!==e||e.startupToken!==i||e.driver!==r){b.info({pendingSessionId:s,actualSessionId:a},"discarding stale codex startup result");return}e.startupInProgress=!1,b.info({pendingSessionId:s,sessionId:a,spawnMs:l},"codex session ready"),a&&a!==s&&this.remapSessionId(e,a,n),this.flushBufferedPrompt(e,!0)}catch(a){if(o(),this.sessions.get(s)!==e||e.startupToken!==i){b.info({pendingSessionId:s,error:String(a)},"ignoring stale codex startup failure");return}e.startupInProgress=!1,e.bufferedPrompts=[],e.active=!1,e.driver=null,e.isResponding=!1,e.currentReplyText="",this.updateGauges(),this.touchSession(e.sessionId),this.noteInventoryChanged("session_updated"),b.error({sessionId:s,cwd:e.cwd,error:String(a)},"async codex createSession error"),this.broadcast(e.sessionId,{type:"error",sessionId:e.sessionId,message:`Failed to start Codex session: ${String(a)}`})}})()}configureDriverBeforeStart(e,n,r){if(e!=="claude"||!(n instanceof on))return;let s=r??(0,vi.randomUUID)().replace(/-/g,"");return n.configureHookBridge(v.port,s),s}registerClaudeHookSession(e){e.agent!=="claude"||!e.claudeHookSecret||this.claudeHookSessions.set(e.claudeHookSecret,e)}unregisterClaudeHookSession(e){if(e.agent!=="claude"||!e.claudeHookSecret)return;this.claudeHookSessions.get(e.claudeHookSecret)===e&&this.claudeHookSessions.delete(e.claudeHookSecret)}resolvePendingClaudeHookApprovals(e,n=sn){for(let r of e.pendingClaudeHookApprovals.values())r.resolve(n);e.pendingClaudeHookApprovals.clear(),e.pendingApproval&&$m(e.pendingApproval.requestId)&&(e.pendingApproval=void 0)}resolveClaudeHookSession(e){if(!e)return;let n=e.trim();if(n)return this.claudeHookSessions.get(n)}handleClaudeSessionStartHook(e,n){let r=this.resolveClaudeHookSession(e);return r?(this.touchSession(r.sessionId),!0):(b.warn({secretPresent:!!e},"received Claude session-start hook for unknown session"),!1)}async handleClaudePermissionHook(e,n){let r=this.resolveClaudeHookSession(e);if(!r||r.agent!=="claude"||!r.active)return b.warn({secretPresent:!!e},"received Claude permission hook for unknown or inactive session"),sn;if(r.approvalMode==="autoApprove")return ou(!0);let i=(typeof n.tool_name=="string"?n.tool_name:typeof n.toolName=="string"?n.toolName:"").trim();if(!i)return sn;let o=n.tool_input??n.toolInput,a=o&&typeof o=="object"&&!Array.isArray(o)?o:{},l=typeof n.tool_use_id=="string"?n.tool_use_id:typeof n.toolUseId=="string"?n.toolUseId:"",c=`${zs}${l.trim()||(0,vi.randomUUID)()}`,u=r.pendingClaudeHookApprovals.get(c);if(u)return u.promise;let d=`Claude requested permissions to use ${i}.`,f,p=new Promise(g=>{f=g});return r.pendingClaudeHookApprovals.set(c,{requestId:c,promise:p,resolve:g=>{r.pendingClaudeHookApprovals.delete(c),f(g)}}),r.pendingApproval={requestId:c,toolName:i,input:a,description:d},_.emit("approval.request",{agent:"claude",sessionId:r.sessionId,toolName:i}),this.touchSession(r.sessionId),this.noteInventoryChanged("session_updated"),this.broadcast(r.sessionId,{type:"approval.request",sessionId:r.sessionId,requestId:c,toolName:i,input:a,description:d}),p}async resolveReconnectSession(e,n,r){if(this.isDeletedSession(e))return;let s=new Date().toISOString(),i=r?.agent,o=r?.cwd??"",a=r?.approvalMode,l=r?.pendingApproval,c=r?.title??"",u=r?.createdAt??s,d=r?.lastActivityAt??s,f=yn(r?.acceptedClientMessageIds),p=r?.isResponding,g=r?"memory":"client",h=this.store.find(e);if(h)i=h.agent,o=h.cwd||o,a=h.approvalMode??a,l=h.pendingApproval??l,c=h.title||c,u=h.createdAt||u,d=h.lastActivityAt||d,f=yn(h.acceptedClientMessageIds,f),g="record";else if(!r){let m=(await pn(n??i)).find(E=>E.sessionId===e);m&&(i=m.agent,o=m.cwd||o,c=m.title??c,u=m.createdAt,d=m.lastActivityAt,p=m.runtime.isResponding??p,g="scanner")}if(!i&&n&&(i=n,g=r?"memory":"client"),!!i)return{agent:i,cwd:o,approvalMode:a,pendingApproval:l,title:c,createdAt:u,lastActivityAt:d,acceptedClientMessageIds:f,source:g,managed:r?.managed??h?.managed,isResponding:p||void 0}}collectReconnectPendingApprovals(){let e=[],n=new Set;for(let r of this.sessions.values()){if(!r.pendingApproval)continue;let s=`${r.agent}:${r.sessionId}:${r.pendingApproval.requestId}`;n.has(s)||(n.add(s),e.push(iu(r.sessionId,r.agent,r.pendingApproval)))}for(let r of this.store.getAll()){if(!r.pendingApproval)continue;let s=`${r.agent}:${r.sessionId}:${r.pendingApproval.requestId}`;n.has(s)||(n.add(s),e.push(iu(r.sessionId,r.agent,r.pendingApproval)))}return e}restoreDriverPendingApproval(e,n){n&&e.restorePendingApproval?.(n)}async reviveSessionForApproval(e){if(e.driver)return!0;if(!e.pendingApproval||e.agent!=="codex")return!1;let n=this.createDriver(e.agent),r=this.configureDriverBeforeStart(e.agent,n,e.claudeHookSecret);return await n.start(e.cwd,e.sessionId,e.approvalMode),this.restoreDriverPendingApproval(n,e.pendingApproval),e.driver=n,e.active=!0,e.isResponding=!1,e.currentReplyText="",e.startupInProgress=!1,e.bufferedPrompts=e.bufferedPrompts??[],e.startupToken=e.startupToken??0,e.claudeHookSecret=r??e.claudeHookSecret,e.pendingClaudeHookApprovals=e.pendingClaudeHookApprovals??new Map,this.registerClaudeHookSession(e),this.bindDriverLifecycle(e,e.agent," (approval resumed)"),this.store.upsert(fe(e)),this.updateGauges(),this.touchSession(e.sessionId),this.noteInventoryChanged("session_updated"),!0}buildPushBody(e){let n=e.replace(/\s+/g," ").trim();return n?n.length<=ru?n:`${n.slice(0,Math.max(1,ru-3)).trimEnd()}...`:Gm}currentPartialReplyText(e){return e?.isResponding&&e.currentReplyText.trim()?e.currentReplyText:void 0}touchSession(e,n=!0){let r=new Date().toISOString(),s=this.sessions.get(e);if(s){s.lastActivityAt=r,s.lastActivityTs=Date.now(),n&&this.store.upsert(fe(s));return}let i=this.store.find(e);i&&this.store.upsert({...i,lastActivityAt:r})}updateGauges(){let e=0;for(let n of this.sessions.values())n.active&&e++;w.gauge("session.active",e)}activeSessionSnapshots(){let e=[];for(let n of this.sessions.values())n.sessionId.startsWith("pending_")||n.active&&e.push({sessionId:n.sessionId,agent:n.agent,cwd:n.cwd,approvalMode:n.approvalMode,title:n.title,createdAt:n.createdAt,lastActivityAt:n.lastActivityAt,...n.pendingApproval?{needsAttention:!0}:{},...n.isResponding?{isResponding:!0}:{},managed:n.managed});return e}getDeletedSessionIds(){return new Set(this.store.getDeletedSessionIds())}isDeletedSession(e){return this.store.isDeleted(e)}async listRecentSessionsForContinue(e,n){return pn(e,n)}async handle(e,n){switch(b.debug({action:n.action},"handling client message"),n.action){case"session.create":await this.createSession(e,n.id,n.agent,n.cwd,n.approvalMode,n.continueSession);break;case"session.resume":await this.resumeSession(e,n.id,n.sessionId,n.agent);break;case"session.send":await this.sendMessage(e,n.id,n.sessionId,n.message,n.agent,n.clientMessageId,n.images);break;case"session.approve":await this.approve(e,n.id,n.sessionId,n.requestId,n.approved);break;case"session.setApprovalMode":await this.setApprovalMode(e,n.id,n.sessionId,n.approvalMode);break;case"session.interrupt":this.interrupt(e,n.id,n.sessionId);break;case"session.stop":this.stopSession(e,n.id,n.sessionId);break;case"session.delete":this.deleteSession(e,n.id,n.sessionId);break;case"session.history":await this.sendHistory(e,n.id,n.sessionId,n.agent);break;case"reconnect.snapshot":await this.sendReconnectSnapshot(e,n.id,n.agent,n.cwd,n.search,n.activeSessionId,n.activeAgent);break;case"sessions.list":await this.listSessions(e,n.id,n.agent,n.cwd,n.search,n.limit,n.cursor);break}}addGlobalClient(e){this.globalClients.add(e)}removeClient(e){this.globalClients.delete(e);for(let n of this.sessions.values())n.clients.delete(e)}shutdown(){this.stopIdleSweep(),this.removeInventoryBackfillListener(),this.globalClients.clear();for(let e of this.sessions.values()){try{this.resolvePendingClaudeHookApprovals(e),e.driver?.stop()}catch(n){b.error({sessionId:e.sessionId,agent:e.agent,error:String(n)},"failed to stop session on shutdown")}e.active=!1,e.driver=null,e.clients.clear(),this.unregisterClaudeHookSession(e)}this.claudeHookSessions.clear(),this.store.flushSync()}getActiveSessionCount(){let e=0;for(let n of this.sessions.values())n.active&&e++;return e}prewarmCaches(){gr({limit:50,activeSessions:this.activeSessionSnapshots(),sessionRecords:this.store.getAll(),deletedSessionIds:this.getDeletedSessionIds()}).catch(()=>{})}getDriverCounts(){let e={};for(let n of this.sessions.values())n.active&&(e[n.agent]=(e[n.agent]??0)+1);return e}noteInventoryChanged(e){if(this.inventoryVersion+=1,this.globalClients.size===0)return;let n={type:"sessions.changed",version:this.inventoryVersion,reason:e},r=JSON.stringify(n);for(let s of this.globalClients)s.readyState===1&&s.send(r)}async createSession(e,n,r,s,i,o){s=br(s),b.info({agent:r,cwd:s,approvalMode:i,continueSession:o},"creating session");try{if(!(await(0,au.stat)(s)).isDirectory()){this.reply(e,n,!1,void 0,`Path is not a directory: ${s}`);return}}catch{this.reply(e,n,!1,void 0,`Directory does not exist: ${s}`);return}if(o)try{let l=(await this.listRecentSessionsForContinue(r,s)).find(c=>!this.isDeletedSession(c.sessionId));if(l)return b.info({sessionId:l.sessionId,cwd:s},"continue mode: resuming last session"),this.resumeSession(e,n,l.sessionId,r,s,i);b.info("continue mode: no previous sessions found, creating new")}catch(a){b.warn({error:String(a)},"continue mode: error finding sessions, creating new")}try{let a=this.createDriver(r),l=this.configureDriverBeforeStart(r,a);if(r==="codex"){let p=`pending_${Date.now()}`;b.info({sessionId:p,agent:r,cwd:s},"session created (pending codex startup)"),w.increment("session.create",{agent:r}),_.emit("session.create",{sessionId:p,agent:r,cwd:s,approvalMode:i});let g={sessionId:p,agent:r,cwd:s,approvalMode:i,driver:a,clients:new Set([e]),title:"New session",createdAt:new Date().toISOString(),lastActivityAt:new Date().toISOString(),active:!0,lastActivityTs:Date.now(),isResponding:!1,currentReplyText:"",acceptedClientMessageIds:[],syntheticApprovalRetries:{},startupInProgress:!0,bufferedPrompts:[],startupToken:1,managed:!0,claudeHookSecret:l,pendingClaudeHookApprovals:new Map};this.sessions.set(p,g),this.registerClaudeHookSession(g),this.store.upsert(fe(g)),this.updateGauges(),yr(),ur(),this.noteInventoryChanged("session_created"),this.bindDriverLifecycle(g,r,"",e),this.reply(e,n,!0,{sessionId:p}),this.startPendingCodexSession(g,e);return}let c=w.startTimer("driver.spawn"),u=await a.start(s,void 0,i),d=c();b.info({sessionId:u,agent:r,spawnMs:d},"session created"),w.increment("session.create",{agent:r}),_.emit("session.create",{sessionId:u,agent:r,cwd:s,approvalMode:i});let f={sessionId:u,agent:r,cwd:s,approvalMode:i,driver:a,clients:new Set([e]),title:"New session",createdAt:new Date().toISOString(),lastActivityAt:new Date().toISOString(),active:!0,lastActivityTs:Date.now(),isResponding:!1,currentReplyText:"",acceptedClientMessageIds:[],syntheticApprovalRetries:{},startupInProgress:!1,bufferedPrompts:[],startupToken:0,managed:!0,claudeHookSecret:l,pendingClaudeHookApprovals:new Map};this.sessions.set(u,f),this.registerClaudeHookSession(f),this.store.upsert(fe(f)),this.updateGauges(),yr(),ur(),this.noteInventoryChanged("session_created"),this.bindDriverLifecycle(f,r,"",e),this.reply(e,n,!0,{sessionId:u})}catch(a){b.error({agent:r,cwd:s,error:String(a)},"createSession error"),this.reply(e,n,!1,void 0,String(a))}}async resumeSession(e,n,r,s,i,o){if(this.isDeletedSession(r)){this.reply(e,n,!1,void 0,"Session not found");return}let a=this.sessions.get(r);if(a&&a.active){a.clients.add(e),this.touchSession(a.sessionId),this.noteInventoryChanged("session_updated");let f=await hn(r,s,a.cwd),p=this.currentPartialReplyText(a);if(f.length>0||p||a.approvalMode||a.pendingApproval){let g={type:"session.history",sessionId:r,messages:f,...Ar(a.acceptedClientMessageIds),isResponding:a.isResponding||void 0,partialReplyText:p,approvalMode:a.approvalMode,pendingApproval:a.pendingApproval};e.readyState===1&&e.send(JSON.stringify(g))}this.reply(e,n,!0,{sessionId:r});return}let l=this.store.find(r),c=i||l?.cwd||"",u=o??l?.approvalMode,d=l?.title??"Resumed session";try{let f=w.startTimer("driver.spawn"),p=this.createDriver(s),g=this.configureDriverBeforeStart(s,p),h=await p.start(c,r,u),y=f();b.info({sessionId:h,agent:s,spawnMs:y},"session resumed"),w.increment("session.resume",{agent:s}),_.emit("session.resume",{sessionId:h,agent:s,cwd:c});let m={sessionId:h,agent:s,cwd:c,approvalMode:u,driver:p,clients:new Set([e]),title:d,createdAt:l?.createdAt??new Date().toISOString(),lastActivityAt:new Date().toISOString(),active:!0,lastActivityTs:Date.now(),isResponding:!1,currentReplyText:"",acceptedClientMessageIds:l?.acceptedClientMessageIds??[],syntheticApprovalRetries:{},startupInProgress:!1,bufferedPrompts:[],startupToken:0,managed:l?.managed,pendingApproval:l?.pendingApproval,claudeHookSecret:g,pendingClaudeHookApprovals:new Map};this.sessions.set(h,m),this.registerClaudeHookSession(m),this.store.upsert(fe(m)),this.updateGauges(),this.noteInventoryChanged("session_updated"),this.bindDriverLifecycle(m,s," (resumed)",e),this.restoreDriverPendingApproval(p,m.pendingApproval);let E=await hn(r,s,c);if(E.length>0||m.pendingApproval){b.info({sessionId:r,historyCount:E.length},"sending history messages");let ae={type:"session.history",sessionId:h,messages:E,...Ar(m.acceptedClientMessageIds),approvalMode:u,pendingApproval:m.pendingApproval};e.readyState===1&&e.send(JSON.stringify(ae))}this.reply(e,n,!0,{sessionId:h})}catch(f){this.reply(e,n,!1,void 0,String(f))}}hasAcceptedClientMessage(e,n){return e.acceptedClientMessageIds.includes(n)}rememberAcceptedClientMessage(e,n){this.hasAcceptedClientMessage(e,n)||(e.acceptedClientMessageIds.push(n),e.acceptedClientMessageIds.length>xr&&e.acceptedClientMessageIds.splice(0,e.acceptedClientMessageIds.length-xr))}async sendMessage(e,n,r,s,i,o,a){if(this.isDeletedSession(r)){this.reply(e,n,!1,void 0,"Session not found");return}let l=this.sessions.get(r);if(!l||!l.driver){let d=await this.resolveReconnectSession(r,i,l);if(!d){b.warn({sessionId:r},"session not found in records or scanner"),this.reply(e,n,!1,void 0,"Session not found");return}b.info({sessionId:r,agent:d.agent,source:d.source},"auto-reconnecting session"),w.increment("session.reconnect",{agent:d.agent,source:d.source}),_.emit("session.reconnect",{sessionId:r,agent:d.agent,source:d.source});try{let f=this.createDriver(d.agent),p=this.configureDriverBeforeStart(d.agent,f,l?.claudeHookSecret);await f.start(d.cwd,r,d.approvalMode),this.restoreDriverPendingApproval(f,d.pendingApproval),l?(l.approvalMode=d.approvalMode,l.pendingApproval=d.pendingApproval,l.driver=f,l.active=!0,l.clients.add(e),l.lastActivityAt=d.lastActivityAt,l.lastActivityTs=Date.now(),l.isResponding=!1,l.currentReplyText="",l.acceptedClientMessageIds=yn(l.acceptedClientMessageIds,d.acceptedClientMessageIds),l.syntheticApprovalRetries=l.syntheticApprovalRetries??{},l.startupInProgress=!1,l.bufferedPrompts=l.bufferedPrompts??[],l.startupToken=l.startupToken??0,l.claudeHookSecret=p??l.claudeHookSecret,l.pendingClaudeHookApprovals=l.pendingClaudeHookApprovals??new Map):(l={sessionId:r,agent:d.agent,cwd:d.cwd,approvalMode:d.approvalMode,driver:f,clients:new Set([e]),title:d.title,createdAt:d.createdAt,lastActivityAt:d.lastActivityAt,active:!0,lastActivityTs:Date.now(),isResponding:!1,currentReplyText:"",acceptedClientMessageIds:d.acceptedClientMessageIds,syntheticApprovalRetries:{},startupInProgress:!1,bufferedPrompts:[],startupToken:0,managed:d.managed,pendingApproval:d.pendingApproval,claudeHookSecret:p,pendingClaudeHookApprovals:new Map},this.sessions.set(r,l)),this.registerClaudeHookSession(l),this.bindDriverLifecycle(l,d.agent," (reconnected)"),this.store.upsert(fe(l)),this.updateGauges(),this.noteInventoryChanged("session_updated")}catch(f){this.reply(e,n,!1,void 0,`Failed to reconnect: ${f}`);return}}if(l.clients.add(e),l.pendingApproval){this.reply(e,n,!1,void 0,"Resolve the pending approval before sending another message.");return}if(o&&this.hasAcceptedClientMessage(l,o)){this.reply(e,n,!0,{sessionId:r,clientMessageId:o,duplicate:!0});return}if(b.info({sessionId:r,clients:l.clients.size,hasDriver:!!l.driver,active:l.active,imageCount:a?.length??0},"sending message"),_.emit("session.send",{sessionId:r,agent:l.agent,messagePreview:s.slice(0,100),imageCount:a?.length??0}),St(l.title)){let d=Qs(s,50);d&&d!==l.title&&(l.title=d),this.store.upsert(fe(l))}o&&this.rememberAcceptedClientMessage(l,o),this.touchSession(l.sessionId);let c=a?.length?a.map(d=>`[Attached image: ${d}]`).join(`
98
98
  `):"",u=c?s?`${s}
99
99
 
package/package.json CHANGED
@@ -1,9 +1,8 @@
1
1
  {
2
2
  "name": "vibelet",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "macOS CLI for installing and running the Vibelet daemon",
5
5
  "homepage": "https://vibelet.icu",
6
- "private": false,
7
6
  "files": [
8
7
  "bin/vibelet.mjs",
9
8
  "bin/vibelet-runtime-policy.mjs",
@@ -25,24 +24,7 @@
25
24
  "publishConfig": {
26
25
  "access": "public"
27
26
  },
28
- "scripts": {
29
- "build": "NX_TUI=false nx run-many -t build",
30
- "build:release": "pnpm -C apps/daemon build:release",
31
- "build:publish": "pnpm build:release",
32
- "dev": "nx run-many -t dev --parallel=10 --verbose",
33
- "dev:app": "pnpm -C apps/app dev",
34
- "dev:daemon": "pnpm -C apps/daemon dev",
35
- "dev:site": "pnpm -C apps/site dev",
36
- "build:site": "nx run site:build",
37
- "test": "pnpm -C apps/app test && pnpm -C apps/daemon test && pnpm -C apps/site test && node --test bin/vibelet-cli.test.mjs scripts/publish-dual-npm.test.mjs",
38
- "prepack": "pnpm build:publish",
39
- "publish:dual": "node ./scripts/publish-dual-npm.mjs",
40
- "publish:dual:dry-run": "node ./scripts/publish-dual-npm.mjs --dry-run"
41
- },
42
27
  "dependencies": {
43
28
  "qrcode": "^1.5.4"
44
- },
45
- "devDependencies": {
46
- "nx": "^22.1.3"
47
29
  }
48
30
  }