vibelet 0.1.25 → 0.1.27

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.
@@ -0,0 +1,11 @@
1
+ const QUICK_TUNNEL_URL_PATTERN = /https:\/\/[a-z0-9-]+\.trycloudflare\.com(?=$|[\s"',)\]])/g;
2
+
3
+ export function extractQuickTunnelUrl(logContent) {
4
+ if (typeof logContent !== 'string' || logContent.length === 0) {
5
+ return null;
6
+ }
7
+
8
+ const match = QUICK_TUNNEL_URL_PATTERN.exec(logContent);
9
+ QUICK_TUNNEL_URL_PATTERN.lastIndex = 0;
10
+ return match?.[0] ?? null;
11
+ }
@@ -0,0 +1,68 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { existsSync } from 'node:fs';
3
+ import { delimiter, join } from 'node:path';
4
+
5
+ function getExecutableCandidates(name, pathExtValue = process.env.PATHEXT ?? '') {
6
+ if (process.platform !== 'win32') {
7
+ return [name];
8
+ }
9
+
10
+ const extensions = pathExtValue
11
+ .split(';')
12
+ .map((entry) => entry.trim())
13
+ .filter(Boolean)
14
+ .map((entry) => (entry.startsWith('.') ? entry : `.${entry}`))
15
+ .map((entry) => entry.toLowerCase());
16
+
17
+ return [name, ...extensions.map((entry) => `${name}${entry}`)];
18
+ }
19
+
20
+ export function findExecutableInPath(name, {
21
+ pathValue = process.env.PATH ?? '',
22
+ pathExtValue = process.env.PATHEXT ?? '',
23
+ } = {}) {
24
+ if (!pathValue) return null;
25
+
26
+ for (const dir of pathValue.split(delimiter)) {
27
+ if (!dir) continue;
28
+ for (const candidate of getExecutableCandidates(name, pathExtValue)) {
29
+ const candidatePath = join(dir, candidate);
30
+ if (existsSync(candidatePath)) {
31
+ return candidatePath;
32
+ }
33
+ }
34
+ }
35
+
36
+ return null;
37
+ }
38
+
39
+ export function resolveCloudflaredBin({
40
+ pathValue = process.env.PATH ?? '',
41
+ pathExtValue = process.env.PATHEXT ?? '',
42
+ spawnSyncImpl = spawnSync,
43
+ } = {}) {
44
+ const directPath = findExecutableInPath('cloudflared', { pathValue, pathExtValue });
45
+ if (directPath) {
46
+ return directPath;
47
+ }
48
+
49
+ const result = spawnSyncImpl('npx', [
50
+ '--yes',
51
+ '--package=cloudflared',
52
+ 'node',
53
+ '-e',
54
+ "console.log(process.env.PATH ?? '')",
55
+ ], {
56
+ encoding: 'utf8',
57
+ timeout: 30_000,
58
+ });
59
+
60
+ if (result.status !== 0 || !result.stdout.trim()) {
61
+ return null;
62
+ }
63
+
64
+ return findExecutableInPath('cloudflared', {
65
+ pathValue: result.stdout.trim(),
66
+ pathExtValue,
67
+ });
68
+ }
package/bin/vibelet.mjs CHANGED
@@ -6,6 +6,8 @@ import { homedir } from 'node:os';
6
6
  import { dirname, join, resolve } from 'node:path';
7
7
  import { fileURLToPath } from 'node:url';
8
8
  import QRCode from 'qrcode';
9
+ import { extractQuickTunnelUrl } from './cloudflared-quick-tunnel.mjs';
10
+ import { resolveCloudflaredBin } from './cloudflared-resolver.mjs';
9
11
  import { shouldReuseHealthyDaemon } from './vibelet-runtime-policy.mjs';
10
12
 
11
13
  // ─── Paths & constants ─────────────────────────────────────────────────────────
@@ -711,25 +713,6 @@ function getAliveTunnel() {
711
713
  return null;
712
714
  }
713
715
 
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
716
  function startTunnel() {
734
717
  return new Promise((resolve, reject) => {
735
718
  const logPath = join(logDir, 'tunnel.stderr.log');
@@ -766,9 +749,9 @@ function startTunnel() {
766
749
  const poll = setInterval(() => {
767
750
  try {
768
751
  const content = readFileSync(logPath, 'utf8');
769
- const match = content.match(/https:\/\/[a-z0-9-]+\.trycloudflare\.com/);
770
- if (match) {
771
- url = match[0];
752
+ const tunnelUrl = extractQuickTunnelUrl(content);
753
+ if (tunnelUrl) {
754
+ url = tunnelUrl;
772
755
  clearInterval(poll);
773
756
  clearTimeout(timeout);
774
757
  saveTunnelState(pid, url);
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.25"}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.27"}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})+`
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "vibelet",
3
- "version": "0.1.25",
3
+ "version": "0.1.27",
4
4
  "description": "macOS CLI for installing and running the Vibelet daemon",
5
5
  "homepage": "https://vibelet.icu",
6
6
  "files": [
7
+ "bin/cloudflared-resolver.mjs",
8
+ "bin/cloudflared-quick-tunnel.mjs",
7
9
  "bin/vibelet.mjs",
8
10
  "bin/vibelet-runtime-policy.mjs",
9
11
  "dist/index.cjs",