@vibecontrols/agent 2026.602.4 → 2026.602.6

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.
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{L as r1}from"./index-d1xjj001.js";import{M as b2}from"./index-b5dhmybd.js";import{O as a$,P as B1}from"./index-e1bw1bwr.js";import{$ as U2,Q as r$,R as c$,S as s0,T as r0,U as e$,V as e0,W as $0,X as $1,Y as D$,Z as E$,_ as J2,ca as z0,da as I2,ea as _2,fa as K0,ga as U1,ha as I1,ia as _1,ja as L2,ka as W0}from"./index-1zf3r23y.js";import{la as J$,ma as X$,na as B$,oa as Q1,ta as w2}from"./index-rw9x93zb.js";import{va as p}from"./index-nmk7cbj5.js";import{Ca as X2}from"./index-4wgjx8bf.js";import{Ea as t1,Fa as k$,Ha as o$,Ma as t0,Oa as s1,Pa as g2,Wa as s$}from"./index-s2xpdnsj.js";import{Xa as l}from"./index-0ckffygp.js";import{Ya as d1,ab as a}from"./index-rc79x8fw.js";import{db as P2}from"./index-52cp759f.js";import{Ib as M2}from"./index-rqq0k5fc.js";import{hc as t$,ic as T$,jc as f,kc as P,lc as B,mc as q0}from"./index-8nqp3a4d.js";import{Cc as x$,Dc as W$,Ec as u$,oc as K,pc as E,qc as L,rc as C,sc as U,tc as j,uc as W,vc as T,wc as I,xc as J,yc as n,zc as G$}from"./index-1mppacnx.js";import{Fc as b0,Gc as r,Hc as v$}from"./index-thammzct.js";import{Lc as w,Nc as A,Oc as y,Pc as m,Qc as L0,Rc as P$}from"./index-b6x6a4xp.js";import{Sc as Z2,Uc as A0,Vc as a1,Xc as G2,Yc as f0,_c as y$,bd as F2,cd as f$,dd as P0,ed as T2,fd as V0,gd as R2,hd as j2,id as E2,jd as N2,ld as B0,md as O1,od as Y$,qd as U$,ud as a0}from"./index-h74va4wd.js";import{Ad as O0,Od as c0}from"./index-js1xn4sq.js";import{$d as Q$,Yd as Y0,ae as V$,be as N$,ce as Z$}from"./index-a4854mwz.js";import{ie as $$}from"./index-c7554sg7.js";import{existsSync as o0}from"fs";import{join as p2}from"path";import{createServer as n2}from"net";function i2(Y,q="0.0.0.0"){return new Promise(($)=>{let Z=n2();Z.once("error",()=>$(!1)),Z.once("listening",()=>{Z.close(()=>$(!0))}),Z.listen({host:q,port:Y,exclusive:!0})})}async function p0(Y,q="0.0.0.0"){let $=Y;while(!await i2($,q))if($++,$>65535)throw Error(`No free port found starting from ${Y}`);return $}function Y1(Y){Y.command("start").description("Start a VibeControls agent instance").option("-p, --port <port>","Port to listen on. Default: 3005 for the 'default' profile, deterministic 3100-3399 for any other profile (FNV-1a hash) so multiple profiles run side-by-side without EADDRINUSE.").option("-n, --name <name>","Agent instance name","default").option("-f, --foreground","Run in foreground mode (default: daemon)",!1).option("--db-path <path>","Path to the agent storage directory").option("--profile <profile>","Profile name for isolated config (env: VIBECONTROLS_PROFILE)").option("--host <host>","Host to bind to","0.0.0.0").option("--skip-plugin-install","Skip automatic installation of default plugins",!1).option("--skip-plugin <name>","Skip a specific default plugin (repeatable). Accepts the short pluginName or the full package name.",(q,$=[])=>[...$,q],[]).option("--no-install-deps","Skip auto-installing missing tools (installed by their plugins on start by default)").option("-y, --yes","Skip the first-run install consent prompt. Equivalent to VIBE_AUTO_ACCEPT=1; useful for CI / Docker / nohup contexts.",!1).option("--client-id <id>","Gateway OAuth client ID (env: VIBE_CLIENT_ID)").option("--client-secret <secret>","Gateway OAuth client secret (env: VIBE_CLIENT_SECRET)").option("--global-gateway-url <url>","Global gateway URL (env: VIBE_GLOBAL_GATEWAY_URL)").option("--workspace-gateway-url <url>","Workspace gateway URL (env: VIBE_WORKSPACE_GATEWAY_URL)").option("--workspace-id <id>","Workspace ID for auto-report (env: VIBE_WORKSPACE_ID)").option("--isolate <plugins>","Comma-separated list of plugin names to force into worker_threads isolation (Phase 4 hostile-plugin mode). Sets VIBE_ISOLATE_PLUGINS in the daemon env.").option("--profiles <names>","Comma-separated list of profiles to host in this daemon (multi-profile boot). When unset, the daemon hosts a single profile resolved via --profile / VIBECONTROLS_PROFILE / 'default'. Sets VIBECONTROLS_PROFILES in the daemon env so app boot can spin up additional ProfileContexts via the in-process registry.").option("--strict-key-fetch","Refuse to boot if any profile's encryption-key fetch fails. Default lenient: a failed profile is marked degraded and the daemon stays up. Sets VIBE_STRICT_KEY_FETCH=1 in the daemon env.",!1).option("--json","Emit JSON").option("--plain","Plain text output (no interactive TUI). Implied for non-TTY / CI.").option("--abilities <list>","Comma-separated ability keys to install non-interactively (e.g. session,ai,gitops). Storage/tunnel/backup are always included.").option("--providers <list>","Comma-separated extra provider plugins to install beyond each meta's default (e.g. session-wezterm,ai-claude). Accepts short names or @vibecontrols/... packages. Persisted; manage later with `vibe capability`.").option("--wait-ready [seconds]","Block until the agent is fully ready (or fails). Polls /health/ready and renders phase transitions live. Without a value, defaults to 60s. Exits non-zero if the agent ends up degraded or times out. Useful for scripts/CI.").option("--no-wait","Skip the phase tracker entirely after spawning the daemon. Restores the old fire-and-print behavior \u2014 for users who want the previous quick-return UX.").action(async function(q){let $={...Y.opts(),...q};try{let x=function(h){if(h==="default")return 3005;let d=2166136261;for(let g=0;g<h.length;g++)d=Math.imul(d^h.charCodeAt(g),16777619);return 3100+Math.abs(d)%300},Z=new p,X=q.profile||process.env.VIBECONTROLS_PROFILE||"default";if(process.env.VIBECONTROLS_PROFILE=X,typeof q.isolate==="string"&&q.isolate.length>0)process.env.VIBE_ISOLATE_PLUGINS=q.isolate;if(typeof q.profiles==="string"&&q.profiles.length>0){let h=q.profiles.split(",").map((d)=>d.trim()).filter(Boolean);if(h.length>0){if(process.env.VIBECONTROLS_PROFILES=h.join(","),process.env.VIBECONTROLS_PROFILE=h[0],h.length>1)j(`--profiles received ${h.length} entries; daemon boots with '${h[0]}'. Remaining (${h.slice(1).join(", ")}) will be attached via /api/profiles after listen.`)}}if(q.strictKeyFetch===!0)process.env.VIBE_STRICT_KEY_FETCH="1";a0();let H=q.dbPath||N$(),Q=Z$(),z=!o0(H)&&!o0(p2(Q,"agents.json")),V=f($),_=V!=="json"&&V!=="plain"&&t$()&&q.yes!==!0,O=r$(Q),F;if(typeof $.abilities==="string"&&$.abilities.trim()!=="")F=e0($.abilities);else if(O!==null)F=O;else if(_)F=await e$();else F=$0();let D=typeof $.providers==="string"&&$.providers.trim()!=="",R=D?s0($.providers):c$(Q);if(O===null){let h=r0({installDeps:q.installDeps===!0,skipPluginInstall:q.skipPluginInstall===!0,skipPlugins:Array.isArray(q.skipPlugin)?q.skipPlugin:[]},F);if(z&&h.plugins.length>0)J(),W(`Installing ${h.plugins.length} plugin(s) for the selected abilities.`),J();$1(Q,h,F,process.env.VIBE_AGENT_VERSION,R)}else if(D)D$(Q,{providers:R,agentVersion:process.env.VIBE_AGENT_VERSION});if((z||D)&&R.length>0&&q.skipPluginInstall!==!0){W(`Installing ${R.length} selected provider plugin(s)...`);try{let{PluginManager:h}=await import("./plugin-system-cwznxqx5.js"),d=new h;for(let g of R)try{await d.install(g),U(`Installed provider ${g}`)}catch(k){j(`Could not install provider ${g}: ${k instanceof Error?k.message:String(k)}`)}}catch(h){j(`Provider install skipped: ${h instanceof Error?h.message:String(h)}`)}J()}if(z){W("First run detected \u2014 running setup..."),J();let h=Array.isArray(q.skipPlugin)?q.skipPlugin:[],d=q.skipPluginInstall?[]:o$(process.platform,F).filter((s)=>!h.includes(s.packageName)&&!h.includes(s.pluginName)).map((s)=>s.packageName),g=t0(d),K$=a$(g).filter((s)=>!s.installed);if(K$.length>0)if(j(`Missing tools: ${K$.map((s)=>s.name).join(", ")}`),q.installDeps)W("Their plugins will install them automatically on startup.");else W("Auto-install skipped (`--no-install-deps`) \u2014 install them yourself or drop the flag.");else U("All plugin tools present.");J()}if(!q.skipPluginInstall){let h=Array.isArray(q.skipPlugin)?q.skipPlugin:[],d=new s$;await d.loadCorePlugins(),await d.loadAll();let g=await d.ensureDefaultPlugins((k)=>{if(k.startsWith("No "))j(k);else if(k.startsWith("Installed "))U(k);else if(k.startsWith("Failed "))j(k);else W(k)},h,F);if(g.length>0)U(`Auto-installed ${g.length} default plugin${g.length>1?"s":""}.`),J()}let G=q.profile||process.env.VIBECONTROLS_PROFILE||q.name||"default",M=q.port?parseInt(q.port,10):x(G);if(isNaN(M)||M<1||M>65535)L("Invalid port number. Must be between 1 and 65535.");let N=await p0(M);if(N!==M)j(`Port ${M} is in use. Auto-selecting port ${K.bold(String(N))} instead.`),M=N;let S=q.host,q$=`http://${S==="0.0.0.0"?"localhost":S}:${M}`,o=q.clientId||process.env.VIBE_CLIENT_ID,v=q.clientSecret||process.env.VIBE_CLIENT_SECRET,u=q.globalGatewayUrl||process.env.VIBE_GLOBAL_GATEWAY_URL,c=q.workspaceGatewayUrl||process.env.VIBE_WORKSPACE_GATEWAY_URL,O$=q.workspaceId||process.env.VIBE_WORKSPACE_ID;if(o&&!v)L("--client-secret is required when --client-id is provided.");if(v&&!o)L("--client-id is required when --client-secret is provided.");if(o&&v){if(!u&&!process.env.VIBE_GLOBAL_GATEWAY_URL)L("--global-gateway-url is required when providing client credentials (none set in env).");if(process.env.VIBE_CLIENT_ID=o,process.env.VIBE_CLIENT_SECRET=v,u)process.env.VIBE_GLOBAL_GATEWAY_URL=u;let{writeAgentConfig:h}=await import("./agent-config-4ppenhqp.js");if(h({clientId:o,clientSecret:v,workspaceId:O$,globalGatewayUrl:u,workspaceGatewayUrl:c}),c)process.env.VIBE_WORKSPACE_GATEWAY_URL=c;if(O$)process.env.VIBE_WORKSPACE_ID=O$;U("Gateway credentials staged in env. Agent will authenticate and persist them on startup."),J()}else if(c||O$||u){if(j("Workspace options provided without --client-id / --client-secret \u2014 they will be staged in env but unused until credentials are configured."),c)process.env.VIBE_WORKSPACE_GATEWAY_URL=c;if(O$)process.env.VIBE_WORKSPACE_ID=O$;if(u)process.env.VIBE_GLOBAL_GATEWAY_URL=u;J()}if(q.foreground){if(!$.json)T("Starting agent in foreground"),I("Name",q.name),I("Port",String(M)),I("Host",S),I("Database",H),J();let{bootstrapWorkspace:h}=await import("./bootstrap-workspace-qgs6d5f0.js");h();let{createApp:d}=await import("./app-8qe1gw9z.js"),g=await d({port:M,host:S,dbPath:H});if(await g.start(),o&&v&&O$&&u&&c){let K$=await g.finalize({clientId:o,clientSecret:v,workspaceId:O$,globalGatewayUrl:u,workspaceGatewayUrl:c});if(!K$.ok)j(`Finalize failed \u2014 agent remains in awaiting-config state: ${K$.error}`)}if(B($,{ok:!0,name:q.name,port:M,host:S,pid:process.pid,url:q$}));else await u$(q$);let k=async()=>{await g.stop(),process.exit(0)};process.on("SIGTERM",k),process.on("SIGINT",k)}else{if(!$.json)T("Starting agent in daemon mode"),I("Name",q.name),I("Port",String(M)),I("Host",S),I("Database",H),J();if(q.installDeps===!1)process.env.VIBE_SKIP_PREREQ_INSTALL="1";await Z.startDaemon({port:M,name:q.name,daemon:!0,dbPath:H,host:S,profile:X});let d=(await Z.getStatus(q.name))?.port??M,k=`http://${S==="0.0.0.0"?"localhost":S}:${d}`,K$=q.waitReady,s=q.wait===!1,l0=K$!==void 0;if(s&&l0)j("--wait-ready is ignored because --no-wait was also passed.");let p$=!s&&l0,n0=!s&&(p$||!$.json),i0=(()=>{let C$=typeof K$==="string"?Number.parseInt(K$,10):NaN;if(Number.isInteger(C$)&&C$>0)return C$*1000;return p$?60000:25000})();if($.json){if(n0){let{trackAgentReady:C$}=await import("./agent-ready-tracker-kgs7td6t.js"),e=await C$(k,{timeoutMs:i0,verbose:!1});if(p$&&(e.outcome==="degraded"||e.outcome==="timeout"))process.exitCode=1;B($,{ok:e.outcome==="ready"||e.outcome==="awaiting-config",name:q.name,port:d,host:S,url:k,abilities:[...F],outcome:e.outcome,bootState:e.bootState,degradedReasons:e.degradedReasons,summary:e.summary})}else B($,{ok:!0,name:q.name,port:d,host:S,url:k});return}if(await u$(k),n0){let{trackAgentReady:C$}=await import("./agent-ready-tracker-kgs7td6t.js");J();let e=await C$(k,{timeoutMs:i0,verbose:!0});if(p$&&(e.outcome==="degraded"||e.outcome==="timeout"))process.exitCode=1}}}catch(Z){let X=Z instanceof Error?C(Z):String(Z);if($.json){B($,{ok:!1,error:X});return}L(`Failed to start agent: ${X}`)}})}function q1(Y){Y.command("stop").description("Stop a running VibeControls agent instance").option("-n, --name <name>","Agent instance name","default").option("--all","Stop all running agent instances",!1).option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{let Z=new p;if(q.all){let X=await Z.listInstances();if(!X||X.length===0){if(B($,{ok:!0,stopped:[]}))return;T("Stopping all agent instances"),J(),W(`${E.info} No running agent instances found.`);return}let H=[];if(!$.json)T("Stopping all agent instances"),J();for(let Q of X)try{if(await Z.stop(Q.name),H.push(Q.name),!$.json)U(`${E.success} Stopped ${K.bold(Q.name)}`)}catch{if(!$.json)L(`Failed to stop ${K.bold(Q.name)}`)}if(B($,{ok:!0,stopped:H,total:X.length}))return;J(),U(`${E.success} Stopped ${H.length}/${X.length} instance(s).`)}else{if(await Z.stop(q.name),B($,{ok:!0,name:q.name}))return;T(`Stopping agent: ${q.name}`),J(),U(`${E.success} Agent ${K.bold(q.name)} stopped.`)}}catch(Z){if($.json){B($,{ok:!1,error:C(Z)});return}L(`Failed to stop agent: ${C(Z)}`)}})}function Z1(Y){Y.command("restart").description("Restart a running VibeControls agent instance").option("-n, --name <name>","Agent instance name","default").option("-p, --port <port>","Port to listen on").option("--db-path <path>","Path to the agent storage directory").option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{let Z=new p;if(!$.json)T(`Restarting agent: ${q.name}`),J(),W(`${E.info} Stopping agent ${K.bold(q.name)}...`);let X=await Z.getStatus(q.name);try{if(await Z.stop(q.name),!$.json)U(`${E.success} Agent stopped.`)}catch{if(!$.json)W(`${E.info} Agent was not running.`)}let H=q.port??X?.port??3005,Q=typeof H==="number"?H:parseInt(H,10);if(isNaN(Q)||Q<1||Q>65535){if($.json){B($,{ok:!1,error:"Invalid port number"});return}L("Invalid port number. Must be between 1 and 65535.");return}let z={port:Q,name:q.name,daemon:!0,dbPath:q.dbPath??X?.config?.dbPath??N$(),host:X?.config?.host,profile:X?.config?.profile};if(!$.json)J(),W(`${E.info} Starting agent ${K.bold(q.name)}...`);await Z.startDaemon(z);let V=`http://localhost:${Q}`;if(B($,{ok:!0,name:q.name,port:Q,url:V}))return;J(),U(`${E.success} Agent ${K.bold(q.name)} restarted.`),J(),I("Port",String(Q)),I("Database",z.dbPath),J(),u$(V)}catch(Z){if($.json){B($,{ok:!1,error:C(Z)});return}L(`Failed to restart agent: ${C(Z)}`)}})}import{existsSync as o2,readFileSync as a2,unlinkSync as X1}from"fs";import{join as z1}from"path";function t2(Y){let q=z1(V$(),Y,"runtime.json");if(!o2(q))return null;try{let $=JSON.parse(a2(q,"utf8"));if(typeof $.pid!=="number")return null;return{...$,pid:$.pid,path:q}}catch{return null}}async function H1(Y){let q=t2(Y);if(!q)return null;if(!B$(q.pid)){try{X1(q.path)}catch{}return`agent pid=${q.pid} (${Y}) already gone (cleaned runtime.json).`}let $=l();if(!$.killProcessTree(q.pid,"SIGTERM"))return`failed to SIGTERM agent pid=${q.pid}.`;if(await new Promise((Z)=>setTimeout(Z,3000)),B$(q.pid))$.killProcessTree(q.pid,"SIGKILL");try{X1(q.path)}catch{}return`agent ${Y} pid=${q.pid}${q.port?` (port ${q.port})`:""} killed.`}async function s2(Y){let q=z1(V$(),Y),$=J$(q);if(!$)return null;if(!B$($.pid))return X$(q),`tunnel pid=${$.pid} already gone (cleaned state).`;let Z=l();if(!Z.killProcessTree($.pid,"SIGTERM"))return`failed to SIGTERM tunnel pid=${$.pid}.`;if(await new Promise((X)=>setTimeout(X,3000)),B$($.pid))Z.killProcessTree($.pid,"SIGKILL");return X$(q),`tunnel ${$.provider} pid=${$.pid} (${$.url??"no url"}) killed.`}function W1(Y){Y.command("kill").description("Force-kill an agent instance and its tunnel. Defaults to active profile.").option("-n, --name <name>","Agent instance name (alias of --profile, kept for back-compat)").option("--profile <name>","Kill a specific profile (overrides --name and VIBECONTROLS_PROFILE)").option("--all","Kill every agent instance and every profile's tunnel",!1).option("-y, --yes","Skip the confirmation prompt (for scripts/CI)",!1).option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q},Z=q.all?"ALL agent instances + every profile's tunnel":`agent '${$.profile??$.name??"active profile"}'`;if(!await q0($,`Force-kill ${Z}? This sends SIGKILL (no graceful shutdown).`)){W("Aborted.");return}let X=[];try{let H=new p;if(q.all){if(!$.json)T("Force killing all agent instances + tunnels"),J();let _=await H.listInstances()??[],O=0,F=new Set;for(let G of _)try{if(await H.kill(G.name),!$.json)U(`${E.success} agent ${K.bold(G.name)} (pid=${G.pid||"?"}) killed.`);X.push(G.name),O++,F.add(G.name)}catch{if(!$.json)j(`${E.warning} could not kill agent ${G.name}.`)}try{let G=await import("fs"),x=V$(),M=G.existsSync(x)?G.readdirSync(x):[];for(let N of M){if(F.has(N))continue;let S=await H1(N);if(S)U(`${E.success} ${S}`),O++}}catch(G){j(`${E.warning} runtime.json sweep failed: ${G instanceof Error?C(G):String(G)}`)}let D=Q1({allProfiles:!0}),R=0;for(let G of D){if(!G.alive){X$(G.profileDir);continue}let x=l();if(x.killProcessTree(G.pid,"SIGTERM"),await new Promise((M)=>setTimeout(M,3000)),B$(G.pid))x.killProcessTree(G.pid,"SIGKILL");X$(G.profileDir),U(`${E.success} tunnel ${G.provider} pid=${G.pid} (${G.url??"no url"}, ${G.profileDir.split("/").pop()}) killed.`),R++}if(B($,{ok:!0,killed:X,tunnels:R}))return;J(),U(`${E.success} killed ${O} agent(s) and ${R} tunnel(s).`);return}let Q=q.profile||q.name||Y0();if(!$.json)T(`Force killing profile: ${Q}`),J();let z=await H.getStatus(Q);if(z){if(await H.kill(Q),X.push(Q),!$.json)U(`${E.success} agent ${K.bold(Q)} pid=${z.pid||"?"} killed.`)}else{let _=await H1(Q);if(_){if(X.push(Q),!$.json)U(`${E.success} ${_}`)}else if(!$.json)W(`${E.info} no running agent service for profile ${Q}.`)}let V=await s2(Q);if(V){if(!$.json)U(`${E.success} ${V}`)}else if(!$.json)W(`${E.info} no tunnel recorded for profile ${Q}.`);B($,{ok:!0,killed:X})}catch(H){if($.json){B($,{ok:!1,error:C(H)});return}L(`Failed to kill: ${C(H)}`)}})}function K1(Y){Y.command("list").alias("ls").description("List all VibeControls agent instances").option("--json","Emit JSON").option("--plain","Force plain text output").action(async function(q){try{let $={...Y.opts(),...q},Z=new p;await P({mode:f($),fetchData:()=>Z.listInstances(),plain:(X)=>{if(T("Agent Instances"),J(),!X||X.length===0){W(`${E.info} No agent instances found.`),W(`Run ${K.bold("vibe start")} to start an agent.`);return}let H=X.map((V)=>({Name:V.name,Status:x$(V.status),PID:V.pid||"-",Port:V.port||"-",Host:V.config?.host||"-",Database:V.config?.dbPath||"-",Started:V.startTime?G$(V.startTime):"-"}));n(H),J();let Q=X.filter((V)=>V.status==="running").length,z=X.length-Q;W(`${E.info} ${X.length} instance(s): ${K.green(String(Q))} running, ${K.dim(String(z))} stopped`)},interactive:async(X)=>{if(!X||X.length===0){T("Agent Instances"),J(),W(`${E.info} No agent instances found.`),W(`Run ${K.bold("vibe start")} to start an agent.`);return}let H=X.map((Q)=>{let z=[`${K.bold(Q.name)} ${x$(Q.status)}`,"",` PID: ${Q.pid??"-"}`,` Port: ${Q.port??"-"}`,` Host: ${Q.config?.host??"-"}`,` Database: ${Q.config?.dbPath??"-"}`,` Started: ${Q.startTime?G$(Q.startTime):"-"}`];return{id:Q.name,label:Q.name,hint:Q.status==="running"?"running":"stopped",detail:z.join(`
2
+ import{L as r1}from"./index-d1xjj001.js";import{M as b2}from"./index-b5dhmybd.js";import{O as a$,P as B1}from"./index-e1bw1bwr.js";import{$ as U2,Q as r$,R as c$,S as s0,T as r0,U as e$,V as e0,W as $0,X as $1,Y as D$,Z as E$,_ as J2,ca as z0,da as I2,ea as _2,fa as K0,ga as U1,ha as I1,ia as _1,ja as L2,ka as W0}from"./index-rvwb9g8g.js";import{la as J$,ma as X$,na as B$,oa as Q1,ta as w2}from"./index-rw9x93zb.js";import{va as p}from"./index-vaxcmbdg.js";import{Ca as X2}from"./index-4wgjx8bf.js";import{Ea as t1,Fa as k$,Ha as o$,Ma as t0,Oa as s1,Pa as g2,Wa as s$}from"./index-9006n9tq.js";import{Xa as l}from"./index-0ckffygp.js";import{Ya as d1,ab as a}from"./index-rc79x8fw.js";import{db as P2}from"./index-52cp759f.js";import{Ib as M2}from"./index-rqq0k5fc.js";import{hc as t$,ic as T$,jc as f,kc as P,lc as B,mc as q0}from"./index-8nqp3a4d.js";import{Cc as x$,Dc as W$,Ec as u$,oc as K,pc as E,qc as L,rc as C,sc as U,tc as j,uc as W,vc as T,wc as I,xc as J,yc as n,zc as G$}from"./index-1mppacnx.js";import{Fc as b0,Gc as r,Hc as v$}from"./index-thammzct.js";import{Lc as w,Nc as A,Oc as y,Pc as m,Qc as L0,Rc as P$}from"./index-b6x6a4xp.js";import{Sc as Z2,Uc as A0,Vc as a1,Xc as G2,Yc as f0,_c as y$,bd as F2,cd as f$,dd as P0,ed as T2,fd as V0,gd as R2,hd as j2,id as E2,jd as N2,ld as B0,md as O1,od as Y$,qd as U$,ud as a0}from"./index-h74va4wd.js";import{Ad as O0,Od as c0}from"./index-js1xn4sq.js";import{$d as Q$,Yd as Y0,ae as V$,be as N$,ce as Z$}from"./index-a4854mwz.js";import{ie as $$}from"./index-c7554sg7.js";import{existsSync as o0}from"fs";import{join as p2}from"path";import{createServer as n2}from"net";function i2(Y,q="0.0.0.0"){return new Promise(($)=>{let Z=n2();Z.once("error",()=>$(!1)),Z.once("listening",()=>{Z.close(()=>$(!0))}),Z.listen({host:q,port:Y,exclusive:!0})})}async function p0(Y,q="0.0.0.0"){let $=Y;while(!await i2($,q))if($++,$>65535)throw Error(`No free port found starting from ${Y}`);return $}function Y1(Y){Y.command("start").description("Start a VibeControls agent instance").option("-p, --port <port>","Port to listen on. Default: 3005 for the 'default' profile, deterministic 3100-3399 for any other profile (FNV-1a hash) so multiple profiles run side-by-side without EADDRINUSE.").option("-n, --name <name>","Agent instance name","default").option("-f, --foreground","Run in foreground mode (default: daemon)",!1).option("--db-path <path>","Path to the agent storage directory").option("--profile <profile>","Profile name for isolated config (env: VIBECONTROLS_PROFILE)").option("--host <host>","Host to bind to","0.0.0.0").option("--skip-plugin-install","Skip automatic installation of default plugins",!1).option("--skip-plugin <name>","Skip a specific default plugin (repeatable). Accepts the short pluginName or the full package name.",(q,$=[])=>[...$,q],[]).option("--no-install-deps","Skip auto-installing missing tools (installed by their plugins on start by default)").option("-y, --yes","Skip the first-run install consent prompt. Equivalent to VIBE_AUTO_ACCEPT=1; useful for CI / Docker / nohup contexts.",!1).option("--client-id <id>","Gateway OAuth client ID (env: VIBE_CLIENT_ID)").option("--client-secret <secret>","Gateway OAuth client secret (env: VIBE_CLIENT_SECRET)").option("--global-gateway-url <url>","Global gateway URL (env: VIBE_GLOBAL_GATEWAY_URL)").option("--workspace-gateway-url <url>","Workspace gateway URL (env: VIBE_WORKSPACE_GATEWAY_URL)").option("--workspace-id <id>","Workspace ID for auto-report (env: VIBE_WORKSPACE_ID)").option("--isolate <plugins>","Comma-separated list of plugin names to force into worker_threads isolation (Phase 4 hostile-plugin mode). Sets VIBE_ISOLATE_PLUGINS in the daemon env.").option("--profiles <names>","Comma-separated list of profiles to host in this daemon (multi-profile boot). When unset, the daemon hosts a single profile resolved via --profile / VIBECONTROLS_PROFILE / 'default'. Sets VIBECONTROLS_PROFILES in the daemon env so app boot can spin up additional ProfileContexts via the in-process registry.").option("--strict-key-fetch","Refuse to boot if any profile's encryption-key fetch fails. Default lenient: a failed profile is marked degraded and the daemon stays up. Sets VIBE_STRICT_KEY_FETCH=1 in the daemon env.",!1).option("--json","Emit JSON").option("--plain","Plain text output (no interactive TUI). Implied for non-TTY / CI.").option("--abilities <list>","Comma-separated ability keys to install non-interactively (e.g. session,ai,gitops). Storage/tunnel/backup are always included.").option("--providers <list>","Comma-separated extra provider plugins to install beyond each meta's default (e.g. session-wezterm,ai-claude). Accepts short names or @vibecontrols/... packages. Persisted; manage later with `vibe capability`.").option("--wait-ready [seconds]","Block until the agent is fully ready (or fails). Polls /health/ready and renders phase transitions live. Without a value, defaults to 60s. Exits non-zero if the agent ends up degraded or times out. Useful for scripts/CI.").option("--no-wait","Skip the phase tracker entirely after spawning the daemon. Restores the old fire-and-print behavior \u2014 for users who want the previous quick-return UX.").action(async function(q){let $={...Y.opts(),...q};try{let x=function(h){if(h==="default")return 3005;let d=2166136261;for(let g=0;g<h.length;g++)d=Math.imul(d^h.charCodeAt(g),16777619);return 3100+Math.abs(d)%300},Z=new p,X=q.profile||process.env.VIBECONTROLS_PROFILE||"default";if(process.env.VIBECONTROLS_PROFILE=X,typeof q.isolate==="string"&&q.isolate.length>0)process.env.VIBE_ISOLATE_PLUGINS=q.isolate;if(typeof q.profiles==="string"&&q.profiles.length>0){let h=q.profiles.split(",").map((d)=>d.trim()).filter(Boolean);if(h.length>0){if(process.env.VIBECONTROLS_PROFILES=h.join(","),process.env.VIBECONTROLS_PROFILE=h[0],h.length>1)j(`--profiles received ${h.length} entries; daemon boots with '${h[0]}'. Remaining (${h.slice(1).join(", ")}) will be attached via /api/profiles after listen.`)}}if(q.strictKeyFetch===!0)process.env.VIBE_STRICT_KEY_FETCH="1";a0();let H=q.dbPath||N$(),Q=Z$(),z=!o0(H)&&!o0(p2(Q,"agents.json")),V=f($),_=V!=="json"&&V!=="plain"&&t$()&&q.yes!==!0,O=r$(Q),F;if(typeof $.abilities==="string"&&$.abilities.trim()!=="")F=e0($.abilities);else if(O!==null)F=O;else if(_)F=await e$();else F=$0();let D=typeof $.providers==="string"&&$.providers.trim()!=="",R=D?s0($.providers):c$(Q);if(O===null){let h=r0({installDeps:q.installDeps===!0,skipPluginInstall:q.skipPluginInstall===!0,skipPlugins:Array.isArray(q.skipPlugin)?q.skipPlugin:[]},F);if(z&&h.plugins.length>0)J(),W(`Installing ${h.plugins.length} plugin(s) for the selected abilities.`),J();$1(Q,h,F,process.env.VIBE_AGENT_VERSION,R)}else if(D)D$(Q,{providers:R,agentVersion:process.env.VIBE_AGENT_VERSION});if((z||D)&&R.length>0&&q.skipPluginInstall!==!0){W(`Installing ${R.length} selected provider plugin(s)...`);try{let{PluginManager:h}=await import("./plugin-system-kaj4069d.js"),d=new h;for(let g of R)try{await d.install(g),U(`Installed provider ${g}`)}catch(k){j(`Could not install provider ${g}: ${k instanceof Error?k.message:String(k)}`)}}catch(h){j(`Provider install skipped: ${h instanceof Error?h.message:String(h)}`)}J()}if(z){W("First run detected \u2014 running setup..."),J();let h=Array.isArray(q.skipPlugin)?q.skipPlugin:[],d=q.skipPluginInstall?[]:o$(process.platform,F).filter((s)=>!h.includes(s.packageName)&&!h.includes(s.pluginName)).map((s)=>s.packageName),g=t0(d),K$=a$(g).filter((s)=>!s.installed);if(K$.length>0)if(j(`Missing tools: ${K$.map((s)=>s.name).join(", ")}`),q.installDeps)W("Their plugins will install them automatically on startup.");else W("Auto-install skipped (`--no-install-deps`) \u2014 install them yourself or drop the flag.");else U("All plugin tools present.");J()}if(!q.skipPluginInstall){let h=Array.isArray(q.skipPlugin)?q.skipPlugin:[],d=new s$;await d.loadCorePlugins(),await d.loadAll();let g=await d.ensureDefaultPlugins((k)=>{if(k.startsWith("No "))j(k);else if(k.startsWith("Installed "))U(k);else if(k.startsWith("Failed "))j(k);else W(k)},h,F);if(g.length>0)U(`Auto-installed ${g.length} default plugin${g.length>1?"s":""}.`),J()}let G=q.profile||process.env.VIBECONTROLS_PROFILE||q.name||"default",M=q.port?parseInt(q.port,10):x(G);if(isNaN(M)||M<1||M>65535)L("Invalid port number. Must be between 1 and 65535.");let N=await p0(M);if(N!==M)j(`Port ${M} is in use. Auto-selecting port ${K.bold(String(N))} instead.`),M=N;let S=q.host,q$=`http://${S==="0.0.0.0"?"localhost":S}:${M}`,o=q.clientId||process.env.VIBE_CLIENT_ID,v=q.clientSecret||process.env.VIBE_CLIENT_SECRET,u=q.globalGatewayUrl||process.env.VIBE_GLOBAL_GATEWAY_URL,c=q.workspaceGatewayUrl||process.env.VIBE_WORKSPACE_GATEWAY_URL,O$=q.workspaceId||process.env.VIBE_WORKSPACE_ID;if(o&&!v)L("--client-secret is required when --client-id is provided.");if(v&&!o)L("--client-id is required when --client-secret is provided.");if(o&&v){if(!u&&!process.env.VIBE_GLOBAL_GATEWAY_URL)L("--global-gateway-url is required when providing client credentials (none set in env).");if(process.env.VIBE_CLIENT_ID=o,process.env.VIBE_CLIENT_SECRET=v,u)process.env.VIBE_GLOBAL_GATEWAY_URL=u;let{writeAgentConfig:h}=await import("./agent-config-4ppenhqp.js");if(h({clientId:o,clientSecret:v,workspaceId:O$,globalGatewayUrl:u,workspaceGatewayUrl:c}),c)process.env.VIBE_WORKSPACE_GATEWAY_URL=c;if(O$)process.env.VIBE_WORKSPACE_ID=O$;U("Gateway credentials staged in env. Agent will authenticate and persist them on startup."),J()}else if(c||O$||u){if(j("Workspace options provided without --client-id / --client-secret \u2014 they will be staged in env but unused until credentials are configured."),c)process.env.VIBE_WORKSPACE_GATEWAY_URL=c;if(O$)process.env.VIBE_WORKSPACE_ID=O$;if(u)process.env.VIBE_GLOBAL_GATEWAY_URL=u;J()}if(q.foreground){if(!$.json)T("Starting agent in foreground"),I("Name",q.name),I("Port",String(M)),I("Host",S),I("Database",H),J();let{bootstrapWorkspace:h}=await import("./bootstrap-workspace-qgs6d5f0.js");h();let{createApp:d}=await import("./app-k4v5pf0w.js"),g=await d({port:M,host:S,dbPath:H});if(await g.start(),o&&v&&O$&&u&&c){let K$=await g.finalize({clientId:o,clientSecret:v,workspaceId:O$,globalGatewayUrl:u,workspaceGatewayUrl:c});if(!K$.ok)j(`Finalize failed \u2014 agent remains in awaiting-config state: ${K$.error}`)}if(B($,{ok:!0,name:q.name,port:M,host:S,pid:process.pid,url:q$}));else await u$(q$);let k=async()=>{await g.stop(),process.exit(0)};process.on("SIGTERM",k),process.on("SIGINT",k)}else{if(!$.json)T("Starting agent in daemon mode"),I("Name",q.name),I("Port",String(M)),I("Host",S),I("Database",H),J();if(q.installDeps===!1)process.env.VIBE_SKIP_PREREQ_INSTALL="1";await Z.startDaemon({port:M,name:q.name,daemon:!0,dbPath:H,host:S,profile:X});let d=(await Z.getStatus(q.name))?.port??M,k=`http://${S==="0.0.0.0"?"localhost":S}:${d}`,K$=q.waitReady,s=q.wait===!1,l0=K$!==void 0;if(s&&l0)j("--wait-ready is ignored because --no-wait was also passed.");let p$=!s&&l0,n0=!s&&(p$||!$.json),i0=(()=>{let C$=typeof K$==="string"?Number.parseInt(K$,10):NaN;if(Number.isInteger(C$)&&C$>0)return C$*1000;return p$?60000:25000})();if($.json){if(n0){let{trackAgentReady:C$}=await import("./agent-ready-tracker-kgs7td6t.js"),e=await C$(k,{timeoutMs:i0,verbose:!1});if(p$&&(e.outcome==="degraded"||e.outcome==="timeout"))process.exitCode=1;B($,{ok:e.outcome==="ready"||e.outcome==="awaiting-config",name:q.name,port:d,host:S,url:k,abilities:[...F],outcome:e.outcome,bootState:e.bootState,degradedReasons:e.degradedReasons,summary:e.summary})}else B($,{ok:!0,name:q.name,port:d,host:S,url:k});return}if(await u$(k),n0){let{trackAgentReady:C$}=await import("./agent-ready-tracker-kgs7td6t.js");J();let e=await C$(k,{timeoutMs:i0,verbose:!0});if(p$&&(e.outcome==="degraded"||e.outcome==="timeout"))process.exitCode=1}}}catch(Z){let X=Z instanceof Error?C(Z):String(Z);if($.json){B($,{ok:!1,error:X});return}L(`Failed to start agent: ${X}`)}})}function q1(Y){Y.command("stop").description("Stop a running VibeControls agent instance").option("-n, --name <name>","Agent instance name","default").option("--all","Stop all running agent instances",!1).option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{let Z=new p;if(q.all){let X=await Z.listInstances();if(!X||X.length===0){if(B($,{ok:!0,stopped:[]}))return;T("Stopping all agent instances"),J(),W(`${E.info} No running agent instances found.`);return}let H=[];if(!$.json)T("Stopping all agent instances"),J();for(let Q of X)try{if(await Z.stop(Q.name),H.push(Q.name),!$.json)U(`${E.success} Stopped ${K.bold(Q.name)}`)}catch{if(!$.json)L(`Failed to stop ${K.bold(Q.name)}`)}if(B($,{ok:!0,stopped:H,total:X.length}))return;J(),U(`${E.success} Stopped ${H.length}/${X.length} instance(s).`)}else{if(await Z.stop(q.name),B($,{ok:!0,name:q.name}))return;T(`Stopping agent: ${q.name}`),J(),U(`${E.success} Agent ${K.bold(q.name)} stopped.`)}}catch(Z){if($.json){B($,{ok:!1,error:C(Z)});return}L(`Failed to stop agent: ${C(Z)}`)}})}function Z1(Y){Y.command("restart").description("Restart a running VibeControls agent instance").option("-n, --name <name>","Agent instance name","default").option("-p, --port <port>","Port to listen on").option("--db-path <path>","Path to the agent storage directory").option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{let Z=new p;if(!$.json)T(`Restarting agent: ${q.name}`),J(),W(`${E.info} Stopping agent ${K.bold(q.name)}...`);let X=await Z.getStatus(q.name);try{if(await Z.stop(q.name),!$.json)U(`${E.success} Agent stopped.`)}catch{if(!$.json)W(`${E.info} Agent was not running.`)}let H=q.port??X?.port??3005,Q=typeof H==="number"?H:parseInt(H,10);if(isNaN(Q)||Q<1||Q>65535){if($.json){B($,{ok:!1,error:"Invalid port number"});return}L("Invalid port number. Must be between 1 and 65535.");return}let z={port:Q,name:q.name,daemon:!0,dbPath:q.dbPath??X?.config?.dbPath??N$(),host:X?.config?.host,profile:X?.config?.profile};if(!$.json)J(),W(`${E.info} Starting agent ${K.bold(q.name)}...`);await Z.startDaemon(z);let V=`http://localhost:${Q}`;if(B($,{ok:!0,name:q.name,port:Q,url:V}))return;J(),U(`${E.success} Agent ${K.bold(q.name)} restarted.`),J(),I("Port",String(Q)),I("Database",z.dbPath),J(),u$(V)}catch(Z){if($.json){B($,{ok:!1,error:C(Z)});return}L(`Failed to restart agent: ${C(Z)}`)}})}import{existsSync as o2,readFileSync as a2,unlinkSync as X1}from"fs";import{join as z1}from"path";function t2(Y){let q=z1(V$(),Y,"runtime.json");if(!o2(q))return null;try{let $=JSON.parse(a2(q,"utf8"));if(typeof $.pid!=="number")return null;return{...$,pid:$.pid,path:q}}catch{return null}}async function H1(Y){let q=t2(Y);if(!q)return null;if(!B$(q.pid)){try{X1(q.path)}catch{}return`agent pid=${q.pid} (${Y}) already gone (cleaned runtime.json).`}let $=l();if(!$.killProcessTree(q.pid,"SIGTERM"))return`failed to SIGTERM agent pid=${q.pid}.`;if(await new Promise((Z)=>setTimeout(Z,3000)),B$(q.pid))$.killProcessTree(q.pid,"SIGKILL");try{X1(q.path)}catch{}return`agent ${Y} pid=${q.pid}${q.port?` (port ${q.port})`:""} killed.`}async function s2(Y){let q=z1(V$(),Y),$=J$(q);if(!$)return null;if(!B$($.pid))return X$(q),`tunnel pid=${$.pid} already gone (cleaned state).`;let Z=l();if(!Z.killProcessTree($.pid,"SIGTERM"))return`failed to SIGTERM tunnel pid=${$.pid}.`;if(await new Promise((X)=>setTimeout(X,3000)),B$($.pid))Z.killProcessTree($.pid,"SIGKILL");return X$(q),`tunnel ${$.provider} pid=${$.pid} (${$.url??"no url"}) killed.`}function W1(Y){Y.command("kill").description("Force-kill an agent instance and its tunnel. Defaults to active profile.").option("-n, --name <name>","Agent instance name (alias of --profile, kept for back-compat)").option("--profile <name>","Kill a specific profile (overrides --name and VIBECONTROLS_PROFILE)").option("--all","Kill every agent instance and every profile's tunnel",!1).option("-y, --yes","Skip the confirmation prompt (for scripts/CI)",!1).option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q},Z=q.all?"ALL agent instances + every profile's tunnel":`agent '${$.profile??$.name??"active profile"}'`;if(!await q0($,`Force-kill ${Z}? This sends SIGKILL (no graceful shutdown).`)){W("Aborted.");return}let X=[];try{let H=new p;if(q.all){if(!$.json)T("Force killing all agent instances + tunnels"),J();let _=await H.listInstances()??[],O=0,F=new Set;for(let G of _)try{if(await H.kill(G.name),!$.json)U(`${E.success} agent ${K.bold(G.name)} (pid=${G.pid||"?"}) killed.`);X.push(G.name),O++,F.add(G.name)}catch{if(!$.json)j(`${E.warning} could not kill agent ${G.name}.`)}try{let G=await import("fs"),x=V$(),M=G.existsSync(x)?G.readdirSync(x):[];for(let N of M){if(F.has(N))continue;let S=await H1(N);if(S)U(`${E.success} ${S}`),O++}}catch(G){j(`${E.warning} runtime.json sweep failed: ${G instanceof Error?C(G):String(G)}`)}let D=Q1({allProfiles:!0}),R=0;for(let G of D){if(!G.alive){X$(G.profileDir);continue}let x=l();if(x.killProcessTree(G.pid,"SIGTERM"),await new Promise((M)=>setTimeout(M,3000)),B$(G.pid))x.killProcessTree(G.pid,"SIGKILL");X$(G.profileDir),U(`${E.success} tunnel ${G.provider} pid=${G.pid} (${G.url??"no url"}, ${G.profileDir.split("/").pop()}) killed.`),R++}if(B($,{ok:!0,killed:X,tunnels:R}))return;J(),U(`${E.success} killed ${O} agent(s) and ${R} tunnel(s).`);return}let Q=q.profile||q.name||Y0();if(!$.json)T(`Force killing profile: ${Q}`),J();let z=await H.getStatus(Q);if(z){if(await H.kill(Q),X.push(Q),!$.json)U(`${E.success} agent ${K.bold(Q)} pid=${z.pid||"?"} killed.`)}else{let _=await H1(Q);if(_){if(X.push(Q),!$.json)U(`${E.success} ${_}`)}else if(!$.json)W(`${E.info} no running agent service for profile ${Q}.`)}let V=await s2(Q);if(V){if(!$.json)U(`${E.success} ${V}`)}else if(!$.json)W(`${E.info} no tunnel recorded for profile ${Q}.`);B($,{ok:!0,killed:X})}catch(H){if($.json){B($,{ok:!1,error:C(H)});return}L(`Failed to kill: ${C(H)}`)}})}function K1(Y){Y.command("list").alias("ls").description("List all VibeControls agent instances").option("--json","Emit JSON").option("--plain","Force plain text output").action(async function(q){try{let $={...Y.opts(),...q},Z=new p;await P({mode:f($),fetchData:()=>Z.listInstances(),plain:(X)=>{if(T("Agent Instances"),J(),!X||X.length===0){W(`${E.info} No agent instances found.`),W(`Run ${K.bold("vibe start")} to start an agent.`);return}let H=X.map((V)=>({Name:V.name,Status:x$(V.status),PID:V.pid||"-",Port:V.port||"-",Host:V.config?.host||"-",Database:V.config?.dbPath||"-",Started:V.startTime?G$(V.startTime):"-"}));n(H),J();let Q=X.filter((V)=>V.status==="running").length,z=X.length-Q;W(`${E.info} ${X.length} instance(s): ${K.green(String(Q))} running, ${K.dim(String(z))} stopped`)},interactive:async(X)=>{if(!X||X.length===0){T("Agent Instances"),J(),W(`${E.info} No agent instances found.`),W(`Run ${K.bold("vibe start")} to start an agent.`);return}let H=X.map((Q)=>{let z=[`${K.bold(Q.name)} ${x$(Q.status)}`,"",` PID: ${Q.pid??"-"}`,` Port: ${Q.port??"-"}`,` Host: ${Q.config?.host??"-"}`,` Database: ${Q.config?.dbPath??"-"}`,` Started: ${Q.startTime?G$(Q.startTime):"-"}`];return{id:Q.name,label:Q.name,hint:Q.status==="running"?"running":"stopped",detail:z.join(`
3
3
  `)}});await r({title:`vibe list \u2014 ${X.length} instance(s)`,rows:H,footer:"\u2191/\u2193 navigate \xB7 q to quit"})},json:(X)=>X.map((H)=>({name:H.name,status:H.status,pid:H.pid??null,port:H.port??null,host:H.config?.host??null,database:H.config?.dbPath??null,startTime:H.startTime??null}))})}catch($){L(`Failed to list instances: ${$.message}`)}})}var V1=5000;function L1(Y){Y.command("logs").description("View logs for a VibeControls agent instance").option("-n, --name <name>","Agent instance name","default").option("-f, --follow","Follow log output",!1).option("--tail <lines>","Number of lines to show from the end","100").option("--json","Emit JSON (one object per line, banners suppressed)").option("--plain","Force plain text output").action(async function(q){try{let $={...Y.opts(),...q},Z=new p,X=parseInt($.tail??"100",10);if(isNaN(X)||X<1||X>V1){L(`Invalid tail value. Must be between 1 and ${V1}.`);return}let H=$.name??"default";if(!await Z.getStatus(H)){L(`Agent instance ${K.bold(H)} not found.`);return}if(!$.json){if($.follow)T(`Following logs: ${H}`),W(`${E.info} Press Ctrl+C to stop following.`);else T(`Logs: ${H}`);J()}await Z.showLogs(H,{follow:!!$.follow,tail:X})}catch($){L(`Failed to get logs: ${C($)}`)}})}function J1(Y){Y.command("setup").description("Install system dependencies and (optionally) write gateway auth config").option("--check","Only check dependencies without installing",!1).option("--client-id <id>","OAuth app client ID (for backend authentication)").option("--client-secret <secret>","OAuth app client secret").option("--workspace-id <id>","Workspace UUID this agent belongs to").option("--global-gateway-url <url>","Global public gateway URL (default: http://localhost:4000/global/graphql)").option("--workspace-gateway-url <url>","Workspace gateway URL (default: http://localhost:4001/workspaces/graphql)").option("--storage-adapter <name>","Named storage adapter (default: skalex, or custom:<path>)").option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q},Z=[];try{if(!$.json)T("VibeControls Agent Setup");let X={};if(q.clientId)X.clientId=q.clientId;if(q.clientSecret)X.clientSecret=q.clientSecret;if(q.workspaceId)X.workspaceId=q.workspaceId;if(q.globalGatewayUrl)X.globalGatewayUrl=O0(q.globalGatewayUrl,"globalGatewayUrl");if(q.workspaceGatewayUrl)X.workspaceGatewayUrl=O0(q.workspaceGatewayUrl,"workspaceGatewayUrl");if(q.storageAdapter)X.storageAdapter=q.storageAdapter;if(Object.keys(X).length>0){let O=U$(X);if(Z.push(...Object.keys(X)),!$.json){U(`Agent config written to ${B0()}`),I("clientId",O.clientId?K.dim("(set)"):K.dim("(unset)")),I("clientSecret",O.clientSecret?K.dim("(set)"):K.dim("(unset)")),I("workspaceId",O.workspaceId??K.dim("(unset)"));let F=O1();if(I("globalGatewayUrl",O.globalGatewayUrl??F.globalGatewayUrl),I("workspaceGatewayUrl",O.workspaceGatewayUrl??F.workspaceGatewayUrl),O.storageAdapter)I("storageAdapter",O.storageAdapter);J()}}else{let O=Y$();if((O.clientId||O.clientSecret||O.workspaceId)&&!$.json)W(`Using existing agent config at ${B0()} (pass --client-id/--client-secret/--workspace-id to update).`),J()}if(!$.json)W("Checking dependencies..."),J();let H=a$(),Q=[],z=[];for(let O of H){if(O.installed)z.push(O.name);if(!$.json){let F=O.installed?E.success:E.error,D=O.version?K.dim(` (${O.version})`):"",R=O.required?"":K.dim(" [optional]");I(`${F} ${O.name}`,`${O.installed?K.green("installed"):K.red("missing")}${D}${R}`)}if(!O.installed)Q.push(O.name)}if(!$.json)J();if(Q.length===0){if(B($,{ok:!0,installed:z,configured:Z}))return;U("All dependencies are installed.");return}if(q.check){if($.json){B($,{ok:!1,installed:z,missing:Q,configured:Z});return}j(`Missing: ${Q.join(", ")}`),W(`Run ${K.bold("vibe setup")} to install them.`),process.exit(1)}if(!$.json)W(`Installing missing dependencies: ${Q.join(", ")}...`),J();let V=await B1(Q),_=Q.filter((O)=>!V.failed.includes(O));if(V.failed.length>0){if($.json){B($,{ok:!1,installed:[...z,..._],failed:V.failed,configured:Z});return}j(`${V.failed.length} tool(s) failed: ${V.failed.join(", ")}`),W("You may need to install manually or use sudo."),process.exit(1)}else{if(B($,{ok:!0,installed:[...z,..._],configured:Z}))return;U("All dependencies installed successfully.")}}catch(X){let H=X instanceof Error?C(X):String(X);if($.json){B($,{ok:!1,error:H});return}L(`Setup failed: ${H}`)}})}function r2(Y){let q=l();return q.which(Y)??`${Y}${q.executableSuffix}`}function C1(Y){Y.command("update").description("Check for and install VibeControls agent updates").option("--check","Only check for updates without installing",!1).option("--allow-incompatible","Override engines.bun compatibility check (use with care)",!1).option("--no-restart","Skip the post-install idle-aware restart of any running agent").option("-n, --name <name>","Agent profile name to restart after update","default").option("--version-target <version>","Install a specific version instead of the latest (e.g. 2026.601.21)").option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{if(!$.json)T("VibeControls Agent Update"),J(),W(`${E.info} Checking for updates...`),J();let Z=await I1();if(Z.error&&!Z.latest){if(B($,{ok:!1,current:Z.current,error:Z.error}))return;L(Z.error);return}if(!$.json)I("Package",K.bold(Z.name)),I("Registry",K.bold(Z.registry)),I("Current version",K.bold(Z.current)),I("Latest version",K.bold(Z.latest??"unknown")),J();if(q.check){if(B($,{ok:!0,current:Z.current,latest:Z.latest,upToDate:!Z.hasUpdate}))return;if(!Z.hasUpdate)U(`${E.success} You are running the latest version.`);else j(`${E.warning} A new version is available: ${K.green(Z.latest??"")}`),W(`${E.info} Run ${K.bold("vibe update")} to install the update.`);return}let X=q.versionTarget;if(!X&&!Z.hasUpdate){if(B($,{ok:!0,current:Z.current,latest:Z.latest,upToDate:!0}))return;U(`${E.success} You are running the latest version.`);return}if(!$.json)W(`${E.info} Updating to ${K.bold(X??Z.latest??"latest")}...`),J();let H=await _1({targetVersion:X,allowIncompatible:!!q.allowIncompatible,restart:q.restart!==!1,name:q.name,onLog:$.json?void 0:(Q)=>W(`${E.info} ${Q}`)});if(!H.ok){if(B($,{ok:!1,current:H.current,previous:H.previous,latest:H.latest,rolledBack:H.rolledBack,error:H.error}))return;L(H.error??"Update failed.");return}if(!$.json)switch(H.restart){case"restarted":U(`${E.success} Restarted agent ${K.bold(q.name)} on the new version.`);break;case"not-running":W(`${E.info} No running agent for profile ${K.bold(q.name)}; nothing to restart.`);break;case"still-busy":j(`${E.warning} Agent still serving requests \u2014 run ${K.bold("vibe restart")} when it's quiet.`);break;case"error":j(`${E.warning} Auto-restart failed: ${H.restartError}. Run ${K.bold("vibe restart")} manually.`);break}if(B($,{ok:!0,current:H.current,previous:H.previous,latest:H.latest,updated:H.updated,restart:H.restart,...H.restartError?{restartError:H.restartError}:{}}))return;if(J(),H.updated)U(`${E.success} Updated to ${K.bold(H.current)} (smoke: ${H.smoke?.step??"ok"}).`);else U(`${E.success} You are running the latest version.`);if(q.restart===!1)W(`${E.info} --no-restart set \u2014 restart running agents manually for the update to take effect.`)}catch(Z){let X=Z instanceof Error?C(Z):String(Z);if($.json){B($,{ok:!1,error:X});return}L(`Update failed: ${X}`)}}),Y.command("rollback").description("Roll the global agent install back to a specific version").argument("<version>","Target CalVer version (e.g. 2026.428.3)").action(async(q)=>{try{T("VibeControls Agent Rollback");let $=await U1();if(I("Package",K.bold($.name)),I("Current version",K.bold($.version)),I("Target version",K.bold(q)),J(),W(`${E.info} Rolling back\u2026`),Bun.spawnSync([r2("npm"),"install","-g",`${$.name}@${q}`,`--registry=${$.registry}`],{stdout:"inherit",stderr:"inherit"}).exitCode!==0){L("Rollback failed.");return}U(`${E.success} Rolled back to ${K.bold(q)}.`)}catch($){L(`Rollback failed: ${$ instanceof Error?C($):String($)}`)}})}import{existsSync as F$,mkdirSync as e2,writeFileSync as I0,unlinkSync as $6,readFileSync as J0}from"fs";import{join as L$}from"path";import{homedir as M$}from"os";var Y6=/^[A-Za-z0-9][A-Za-z0-9:_-]{0,63}$/,q6=/^--[A-Za-z0-9][A-Za-z0-9-]{0,63}$/;function R1(Y){return Y6.test(Y)?Y:null}function j1(Y){return Y.filter((q)=>R1(q))}function Z6(Y){return Y.filter((q)=>q6.test(q))}function w$(Y){return Y.commands.flatMap((q)=>{let $=R1(q.name());if(!$)return[];return[{name:$,description:q.description()||"",options:q.options.map((Z)=>({flags:Z.flags,description:Z.description||""})),subcommands:w$(q)}]})}function X6(Y){return j1(Y.map((q)=>q.name))}function H6(Y,q){let $=Y.find((X)=>X.name===q);if(!$)return[];let Z=[];for(let X of $.options){let H=X.flags.match(/--([\w-]+)/);if(H)Z.push(`--${H[1]}`)}return Z6(Z)}function E1(Y){let q=X6(Y),Z=Y.filter((H)=>H.subcommands.length>0).map((H)=>({name:H.name,subs:j1(H.subcommands.map((Q)=>Q.name))})).map((H)=>` ${H.name})
4
4
  COMPREPLY=($(compgen -W "${H.subs.join(" ")}" -- "\${cur}"))
5
5
  return 0
@@ -227,5 +227,5 @@ Enter: print this help and exit
227
227
  `);return}if(!Z.plain&&t$()){if(await A3(Y))return}S2(Y,!!Z.plain)}})}var S3="http://localhost:3005",h3=5000;function v3(Y,q,$){let Z=Number.parseInt(Y,10);if(!Number.isInteger(Z)||Z<1)return q;return Math.min(Z,$)}function y2(Y){Y.command("audit").description("View persistent audit log").command("list").description("List recent audit events").option("--since <iso>","Lower-bound ISO 8601 timestamp").option("--limit <n>","Maximum events to show","100").option("--event <pattern>","Filter by event name (supports * glob)").option("--agent-url <url>","Agent URL",S3).option("--json","Emit JSON (one object per line)").option("--plain","Force plain text output").action(async function($){try{let Z={...Y.opts(),...$},X=w(Z),H=encodeURIComponent(A(Z)),Q=new URLSearchParams;if(Q.set("limit",String(v3(String(Z.limit),100,h3))),Z.since)Q.set("since",String(Z.since));if(Z.event)Q.set("event",String(Z.event));let V=(await y(X,`/api/profiles/${H}/agent/audit?${Q.toString()}`)).events??[];if(Z.json){for(let _ of V)process.stdout.write(`${JSON.stringify(_)}
228
228
  `);return}if(V.length===0){W("No audit events found.");return}T("Audit events"),J();for(let _ of V){let O=_.timestamp?K.dim(G$(_.timestamp)):"",F=_.source?K.cyan(`[${_.source}]`):"",D=K.bold(_.event??"?"),R=_.payload?K.dim(JSON.stringify(_.payload)):"";console.log(` ${D} ${F} ${R} ${O}`)}}catch(Z){L(C(Z))}})}function f2(Y){let q=Y.command("alias").description("Manage per-profile aliases");q.command("list").description("List aliases for the current profile").option("--json","Emit JSON").option("--plain","Force plain text output").action(async function($){try{let Z={...Y.opts(),...$},X=w(Z),H=encodeURIComponent(A(Z));await P({mode:f(Z),fetchData:async()=>{return(await y(X,`/api/profiles/${H}/agent/aliases`)).aliases??[]},plain:(Q)=>{if(T("Aliases"),J(),!Q.length){W("No aliases defined.");return}let z=Q.map((V)=>({Name:V.name,Command:V.command.length>60?`${V.command.slice(0,57)}\u2026`:V.command,Description:V.description??"-",Updated:G$(V.updatedAt)}));n(z),J()}})}catch(Z){L(C(Z))}}),q.command("get <name>").description("Show an alias by name").option("--json","Emit JSON").action(async function($,Z){try{let X={...Y.opts(),...Z},H=w(X),Q=encodeURIComponent(A(X)),z=await y(H,`/api/profiles/${Q}/agent/aliases/${encodeURIComponent($)}`);if(X.json){process.stdout.write(`${JSON.stringify(z,null,2)}
229
229
  `);return}T(`Alias: ${z.name}`),J(),console.log(` ${K.bold("Command: ")} ${z.command}`),console.log(` ${K.bold("Description:")} ${z.description??"-"}`),console.log(` ${K.bold("Cwd: ")} ${z.cwd??"$HOME (default)"}`),console.log(` ${K.bold("Profile: ")} ${z.profile}`),console.log(` ${K.bold("Created: ")} ${z.createdAt}`),console.log(` ${K.bold("Updated: ")} ${z.updatedAt}`),J()}catch(X){L(C(X))}}),q.command("create <name>").description("Create a new alias").requiredOption("--command <cmd>","The shell command to run").option("--description <text>","Optional description").option("--cwd <dir>","Working directory the command runs in (supports ~, absolute, or relative-to-$HOME). Defaults to $HOME.").action(async function($,Z){try{let X={...Y.opts(),...Z},H=w(X),Q=encodeURIComponent(A(X)),z=await m(H,`/api/profiles/${Q}/agent/aliases`,{name:$,command:Z.command,description:Z.description,cwd:Z.cwd});U(`Created alias '${z.name}'`)}catch(X){L(C(X))}}),q.command("update <name>").description("Update an existing alias").option("--command <cmd>","Replacement shell command").option("--description <text>","Replacement description").option("--cwd <dir>","Replacement working directory. Pass an empty string to reset to $HOME.").action(async function($,Z){try{if(Z.command===void 0&&Z.description===void 0&&Z.cwd===void 0){L("Provide --command, --description, or --cwd to update.");return}let X={...Y.opts(),...Z},H=w(X),Q=encodeURIComponent(A(X)),z=await L0(H,`/api/profiles/${Q}/agent/aliases/${encodeURIComponent($)}`,{command:Z.command,description:Z.description,cwd:Z.cwd});U(`Updated alias '${z.name}'`)}catch(X){L(C(X))}}),q.command("delete <name>").description("Delete an alias").action(async function($,Z){try{let X={...Y.opts(),...Z},H=w(X),Q=encodeURIComponent(A(X));await P$(H,`/api/profiles/${Q}/agent/aliases/${encodeURIComponent($)}`),U(`Deleted alias '${$}'`)}catch(X){L(C(X))}})}function k2(Y){Y.command("run <name> [args...]").description("Run a stored alias by name").allowUnknownOption(!0).action(async function(q,$=[],Z){try{let X={...Y.opts(),...Z},H=w(X),Q=encodeURIComponent(A(X)),z;try{z=await y(H,`/api/profiles/${Q}/agent/aliases/${encodeURIComponent(q)}`)}catch{console.error(`alias '${q}' not found`),c0().audit.emit("agent","alias.executed",{exit_code:1}),process.exit(1)}let{exitCode:V}=await b2(z,$);c0().audit.emit("agent","alias.executed",{exit_code:V}),P2("alias.executed",{exit_code:V}),process.exit(V)}catch(X){L(C(X))}})}function u2(Y){Y.command("retry-config").description("Force the background finalize-retry worker to attempt finalize immediately. Use when the gateway came back online and you don't want to wait the current backoff.").option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{let Z=w($),X=await fetch(`${Z}/api/agent/retry-config`,{method:"POST"}),H;try{H=await X.json()}catch{if($.json)B($,{ok:!1,error:`agent returned non-JSON (HTTP ${X.status})`}),process.exit(1);L(`Agent returned non-JSON response (HTTP ${X.status}). The daemon may be on an older build without /api/agent/retry-config.`),process.exit(1);return}if($.json){if(B($,H),H.state!=="ready")process.exit(H.ok?0:3);return}if(X.status===409){T("Retry not available"),W(H.error??"No active finalize-retry worker."),process.exit(2);return}if(T("Force finalize retry"),I("Result",H.ok?K.green("ok"):K.red("failed")),H.state)I("Boot state",H.state);if(H.worker){if(I("Attempt",String(H.worker.attempt)),H.worker.nextAttemptAt)I("Next attempt",H.worker.nextAttemptAt)}if(J(),H.ok&&H.state==="ready")W(`${K.green("\u2713")} Agent finalized \u2014 state=ready.`),process.exit(0);else if(H.ok)W(`${K.yellow("\u26A0")} Attempt completed but agent is still in '${H.state}'. The worker will continue to retry in the background; check ${K.bold("vibe status")} for progress.`),process.exit(0);else j(`Retry failed: ${H.error??"unknown error"}. The worker will keep retrying on the configured backoff. View the full trace with ${K.bold("vibe logs --since 10m")}.`),process.exit(3)}catch(Z){let X=Z instanceof Error?C(Z):String(Z);if($.json){B($,{ok:!1,error:X}),process.exit(1);return}L(`Failed to reach agent: ${X}`),process.exit(1)}})}var t="http://localhost:3005";function y3(Y){return(Y||[]).map((q)=>({id:q.id??null,name:q.name??null,status:q.status??null,port:q.port??null,project:q.project??q.projectId??null}))}async function c2(Y,q,$,Z,X){await P({mode:f(X),fetchData:async()=>{return(await y(Y,q)).sessions||[]},plain:(H)=>{if(!H||H.length===0){W(Z);return}T($),n(H.map((Q)=>({ID:W$(Q.id||""),Name:Q.name||"-",Status:x$(Q.status||""),Port:Q.port??"-",Project:Q.project||Q.projectId||"-"})))},interactive:async(H)=>{if(!H||H.length===0){T($),W(Z);return}let Q=H.map((z)=>({id:String(z.id??""),label:z.name||W$(z.id||""),hint:z.status||"",detail:[`ID: ${z.id??"-"}`,`Name: ${z.name??"-"}`,`Status: ${x$(z.status||"")}`,`Port: ${z.port??"-"}`,`Project: ${z.project??z.projectId??"-"}`].join(`
230
- `)}));await r({title:`${$} \u2014 ${H.length} session(s)`,rows:Q})},json:(H)=>y3(H)})}function d2(Y){let q=Y.command("session").description("Manage terminal sessions");q.command("system").description("List system sessions (alias for `session list --system`)").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));await c2(X,`/api/profiles/${H}/sessions/system`,"System Sessions","No system sessions found.",Z)}catch(X){L(C(X))}}),q.command("list").description("List all sessions").option("--system","Show system sessions instead of user sessions").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=$.system?`/api/profiles/${H}/sessions/system`:`/api/profiles/${H}/sessions`;await c2(X,Q,"Sessions","No sessions found.",Z)}catch(X){L(C(X))}}),q.command("create").description("Create a new session").requiredOption("--name <name>","Session name").option("--project <id>","Project ID","default").option("--command <cmd>","Initial command to run").option("--cwd <dir>","Working directory").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q={sessionName:$.name,projectId:$.project};if($.command)Q.command=$.command;if($.cwd)Q.startDirectory=$.cwd;let z=await m(X,`/api/profiles/${H}/sessions/create`,Q),V=z?.session?.id||z?.id||z?.sessionId;if(B(Z,{ok:!0,id:V,name:$.name,project:$.project}))return;U(`Session created: ${W$(V)}`),I("Name",$.name),I("Project",$.project)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("kill").description("Kill a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await P$(X,`/api/profiles/${H}/sessions/${$.id}`),B(Z,{ok:!0,id:$.id}))return;U(`Session ${W$($.id)} killed.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("exec").description("Execute a command in a session").requiredOption("-i, --id <id>","Session ID").requiredOption("-c, --command <cmd>","Command to execute").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await m(X,`/api/profiles/${H}/sessions/${$.id}/command`,{command:$.command});if(B(Z,{ok:!0,id:$.id,output:Q?.output??null}))return;if(U("Command executed."),Q?.output)J(),console.log(Q.output)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("capture").description("Capture session terminal output").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));await P({mode:f(Z),fetchData:()=>y(X,`/api/profiles/${H}/sessions/${$.id}/capture`),plain:(Q)=>{if(Q?.content||Q?.output)console.log(Q.content||Q.output);else W("No capture data available.")},json:(Q)=>({id:$.id,content:Q?.content??Q?.output??null})})}catch(X){L(C(X))}}),q.command("keys").description("Send keys to a session").requiredOption("-i, --id <id>","Session ID").requiredOption("-k, --keys <keys>","Keys to send").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await m(X,`/api/profiles/${H}/sessions/${$.id}/keys`,{keys:$.keys}),B(Z,{ok:!0,id:$.id}))return;U("Keys sent.")}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("interrupt").description("Send interrupt signal to a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await m(X,`/api/profiles/${H}/sessions/${$.id}/interrupt`,{}),B(Z,{ok:!0,id:$.id}))return;U(`Session ${W$($.id)} interrupted.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("rename").description("Rename a session").requiredOption("-i, --id <id>","Session ID").requiredOption("--name <name>","New session name").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await L0(X,`/api/profiles/${H}/sessions/${$.id}/rename`,{newName:$.name}),B(Z,{ok:!0,id:$.id,name:$.name}))return;U(`Session ${W$($.id)} renamed to "${$.name}".`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("toggle-mouse").description("Toggle mouse support in a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await m(X,`/api/profiles/${H}/sessions/${$.id}/toggle-mouse`,{});if(B(Z,{ok:!0,id:$.id,mouseEnabled:!!Q?.mouseEnabled}))return;U(`Mouse support ${Q?.mouseEnabled?"enabled":"toggled"} for session ${W$($.id)}.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("terminal-start").description("Start terminal for a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await m(X,`/api/profiles/${H}/sessions/${$.id}/terminal`,{});if(B(Z,{ok:!0,id:$.id,port:Q?.port??null}))return;if(U(`Terminal started for session ${W$($.id)}.`),Q?.port)I("Port",Q.port)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("terminal-stop").description("Stop terminal for a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await m(X,`/api/profiles/${H}/sessions/${$.id}/terminal/stop`,{}),B(Z,{ok:!0,id:$.id}))return;U(`Terminal stopped for session ${W$($.id)}.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("health-check").description("Run health check on all sessions").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await y(X,`/api/profiles/${H}/sessions`),z=await m(X,`/api/profiles/${H}/sessions/health-check`,{sessionIds:(Q.sessions||[]).map((V)=>V.id)});if(B(Z,{ok:!0,healthy:z?.healthy??null,checked:z?.checked??null,fixed:z?.fixed??null}))return;if(U("Health check completed."),z?.healthy!==void 0)I("Healthy",z.healthy);if(z?.checked!==void 0)I("Checked",z.checked);if(z?.fixed!==void 0)I("Fixed",z.fixed)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}})}function m2(Y){Y.command("reuse-db").description("Point this agent at an EXISTING database (reuse data from another same-workspace agent)").option("--adapter <name>","Storage adapter to use (e.g. postgres, skalex). Defaults to the configured/default adapter.").option("--connection-string <conn>","Connection string for the adapter (e.g. postgres://user:pass@host/db)").option("--storage-options <json>","Raw adapter options as a JSON object (alternative/in addition to --connection-string)").option("--db-path <path>","Data directory the adapter should use (e.g. an existing Skalex agent-db dir)").option("-y, --yes","Skip the confirmation prompt").option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{let Z={};if(q.storageOptions){let Q;try{Q=JSON.parse(q.storageOptions)}catch{L("--storage-options must be valid JSON.");return}if(!Q||typeof Q!=="object"||Array.isArray(Q)){L("--storage-options must be a JSON object.");return}for(let[z,V]of Object.entries(Q))Z[z]=typeof V==="string"?V:JSON.stringify(V)}if(q.connectionString)Z.connectionString=String(q.connectionString);if(!q.adapter&&!q.dbPath&&Object.keys(Z).length===0){L("Nothing to set. Provide --adapter with --connection-string (or --storage-options), and/or --db-path.");return}if(!$.json){if(T("Reuse an existing database"),q.adapter)I("Adapter",K.bold(q.adapter));if(q.dbPath)I("Data path",K.bold(q.dbPath));if(Object.keys(Z).length>0)I("Options",K.dim(Object.keys(Z).join(", ")));J(),j(`${E.warning} Reuse is safe ONLY for a database from the SAME workspace \u2014 the encryption key is per-workspace, so a foreign DB won't decrypt (the agent will go degraded).`),j(`${E.warning} Two agents writing the same database concurrently can corrupt it. Keep this a single-writer setup unless your adapter is explicitly configured for shared writes.`),J()}if(!q.yes&&!$.json){if(!await T$(K.bold("Write this storage configuration to the agent config?"))){W("Cancelled.");return}}let X={};if(q.adapter)X.storageAdapter=String(q.adapter);if(Object.keys(Z).length>0)X.storageOptions=Z;if(q.dbPath)X.dbPath=String(q.dbPath);U$(X);let H=Y$();if(B($,{ok:!0,storageAdapter:H.storageAdapter??null,dbPath:H.dbPath??null,storageOptionKeys:Object.keys(H.storageOptions??{})}))return;U(`${E.success} Storage configuration written. Run ${K.bold("vibe restart")} so the agent connects to the existing database.`)}catch(Z){let X=Z instanceof Error?C(Z):String(Z);if($.json){B($,{ok:!1,error:X});return}L(`reuse-db failed: ${X}`)}})}function d0(Y){return new Set([...r$(Y)??$0()])}function m0(Y){return o$(process.platform,new Set(Y)).map((q)=>q.packageName)}async function g0(){let{PluginManager:Y}=await import("./plugin-system-cwznxqx5.js"),q=new Y;return{install:($)=>q.install($),remove:($)=>q.remove($)}}function l2(Y){let q=Y.command("capability").alias("cap").description("Select agent capabilities (abilities) + providers");q.command("list",{isDefault:!0}).description("List capabilities and whether each is enabled").option("--json","Emit JSON").action(($)=>{let Z={...Y.opts(),...$},X=Z$(),H=d0(X),Q=c$(X);if(B(Z,{abilities:k$.map((z)=>({key:z.key,label:z.label,mandatory:z.mandatory,enabled:z.mandatory||H.has(z.key)})),providers:Q}))return;if(T("Capabilities"),n(k$.map((z)=>({Key:z.key,Capability:z.label,Status:z.mandatory?"required":H.has(z.key)?"enabled":"disabled",Description:z.description}))),Q.length>0){J(),T("Extra providers");for(let z of Q)I("\u2022",z)}J(),W("Enable: vibe capability enable <key...> [--provider <pkg...>]"),W("Disable: vibe capability disable <key...>"),W("Re-run the interactive selector: vibe capability select")}),q.command("enable").description("Enable capabilities (installs their meta plugin) and/or extra providers").argument("[keys...]","Ability keys (e.g. gitops security)").option("--provider <pkg...>","Extra provider plugin(s) to install (short name or @vibecontrols/...)").option("--json","Emit JSON").action(async($,Z)=>{try{let X={...Y.opts(),...Z},H=Z$(),Q=new Set(k$.map((x)=>x.key)),z=($??[]).map((x)=>x.trim().toLowerCase()).filter((x)=>Q.has(x));for(let x of($??[]).filter((M)=>!Q.has(M.trim().toLowerCase())))j(`Unknown capability "${x}" \u2014 see \`vibe capability list\`.`);let _=(Array.isArray(Z.provider)?Z.provider:Z.provider?[Z.provider]:[]).map((x)=>g2(x)).filter((x)=>Boolean(x));if(z.length===0&&_.length===0){L("Provide at least one capability key or --provider <pkg>.");return}let O=d0(H);for(let x of z)O.add(x);let F=[...new Set([...m0(z),..._])],D=await g0(),R=[];for(let x of F)try{await D.install(x),R.push({package:x,ok:!0})}catch(M){R.push({package:x,ok:!1,error:C(M)})}let G=[...new Set([...c$(H),..._])];if(D$(H,{abilities:O,providers:G}),B(X,{ok:!0,action:"enable",abilities:[...O],providers:G,installed:R}))return;for(let x of R)if(x.ok)U(`Installed ${x.package}`);else j(`Failed to install ${x.package}: ${x.error}`);U("Capabilities updated. Restart the agent to load: vibe restart")}catch(X){L(C(X))}}),q.command("disable").description("Disable capabilities (removes their meta plugin)").argument("<keys...>","Ability keys").option("--json","Emit JSON").action(async($,Z)=>{try{let X={...Y.opts(),...Z},H=Z$(),Q=new Set(k$.map((R)=>R.key)),z=new Set(k$.filter((R)=>R.mandatory).map((R)=>R.key)),V=($??[]).map((R)=>R.trim().toLowerCase()).filter((R)=>Q.has(R));for(let R of V.filter((G)=>z.has(G)))j(`"${R}" is required and cannot be disabled.`);let _=V.filter((R)=>!z.has(R));if(_.length===0){L("Nothing to disable.");return}let O=d0(H);for(let R of _)O.delete(R);let F=await g0(),D=[];for(let R of m0(_))try{await F.remove(R),D.push({package:R,ok:!0})}catch(G){D.push({package:R,ok:!1,error:C(G)})}if(D$(H,{abilities:O}),B(X,{ok:!0,action:"disable",abilities:[...O],removed:D}))return;for(let R of D)if(R.ok)U(`Removed ${R.package}`);else j(`Failed to remove ${R.package}: ${R.error}`);U("Capabilities updated. Restart the agent to apply: vibe restart")}catch(X){L(C(X))}}),q.command("select").description("Re-run the interactive capability selector and apply it").option("--json","Emit JSON").action(async($)=>{try{let Z={...Y.opts(),...$},X=Z$(),H=await e$(),Q=await g0();for(let z of m0(H))try{await Q.install(z)}catch{}if(D$(X,{abilities:H}),B(Z,{ok:!0,action:"select",abilities:[...H]}))return;U(`Selection saved (${[...H].join(", ")||"none"}). Restart to apply: vibe restart`)}catch(Z){L(C(Z))}})}function _q(Y){Y1(Y),q1(Y),Z1(Y),W1(Y),K1(Y),L1(Y),J1(Y),C1(Y),A1(Y),h1(Y),b1(Y),m1(Y),l1(Y),Y2(Y),H2(Y),Q2(Y),V2(Y),O2(Y),C2(Y),D2(Y),x2(Y),A2(Y),v2(Y),y2(Y),f2(Y),k2(Y),u2(Y),d2(Y),m2(Y),l2(Y)}
230
+ `)}));await r({title:`${$} \u2014 ${H.length} session(s)`,rows:Q})},json:(H)=>y3(H)})}function d2(Y){let q=Y.command("session").description("Manage terminal sessions");q.command("system").description("List system sessions (alias for `session list --system`)").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));await c2(X,`/api/profiles/${H}/sessions/system`,"System Sessions","No system sessions found.",Z)}catch(X){L(C(X))}}),q.command("list").description("List all sessions").option("--system","Show system sessions instead of user sessions").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=$.system?`/api/profiles/${H}/sessions/system`:`/api/profiles/${H}/sessions`;await c2(X,Q,"Sessions","No sessions found.",Z)}catch(X){L(C(X))}}),q.command("create").description("Create a new session").requiredOption("--name <name>","Session name").option("--project <id>","Project ID","default").option("--command <cmd>","Initial command to run").option("--cwd <dir>","Working directory").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q={sessionName:$.name,projectId:$.project};if($.command)Q.command=$.command;if($.cwd)Q.startDirectory=$.cwd;let z=await m(X,`/api/profiles/${H}/sessions/create`,Q),V=z?.session?.id||z?.id||z?.sessionId;if(B(Z,{ok:!0,id:V,name:$.name,project:$.project}))return;U(`Session created: ${W$(V)}`),I("Name",$.name),I("Project",$.project)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("kill").description("Kill a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await P$(X,`/api/profiles/${H}/sessions/${$.id}`),B(Z,{ok:!0,id:$.id}))return;U(`Session ${W$($.id)} killed.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("exec").description("Execute a command in a session").requiredOption("-i, --id <id>","Session ID").requiredOption("-c, --command <cmd>","Command to execute").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await m(X,`/api/profiles/${H}/sessions/${$.id}/command`,{command:$.command});if(B(Z,{ok:!0,id:$.id,output:Q?.output??null}))return;if(U("Command executed."),Q?.output)J(),console.log(Q.output)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("capture").description("Capture session terminal output").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));await P({mode:f(Z),fetchData:()=>y(X,`/api/profiles/${H}/sessions/${$.id}/capture`),plain:(Q)=>{if(Q?.content||Q?.output)console.log(Q.content||Q.output);else W("No capture data available.")},json:(Q)=>({id:$.id,content:Q?.content??Q?.output??null})})}catch(X){L(C(X))}}),q.command("keys").description("Send keys to a session").requiredOption("-i, --id <id>","Session ID").requiredOption("-k, --keys <keys>","Keys to send").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await m(X,`/api/profiles/${H}/sessions/${$.id}/keys`,{keys:$.keys}),B(Z,{ok:!0,id:$.id}))return;U("Keys sent.")}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("interrupt").description("Send interrupt signal to a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await m(X,`/api/profiles/${H}/sessions/${$.id}/interrupt`,{}),B(Z,{ok:!0,id:$.id}))return;U(`Session ${W$($.id)} interrupted.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("rename").description("Rename a session").requiredOption("-i, --id <id>","Session ID").requiredOption("--name <name>","New session name").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await L0(X,`/api/profiles/${H}/sessions/${$.id}/rename`,{newName:$.name}),B(Z,{ok:!0,id:$.id,name:$.name}))return;U(`Session ${W$($.id)} renamed to "${$.name}".`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("toggle-mouse").description("Toggle mouse support in a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await m(X,`/api/profiles/${H}/sessions/${$.id}/toggle-mouse`,{});if(B(Z,{ok:!0,id:$.id,mouseEnabled:!!Q?.mouseEnabled}))return;U(`Mouse support ${Q?.mouseEnabled?"enabled":"toggled"} for session ${W$($.id)}.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("terminal-start").description("Start terminal for a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await m(X,`/api/profiles/${H}/sessions/${$.id}/terminal`,{});if(B(Z,{ok:!0,id:$.id,port:Q?.port??null}))return;if(U(`Terminal started for session ${W$($.id)}.`),Q?.port)I("Port",Q.port)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("terminal-stop").description("Stop terminal for a session").requiredOption("-i, --id <id>","Session ID").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z));if(await m(X,`/api/profiles/${H}/sessions/${$.id}/terminal/stop`,{}),B(Z,{ok:!0,id:$.id}))return;U(`Terminal stopped for session ${W$($.id)}.`)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}}),q.command("health-check").description("Run health check on all sessions").option("--agent-url <url>","Agent URL",t).option("--json","Emit JSON").action(async function($){let Z={...Y.opts(),...$};try{let X=w($),H=encodeURIComponent(A(Z)),Q=await y(X,`/api/profiles/${H}/sessions`),z=await m(X,`/api/profiles/${H}/sessions/health-check`,{sessionIds:(Q.sessions||[]).map((V)=>V.id)});if(B(Z,{ok:!0,healthy:z?.healthy??null,checked:z?.checked??null,fixed:z?.fixed??null}))return;if(U("Health check completed."),z?.healthy!==void 0)I("Healthy",z.healthy);if(z?.checked!==void 0)I("Checked",z.checked);if(z?.fixed!==void 0)I("Fixed",z.fixed)}catch(X){if(Z.json){B(Z,{ok:!1,error:C(X)});return}L(C(X))}})}function m2(Y){Y.command("reuse-db").description("Point this agent at an EXISTING database (reuse data from another same-workspace agent)").option("--adapter <name>","Storage adapter to use (e.g. postgres, skalex). Defaults to the configured/default adapter.").option("--connection-string <conn>","Connection string for the adapter (e.g. postgres://user:pass@host/db)").option("--storage-options <json>","Raw adapter options as a JSON object (alternative/in addition to --connection-string)").option("--db-path <path>","Data directory the adapter should use (e.g. an existing Skalex agent-db dir)").option("-y, --yes","Skip the confirmation prompt").option("--json","Emit JSON").action(async function(q){let $={...Y.opts(),...q};try{let Z={};if(q.storageOptions){let Q;try{Q=JSON.parse(q.storageOptions)}catch{L("--storage-options must be valid JSON.");return}if(!Q||typeof Q!=="object"||Array.isArray(Q)){L("--storage-options must be a JSON object.");return}for(let[z,V]of Object.entries(Q))Z[z]=typeof V==="string"?V:JSON.stringify(V)}if(q.connectionString)Z.connectionString=String(q.connectionString);if(!q.adapter&&!q.dbPath&&Object.keys(Z).length===0){L("Nothing to set. Provide --adapter with --connection-string (or --storage-options), and/or --db-path.");return}if(!$.json){if(T("Reuse an existing database"),q.adapter)I("Adapter",K.bold(q.adapter));if(q.dbPath)I("Data path",K.bold(q.dbPath));if(Object.keys(Z).length>0)I("Options",K.dim(Object.keys(Z).join(", ")));J(),j(`${E.warning} Reuse is safe ONLY for a database from the SAME workspace \u2014 the encryption key is per-workspace, so a foreign DB won't decrypt (the agent will go degraded).`),j(`${E.warning} Two agents writing the same database concurrently can corrupt it. Keep this a single-writer setup unless your adapter is explicitly configured for shared writes.`),J()}if(!q.yes&&!$.json){if(!await T$(K.bold("Write this storage configuration to the agent config?"))){W("Cancelled.");return}}let X={};if(q.adapter)X.storageAdapter=String(q.adapter);if(Object.keys(Z).length>0)X.storageOptions=Z;if(q.dbPath)X.dbPath=String(q.dbPath);U$(X);let H=Y$();if(B($,{ok:!0,storageAdapter:H.storageAdapter??null,dbPath:H.dbPath??null,storageOptionKeys:Object.keys(H.storageOptions??{})}))return;U(`${E.success} Storage configuration written. Run ${K.bold("vibe restart")} so the agent connects to the existing database.`)}catch(Z){let X=Z instanceof Error?C(Z):String(Z);if($.json){B($,{ok:!1,error:X});return}L(`reuse-db failed: ${X}`)}})}function d0(Y){return new Set([...r$(Y)??$0()])}function m0(Y){return o$(process.platform,new Set(Y)).map((q)=>q.packageName)}async function g0(){let{PluginManager:Y}=await import("./plugin-system-kaj4069d.js"),q=new Y;return{install:($)=>q.install($),remove:($)=>q.remove($)}}function l2(Y){let q=Y.command("capability").alias("cap").description("Select agent capabilities (abilities) + providers");q.command("list",{isDefault:!0}).description("List capabilities and whether each is enabled").option("--json","Emit JSON").action(($)=>{let Z={...Y.opts(),...$},X=Z$(),H=d0(X),Q=c$(X);if(B(Z,{abilities:k$.map((z)=>({key:z.key,label:z.label,mandatory:z.mandatory,enabled:z.mandatory||H.has(z.key)})),providers:Q}))return;if(T("Capabilities"),n(k$.map((z)=>({Key:z.key,Capability:z.label,Status:z.mandatory?"required":H.has(z.key)?"enabled":"disabled",Description:z.description}))),Q.length>0){J(),T("Extra providers");for(let z of Q)I("\u2022",z)}J(),W("Enable: vibe capability enable <key...> [--provider <pkg...>]"),W("Disable: vibe capability disable <key...>"),W("Re-run the interactive selector: vibe capability select")}),q.command("enable").description("Enable capabilities (installs their meta plugin) and/or extra providers").argument("[keys...]","Ability keys (e.g. gitops security)").option("--provider <pkg...>","Extra provider plugin(s) to install (short name or @vibecontrols/...)").option("--json","Emit JSON").action(async($,Z)=>{try{let X={...Y.opts(),...Z},H=Z$(),Q=new Set(k$.map((x)=>x.key)),z=($??[]).map((x)=>x.trim().toLowerCase()).filter((x)=>Q.has(x));for(let x of($??[]).filter((M)=>!Q.has(M.trim().toLowerCase())))j(`Unknown capability "${x}" \u2014 see \`vibe capability list\`.`);let _=(Array.isArray(Z.provider)?Z.provider:Z.provider?[Z.provider]:[]).map((x)=>g2(x)).filter((x)=>Boolean(x));if(z.length===0&&_.length===0){L("Provide at least one capability key or --provider <pkg>.");return}let O=d0(H);for(let x of z)O.add(x);let F=[...new Set([...m0(z),..._])],D=await g0(),R=[];for(let x of F)try{await D.install(x),R.push({package:x,ok:!0})}catch(M){R.push({package:x,ok:!1,error:C(M)})}let G=[...new Set([...c$(H),..._])];if(D$(H,{abilities:O,providers:G}),B(X,{ok:!0,action:"enable",abilities:[...O],providers:G,installed:R}))return;for(let x of R)if(x.ok)U(`Installed ${x.package}`);else j(`Failed to install ${x.package}: ${x.error}`);U("Capabilities updated. Restart the agent to load: vibe restart")}catch(X){L(C(X))}}),q.command("disable").description("Disable capabilities (removes their meta plugin)").argument("<keys...>","Ability keys").option("--json","Emit JSON").action(async($,Z)=>{try{let X={...Y.opts(),...Z},H=Z$(),Q=new Set(k$.map((R)=>R.key)),z=new Set(k$.filter((R)=>R.mandatory).map((R)=>R.key)),V=($??[]).map((R)=>R.trim().toLowerCase()).filter((R)=>Q.has(R));for(let R of V.filter((G)=>z.has(G)))j(`"${R}" is required and cannot be disabled.`);let _=V.filter((R)=>!z.has(R));if(_.length===0){L("Nothing to disable.");return}let O=d0(H);for(let R of _)O.delete(R);let F=await g0(),D=[];for(let R of m0(_))try{await F.remove(R),D.push({package:R,ok:!0})}catch(G){D.push({package:R,ok:!1,error:C(G)})}if(D$(H,{abilities:O}),B(X,{ok:!0,action:"disable",abilities:[...O],removed:D}))return;for(let R of D)if(R.ok)U(`Removed ${R.package}`);else j(`Failed to remove ${R.package}: ${R.error}`);U("Capabilities updated. Restart the agent to apply: vibe restart")}catch(X){L(C(X))}}),q.command("select").description("Re-run the interactive capability selector and apply it").option("--json","Emit JSON").action(async($)=>{try{let Z={...Y.opts(),...$},X=Z$(),H=await e$(),Q=await g0();for(let z of m0(H))try{await Q.install(z)}catch{}if(D$(X,{abilities:H}),B(Z,{ok:!0,action:"select",abilities:[...H]}))return;U(`Selection saved (${[...H].join(", ")||"none"}). Restart to apply: vibe restart`)}catch(Z){L(C(Z))}})}function _q(Y){Y1(Y),q1(Y),Z1(Y),W1(Y),K1(Y),L1(Y),J1(Y),C1(Y),A1(Y),h1(Y),b1(Y),m1(Y),l1(Y),Y2(Y),H2(Y),Q2(Y),V2(Y),O2(Y),C2(Y),D2(Y),x2(Y),A2(Y),v2(Y),y2(Y),f2(Y),k2(Y),u2(Y),d2(Y),m2(Y),l2(Y)}
231
231
  export{M3 as I,_q as J};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{va as D}from"./index-nmk7cbj5.js";import{Fa as U,Ha as M,Pa as R}from"./index-s2xpdnsj.js";import{Xa as I}from"./index-0ckffygp.js";import{Mc as b}from"./index-b6x6a4xp.js";import{Id as x,Od as u}from"./index-js1xn4sq.js";import{$d as V,de as C}from"./index-a4854mwz.js";import{ie as L}from"./index-c7554sg7.js";import{existsSync as g,readFileSync as E,unlinkSync as Wz,writeFileSync as A}from"fs";import{join as c}from"path";var l=".consent.json";function Oz(z){try{let J=E(q(z),"utf8"),G=JSON.parse(J);if(Array.isArray(G.abilities)&&G.abilities.length>0)return new Set(G.abilities)}catch{}return null}function Uz(z){try{let J=E(q(z),"utf8"),G=JSON.parse(J);if(Array.isArray(G.providers))return G.providers.filter((X)=>typeof X==="string")}catch{}return[]}function _z(z){let J=new Set;for(let G of z.split(",").map((X)=>X.trim()).filter(Boolean)){let X=R(G);if(X)J.add(X)}return[...J]}function q(z){return c(z,l)}function Nz(z,J){let G=J??new Set(U.filter((Q)=>Q.defaultSelected||Q.mandatory).map((Q)=>Q.key)),X=z.skipPluginInstall?[]:M(process.platform,G).filter((Q)=>!z.skipPlugins.includes(Q.packageName)&&!z.skipPlugins.includes(Q.pluginName)).map((Q)=>({packageName:Q.packageName,pluginName:Q.pluginName,reason:Q.description}));return{tools:[],plugins:X}}async function Fz(){let z=new Set(U.filter((G)=>G.defaultSelected||G.mandatory).map((G)=>G.key));for(let G of U)if(G.mandatory)z.add(G.key);if(!(Boolean(process.stdin.isTTY)&&process.env.VIBE_AUTO_ACCEPT!=="1"))return z;try{let{interactiveCheckboxes:G}=await import("./interactive-qc1j66mq.js"),X=await G("Select the agent abilities to install",U.map((Q)=>({key:Q.key,label:Q.label,description:Q.description,mandatory:Q.mandatory})),z);if(X){for(let Q of U)if(Q.mandatory)X.add(Q.key);return X}return z}catch(G){process.stdout.write(`
2
+ import{va as D}from"./index-vaxcmbdg.js";import{Fa as U,Ha as M,Pa as R}from"./index-9006n9tq.js";import{Xa as I}from"./index-0ckffygp.js";import{Mc as b}from"./index-b6x6a4xp.js";import{Id as x,Od as u}from"./index-js1xn4sq.js";import{$d as V,de as C}from"./index-a4854mwz.js";import{ie as L}from"./index-c7554sg7.js";import{existsSync as g,readFileSync as E,unlinkSync as Wz,writeFileSync as A}from"fs";import{join as c}from"path";var l=".consent.json";function Oz(z){try{let J=E(q(z),"utf8"),G=JSON.parse(J);if(Array.isArray(G.abilities)&&G.abilities.length>0)return new Set(G.abilities)}catch{}return null}function Uz(z){try{let J=E(q(z),"utf8"),G=JSON.parse(J);if(Array.isArray(G.providers))return G.providers.filter((X)=>typeof X==="string")}catch{}return[]}function _z(z){let J=new Set;for(let G of z.split(",").map((X)=>X.trim()).filter(Boolean)){let X=R(G);if(X)J.add(X)}return[...J]}function q(z){return c(z,l)}function Nz(z,J){let G=J??new Set(U.filter((Q)=>Q.defaultSelected||Q.mandatory).map((Q)=>Q.key)),X=z.skipPluginInstall?[]:M(process.platform,G).filter((Q)=>!z.skipPlugins.includes(Q.packageName)&&!z.skipPlugins.includes(Q.pluginName)).map((Q)=>({packageName:Q.packageName,pluginName:Q.pluginName,reason:Q.description}));return{tools:[],plugins:X}}async function Fz(){let z=new Set(U.filter((G)=>G.defaultSelected||G.mandatory).map((G)=>G.key));for(let G of U)if(G.mandatory)z.add(G.key);if(!(Boolean(process.stdin.isTTY)&&process.env.VIBE_AUTO_ACCEPT!=="1"))return z;try{let{interactiveCheckboxes:G}=await import("./interactive-qc1j66mq.js"),X=await G("Select the agent abilities to install",U.map((Q)=>({key:Q.key,label:Q.label,description:Q.description,mandatory:Q.mandatory})),z);if(X){for(let Q of U)if(Q.mandatory)X.add(Q.key);return X}return z}catch(G){process.stdout.write(`
3
3
  [vibe] Falling back to plain prompt \u2014 ${G instanceof Error?G.message:String(G)}
4
4
 
5
5
  `);let X=await d("Select the agent abilities to install",U.map((Q)=>({key:Q.key,label:Q.label,description:Q.description,mandatory:Q.mandatory})),z);if(X){for(let Q of U)if(Q.mandatory)X.add(Q.key);return X}return z}}async function d(z,J,G){let X=new Set(G);for(let Y of J)if(Y.mandatory)X.add(Y.key);let Q=()=>{process.stdout.write(`
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{Da as D}from"./index-s2xpdnsj.js";import{Xa as V}from"./index-0ckffygp.js";import{$d as A,Sd as _,Td as w,Ud as x,Vd as N,Wd as j,Zd as X,ce as I}from"./index-a4854mwz.js";import{ie as S}from"./index-c7554sg7.js";import{existsSync as $,readdirSync as v,readFileSync as O,writeFileSync as M,mkdirSync as E,openSync as T,closeSync as b,unlinkSync as R}from"fs";import{join as Q}from"path";import{tmpdir as F}from"os";import{spawn as h}from"child_process";class P{registryPath;logsDir;productDir;constructor(){let q=I();this.productDir=q,this.registryPath=Q(q,"agents.json");let z=A();this.logsDir=Q(z,"logs"),E(q,{recursive:!0}),E(z,{recursive:!0}),E(this.logsDir,{recursive:!0})}async startDaemon(q){return X(q.name),this.withInstanceLock(q.name,async()=>{let z=await this.findProcessByName(q.name);if(z&&z.status==="running"){let U=z.version,W=D();if(U===W){console.log(`\u26A0\uFE0F Agent '${q.name}' is already running on port ${z.port}`);return}console.log(`\uD83D\uDD04 Agent '${q.name}' is running an older build (${U??"unknown"} \u2192 ${W}) \u2014 restarting to apply the update`);try{await this.stopInternal(q.name)}catch(Z){console.log(`\u26A0\uFE0F Could not cleanly stop the stale daemon (${Z instanceof Error?Z.message:String(Z)}); proceeding to start the new build`)}}let B=Q(this.logsDir,`${q.name}.log`),C=T(B,"a"),H=Q(import.meta.dir,"index.js"),G=Q(import.meta.dir,"..","index.ts"),L=$(H)?H:G,K=h(process.execPath,["run",L],{detached:!0,windowsHide:!0,stdio:["ignore",C,C],env:{...process.env,VIBECONTROLS_PROFILE:q.profile||"default",PORT:q.port.toString(),DB_PATH:q.dbPath,NODE_ENV:"production",AGENT_LOG_FILE:B}});K.on("error",()=>{}),b(C),await new Promise((U)=>setTimeout(U,2000));let J=K.pid;if(!(J!==void 0&&await this.isProcessRunning(J))){let U="";try{U=O(B,"utf8").split(/\r?\n/).filter((k)=>k.trim()).slice(-25).join(`
2
+ import{Da as D}from"./index-9006n9tq.js";import{Xa as V}from"./index-0ckffygp.js";import{$d as A,Sd as _,Td as w,Ud as x,Vd as N,Wd as j,Zd as X,ce as I}from"./index-a4854mwz.js";import{ie as S}from"./index-c7554sg7.js";import{existsSync as $,readdirSync as v,readFileSync as O,writeFileSync as M,mkdirSync as E,openSync as T,closeSync as b,unlinkSync as R}from"fs";import{join as Q}from"path";import{tmpdir as F}from"os";import{spawn as h}from"child_process";class P{registryPath;logsDir;productDir;constructor(){let q=I();this.productDir=q,this.registryPath=Q(q,"agents.json");let z=A();this.logsDir=Q(z,"logs"),E(q,{recursive:!0}),E(z,{recursive:!0}),E(this.logsDir,{recursive:!0})}async startDaemon(q){return X(q.name),this.withInstanceLock(q.name,async()=>{let z=await this.findProcessByName(q.name);if(z&&z.status==="running"){let U=z.version,W=D();if(U===W){console.log(`\u26A0\uFE0F Agent '${q.name}' is already running on port ${z.port}`);return}console.log(`\uD83D\uDD04 Agent '${q.name}' is running an older build (${U??"unknown"} \u2192 ${W}) \u2014 restarting to apply the update`);try{await this.stopInternal(q.name)}catch(Z){console.log(`\u26A0\uFE0F Could not cleanly stop the stale daemon (${Z instanceof Error?Z.message:String(Z)}); proceeding to start the new build`)}}let B=Q(this.logsDir,`${q.name}.log`),C=T(B,"a"),H=Q(import.meta.dir,"index.js"),G=Q(import.meta.dir,"..","index.ts"),L=$(H)?H:G,K=h(process.execPath,["run",L],{detached:!0,windowsHide:!0,stdio:["ignore",C,C],env:{...process.env,VIBECONTROLS_PROFILE:q.profile||"default",PORT:q.port.toString(),DB_PATH:q.dbPath,NODE_ENV:"production",AGENT_LOG_FILE:B}});K.on("error",()=>{}),b(C),await new Promise((U)=>setTimeout(U,2000));let J=K.pid;if(!(J!==void 0&&await this.isProcessRunning(J))){let U="";try{U=O(B,"utf8").split(/\r?\n/).filter((k)=>k.trim()).slice(-25).join(`
3
3
  `)}catch{}let W=`See ${B}`;throw Error(U?`Failed to start agent '${q.name}'. ${W}
4
4
  --- last log lines ---
5
5
  ${U}`:`Failed to start agent '${q.name}'. ${W}`)}K.unref(),await this.saveProcessInfo(q.name,J,q),console.log(`\uD83D\uDE80 Agent '${q.name}' started (PID: ${J}, Port: ${q.port})`)})}async stop(q){return X(q),this.withInstanceLock(q,()=>this.stopInternal(q))}async stopInternal(q){let z=await this.findProcessByName(q);if(!z||z.status!=="running"){console.log(`\u26A0\uFE0F Agent '${q}' is not running`);return}try{if(process.kill(z.pid,"SIGTERM"),await new Promise((C)=>setTimeout(C,3000)),await this.isProcessRunning(z.pid))process.kill(z.pid,"SIGKILL");await this.updateProcessStatus(q,"stopped"),console.log(`\u2705 Agent '${q}' stopped (tunnel + API key preserved)`)}catch(B){throw Error(`Failed to stop agent '${q}': ${B}`,{cause:B})}}async restart(q,z){X(q),X(z.name);let B=await this.findProcessByName(q);if(B&&B.status==="running")await this.stop(q);await this.startDaemon(z),console.log(`\uD83D\uDD04 Agent '${q}' restarted (tunnel + API key preserved)`)}async kill(q){return X(q),this.withInstanceLock(q,async()=>{let z=await this.findProcessByName(q);if(!z||z.status!=="running"){console.log(`\u26A0\uFE0F Agent '${q}' is not running`);return}let B=Q(F(),`.boff-vibecontrols-kill-${z.pid}`);try{await Bun.write(B,"kill")}catch{}try{process.kill(z.pid,"SIGTERM"),await new Promise((H)=>setTimeout(H,5000))}catch{}if(await this.isProcessRunning(z.pid))await this.killProcessTree(z.pid);await this.updateProcessStatus(q,"stopped"),console.log(`\uD83D\uDC80 Agent '${q}' killed (tunnel + state torn down)`)})}async getStatus(q){return X(q),this.findProcessByName(q)}discoverRuntimeInstances(){let q=Q(this.productDir,"agents");if(!$(q))return[];let z;try{z=v(q,{withFileTypes:!0}).filter((C)=>C.isDirectory()).map((C)=>C.name)}catch{return[]}let B=[];for(let C of z){let H=Q(q,C,"runtime.json");if(!$(H))continue;try{let G=JSON.parse(O(H,"utf8"));if(typeof G.pid!=="number"||typeof G.port!=="number")continue;let L=G.profile||C;try{X(L)}catch{continue}B.push({name:L,pid:G.pid,port:G.port,config:{name:L,port:G.port,daemon:!0,dbPath:Q(q,C,"agent-db"),host:G.host,profile:L},startTime:G.startedAt??new Date(0).toISOString(),status:"unknown",version:G.version})}catch{}}return B}async getStatusAll(){let q=this.loadRegistry(),z=new Set(q.map((G)=>G.name)),B=[...q];for(let G of this.discoverRuntimeInstances())if(!z.has(G.name))B.push(G);let C=[];for(let G of B){let L=await this.isManagedProcessRunning(G);if(!z.has(G.name)&&!L)continue;C.push({...G,status:L?"running":"stopped"})}let H=C.filter((G)=>G.status==="running"&&!z.has(G.name));if(H.length>0)try{await _(()=>{let G=this.loadRegistry(),L=new Set(G.map((J)=>J.name)),K=H.filter((J)=>!L.has(J.name));if(K.length>0)this.saveRegistry([...G,...K.map((J)=>({...J,status:"running"}))])})}catch{}return C}async listInstances(){return this.getStatusAll()}getDefaultProfile(){return N()}setDefaultProfile(q){j(X(q))}async showLogs(q,z){X(q);let B=Q(this.logsDir,`${q}.log`);if(!$(B)){console.log(`No logs found for agent '${q}'`);return}if(z.follow)try{let C=async(J)=>{let Y=await Bun.file(B).text(),W=Y.split(`