@vibecontrols/agent 2026.602.4 → 2026.602.5

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,2 +1,2 @@
1
1
  // @bun
2
- import{n as a}from"./index-qzwphe3q.js";import"./index-5wpck4aw.js";import"./index-ytgmhxsj.js";import"./index-6jzsthh9.js";import"./index-1zf3r23y.js";import"./index-rw9x93zb.js";import"./index-nmk7cbj5.js";import"./index-a9ejdv22.js";import"./index-4wgjx8bf.js";import"./index-s2xpdnsj.js";import"./index-0ckffygp.js";import"./index-rc79x8fw.js";import"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-hvjqgb97.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{a as createApp};
2
+ import{n as a}from"./index-hwtd3ank.js";import"./index-5wpck4aw.js";import"./index-btt96dhd.js";import"./index-6jzsthh9.js";import"./index-cjbfremy.js";import"./index-rw9x93zb.js";import"./index-pk3ejfc4.js";import"./index-dxtnaa3g.js";import"./index-4wgjx8bf.js";import"./index-kmkhjf1c.js";import"./index-0ckffygp.js";import"./index-rc79x8fw.js";import"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-hvjqgb97.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{a as createApp};
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{H as O}from"./index-mxc61yr1.js";import{I as Q,J as w}from"./index-aq81xmn0.js";import"./index-d1xjj001.js";import"./index-b5dhmybd.js";import"./index-e1bw1bwr.js";import"./index-1zf3r23y.js";import"./index-rw9x93zb.js";import"./index-nmk7cbj5.js";import{wa as Z,za as I}from"./index-a9ejdv22.js";import{Aa as G,Ba as H}from"./index-4wgjx8bf.js";import{Wa as J}from"./index-s2xpdnsj.js";import{Xa as U}from"./index-0ckffygp.js";import"./index-rc79x8fw.js";import{bb as K}from"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import{dc as $}from"./index-8sdrhr3q.js";import"./index-8nqp3a4d.js";import{nc as E}from"./index-1mppacnx.js";import"./index-thammzct.js";import"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import{Od as Y}from"./index-js1xn4sq.js";import{$d as W,de as X}from"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";import{join as B}from"path";if(typeof Bun>"u")console.error(`\x1B[31mError:\x1B[0m VibeControls Agent requires the Bun runtime.
3
+ import{H as O}from"./index-mxc61yr1.js";import{I as Q,J as w}from"./index-9430ndf7.js";import"./index-d1xjj001.js";import"./index-b5dhmybd.js";import"./index-e1bw1bwr.js";import"./index-cjbfremy.js";import"./index-rw9x93zb.js";import"./index-pk3ejfc4.js";import{wa as Z,za as I}from"./index-dxtnaa3g.js";import{Aa as G,Ba as H}from"./index-4wgjx8bf.js";import{Wa as J}from"./index-kmkhjf1c.js";import{Xa as U}from"./index-0ckffygp.js";import"./index-rc79x8fw.js";import{bb as K}from"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import{dc as $}from"./index-8sdrhr3q.js";import"./index-8nqp3a4d.js";import{nc as E}from"./index-1mppacnx.js";import"./index-thammzct.js";import"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import{Od as Y}from"./index-js1xn4sq.js";import{$d as W,de as X}from"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";import{join as B}from"path";if(typeof Bun>"u")console.error(`\x1B[31mError:\x1B[0m VibeControls Agent requires the Bun runtime.
4
4
  Install Bun: https://bun.sh
5
5
  Then run: bun run vibe ...`),process.exit(1);var T=process.argv.slice(2),_=T.includes("--plain")||T.includes("--json")||process.env.NO_COLOR==="1"||!process.stdout.isTTY;E(!_);try{O()}catch{}var N="1.0.0";try{let q=B(import.meta.dir,"..","package.json");N=(await Bun.file(q).json()).version}catch{}var x=new $;x.name("vibe").description("VibeControls Agent CLI \u2014 Remote development environment management").version(N,"-v, --version").option("--provider <name>","Override the default provider for tunnel/session operations").option("-p, --profile <name>","Target a specific profile (one-off; doesn't change the persisted default). See `vibe profile`.").option("--json","Emit machine-readable JSON instead of human output.").option("--plain","Force plain-text output (no interactive UI).").hook("preAction",(q,z)=>{let F=q.opts().profile;if(F)process.env.VIBECONTROLS_PROFILE=F;try{K.init(),K.emit("command.executed",{command_name:z.name()})}catch{}});w(x);async function M(){let q=new J;try{await q.loadCorePlugins()}catch{}try{await q.loadAll()}catch{}let z=new Z,F={storage:{async get(){return null},async set(){},async delete(){return!1},async list(){return[]},async deleteAll(){return 0}},logger:Y().logger,serviceRegistry:z,getProvider:(L)=>z.getProvider(L),getAgentBaseUrl:()=>process.env.AGENT_URL||"http://localhost:3005",getAgentVersion:()=>N,broadcast:()=>{},workspaceQuery:async()=>({data:void 0,errors:[{message:"workspaceQuery is not available in CLI mode"}]}),isGatewayConfigured:()=>!1,getAgentRecordId:async()=>null,getWorkspaceId:async()=>null,getConfig:async()=>{return},getPluginRegistry:()=>X(),getDataDir:()=>W(),cliContributors:new G,telemetry:{emit:(L,D)=>{try{K.emit(L,D??{})}catch{}}},os:U(),iframeBridge:I()};H(F.cliContributors);try{await q.dispatchCliSetup(x,F)}catch{}x.configureHelp({formatHelp:()=>Q(x,!0)}),await x.parseAsync()}M().then(()=>{process.exit(process.exitCode??0)}).catch((q)=>{console.error(`\x1B[31mFatal:\x1B[0m ${q instanceof Error?q.message:q}`),process.exit(1)});
@@ -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-cjbfremy.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-pk3ejfc4.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-kmkhjf1c.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-8hfz23sx.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-bjmh5b5w.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-8hfz23sx.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{wa as qa,za as Fa}from"./index-a9ejdv22.js";import{Aa as Ka}from"./index-4wgjx8bf.js";import{Da as ka,Wa as Ua}from"./index-s2xpdnsj.js";import{Xa as Pa}from"./index-0ckffygp.js";import{nb as ja}from"./index-hvjqgb97.js";import{Jb as Ma}from"./index-rqq0k5fc.js";import{qd as ba,sd as yt}from"./index-h74va4wd.js";import{Ad as Gt,Cd as os,Ed as Ra,Id as v,Md as Ta,Od as g,Pd as Oa}from"./index-js1xn4sq.js";import{Zd as Xt,ce as Ia}from"./index-a4854mwz.js";import{ie as Ae}from"./index-c7554sg7.js";var Qt=[0,5000,15000,30000,60000],za=2000,Ba=5000,Xa=120000,cs=10,Ha=1048576;class Zt extends Error{resetAt;resource;constructor(e,t,i){super(e);this.name="RateLimitError",this.resource=t,this.resetAt=i}}function ei(e,t){if(!e?.length)return null;let i=e.find((r)=>r.extensions?.code==="RATE_LIMITED");if(!i)return null;let s=i.extensions?.resetAt,n=null;if(s){let r=new Date(s);if(!Number.isNaN(r.getTime()))n=r}return new Zt(`${t} rate limited${n?` until ${n.toISOString()}`:""}`,t,n)}function Va(e){if(!e.resetAt)return 60000;let t=e.resetAt.getTime()-Date.now()+za;return Math.min(Math.max(t,Ba),Xa)}async function Ja(e,t){let i=e.headers.get("content-length");if(i){let o=Number.parseInt(i,10);if(Number.isInteger(o)&&o>t)throw Error(`Gateway response is too large (${o} bytes)`)}if(!e.body)return"";let s=e.body.getReader(),n=[],r=0;try{while(!0){let{done:o,value:c}=await s.read();if(o)break;if(!c)continue;if(r+=c.byteLength,r>t)throw await s.cancel().catch(()=>{return}),Error(`Gateway response exceeds ${t} bytes`);n.push(c)}}finally{s.releaseLock()}let a=new Uint8Array(r),l=0;for(let o of n)a.set(o,l),l+=o.byteLength;return new TextDecoder().decode(a)}async function ti(e,t){let i=await Ja(e,Ha),s;try{s=i?JSON.parse(i):{}}catch(n){let r=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} returned non-JSON response (${e.status} ${e.statusText})${r?`: ${r}`:""}`,{cause:n})}if(!e.ok){let n=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} failed (${e.status} ${e.statusText})${n?`: ${n}`:""}`)}return s}function ii(e){return e.endsWith("/graphql")?e:`${e}/graphql`}function Ya(e){let t;try{t=new URL(e).hostname.toLowerCase().replace(/^\[|\]$/g,"")}catch{return!1}if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="0.0.0.0"||t==="host.docker.internal")return!0;return t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".local.burdenoff.com")}function si(e){if(!(process.env.VIBE_DEV_INSECURE_TLS==="1"||process.env.NODE_TLS_REJECT_UNAUTHORIZED==="0")&&!Ya(e))return{};return{tls:{rejectUnauthorized:!1}}}async function Wa(e,t,i){let s=await fetch(ii(e),{method:"POST",...si(e),headers:{"Content-Type":"application/json"},body:JSON.stringify({query:`mutation AuthenticateApp($input: AuthenticateAppInput!) {
2
+ import{wa as qa,za as Fa}from"./index-dxtnaa3g.js";import{Aa as Ka}from"./index-4wgjx8bf.js";import{Da as ka,Wa as Ua}from"./index-kmkhjf1c.js";import{Xa as Pa}from"./index-0ckffygp.js";import{nb as ja}from"./index-hvjqgb97.js";import{Jb as Ma}from"./index-rqq0k5fc.js";import{qd as ba,sd as yt}from"./index-h74va4wd.js";import{Ad as Gt,Cd as os,Ed as Ra,Id as v,Md as Ta,Od as g,Pd as Oa}from"./index-js1xn4sq.js";import{Zd as Xt,ce as Ia}from"./index-a4854mwz.js";import{ie as Ae}from"./index-c7554sg7.js";var Qt=[0,5000,15000,30000,60000],za=2000,Ba=5000,Xa=120000,cs=10,Ha=1048576;class Zt extends Error{resetAt;resource;constructor(e,t,i){super(e);this.name="RateLimitError",this.resource=t,this.resetAt=i}}function ei(e,t){if(!e?.length)return null;let i=e.find((r)=>r.extensions?.code==="RATE_LIMITED");if(!i)return null;let s=i.extensions?.resetAt,n=null;if(s){let r=new Date(s);if(!Number.isNaN(r.getTime()))n=r}return new Zt(`${t} rate limited${n?` until ${n.toISOString()}`:""}`,t,n)}function Va(e){if(!e.resetAt)return 60000;let t=e.resetAt.getTime()-Date.now()+za;return Math.min(Math.max(t,Ba),Xa)}async function Ja(e,t){let i=e.headers.get("content-length");if(i){let o=Number.parseInt(i,10);if(Number.isInteger(o)&&o>t)throw Error(`Gateway response is too large (${o} bytes)`)}if(!e.body)return"";let s=e.body.getReader(),n=[],r=0;try{while(!0){let{done:o,value:c}=await s.read();if(o)break;if(!c)continue;if(r+=c.byteLength,r>t)throw await s.cancel().catch(()=>{return}),Error(`Gateway response exceeds ${t} bytes`);n.push(c)}}finally{s.releaseLock()}let a=new Uint8Array(r),l=0;for(let o of n)a.set(o,l),l+=o.byteLength;return new TextDecoder().decode(a)}async function ti(e,t){let i=await Ja(e,Ha),s;try{s=i?JSON.parse(i):{}}catch(n){let r=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} returned non-JSON response (${e.status} ${e.statusText})${r?`: ${r}`:""}`,{cause:n})}if(!e.ok){let n=i.slice(0,240).replace(/\s+/g," ");throw Error(`${t} failed (${e.status} ${e.statusText})${n?`: ${n}`:""}`)}return s}function ii(e){return e.endsWith("/graphql")?e:`${e}/graphql`}function Ya(e){let t;try{t=new URL(e).hostname.toLowerCase().replace(/^\[|\]$/g,"")}catch{return!1}if(t==="localhost"||t==="127.0.0.1"||t==="::1"||t==="0.0.0.0"||t==="host.docker.internal")return!0;return t.endsWith(".localhost")||t.endsWith(".local")||t.endsWith(".local.burdenoff.com")}function si(e){if(!(process.env.VIBE_DEV_INSECURE_TLS==="1"||process.env.NODE_TLS_REJECT_UNAUTHORIZED==="0")&&!Ya(e))return{};return{tls:{rejectUnauthorized:!1}}}async function Wa(e,t,i){let s=await fetch(ii(e),{method:"POST",...si(e),headers:{"Content-Type":"application/json"},body:JSON.stringify({query:`mutation AuthenticateApp($input: AuthenticateAppInput!) {
3
3
  authenticateApp(input: $input) { accessToken expiresIn }
4
4
  }`,variables:{input:{clientId:t,clientSecret:i,scopes:[]}}}),signal:AbortSignal.timeout(15000)}),n=await ti(s,"authenticateApp"),r=ei(n.errors,"authenticateApp");if(r)throw r;if(n.errors?.length){let l=n.errors.map((o)=>o.extensions?.code??"UNKNOWN").join(",");throw Error(`authenticateApp errors [${l}]: ${n.errors.map((o)=>o.message).join("; ")}`)}let a=n.data?.authenticateApp?.accessToken;if(!a)throw Error("authenticateApp returned no token");return a}async function Qa(e,t,i,s){let n=await fetch(ii(e),{method:"POST",...si(e),headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({query:`mutation IssueAgentWorkspaceToken($input: IssueWorkspaceTokenInput!) {
5
5
  issueWorkspaceToken(input: $input) {
@@ -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-pk3ejfc4.js";import{Fa as U,Ha as M,Pa as R}from"./index-kmkhjf1c.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{Sa as k}from"./index-s2xpdnsj.js";import{Eb as F,Fb as h,Gb as S,Hb as q,Jb as N,wb as f,zb as c}from"./index-rqq0k5fc.js";import{Vb as P}from"./index-pgew6sge.js";import{Od as V}from"./index-js1xn4sq.js";var U=["tunnel","session","ai","plan","gitops","security"];class m{providers=new Map;providerOrder=new Map;defaults=new Map;services=new Map;db;constructor(z){this.db=z}getDb(){return this.db}setProviderDefault(z,J){this.defaults.set(z,J)}clearProviderDefault(z,J){if(!J||this.defaults.get(z)===J)this.defaults.delete(z)}async hydrateDefaultsFromDb(){if(!this.db)return;for(let z of U)try{let J=await this.db.getConfig(`provider:default:${z}`);if(J)this.defaults.set(z,J)}catch{}}registerProvider(z,J,Q){if(!this.providers.has(z))this.providers.set(z,new Map),this.providerOrder.set(z,[]);let W=this.providers.get(z),Z=this.providerOrder.get(z);if(W.has(Q))V().logger.info("service-registry",`Updating ${z} provider from plugin '${Q}'`);else V().logger.info("service-registry",`Registered ${z} provider from plugin '${Q}'`);if(W.set(Q,{provider:J,pluginName:Q,registeredAt:new Date}),!Z.includes(Q))Z.push(Q)}getProvider(z){let J=this.providers.get(z);if(!J||J.size===0)return;let Q=this.defaults.get(z);if(Q&&J.has(Q))return J.get(Q).provider;let W=this.providerOrder.get(z);if(W&&W.length>0){let Z=W[0];return J.get(Z)?.provider}return}getProviderByName(z,J){let Q=this.providers.get(z);if(!Q)return;return Q.get(J)?.provider}hasProvider(z){let J=this.providers.get(z);return!!J&&J.size>0}unregisterProvider(z,J){let Q=this.providers.get(z);if(!Q)return!1;let W=Q.delete(J);if(W){let Z=this.providerOrder.get(z);if(Z){let X=Z.indexOf(J);if(X!==-1)Z.splice(X,1)}this.clearProviderDefault(z,J),V().logger.info("service-registry",`Unregistered ${z} provider from plugin '${J}'`)}return W}unregisterPlugin(z){for(let J of U)this.unregisterProvider(J,z);this.unregisterServices(z)}listProvidersForType(z){let J=this.providers.get(z);if(!J)return[];let Q=this.defaults.get(z);if(!Q||!J.has(Q)){let W=this.providerOrder.get(z);Q=W&&W.length>0?W[0]:void 0}return Array.from(J.keys()).map((W)=>({pluginName:W,isDefault:W===Q}))}registerService(z,J,Q){let W=`${z}:${J}`;this.services.set(W,{service:Q,pluginName:z}),V().logger.debug("service-registry",`Registered service '${W}'`)}getService(z,J){let Q=`${z}:${J}`;return this.services.get(Q)?.service}unregisterServices(z){let J=[];for(let[Q,W]of this.services)if(W.pluginName===z)J.push(Q);for(let Q of J)this.services.delete(Q);if(J.length>0)V().logger.info("service-registry",`Unregistered ${J.length} services from ${z}`)}listProviders(){let z=[];for(let[J,Q]of this.providers)for(let[W,Z]of Q)z.push({type:J,name:W,pluginName:Z.pluginName});return z}listServices(){return Array.from(this.services.entries()).map(([z,J])=>({pluginName:J.pluginName,serviceName:z.split(":").slice(1).join(":")}))}clear(){this.providers.clear(),this.providerOrder.clear(),this.defaults.clear(),this.services.clear()}}import{extname as g,relative as o,resolve as u}from"path";import{realpath as E}from"fs/promises";var n=["'self'","http://localhost:*","http://127.0.0.1:*","https://localhost:*","https://127.0.0.1:*","https://*.local.burdenoff.com","https://vibecontrols.com","https://*.vibecontrols.com","https://burdenoff.com","https://app.burdenoff.com","https://alphaapp.burdenoff.com"],D=!1;function w(){let z=process.env.VIBE_UI_FRAME_ANCESTORS?.trim(),J=z?z.split(/[\s,]+/).filter(Boolean):n;if(z&&!D&&(J.includes("*")||!J.includes("'self'")))D=!0,console.warn(`[ui-server] VIBE_UI_FRAME_ANCESTORS override does not include "'self'" or contains "*". This significantly weakens CSP frame-ancestors and is almost never intended. Override: ${z}`);return`frame-ancestors ${J.join(" ")}`}var l={".html":"text/html",".js":"application/javascript",".mjs":"application/javascript",".css":"text/css",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".map":"application/json",".wasm":"application/wasm"};function s(z){return l[g(z).toLowerCase()]||"application/octet-stream"}var b=`<script>
2
+ import{Sa as k}from"./index-kmkhjf1c.js";import{Eb as F,Fb as h,Gb as S,Hb as q,Jb as N,wb as f,zb as c}from"./index-rqq0k5fc.js";import{Vb as P}from"./index-pgew6sge.js";import{Od as V}from"./index-js1xn4sq.js";var U=["tunnel","session","ai","plan","gitops","security"];class m{providers=new Map;providerOrder=new Map;defaults=new Map;services=new Map;db;constructor(z){this.db=z}getDb(){return this.db}setProviderDefault(z,J){this.defaults.set(z,J)}clearProviderDefault(z,J){if(!J||this.defaults.get(z)===J)this.defaults.delete(z)}async hydrateDefaultsFromDb(){if(!this.db)return;for(let z of U)try{let J=await this.db.getConfig(`provider:default:${z}`);if(J)this.defaults.set(z,J)}catch{}}registerProvider(z,J,Q){if(!this.providers.has(z))this.providers.set(z,new Map),this.providerOrder.set(z,[]);let W=this.providers.get(z),Z=this.providerOrder.get(z);if(W.has(Q))V().logger.info("service-registry",`Updating ${z} provider from plugin '${Q}'`);else V().logger.info("service-registry",`Registered ${z} provider from plugin '${Q}'`);if(W.set(Q,{provider:J,pluginName:Q,registeredAt:new Date}),!Z.includes(Q))Z.push(Q)}getProvider(z){let J=this.providers.get(z);if(!J||J.size===0)return;let Q=this.defaults.get(z);if(Q&&J.has(Q))return J.get(Q).provider;let W=this.providerOrder.get(z);if(W&&W.length>0){let Z=W[0];return J.get(Z)?.provider}return}getProviderByName(z,J){let Q=this.providers.get(z);if(!Q)return;return Q.get(J)?.provider}hasProvider(z){let J=this.providers.get(z);return!!J&&J.size>0}unregisterProvider(z,J){let Q=this.providers.get(z);if(!Q)return!1;let W=Q.delete(J);if(W){let Z=this.providerOrder.get(z);if(Z){let X=Z.indexOf(J);if(X!==-1)Z.splice(X,1)}this.clearProviderDefault(z,J),V().logger.info("service-registry",`Unregistered ${z} provider from plugin '${J}'`)}return W}unregisterPlugin(z){for(let J of U)this.unregisterProvider(J,z);this.unregisterServices(z)}listProvidersForType(z){let J=this.providers.get(z);if(!J)return[];let Q=this.defaults.get(z);if(!Q||!J.has(Q)){let W=this.providerOrder.get(z);Q=W&&W.length>0?W[0]:void 0}return Array.from(J.keys()).map((W)=>({pluginName:W,isDefault:W===Q}))}registerService(z,J,Q){let W=`${z}:${J}`;this.services.set(W,{service:Q,pluginName:z}),V().logger.debug("service-registry",`Registered service '${W}'`)}getService(z,J){let Q=`${z}:${J}`;return this.services.get(Q)?.service}unregisterServices(z){let J=[];for(let[Q,W]of this.services)if(W.pluginName===z)J.push(Q);for(let Q of J)this.services.delete(Q);if(J.length>0)V().logger.info("service-registry",`Unregistered ${J.length} services from ${z}`)}listProviders(){let z=[];for(let[J,Q]of this.providers)for(let[W,Z]of Q)z.push({type:J,name:W,pluginName:Z.pluginName});return z}listServices(){return Array.from(this.services.entries()).map(([z,J])=>({pluginName:J.pluginName,serviceName:z.split(":").slice(1).join(":")}))}clear(){this.providers.clear(),this.providerOrder.clear(),this.defaults.clear(),this.services.clear()}}import{extname as g,relative as o,resolve as u}from"path";import{realpath as E}from"fs/promises";var n=["'self'","http://localhost:*","http://127.0.0.1:*","https://localhost:*","https://127.0.0.1:*","https://*.local.burdenoff.com","https://vibecontrols.com","https://*.vibecontrols.com","https://burdenoff.com","https://app.burdenoff.com","https://alphaapp.burdenoff.com"],D=!1;function w(){let z=process.env.VIBE_UI_FRAME_ANCESTORS?.trim(),J=z?z.split(/[\s,]+/).filter(Boolean):n;if(z&&!D&&(J.includes("*")||!J.includes("'self'")))D=!0,console.warn(`[ui-server] VIBE_UI_FRAME_ANCESTORS override does not include "'self'" or contains "*". This significantly weakens CSP frame-ancestors and is almost never intended. Override: ${z}`);return`frame-ancestors ${J.join(" ")}`}var l={".html":"text/html",".js":"application/javascript",".mjs":"application/javascript",".css":"text/css",".json":"application/json",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".ico":"image/x-icon",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".map":"application/json",".wasm":"application/wasm"};function s(z){return l[g(z).toLowerCase()]||"application/octet-stream"}var b=`<script>
3
3
  window.__VIBE_AUTH__={apiKey:null};
4
4
  (function(){
5
5
  var p=new URLSearchParams(window.location.search);
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{h as y,i as c}from"./index-cs78wq6y.js";import{A as p$,B as i$,y as l$}from"./index-ytgmhxsj.js";import{N as j$}from"./index-b5dhmybd.js";import{O as H$,P as K$}from"./index-e1bw1bwr.js";import{va as g}from"./index-nmk7cbj5.js";import"./index-a9ejdv22.js";import{Ca as k$}from"./index-4wgjx8bf.js";import"./index-s2xpdnsj.js";import"./index-0ckffygp.js";import{ab as v}from"./index-rc79x8fw.js";import{db as Y$}from"./index-52cp759f.js";import"./index-hvjqgb97.js";import{Jb as C$,Kb as D$,tb as X$,vb as L$}from"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import{Ub as F,Vb as p}from"./index-pgew6sge.js";import{Xb as g$}from"./index-rzpaqrhx.js";import"./index-8sdrhr3q.js";import{jc as x,kc as _,lc as c$}from"./index-8nqp3a4d.js";import{Ac as s,Bc as N,Cc as u,oc as V,pc as Z,qc as Y,rc as H,sc as A,uc as z,vc as X,wc as J,xc as Q,yc as h$,zc as k}from"./index-1mppacnx.js";import{Hc as K}from"./index-thammzct.js";import{Lc as T,Nc as b,Oc as M,Pc as y$}from"./index-b6x6a4xp.js";import{qd as T$}from"./index-h74va4wd.js";import{Id as z$,Ld as q$,Od as q}from"./index-js1xn4sq.js";import{$d as $$,Yd as J$,_d as a,ae as U$}from"./index-a4854mwz.js";import"./index-4qq083yd.js";import{ie as d}from"./index-c7554sg7.js";function t(f){let{name:W,onInit:w,onShutdown:U,onNuke:R,telemetryEventName:$,skipPlatforms:G}=f;return{onServerStart:async(I,O)=>{if(G&&G.includes(process.platform)){process.stderr.write(`[${W}] skipping init on unsupported platform '${process.platform}'
2
+ import{h as y,i as c}from"./index-cs78wq6y.js";import{A as p$,B as i$,y as l$}from"./index-btt96dhd.js";import{N as j$}from"./index-b5dhmybd.js";import{O as H$,P as K$}from"./index-e1bw1bwr.js";import{va as g}from"./index-pk3ejfc4.js";import"./index-dxtnaa3g.js";import{Ca as k$}from"./index-4wgjx8bf.js";import"./index-kmkhjf1c.js";import"./index-0ckffygp.js";import{ab as v}from"./index-rc79x8fw.js";import{db as Y$}from"./index-52cp759f.js";import"./index-hvjqgb97.js";import{Jb as C$,Kb as D$,tb as X$,vb as L$}from"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import{Ub as F,Vb as p}from"./index-pgew6sge.js";import{Xb as g$}from"./index-rzpaqrhx.js";import"./index-8sdrhr3q.js";import{jc as x,kc as _,lc as c$}from"./index-8nqp3a4d.js";import{Ac as s,Bc as N,Cc as u,oc as V,pc as Z,qc as Y,rc as H,sc as A,uc as z,vc as X,wc as J,xc as Q,yc as h$,zc as k}from"./index-1mppacnx.js";import{Hc as K}from"./index-thammzct.js";import{Lc as T,Nc as b,Oc as M,Pc as y$}from"./index-b6x6a4xp.js";import{qd as T$}from"./index-h74va4wd.js";import{Id as z$,Ld as q$,Od as q}from"./index-js1xn4sq.js";import{$d as $$,Yd as J$,_d as a,ae as U$}from"./index-a4854mwz.js";import"./index-4qq083yd.js";import{ie as d}from"./index-c7554sg7.js";function t(f){let{name:W,onInit:w,onShutdown:U,onNuke:R,telemetryEventName:$,skipPlatforms:G}=f;return{onServerStart:async(I,O)=>{if(G&&G.includes(process.platform)){process.stderr.write(`[${W}] skipping init on unsupported platform '${process.platform}'
3
3
  `);return}if(w)await w(O);if($)O.telemetry?.emit($,{plugin:W})},onServerStop:async(I)=>{if(U)await U(I)},onNuke:async(I,O)=>{if(R)return R(I,O)}}}var e=class{constructor(f,W){this.logger=f,this.source=W}logger;source;info(f,W){this.logger?.info?.(this.source,f,W)}warn(f,W){this.logger?.warn?.(this.source,f,W)}error(f,W){this.logger?.error?.(this.source,f,W)}debug(f,W){this.logger?.debug?.(this.source,f,W)}};import{existsSync as t$,rmSync as e$,statSync as a$}from"fs";import{resolve as $U}from"path";function R$(f=$$()){let W=[],w=$U(f),U=U$();if(!a(U,w))throw Error("Refusing to reset a path outside the agents directory");if(t$(w)&&a$(w).isDirectory())e$(w,{recursive:!0,force:!0}),W.push(w);return{removed:W,agentDir:w}}var S="alias",G$=/^[a-zA-Z0-9_-]{1,64}$/,w$=16384,f$=256,W$=1024,UU=new Set(["help","start","stop","restart","kill","list","status","setup","update","completion","autostart","export","import","diagnostics","nuke","doctor","log-level","gc","deploy","network","profile","peer-bootstrap","gateway-auth","info","key","system","url","health","notify","tunnel","session","git","config","log","plugin","ai","audit","alias","run"]);class D extends Error{code;constructor(f,W){super(W);this.code=f,this.name="AliasValidationError"}}class E extends Error{constructor(f){super(`alias '${f}' already exists`);this.name="AliasConflictError"}}class P extends Error{constructor(f){super(`alias '${f}' not found`);this.name="AliasNotFoundError"}}function RU(f){if(typeof f!=="string"||!G$.test(f))throw new D("invalid_name",`alias name must match ${G$} (got '${f}')`);if(UU.has(f))throw new D("reserved_name",`alias name '${f}' is reserved`)}function I$(f){if(typeof f!=="string"||f.length===0)throw new D("invalid_command","alias command must be a non-empty string");if(f.length>w$)throw new D("command_too_long",`alias command exceeds ${w$} bytes`)}function O$(f){if(f===void 0)return;if(typeof f!=="string")throw new D("invalid_description","alias description must be a string");if(f.length>f$)throw new D("description_too_long",`alias description exceeds ${f$} chars`)}function F$(f){if(f===void 0||f===null||f==="")return;if(typeof f!=="string")throw new D("invalid_cwd","alias cwd must be a string");if(f.length>W$)throw new D("cwd_too_long",`alias cwd exceeds ${W$} chars`);if(f.includes("\x00"))throw new D("invalid_cwd","alias cwd must not contain NUL bytes")}function GU(f){if(!f)return;try{return JSON.parse(f)}catch{return}}async function i(f){let W=await f.getAllPluginState(S),w=[];for(let U of W){let R=GU(U.value);if(R)w.push(R)}return w.sort((U,R)=>U.name.localeCompare(R.name)),w}async function n(f,W){return(await i(f)).find((U)=>U.name===W)}function V$(f){if(f===void 0||f===null)return null;let W=f.trim();return W===""?null:W}async function Q$(f,W){if(RU(W.name),I$(W.command),O$(W.description),F$(W.cwd),await n(f,W.name))throw new E(W.name);let U=new Date().toISOString(),R={id:crypto.randomUUID(),name:W.name,command:W.command,description:W.description,cwd:V$(W.cwd),profile:J$(),createdAt:U,updatedAt:U};return await f.setPluginState(S,R.id,JSON.stringify(R)),R}async function Z$(f,W,w){let U=await n(f,W);if(!U)throw new P(W);if(w.command!==void 0)I$(w.command);if(w.description!==void 0)O$(w.description);if(w.cwd!==void 0)F$(w.cwd);let R={...U,command:w.command??U.command,description:w.description!==void 0?w.description:U.description,cwd:w.cwd!==void 0?V$(w.cwd):U.cwd,updatedAt:new Date().toISOString()};return await f.setPluginState(S,R.id,JSON.stringify(R)),R}async function B$(f,W){let w=await n(f,W);if(!w)throw new P(W);await f.deletePluginState(S,w.id)}function m(){let f=q$()??q();return{dir:f.dataDir,scope:f.name}}function M$(f){let{serviceRegistry:W,db:w}=f;return new p().get("/api-key",()=>({apiKey:C$()})).post("/reset-key",async({body:U,set:R})=>{let $=U.apiKey;if(!$||typeof $!=="string")return R.status=400,{error:"Missing required field: apiKey"};try{return await D$($),await q().keyVault.bindApiKey($),q().logger.info("auth","Adopted backend-rotated agent API key via /reset-key"),{success:!0}}catch(G){return R.status=400,{error:"reset-key failed",message:G instanceof Error?G.message:String(G)}}},{body:F.Object({apiKey:F.String()})}).get("/audit",({query:U})=>{let R=U,$=R.limit?Math.min(5000,Math.max(1,Number.parseInt(R.limit,10)||100)):100,G=q().audit.listEvents({since:R.since,limit:$,event:R.event});return{events:G,count:G.length}},{query:F.Object({since:F.Optional(F.String()),limit:F.Optional(F.String()),event:F.Optional(F.String())})}).get("/setup/check",()=>{let U=H$();return{ready:U.filter(($)=>$.required).every(($)=>$.installed),dependencies:U}}).post("/setup/install",async({request:U,server:R,set:$})=>{let G=await c(U,"VIBECONTROLS_ALLOW_REMOTE_SETUP_INSTALL",R);if(G)return $.status=403,{error:"Forbidden",message:G};return await K$()}).get("/url",async()=>{let U=W.getProvider("tunnel"),R=U&&U.getActiveTunnelUrl?await U.getActiveTunnelUrl():null,$=`http://localhost:${process.env.PORT||3005}`;return{url:R||$,tunnelUrl:R,localUrl:$,source:R?"tunnel":"local"}}).get("/lifecycle/state",()=>{return{state:W.getService("agent","lifecycle")?.getState()??"running"}}).post("/lifecycle/stop",async({set:U})=>{let R=W.getService("agent","lifecycle");if(!R)return U.status=500,{error:"Lifecycle manager not initialized"};return await R.stop(),{state:"stopped"}}).post("/lifecycle/start",async({set:U})=>{let R=W.getService("agent","lifecycle");if(!R)return U.status=500,{error:"Lifecycle manager not initialized"};return await R.start(),{state:"running"}}).post("/lifecycle/kill",async({set:U})=>{let R=W.getService("agent","lifecycle");if(!R)return U.status=500,{error:"Lifecycle manager not initialized"};return setTimeout(()=>R.kill(),100),{state:"killing"}}).post("/log-level",async({body:U,request:R,server:$,set:G})=>{let I=await c(R,"VIBECONTROLS_ALLOW_REMOTE_LOG_LEVEL",$);if(I)return G.status=403,{error:"Forbidden",message:I};let O=String(U.level??"").toLowerCase();if(!["debug","info","warn","error"].includes(O))return G.status=400,{error:"Invalid level",message:"level must be debug | info | warn | error"};return q().logger.setLevel(O),q().logger.info("agent",`Log level set to ${O} via API`),{ok:!0,level:O}},{body:F.Object({level:F.String()})}).post("/reset",async({body:U,request:R,server:$,set:G})=>{if(!U.confirm)return G.status=400,{error:"Reset confirmation required",message:"Send { confirm: true } to reset local agent state."};let I=await c(R,"VIBECONTROLS_ALLOW_REMOTE_RESET",$);if(I)return G.status=403,{error:"Forbidden",message:I};let O=W.getService("agent","lifecycle");try{if(O)await O.prepareForReset()}catch(h){q().logger.warn("agent","prepareForReset failed during reset \u2014 proceeding to wipe anyway",{error:String(h)})}try{z$.configure({globalGatewayUrl:"",workspaceGatewayUrl:void 0,clientId:"",clientSecret:"",workspaceId:void 0})}catch{}await w.close();let{removed:B,agentDir:L}=R$();q().logger.info("agent","Reset wiped local agent state",{agentDir:L,removed:B});let C=new Uint8Array(32);crypto.getRandomValues(C);let j=`vcak_${Buffer.from(C).toString("base64url")}`;return T$({"static-api-key":j},m()),q().setBootState("awaiting-config"),G.status=200,{success:!0,state:"awaiting-config",...y(R,$)||process.env.VIBECONTROLS_RETURN_RESET_API_KEY==="1"?{newApiKey:j}:{},agentDir:L,removed:B}},{body:F.Object({confirm:F.Boolean()})}).post("/sessions/:sessionId/share",async({params:U,body:R,server:$,request:G,set:I})=>{if(!y(G,$)&&process.env.VIBECONTROLS_ALLOW_REMOTE_SESSION_SHARE!=="1")return I.status=403,{error:"Forbidden",message:"Session-share mint must come from a local request unless VIBECONTROLS_ALLOW_REMOTE_SESSION_SHARE=1."};if(!X$(U.sessionId))return I.status=400,{error:"BadRequest",message:"invalid sessionId"};let O=wU(R?.expiresIn)??1800000,B=crypto.randomUUID(),L=new Uint8Array(32);crypto.getRandomValues(L);let C=`vcak_${Buffer.from(L).toString("base64url")}`,j=new Date(Date.now()+O).toISOString(),r=[...(await import("./agent-config-4ppenhqp.js")).readAgentConfig({dir:m().dir}).apiKeys??[],{id:B,name:`session-share:${U.sessionId}:${R?.label??"viewer"}`,key:C,scopes:["read"],expiresAt:j,createdAt:new Date().toISOString()}];(await import("./agent-config-4ppenhqp.js")).writeAgentConfig({apiKeys:r},m());let h=W.getProvider("tunnel"),d$=(h&&h.getActiveTunnelUrl?await h.getActiveTunnelUrl():null)??`http://localhost:${process.env.PORT||3005}`,s$=L$({pathPrefixes:[`/terminal/${U.sessionId}`],methods:["GET"]},Math.min(600,Math.floor(O/1000))),r$=`${d$.replace(/\/$/,"")}/terminal/${encodeURIComponent(U.sessionId)}/#vt=${encodeURIComponent(s$.token)}`;return q().logger.info("session-share","Minted share credential",{sessionId:U.sessionId,keyId:B,expiresAt:j}),{ok:!0,keyId:B,apiKey:C,joinUrl:r$,sessionId:U.sessionId,expiresAt:j}},{params:F.Object({sessionId:F.String()}),body:F.Optional(F.Object({permissions:F.Optional(F.Array(F.String())),expiresIn:F.Optional(F.String()),label:F.Optional(F.String())}))}).get("/aliases",async()=>{return{aliases:await i(w)}}).get("/aliases/:name",async({params:U,set:R})=>{let $=await n(w,U.name);if(!$)return R.status=404,{error:"Alias not found"};return $},{params:F.Object({name:F.String()})}).post("/aliases",async({body:U,set:R})=>{try{let $=await Q$(w,U);return R.status=201,$}catch($){if($ instanceof E)return R.status=409,{error:"Alias already exists",message:$.message};if($ instanceof D)return R.status=400,{error:$.code,message:$.message};throw $}},{body:F.Object({name:F.String(),command:F.String(),description:F.Optional(F.String()),cwd:F.Optional(F.Union([F.String(),F.Null()]))})}).put("/aliases/:name",async({params:U,body:R,set:$})=>{try{return await Z$(w,U.name,R)}catch(G){if(G instanceof P)return $.status=404,{error:"Alias not found"};if(G instanceof D)return $.status=400,{error:G.code,message:G.message};throw G}},{params:F.Object({name:F.String()}),body:F.Object({command:F.Optional(F.String()),description:F.Optional(F.String()),cwd:F.Optional(F.Union([F.String(),F.Null()]))})}).delete("/aliases/:name",async({params:U,set:R})=>{try{return await B$(w,U.name),R.status=204,null}catch($){if($ instanceof P)return R.status=404,{error:"Alias not found"};throw $}},{params:F.Object({name:F.String()})}).post("/aliases/:name/execute",async({params:U,body:R,set:$})=>{let G=await n(w,U.name);if(!G)return $.status=404,{error:"Alias not found"};let I=R?.args??[],O=await j$(G,I);q().audit.emit("agent","alias.executed",{exit_code:O.exit_code});let B=Y$("alias.executed",{exit_code:O.exit_code});if(!B.ok)q().logger.debug("alias",`telemetry validate failed: ${B.reason}`);if(O.timed_out)$.status=408;return{exit_code:O.exit_code,stdout:O.stdout,stderr:O.stderr,duration_ms:O.duration_ms,truncated:O.truncated,cwd:O.cwd}},{params:F.Object({name:F.String()}),body:F.Optional(F.Object({args:F.Optional(F.Array(F.String()))}))}).post("/sessions/share/:keyId/revoke",async({params:U,server:R,request:$,set:G})=>{if(!y($,R)&&process.env.VIBECONTROLS_ALLOW_REMOTE_SESSION_SHARE!=="1")return G.status=403,{error:"Forbidden"};let I=await import("./agent-config-4ppenhqp.js"),O=m(),B=I.readAgentConfig({dir:O.dir}),L=(B.apiKeys??[]).length,C=(B.apiKeys??[]).filter((j)=>j.id!==U.keyId);if(C.length===L)return G.status=404,{error:"No such share key"};return I.writeAgentConfig({apiKeys:C},O),{ok:!0,revoked:U.keyId}},{params:F.Object({keyId:F.String()})})}function wU(f){if(!f)return null;let W=/^(\d+)([smhdw]?)$/.exec(f.trim());if(!W)return null;let w=Number(W[1]),U=W[2]||"m";return U==="s"?w*1000:U==="m"?w*60000:U==="h"?w*3600000:U==="d"?w*86400000:w*7*86400000}var fU="http://localhost:3005";function x$(f){f.command("health").description("Check health of a VibeControls agent instance").option("-n, --name <name>","Agent instance name").option("--agent-url <url>","Agent URL",fU).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function(W){try{let w={...f.opts(),...W};await _({mode:x(w),fetchData:async()=>{if(w.name){let $=await new g().checkHealth(w.name);return{mode:"named",agentUrl:T(w),name:w.name,healthy:$.healthy,details:$.details??{}}}let U=T(w);try{let R=await M(U,"/health");return{mode:"url",agentUrl:U,healthy:!0,details:R}}catch(R){return{mode:"url",agentUrl:U,healthy:!1,details:{status:"unhealthy",...R instanceof Error?{error:H(R)}:{}}}}},plain:(U)=>{if(X("Agent Health"),Q(),U.mode==="named"){if(!U.healthy){Y(`Agent instance ${V.bold(U.name??"")} is not responding.`);return}let R=U.details;if(J("Instance",U.name??""),J("Status",u(R.status??"healthy")),R.uptime!==void 0)J("Uptime",`${R.uptime}s`);if(R.checks){Q(),z(`${Z.info} Health checks:`);for(let[$,G]of Object.entries(R.checks)){let I=G.status==="healthy"?Z.success:Z.error;J(` ${I} ${$}`,u(G.status))}}}else{if(J("URL",U.agentUrl),J("Status",u(U.details.status??"unhealthy")),U.details.version)J("Version",U.details.version);if(U.details.uptime!==void 0)J("Uptime",`${U.details.uptime}s`);if(U.details.timestamp)J("Timestamp",U.details.timestamp);if(U.details.checks){Q(),z(`${Z.info} Health checks:`);for(let[R,$]of Object.entries(U.details.checks)){let G=$.status==="healthy"?Z.success:Z.error;J(` ${G} ${R}`,u($.status))}}}if(Q(),U.healthy)A(`${Z.success} Agent is healthy.`)},interactive:async(U)=>{let R=[];if(U.mode==="named")R.push(`Instance: ${U.name??""}`);else R.push(`URL: ${U.agentUrl}`);if(R.push(`Status: ${u(U.details.status??(U.healthy?"healthy":"unhealthy"))}`),U.details.version)R.push(`Version: ${U.details.version}`);if(U.details.uptime!==void 0)R.push(`Uptime: ${U.details.uptime}s`);if(U.details.timestamp)R.push(`Time: ${U.details.timestamp}`);if(U.details.checks){R.push(""),R.push("Checks:");for(let[$,G]of Object.entries(U.details.checks))R.push(` ${$}: ${G.status}`)}await K({title:"Agent Health",body:R.join(`
4
4
  `),footer:"press q to exit"})},json:(U)=>({mode:U.mode,agentUrl:U.agentUrl,name:U.name??null,healthy:U.healthy,details:U.details})})}catch(w){Y(`Health check failed: ${H(w)}`)}})}import{platform as WU,arch as JU,release as IU,hostname as OU,cpus as FU,totalmem as VU}from"os";var QU="http://localhost:3005";function _$(f){f.command("info").description("Show local and remote VibeControls agent information").option("--agent-url <url>","Agent URL",QU).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function(W){try{let w={...f.opts(),...W},U=T(w),R=encodeURIComponent(b(w));await _({mode:x(w),fetchData:async()=>{let $={hostname:OU(),platform:WU(),arch:JU(),release:IU(),cpus:FU().length,totalMemory:VU(),nodeVersion:process.version,bunVersion:process.versions.bun};try{let G=await M(U,`/api/profiles/${R}/agent/version`);return{local:$,agentUrl:U,remote:G}}catch(G){return{local:$,agentUrl:U,remote:null,remoteError:G instanceof Error?H(G):String(G)}}},plain:($)=>{if(X("VibeControls Agent Info"),Q(),z(`${Z.info} Local System`),J("Hostname",$.local.hostname),J("Platform",`${$.local.platform} ${$.local.arch}`),J("OS Release",$.local.release),J("CPUs",String($.local.cpus)),J("Total Memory",N($.local.totalMemory)),J("Node.js",$.local.nodeVersion),$.local.bunVersion)J("Bun",$.local.bunVersion);if(Q(),z(`${Z.info} Remote Agent`),J("URL",$.agentUrl),$.remote){if(J("Version",V.bold($.remote.version)),$.remote.build)J("Build",$.remote.build);if($.remote.commit)J("Commit",$.remote.commit);if($.remote.nodeVersion)J("Node.js (remote)",$.remote.nodeVersion);if($.remote.bunVersion)J("Bun (remote)",$.remote.bunVersion)}else J("Status",V.dim("not reachable"));Q()},interactive:async($)=>{let G=[];if(G.push("Local System"),G.push(` Hostname: ${$.local.hostname}`),G.push(` Platform: ${$.local.platform} ${$.local.arch}`),G.push(` OS Release: ${$.local.release}`),G.push(` CPUs: ${$.local.cpus}`),G.push(` Total Memory: ${N($.local.totalMemory)}`),G.push(` Node.js: ${$.local.nodeVersion}`),$.local.bunVersion)G.push(` Bun: ${$.local.bunVersion}`);if(G.push(""),G.push("Remote Agent"),G.push(` URL: ${$.agentUrl}`),$.remote){if(G.push(` Version: ${$.remote.version}`),$.remote.build)G.push(` Build: ${$.remote.build}`);if($.remote.commit)G.push(` Commit: ${$.remote.commit}`);if($.remote.nodeVersion)G.push(` Node.js: ${$.remote.nodeVersion} (remote)`);if($.remote.bunVersion)G.push(` Bun: ${$.remote.bunVersion} (remote)`)}else G.push(" Status: not reachable");await K({title:"VibeControls Agent Info",body:G.join(`
5
5
  `),footer:"press q to exit"})},json:($)=>({local:$.local,agentUrl:$.agentUrl,remote:$.remote,remoteError:$.remoteError??null})})}catch(w){Y(`Failed to get info: ${H(w)}`)}})}var ZU="http://localhost:3005";function b$(f){f.command("system").description("Show system information for a running VibeControls agent").option("--agent-url <url>","Agent URL",ZU).option("--json","Emit JSON").option("--plain","Force plain text output").action(async function(W){try{let w={...f.opts(),...W},U=T(w),R=encodeURIComponent(b(w));await _({mode:x(w),fetchData:()=>M(U,`/api/profiles/${R}/agent/system`),plain:($)=>{if(X("Agent System Information"),Q(),z(`${Z.info} Agent`),J("Version",V.bold($.agentVersion)),$.bunVersion)J("Bun",$.bunVersion);if($.environment)J("Environment",$.environment);J("Uptime",s($.uptime)),Q(),z(`${Z.info} Platform`),J("OS",`${$.platform} ${$.arch}`),J("Hostname",$.hostname),J("Release",$.release),Q(),z(`${Z.info} Resources`),J("CPUs",String($.cpus)),J("Total Memory",N($.totalMemory)),J("Free Memory",N($.freeMemory)),Q(),z(`${Z.info} Paths`),J("Home",$.homeDir),J("CWD",$.cwd),Q()},interactive:async($)=>{let G=["Agent",` Version: ${$.agentVersion}`,...$.bunVersion?[` Bun: ${$.bunVersion}`]:[],...$.environment?[` Environment: ${$.environment}`]:[],` Uptime: ${s($.uptime)}`,"","Platform",` OS: ${$.platform} ${$.arch}`,` Hostname: ${$.hostname}`,` Release: ${$.release}`,"","Resources",` CPUs: ${$.cpus}`,` Total Mem: ${N($.totalMemory)}`,` Free Mem: ${N($.freeMemory)}`,"","Paths",` Home: ${$.homeDir}`,` CWD: ${$.cwd}`];await K({title:"Agent System Information",body:G.join(`
@@ -1,7 +1,7 @@
1
1
  // @bun
2
- import{o as F4,q as J4}from"./index-5wpck4aw.js";import{u as r4,v as U5,w as j5}from"./index-ytgmhxsj.js";import{E as K4}from"./index-6jzsthh9.js";import{$ as y4,Q as C5,aa as L2,ba as x0,ca as f4,da as u4,ea as i4,fa as b4,ha as E2,ia as l2,ja as o2,ka as I2}from"./index-1zf3r23y.js";import{la as E5,qa as I5,sa as C0}from"./index-rw9x93zb.js";import{va as c2}from"./index-nmk7cbj5.js";import{wa as N5,xa as x5,ya as O5,za as M5}from"./index-a9ejdv22.js";import{Aa as _5}from"./index-4wgjx8bf.js";import{Ja as T0,Wa as T5}from"./index-s2xpdnsj.js";import{Xa as N2}from"./index-0ckffygp.js";import{ab as P2}from"./index-rc79x8fw.js";import{eb as $5,fb as W5,gb as z5,hb as H5,ib as G5,jb as Y2,kb as B5,lb as V5,mb as K5,nb as F5,pb as L5}from"./index-hvjqgb97.js";import{Ab as i0,Eb as M2,Fb as Y0,Gb as Z5,Hb as J5,Ib as j0,Jb as V2,Lb as m,Mb as l,Nb as d4,Ob as n4,Pb as X5,Qb as Y5,tb as l0,ub as v2,vb as d0,wb as X0,xb as n0,yb as R2}from"./index-rqq0k5fc.js";import{Ub as z,Vb as D}from"./index-pgew6sge.js";import{nd as e0,od as t,pd as p0,qd as b2,rd as h2}from"./index-h74va4wd.js";import{Ad as B2,Dd as i2,Id as g,Kd as M0,Ld as c,Md as s,Od as G,Pd as W0,wd as O0,xd as t4,yd as e4,zd as Q5}from"./index-js1xn4sq.js";import{$d as D2,Sd as r0,Td as H0,Vd as f2,Wd as t0,Yd as C2,Zd as d,be as T2,ce as F2,de as n2}from"./index-a4854mwz.js";import{fe as v0,ie as b}from"./index-c7554sg7.js";var R0=typeof new Headers()?.toJSON==="function",A5=($)=>{if(R0)return Object.keys($.toJSON()).join(", ");let Z="",Q=0;return $.forEach((Y,X)=>{if(Q)Z=Z+", "+X;else Z=X;Q++}),Z},A0=($)=>{let{aot:Z=!0,origin:Q=!0,methods:Y=!0,allowedHeaders:X=!0,exposeHeaders:J=!0,credentials:W=!0,maxAge:H=5,preflight:B=!0}=$??{};if(Array.isArray(X))X=X.join(", ");if(Array.isArray(J))J=J.join(", ");let K=typeof Q==="boolean"?void 0:Array.isArray(Q)?Q:[Q],L=new D({name:"@elysiajs/cors",seed:$,aot:Z}),w=K?.some((N)=>N==="*"),E={};if(K){for(let N of K)if(typeof N==="string")E[N]=!0}let x=(N,T,O)=>{if(Array.isArray(N))return N.some((I)=>x(I,T,O));switch(typeof N){case"string":if(O in E)return!0;let I=O.indexOf("://");if(I!==-1)O=O.slice(I+3);return N===O;case"function":return N(T)===!0;case"object":if(N instanceof RegExp)return N.test(O)}return!1},V=(N,T)=>{if(Q===!0){N.headers.vary="*",N.headers["access-control-allow-origin"]=T.headers.get("Origin")||"*";return}if(w){N.headers.vary="*",N.headers["access-control-allow-origin"]="*";return}if(!K?.length)return;if(K.length){let O=T.headers.get("Origin")??"";for(let I=0;I<K.length;I++)if(x(K[I],T,O)===!0){N.headers.vary=Q?"Origin":"*",N.headers["access-control-allow-origin"]=O||"*";return}}N.headers.vary="Origin"},C=(N,T)=>{if(!T)return;if(Y===!0)return N.headers["access-control-allow-methods"]=T??"*";if(Y===!1||!Y?.length)return;if(Y==="*")return N.headers["access-control-allow-methods"]="*";if(!Array.isArray(Y))return N.headers["access-control-allow-methods"]=Y;N.headers["access-control-allow-methods"]=Y.join(", ")},q={};if(typeof J==="string")q["access-control-expose-headers"]=J;if(typeof X==="string")q["access-control-allow-headers"]=X;if(W===!0)q["access-control-allow-credentials"]="true";L.headers(q);function v({set:N,request:T,headers:O}){if(V(N,T),C(N,T.headers.get("access-control-request-method")),X===!0||J===!0){if(X===!0)N.headers["access-control-allow-headers"]=O["access-control-request-headers"];if(J===!0)N.headers["access-control-expose-headers"]=Object.keys(O).join(",")}if(H)N.headers["access-control-max-age"]=H.toString();return new Response(null,{status:204})}if(B)L.options("/",v).options("/*",v);return L.onRequest(function({set:T,request:O}){if(V(T,O),B&&O.method==="OPTIONS")return v({set:T,request:O,headers:R0?O.headers.toJSON():Object.fromEntries(O.headers.entries())});if(C(T,O.method),X===!0||J===!0){let I=A5(O.headers);if(X===!0)T.headers["access-control-allow-headers"]=I;if(J===!0)T.headers["access-control-expose-headers"]=I}})};var k5="/code-server";function k0($,Z,Q=R2){let Y=$.method.toUpperCase();if(Y!=="GET"&&Y!=="HEAD")return null;let X=new URL($.url),J=X.searchParams.get("vt");if(!J||!Q(J,k5,"GET"))return null;X.searchParams.delete("vt");let W=new Headers($.headers);return W.set("x-agent-api-key",Z()),new Request(`${X.origin}${X.pathname}${X.search}`,{method:$.method,headers:W})}import{createHash as D0}from"crypto";var W2="idempotency",S5=300000,S0=1e4,A2=new Map;function D5($,Z,Q,Y){return D0("sha256").update(`${$}|${Z}|${Q}|${Y}`).digest("hex")}async function h5($,Z){let Q=await $.getPluginState(W2,Z);if(!Q)return null;try{let Y=JSON.parse(Q);if(Y.expiresAt<Date.now())return await $.deletePluginState(W2,Z),null;return Y}catch{return null}}async function v5($,Z,Q){await $.setPluginState(W2,Z,JSON.stringify(Q))}async function P5($){let Z=await $.getAllPluginState(W2),Q=Date.now(),Y=0,X=[];for(let J of Z)try{if(JSON.parse(J.value).expiresAt<Q)await $.deletePluginState(W2,J.key),Y+=1;else X.push({key:J.key,updatedAt:J.updatedAt})}catch{await $.deletePluginState(W2,J.key),Y+=1}if(X.length>S0){X.sort((W,H)=>(W.updatedAt??"").localeCompare(H.updatedAt??""));let J=X.slice(0,X.length-S0);for(let W of J)await $.deletePluginState(W2,W.key),Y+=1}if(Y>0)G().logger.info("idempotency",`Swept ${Y} expired/over-cap entries`)}var Q0=null,f5=600000;function b5($){if(Q0)return;Q0=setInterval(()=>{let Z=$.getDb();if(!Z)return;P5(Z).catch((Q)=>{G().logger.warn("idempotency","Sweep failed",{error:String(Q)})})},f5),Q0.unref?.()}function h0($){return b5($),new D({name:"plugin/idempotency"}).onBeforeHandle(async({request:Z,path:Q,set:Y,store:X})=>{if(Z.method!=="POST"&&Z.method!=="PUT")return;let J=Z.headers.get("x-idempotency-key")??Z.headers.get("X-Idempotency-Key");if(!J)return;if(J.length<8||J.length>200)return Y.status=400,{error:"X-Idempotency-Key must be 8\u2013200 chars",code:"BAD_REQUEST"};let W=$.getDb();if(!W)return;let H="no-body";try{let C=await Z.clone().text();H=D0("sha256").update(C).digest("hex")}catch{}let B=D5(Z.method,Q,J,H),K=await h5(W,B);if(K){Y.status=K.status;let V=Y.headers??={};V["Content-Type"]=K.contentType,V["X-Idempotency-Replay"]="true",X.__idemReplay=K.body;try{return JSON.parse(K.body)}catch{return K.body}}let L=A2.get(B);if(L){let V=await L.catch(()=>null);if(V){Y.status=V.status;let C=Y.headers??={};C["Content-Type"]=V.contentType,C["X-Idempotency-Replay"]="true",X.__idemReplay=V.body;try{return JSON.parse(V.body)}catch{return V.body}}}let w,E,x=new Promise((V,C)=>{w=V,E=C});A2.set(B,x),X.__idemKey=B,X.__idemResolve=w,X.__idemReject=E}).onAfterHandle(async({response:Z,set:Q,store:Y})=>{let X=Y.__idemKey;if(!X)return;let J=Y.__idemResolve,W=$.getDb(),H=Q.status??200,B=typeof Z==="string"?Z:JSON.stringify(Z),L=Q.headers?.["Content-Type"]??"application/json",w={status:H,body:B,contentType:L,expiresAt:Date.now()+S5},E=H>=200&&H<300;try{if(W&&E)await v5(W,X,w)}catch(x){G().logger.warn("idempotency","Failed to persist response",{error:String(x)})}finally{try{J?.(E?w:null)}catch{}A2.delete(X)}}).onError(({store:Z})=>{let Q=Z.__idemKey;if(!Q)return;let Y=Z.__idemReject;try{Y?.(Error("idempotency: handler errored"))}catch{}A2.delete(Q)}).as("global")}import u from"os";import{readFileSync as t5}from"fs";import{join as e5}from"path";var P0={enabled:!1,async scrape(){return`# vibecontrols agent metrics disabled (OTel SDK not initialised)
2
+ import{o as F4,q as J4}from"./index-5wpck4aw.js";import{u as r4,v as U5,w as j5}from"./index-btt96dhd.js";import{E as K4}from"./index-6jzsthh9.js";import{$ as y4,Q as C5,aa as L2,ba as x0,ca as f4,da as u4,ea as i4,fa as b4,ha as E2,ia as l2,ja as o2,ka as I2}from"./index-cjbfremy.js";import{la as E5,qa as I5,sa as C0}from"./index-rw9x93zb.js";import{va as c2}from"./index-pk3ejfc4.js";import{wa as N5,xa as x5,ya as O5,za as M5}from"./index-dxtnaa3g.js";import{Aa as _5}from"./index-4wgjx8bf.js";import{Ja as T0,Wa as T5}from"./index-kmkhjf1c.js";import{Xa as N2}from"./index-0ckffygp.js";import{ab as P2}from"./index-rc79x8fw.js";import{eb as $5,fb as W5,gb as z5,hb as H5,ib as G5,jb as Y2,kb as B5,lb as V5,mb as K5,nb as F5,pb as L5}from"./index-hvjqgb97.js";import{Ab as i0,Eb as M2,Fb as Y0,Gb as Z5,Hb as J5,Ib as j0,Jb as V2,Lb as m,Mb as l,Nb as d4,Ob as n4,Pb as X5,Qb as Y5,tb as l0,ub as v2,vb as d0,wb as X0,xb as n0,yb as R2}from"./index-rqq0k5fc.js";import{Ub as z,Vb as D}from"./index-pgew6sge.js";import{nd as e0,od as t,pd as p0,qd as b2,rd as h2}from"./index-h74va4wd.js";import{Ad as B2,Dd as i2,Id as g,Kd as M0,Ld as c,Md as s,Od as G,Pd as W0,wd as O0,xd as t4,yd as e4,zd as Q5}from"./index-js1xn4sq.js";import{$d as D2,Sd as r0,Td as H0,Vd as f2,Wd as t0,Yd as C2,Zd as d,be as T2,ce as F2,de as n2}from"./index-a4854mwz.js";import{fe as v0,ie as b}from"./index-c7554sg7.js";var R0=typeof new Headers()?.toJSON==="function",A5=($)=>{if(R0)return Object.keys($.toJSON()).join(", ");let Z="",Q=0;return $.forEach((Y,X)=>{if(Q)Z=Z+", "+X;else Z=X;Q++}),Z},A0=($)=>{let{aot:Z=!0,origin:Q=!0,methods:Y=!0,allowedHeaders:X=!0,exposeHeaders:J=!0,credentials:W=!0,maxAge:H=5,preflight:B=!0}=$??{};if(Array.isArray(X))X=X.join(", ");if(Array.isArray(J))J=J.join(", ");let K=typeof Q==="boolean"?void 0:Array.isArray(Q)?Q:[Q],L=new D({name:"@elysiajs/cors",seed:$,aot:Z}),w=K?.some((N)=>N==="*"),E={};if(K){for(let N of K)if(typeof N==="string")E[N]=!0}let x=(N,T,O)=>{if(Array.isArray(N))return N.some((I)=>x(I,T,O));switch(typeof N){case"string":if(O in E)return!0;let I=O.indexOf("://");if(I!==-1)O=O.slice(I+3);return N===O;case"function":return N(T)===!0;case"object":if(N instanceof RegExp)return N.test(O)}return!1},V=(N,T)=>{if(Q===!0){N.headers.vary="*",N.headers["access-control-allow-origin"]=T.headers.get("Origin")||"*";return}if(w){N.headers.vary="*",N.headers["access-control-allow-origin"]="*";return}if(!K?.length)return;if(K.length){let O=T.headers.get("Origin")??"";for(let I=0;I<K.length;I++)if(x(K[I],T,O)===!0){N.headers.vary=Q?"Origin":"*",N.headers["access-control-allow-origin"]=O||"*";return}}N.headers.vary="Origin"},C=(N,T)=>{if(!T)return;if(Y===!0)return N.headers["access-control-allow-methods"]=T??"*";if(Y===!1||!Y?.length)return;if(Y==="*")return N.headers["access-control-allow-methods"]="*";if(!Array.isArray(Y))return N.headers["access-control-allow-methods"]=Y;N.headers["access-control-allow-methods"]=Y.join(", ")},q={};if(typeof J==="string")q["access-control-expose-headers"]=J;if(typeof X==="string")q["access-control-allow-headers"]=X;if(W===!0)q["access-control-allow-credentials"]="true";L.headers(q);function v({set:N,request:T,headers:O}){if(V(N,T),C(N,T.headers.get("access-control-request-method")),X===!0||J===!0){if(X===!0)N.headers["access-control-allow-headers"]=O["access-control-request-headers"];if(J===!0)N.headers["access-control-expose-headers"]=Object.keys(O).join(",")}if(H)N.headers["access-control-max-age"]=H.toString();return new Response(null,{status:204})}if(B)L.options("/",v).options("/*",v);return L.onRequest(function({set:T,request:O}){if(V(T,O),B&&O.method==="OPTIONS")return v({set:T,request:O,headers:R0?O.headers.toJSON():Object.fromEntries(O.headers.entries())});if(C(T,O.method),X===!0||J===!0){let I=A5(O.headers);if(X===!0)T.headers["access-control-allow-headers"]=I;if(J===!0)T.headers["access-control-expose-headers"]=I}})};var k5="/code-server";function k0($,Z,Q=R2){let Y=$.method.toUpperCase();if(Y!=="GET"&&Y!=="HEAD")return null;let X=new URL($.url),J=X.searchParams.get("vt");if(!J||!Q(J,k5,"GET"))return null;X.searchParams.delete("vt");let W=new Headers($.headers);return W.set("x-agent-api-key",Z()),new Request(`${X.origin}${X.pathname}${X.search}`,{method:$.method,headers:W})}import{createHash as D0}from"crypto";var W2="idempotency",S5=300000,S0=1e4,A2=new Map;function D5($,Z,Q,Y){return D0("sha256").update(`${$}|${Z}|${Q}|${Y}`).digest("hex")}async function h5($,Z){let Q=await $.getPluginState(W2,Z);if(!Q)return null;try{let Y=JSON.parse(Q);if(Y.expiresAt<Date.now())return await $.deletePluginState(W2,Z),null;return Y}catch{return null}}async function v5($,Z,Q){await $.setPluginState(W2,Z,JSON.stringify(Q))}async function P5($){let Z=await $.getAllPluginState(W2),Q=Date.now(),Y=0,X=[];for(let J of Z)try{if(JSON.parse(J.value).expiresAt<Q)await $.deletePluginState(W2,J.key),Y+=1;else X.push({key:J.key,updatedAt:J.updatedAt})}catch{await $.deletePluginState(W2,J.key),Y+=1}if(X.length>S0){X.sort((W,H)=>(W.updatedAt??"").localeCompare(H.updatedAt??""));let J=X.slice(0,X.length-S0);for(let W of J)await $.deletePluginState(W2,W.key),Y+=1}if(Y>0)G().logger.info("idempotency",`Swept ${Y} expired/over-cap entries`)}var Q0=null,f5=600000;function b5($){if(Q0)return;Q0=setInterval(()=>{let Z=$.getDb();if(!Z)return;P5(Z).catch((Q)=>{G().logger.warn("idempotency","Sweep failed",{error:String(Q)})})},f5),Q0.unref?.()}function h0($){return b5($),new D({name:"plugin/idempotency"}).onBeforeHandle(async({request:Z,path:Q,set:Y,store:X})=>{if(Z.method!=="POST"&&Z.method!=="PUT")return;let J=Z.headers.get("x-idempotency-key")??Z.headers.get("X-Idempotency-Key");if(!J)return;if(J.length<8||J.length>200)return Y.status=400,{error:"X-Idempotency-Key must be 8\u2013200 chars",code:"BAD_REQUEST"};let W=$.getDb();if(!W)return;let H="no-body";try{let C=await Z.clone().text();H=D0("sha256").update(C).digest("hex")}catch{}let B=D5(Z.method,Q,J,H),K=await h5(W,B);if(K){Y.status=K.status;let V=Y.headers??={};V["Content-Type"]=K.contentType,V["X-Idempotency-Replay"]="true",X.__idemReplay=K.body;try{return JSON.parse(K.body)}catch{return K.body}}let L=A2.get(B);if(L){let V=await L.catch(()=>null);if(V){Y.status=V.status;let C=Y.headers??={};C["Content-Type"]=V.contentType,C["X-Idempotency-Replay"]="true",X.__idemReplay=V.body;try{return JSON.parse(V.body)}catch{return V.body}}}let w,E,x=new Promise((V,C)=>{w=V,E=C});A2.set(B,x),X.__idemKey=B,X.__idemResolve=w,X.__idemReject=E}).onAfterHandle(async({response:Z,set:Q,store:Y})=>{let X=Y.__idemKey;if(!X)return;let J=Y.__idemResolve,W=$.getDb(),H=Q.status??200,B=typeof Z==="string"?Z:JSON.stringify(Z),L=Q.headers?.["Content-Type"]??"application/json",w={status:H,body:B,contentType:L,expiresAt:Date.now()+S5},E=H>=200&&H<300;try{if(W&&E)await v5(W,X,w)}catch(x){G().logger.warn("idempotency","Failed to persist response",{error:String(x)})}finally{try{J?.(E?w:null)}catch{}A2.delete(X)}}).onError(({store:Z})=>{let Q=Z.__idemKey;if(!Q)return;let Y=Z.__idemReject;try{Y?.(Error("idempotency: handler errored"))}catch{}A2.delete(Q)}).as("global")}import u from"os";import{readFileSync as t5}from"fs";import{join as e5}from"path";var P0={enabled:!1,async scrape(){return`# vibecontrols agent metrics disabled (OTel SDK not initialised)
3
3
  `},recordHttpRequest(){},setPluginsLoaded(){}},J2=null,k2=null;async function S2($){if(J2)return J2;if(k2)return k2;return k2=(async()=>{try{let{MeterProvider:Z}=await import("./index-p23tet7a.js").then((m)=>v0(m.default,1)),{PrometheusExporter:Q,PrometheusSerializer:Y}=await import("./index-qwtspxw8.js").then((m)=>v0(m.default,1)),X=new Q({preventServerStart:!0}),J=new Y,H=new Z({readers:[X]}).getMeter("vibecontrols-agent"),B=H.createGauge("vibecontrols_agent_info",{description:"Static info about the agent process; value is always 1."});H.createObservableGauge("vibecontrols_agent_uptime_seconds",{description:"Process uptime in seconds."}).addCallback((V)=>{V.observe(process.uptime())});let L=H.createCounter("vibecontrols_http_requests_total",{description:"Total HTTP requests handled by the agent, labelled by method, route, status."}),w={};H.createObservableGauge("vibecontrols_plugins_loaded",{description:"Plugins loaded by the agent, broken down by status (loaded, failed, etc.)."}).addCallback((V)=>{for(let[C,q]of Object.entries(w))V.observe(q,{status:C})}),B.record(1,{version:$?.version??"unknown",profile:$?.profile??"default"});let x={enabled:!0,async scrape(){let V=await X.collect();if(!V.resourceMetrics)return"";return J.serialize(V.resourceMetrics)},recordHttpRequest(V,C,q){L.add(1,{method:V,route:C,status:String(q)})},setPluginsLoaded(V){w={...V}}};return J2=x,G().logger.info("metrics","OTel Prometheus registry initialised"),x}catch(Z){return G().logger.warn("metrics","Failed to initialise OTel metrics; /metrics will return a stub body",{error:Z instanceof Error?Z.message:String(Z)}),J2=P0,P0}})(),k2}function f0($,Z,Q){if(!J2)return;J2.recordHttpRequest($,Z,Q)}function b0($){if(!J2)return;J2.setPluginsLoaded($)}var c5=new Set(["127.0.0.1","::1"]),c0=!1;function y5(){if(c0)return;if(process.env.METRICS_ANONYMOUS_LOCALHOST==="true")c0=!0,G().logger.warn("metrics","METRICS_ANONYMOUS_LOCALHOST=true \u2014 /metrics is open to TCP loopback peers without an API key. Prefer issuing a scoped API key for your scraper.")}function u5($){let Z=$.replace(/^\[|\]$/g,"");if(Z.startsWith("::ffff:"))return Z.slice(7);return Z}function $0($,Z){let Q=Z?.requestIP($)?.address;if(!Q)return!1;return c5.has(u5(Q))}function y0(){return y5(),new D({name:"routes/metrics"}).get("/metrics",async({request:$,server:Z,set:Q})=>{if(!(process.env.METRICS_ANONYMOUS_LOCALHOST==="true"&&$0($,Z))){let W=m(Object.fromEntries($.headers.entries()));if(!l(W))return Q.status=401,Q.headers["content-type"]="application/json",JSON.stringify({error:"Unauthorized",message:"Invalid or missing API key"})}let J=await(await S2()).scrape();return Q.headers["content-type"]="text/plain; version=0.0.4; charset=utf-8",J})}import{randomBytes as m5,timingSafeEqual as g5}from"crypto";import{chmodSync as p5,existsSync as u0,mkdirSync as l5,readFileSync as d5,unlinkSync as n5,writeFileSync as i5}from"fs";import{dirname as o5,join as a5}from"path";var z2=null;function m0(){return a5(D2(),"pairing-token")}function s5(){return m5(32).toString("base64url")}function r5($,Z){let Q=Buffer.from($),Y=Buffer.from(Z);if(Q.length!==Y.length)return!1;try{return g5(Q,Y)}catch{return!1}}function H6(){if(z2)return z2;let $=m0();try{if(u0($)){let Q=d5($,"utf8").trim();if(Q.length>=32)return z2=Q,Q}}catch{}let Z=s5();try{l5(o5($),{recursive:!0}),i5($,Z,{encoding:"utf8"});try{p5($,384)}catch{}}catch(Q){}return z2=Z,Z}function Z0($){if(!$)return!1;if(!z2)return!1;return r5($,z2)}function g0(){z2=null;try{let $=m0();if(u0($))n5($)}catch{}}function J0($){return $["x-pairing-token"]??$["X-Pairing-Token"]??null}function QQ(){let $=u.hostname(),Z=u.platform(),Q=u.arch(),Y=new Bun.CryptoHasher("sha256");return Y.update(`${$}-${Z}-${Q}`),Y.digest("hex").substring(0,16)}function $Q(){for(let $ of["..","../.."])try{let Z=e5(import.meta.dir,$,"package.json"),Y=JSON.parse(t5(Z,"utf8")).version;if(Y)return Y}catch{}return"0.0.0"}async function ZQ($){let Z=[],Q=$.getProvider("tunnel");if(Q)Z.push(Q);for(let Y of $.listProvidersForType("tunnel")){let X=$.getProviderByName("tunnel",Y.pluginName);if(X&&!Z.includes(X))Z.push(X)}for(let Y of Z){if(!Y.getActiveTunnelUrl)continue;let X=await Y.getActiveTunnelUrl();if(X)return X}return null}function o0({serviceRegistry:$,runFinalize:Z,getDb:Q}){let Y=$Q(),X=QQ();return new D({prefix:"/api/agent"}).get("/identity",()=>({hostname:u.hostname(),platform:u.platform(),architecture:u.arch(),agentVersion:Y,agentInstanceId:p0()})).get("/version",()=>({version:Y,runtime:"bun",runtimeVersion:typeof Bun<"u"?Bun.version:"unknown"})).get("/api-key",({request:J,server:W,set:H})=>{if(!$0(J,W)){let K=m(Object.fromEntries(J.headers.entries()));if(!l(K))return H.status=401,{error:"Unauthorized",message:"Invalid or missing API key"}}return{apiKey:V2()}}).post("/iframe-token",({body:J,request:W,set:H})=>{let B=m(Object.fromEntries(W.headers.entries()));if(!l(B))return H.status=401,{error:"Unauthorized",message:"Invalid or missing API key"};try{if(Array.isArray(J.pathPrefixes)&&J.pathPrefixes.length>0)return d0({pathPrefixes:J.pathPrefixes,methods:J.methods},J.ttlSeconds??void 0);if(!J.pathPrefix)return H.status=400,{error:"BadRequest",message:"Provide either pathPrefix (string) or pathPrefixes (string[])"};return v2(J.pathPrefix,J.ttlSeconds??void 0)}catch(K){return H.status=400,{error:"BadRequest",message:K instanceof Error?K.message:String(K)}}},{body:z.Object({pathPrefix:z.Optional(z.String({minLength:1})),pathPrefixes:z.Optional(z.Array(z.String({minLength:1}),{minItems:1,maxItems:16})),methods:z.Optional(z.Array(z.String({minLength:1}),{minItems:1,maxItems:8})),ttlSeconds:z.Optional(z.Number())})}).post("/terminal-exchange",({body:J,set:W})=>{let{sid:H,token:B}=J;if(!H||!B)return W.status=400,{error:"BadRequest",message:"sid and token required"};if(!l0(H))return W.status=400,{error:"BadRequest",message:"invalid sid"};let K=`/terminal/${H}`,L=n0(B,K);if(!L.ok)return G().logger.warn("terminal-exchange","iframe token rejected",{sid:H,reason:L.reason}),W.status=401,{error:"Unauthorized",message:"invalid iframe token",code:L.reason==="expired"?"expired":L.reason==="replayed"?"replayed":"invalid"};let w=i0(H,600),E=`vt_term_${H}`;return W.headers["set-cookie"]=`${E}=${w.token}; HttpOnly; Secure; SameSite=None; Path=/terminal/${H}; Max-Age=600`,W.status=204,null},{body:z.Object({sid:z.String({minLength:1}),token:z.String({minLength:1})})}).post("/ui-exchange",({body:J,set:W})=>{let{plugin:H,token:B}=J;if(!H||!B)return W.status=400,{error:"BadRequest",message:"plugin and token required"};if(!M2(H))return W.status=400,{error:"BadRequest",message:"invalid plugin name"};let K=`/ui/${H}`;if(!X0(B,K))return W.status=401,{error:"Unauthorized",message:"invalid iframe token"};let L=Y0(H,600),w=`vt_ui_${H}`;return W.headers["set-cookie"]=`${w}=${L.token}; HttpOnly; Secure; SameSite=None; Path=/ui/${H}/; Max-Age=600`,W.status=204,null},{body:z.Object({plugin:z.String({minLength:1}),token:z.String({minLength:1})})}).post("/ui-exchange-plugin",({body:J,set:W})=>{let{plugin:H,token:B}=J;if(!H||!B)return W.status=400,{error:"BadRequest",message:"plugin and token required"};if(!M2(H))return W.status=400,{error:"BadRequest",message:"invalid plugin name"};if(![`/api/plugins/${H}/ui`,`/${H}`].find((x)=>X0(B,x)))return W.status=401,{error:"Unauthorized",message:"invalid iframe token"};let w=Y0(H,600),E=`vt_ui_${H}`;return W.headers["set-cookie"]=`${E}=${w.token}; HttpOnly; Secure; SameSite=None; Path=/api/plugins/${H}/ui/; Max-Age=600`,W.status=204,null},{body:z.Object({plugin:z.String({minLength:1}),token:z.String({minLength:1})})}).get("/system",({request:J,set:W})=>{let H=m(Object.fromEntries(J.headers.entries()));if(!l(H))return W.status=401,{error:"Unauthorized",message:"Invalid or missing API key"};return{machineId:X,hostname:u.hostname(),platform:u.platform(),arch:u.arch(),release:u.release(),cpus:u.cpus().length,totalMemory:u.totalmem(),freeMemory:u.freemem(),uptime:u.uptime(),bunVersion:typeof Bun<"u"?Bun.version:void 0,agentVersion:Y,homeDir:u.homedir(),cwd:process.cwd(),environment:"production"}}).get("/tunnel",async({request:J,set:W})=>{let H=Object.fromEntries(J.headers.entries()),B=l(m(H)),K=Z0(J0(H));if(!B&&!K)return W.status=401,{error:"Unauthorized",message:"Provide x-agent-api-key OR x-pairing-token to read tunnel URL"};let L=await ZQ($);if(!L)return{tunnelUrl:null,message:"No tunnel provider registered"};return{tunnelUrl:L}}).get("/status",()=>{let J=["tunnel","session","ai"].filter((W)=>$.hasProvider(W));return{state:G().getBootState(),status:G().getBootState(),version:Y,providers:J,timestamp:new Date().toISOString()}}).get("/gateway-auth",()=>({configured:g.isConfigured(),config:P2(g.getConfig()),state:G().getBootState()})).post("/retry-config",async({set:J})=>{let{getFinalizeRetryHandle:W}=await import("./finalize-retry-handle-registry-xnm9kxry.js"),H=W();if(!H)return J.status=409,{ok:!1,error:"No finalize retry worker is active. The agent either never had cached credentials to retry with, or it already reached the ready state."};let B=await H.forceRetryNow();if(!B.ok)J.status=503;return{ok:B.ok,error:B.ok?void 0:B.error,state:G().getBootState(),worker:H.getState()}}).post("/gateway-auth",async({body:J,request:W,set:H})=>{let B=G().getBootState(),K=Object.fromEntries(W.headers.entries());if(B==="ready"){let N=m(K);if(!l(N))return H.status=401,{success:!1,state:B,error:"Unauthorized: API key required to reconfigure"}}else{let N=m(K),T=J0(K),O=l(N),I=Z0(T);if(!O&&!I)return H.status=401,{success:!1,state:B,error:"Unauthorized: provide x-agent-api-key OR x-pairing-token for bootstrap"}}let{clientId:L,clientSecret:w,workspaceId:E,globalGatewayUrl:x,workspaceGatewayUrl:V}=J;if(!L||!w||!E||!x||!V)return H.status=400,{success:!1,state:G().getBootState(),error:"clientId, clientSecret, workspaceId, globalGatewayUrl, and workspaceGatewayUrl are required"};let C,q;try{C=B2(x,"globalGatewayUrl"),q=B2(V,"workspaceGatewayUrl")}catch(N){return H.status=400,{success:!1,state:G().getBootState(),error:N instanceof Error?N.message:String(N)}}{let N=c()??G();try{await h2({clientId:L,clientSecret:w,workspaceId:E,ownerUserId:J.ownerUserId,organizationId:J.organizationId,globalGatewayUrl:C,workspaceGatewayUrl:q,agentRecordId:J.agentRecordId,scopes:J.scopes,...J.storageAdapter?{storageAdapter:J.storageAdapter}:{},...J.storageOptions?{storageOptions:J.storageOptions}:{},...J.dbPath?{dbPath:J.dbPath}:{}},{dir:N.dataDir,scope:N.name})}catch(T){return H.status=500,{success:!1,state:G().getBootState(),error:`Failed to persist gateway credentials to secrets backend: ${T instanceof Error?T.message:String(T)}`}}}let v=G().getBootState();if(v==="ready"){let N=Q();if(N){if(await N.setConfig("gateway-auth:clientId",L),await N.setConfig("gateway-auth:clientSecret",w),await N.setConfig("gateway-auth:workspaceId",E),J.organizationId)await N.setConfig("gateway-auth:organizationId",J.organizationId);if(await N.setConfig("gateway-auth:globalGatewayUrl",C),await N.setConfig("gateway-auth:workspaceGatewayUrl",q),J.agentRecordId)await N.setConfig("gateway-auth:agentRecordId",J.agentRecordId)}g.configure({globalGatewayUrl:C,workspaceGatewayUrl:q,clientId:L,clientSecret:w,workspaceId:E,organizationId:J.organizationId}),G().logger.info("preconfig","Gateway credentials re-configured (agent was already ready)");let T=!!(J.storageAdapter||J.storageOptions||J.dbPath);return{success:!0,state:v,message:T?"Gateway auth re-configured. Restart the agent (vibe restart) to apply the new storage configuration.":"Gateway auth re-configured"}}return G().logger.info("preconfig","Gateway credentials received \u2014 beginning finalize (background)"),g0(),Z({clientId:L,clientSecret:w,workspaceId:E,organizationId:J.organizationId,globalGatewayUrl:C,workspaceGatewayUrl:q},{agentRecordId:J.agentRecordId,scopes:J.scopes}).catch((N)=>{G().logger.error("preconfig","Background finalize threw",{error:N instanceof Error?N.message:String(N)})}),H.status=202,{success:!0,state:G().getBootState(),agentRecordId:J.agentRecordId,message:"Gateway credentials accepted; finalize is running in the background. Poll /health/ready for completion."}},{body:z.Object({clientId:z.Optional(z.String()),clientSecret:z.Optional(z.String()),workspaceId:z.Optional(z.String()),ownerUserId:z.Optional(z.String()),organizationId:z.Optional(z.String()),globalGatewayUrl:z.Optional(z.String()),workspaceGatewayUrl:z.Optional(z.String()),scopes:z.Optional(z.Array(z.String())),agentRecordId:z.Optional(z.String()),storageAdapter:z.Optional(z.String()),storageOptions:z.Optional(z.Record(z.String(),z.String())),dbPath:z.Optional(z.String())})})}import{existsSync as $2,mkdirSync as JQ,rmSync as a0,readdirSync as Q4}from"fs";import{join as y2}from"path";function a($){return y2(F2(),"agents",d($))}function XQ(){let $=y2(F2(),"agents");if(!$2($))return[];return Q4($,{withFileTypes:!0}).filter((Z)=>Z.isDirectory()).map((Z)=>Z.name).filter((Z)=>/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(Z))}function $4($){return y2(F2(),"agents",d($))}function z0($){return t({dir:$4($)})}function s0($,Z){return b2(Z,{dir:$4($),scope:d($)})}function K2($){let Z=f2(),Q=H0().find((J)=>J.name===$),Y=s.get($),X={name:$,isDefault:$===Z,isRunning:Q?.status==="running",attached:Y!==void 0,bootState:Y?Y.getBootState():null,dataDir:Y?Y.dataDir:null};if(Q)X.port=Q.port,X.pid=Q.pid,X.startTime=Q.startTime;if($2(a($)))X.config=P2(z0($));return X}function Z4($={}){let Z=$.serviceManagerFactory?$.serviceManagerFactory():new c2;return new D({prefix:"/api/profiles"}).get("/",()=>{let Q=XQ(),Y=f2(),X=new Set(Q);return X.add(Y),[...X].sort().map((J)=>K2(J))}).post("/",async({body:Q,set:Y})=>{try{let X=d(Q.name),J=a(X);if($2(J))return Y.status=409,{error:"exists",message:`Profile '${X}' already exists.`};let W;if(Q.copyFrom){let H=d(Q.copyFrom);if(!$2(a(H)))return Y.status=400,{error:"copy-source-missing",message:`Profile '${H}' does not exist.`};W=z0(H),delete W["static-api-key"],delete W.agentRecordId,delete W.apiKeys}else W=e0();if(Q.gatewayUrl)W.globalGatewayUrl=Q.gatewayUrl;if(Q.workspaceGatewayUrl)W.workspaceGatewayUrl=Q.workspaceGatewayUrl;if(Q.clientId)W.clientId=Q.clientId;if(Q.clientSecret)W.clientSecret=Q.clientSecret;if(Q.workspaceId)W.workspaceId=Q.workspaceId;if(Q.organizationId)W.organizationId=Q.organizationId;JQ(J,{recursive:!0}),s0(X,W);try{W0(X)}catch(H){G().logger.warn("profile-mgmt",`In-process attach failed for '${X}'`,{error:String(H)})}if(G().logger.info("profile-mgmt",`Created profile '${X}' at ${J}`),Q.start){let H={name:X,port:Q.port??0,daemon:!0,dbPath:T2(),profile:X};await Z.startDaemon(H)}return Y.status=201,K2(X)}catch(X){return Y.status=400,{error:"create-failed",message:X instanceof Error?X.message:String(X)}}},{body:z.Object({name:z.String(),gatewayUrl:z.Optional(z.String()),workspaceGatewayUrl:z.Optional(z.String()),clientId:z.Optional(z.String()),clientSecret:z.Optional(z.String()),workspaceId:z.Optional(z.String()),organizationId:z.Optional(z.String()),copyFrom:z.Optional(z.String()),start:z.Optional(z.Boolean()),port:z.Optional(z.Number())})}).get("/:name",({params:Q,set:Y})=>{try{let X=d(Q.name);if(!$2(a(X)))return Y.status=404,{error:"not-found",message:`No profile '${X}'.`};return K2(X)}catch(X){return Y.status=400,{error:"bad-request",message:X instanceof Error?X.message:String(X)}}},{params:z.Object({name:z.String()})}).put("/:name",({params:Q,body:Y,set:X})=>{try{let J=d(Q.name);if(!$2(a(J)))return X.status=404,{error:"not-found",message:`No profile '${J}'.`};let W=["static-api-key","apiKeys","agentRecordId"];for(let K of W)if(K in Y)return X.status=400,{error:"forbidden-field",message:`Field '${K}' is managed via dedicated commands (vibe key rotate / vibe profile create). It cannot be patched here.`};if("registry"in Y)return X.status=400,{error:"forbidden-field",message:"Field 'registry' cannot be patched via this endpoint. Use POST /api/agent/registry with operator confirmation (VIBE_ALLOW_REGISTRY_CHANGE=1) so the change is auditable."};let B={...z0(J),...Y};return s0(J,B),K2(J)}catch(J){return X.status=400,{error:"update-failed",message:J instanceof Error?J.message:String(J)}}},{params:z.Object({name:z.String()}),body:z.Record(z.String(),z.Any())}).delete("/:name",async({params:Q,body:Y,query:X,set:J})=>{try{let W=d(Q.name);if(W===f2())return J.status=409,{error:"is-default",message:`Cannot delete active default profile '${W}'. Switch to another profile first.`};let H=X?.purge==="true"||X?.purge==="1",B=$2(a(W)),K=s.has(W);if(!B&&!K)return J.status=404,{error:"not-found",message:`No profile '${W}'.`};if(B&&!H&&!Y?.confirm)return J.status=400,{error:"confirm-required",message:"Pass { confirm: true } in the body or `?purge=true` in the query to delete the on-disk dataDir (destructive)."};try{await Z.stop(W)}catch{}try{await s.destroy(W)}catch(L){G().logger.warn("profile-mgmt",`In-process detach failed for '${W}'`,{error:String(L)})}if(B)if(Y?.keepConfig)for(let L of Q4(a(W))){if(L==="config.json")continue;a0(y2(a(W),L),{recursive:!0,force:!0})}else a0(a(W),{recursive:!0,force:!0});return G().logger.info("profile-mgmt",`Deleted profile '${W}'`),{ok:!0,deleted:W,keptConfig:!!Y?.keepConfig,detached:K,purged:B}}catch(W){return J.status=400,{error:"delete-failed",message:W instanceof Error?W.message:String(W)}}},{params:z.Object({name:z.String()}),query:z.Optional(z.Object({purge:z.Optional(z.String())})),body:z.Optional(z.Object({confirm:z.Optional(z.Boolean()),keepConfig:z.Optional(z.Boolean())}))}).post("/:name/switch",async({params:Q,set:Y})=>{try{let X=d(Q.name);if(!$2(a(X)))return Y.status=404,{error:"not-found",message:`No profile '${X}'.`};return await r0(()=>t0(X)),G().logger.info("profile-mgmt",`Default profile switched to '${X}'`),{ok:!0,defaultProfile:X}}catch(X){return Y.status=400,{error:"switch-failed",message:X instanceof Error?X.message:String(X)}}},{params:z.Object({name:z.String()})}).post("/:name/start",async({params:Q,body:Y,set:X})=>{try{let J=d(Q.name);if(!$2(a(J)))return X.status=404,{error:"not-found",message:`No profile '${J}'.`};try{W0(J)}catch(H){G().logger.warn("profile-mgmt",`In-process attach failed for '${J}'`,{error:String(H)})}if(!H0().some((H)=>H.name===J&&H.status==="running")){let H={name:J,port:Y?.port??0,daemon:!0,dbPath:T2(),profile:J};await Z.startDaemon(H)}return K2(J)}catch(J){return X.status=500,{error:"start-failed",message:J instanceof Error?J.message:String(J)}}},{params:z.Object({name:z.String()}),body:z.Optional(z.Object({port:z.Optional(z.Number())}))}).post("/:name/stop",async({params:Q,set:Y})=>{try{let X=d(Q.name);try{await Z.stop(X)}catch{}try{await s.destroy(X)}catch(J){G().logger.warn("profile-mgmt",`In-process detach failed for '${X}'`,{error:String(J)})}return K2(X)}catch(X){return Y.status=500,{error:"stop-failed",message:X instanceof Error?X.message:String(X)}}},{params:z.Object({name:z.String()})})}function YQ(){let $=process.memoryUsage(),Z=process.resourceUsage(),Q=Z.userCPUTime/1000,Y=Z.systemCPUTime/1000,X=Q+Y,J=s.list().map((W)=>{let H;try{H=J4(W.spawnOwnerKey).length}catch{H=0}return{name:W.name,status:W.getBootState(),childPidCount:H,cpuMs:X,heapBytes:$.heapUsed,dataDir:W.dataDir}});return{process:{pid:process.pid,uptimeSeconds:process.uptime(),cpuUserMs:Q,cpuSystemMs:Y,heapUsedBytes:$.heapUsed,heapTotalBytes:$.heapTotal,rssBytes:$.rss},profiles:J,notes:{perProfileCpu:"deferred",perProfileHeap:"deferred"}}}function X4(){return new D({prefix:"/api/profile-stats"}).get("/",()=>YQ())}function u2($,Z){return Promise.race([$,new Promise((Q,Y)=>setTimeout(()=>Y(Error(`timeout after ${Z}ms`)),Z))])}function WQ($){let Z=$ instanceof Error?$.message:String($);return/ENOENT/.test(Z)||/no such file or directory/i.test(Z)}async function Y4($){let Q=`__health__:probe:${typeof crypto<"u"&&typeof crypto.randomUUID==="function"?crypto.randomUUID():`${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`}`,Y=String(Date.now());if(await u2($.setConfig(Q,Y),2000),await u2($.getConfig(Q),2000)!==Y)throw Error("round-trip mismatch");try{await u2($.deleteConfig(Q),500)}catch{}}async function zQ($,Z){if(!$)return{ok:!1,message:"database not opened"};let Q=performance.now();try{return await Y4($),{ok:!0,durationMs:performance.now()-Q}}catch(Y){if(Z&&WQ(Y))try{return(await import("fs")).mkdirSync(Z,{recursive:!0}),await Y4($),{ok:!0,message:`recovered: dbPath ${Z} was missing \u2014 recreated`,durationMs:performance.now()-Q}}catch(X){return{ok:!1,message:`ENOENT on dbPath ${Z}: ${X instanceof Error?X.message:String(X)}`,durationMs:performance.now()-Q}}return{ok:!1,message:Y instanceof Error?Y.message:String(Y),durationMs:performance.now()-Q}}}function W4($,Z){if(!$)return{ok:!1,message:"no service registry"};let Y=G().getBootState()==="awaiting-config";if(Z==="tunnel"){let X=$.getProvider("tunnel");if(!X&&process.env.AGENT_TUNNEL==="false")return{ok:!0,message:"tunnel disabled via AGENT_TUNNEL=false"};if(X)return{ok:!0,message:`provider: ${X.name}`};return{ok:!1,message:Y?"agent is awaiting-config \u2014 POST OAuth credentials to /api/agent/gateway-auth to register tunnel provider":"no tunnel provider registered"}}if(Z==="session"){let X=$.getProvider("session");if(X)return{ok:!0,message:`provider: ${X.name}`};return{ok:!1,message:Y?"agent is awaiting-config \u2014 POST OAuth credentials to /api/agent/gateway-auth to register session provider":"no session provider registered"}}return{ok:!0}}async function HQ($){if(!$)return{};let Z={};for(let Q of $.getAllPlugins()){let Y=Q.getHealth;if(typeof Y!=="function")continue;let X=performance.now();try{let J=await u2(Promise.resolve(Y.call(Q)),2000);Z[Q.name]={ok:J?.ok!==!1,message:J?.message,durationMs:performance.now()-X}}catch(J){Z[Q.name]={ok:!1,message:J instanceof Error?J.message:String(J),durationMs:performance.now()-X}}}return Z}function z4($){let Z=$&&"serviceRegistry"in $?$:{serviceRegistry:$};return new D({prefix:"/health"}).get("/",()=>{return{status:"ok",lifecycleState:Z.serviceRegistry?.getService("agent","lifecycle")?.getState()??"running",bootState:G().getBootState(),timestamp:new Date().toISOString(),uptime:process.uptime()}}).get("/live",()=>({status:"ok"})).get("/ready",async({set:Q})=>{let X=Z.serviceRegistry?.getService("agent","lifecycle")?.getState()??"running",J=G().getBootState(),W={};W.boot={ok:J==="ready",message:J==="ready"?void 0:`boot state ${J}`},W.lifecycle={ok:X==="running",message:X==="running"?void 0:`lifecycle ${X}`},W.db=await zQ(Z.getDb?.()??null,Z.getDbPath?.()??null),W.tunnel=W4(Z.serviceRegistry,"tunnel"),W.session=W4(Z.serviceRegistry,"session");try{let{gatewayClient:V}=await import("./gateway-client-9kwnmk89.js");if(!V.isConfigured())W.registration={ok:!0,message:"not configured"};else{let C=Z.getDb?.()??null;if(C?await C.getConfig("gateway-auth:agentRecordId"):null)W.registration={ok:!0};else{let v=G().getDegradedReasons().some((N)=>N.plugin==="agent-registration");W.registration=v?{ok:!1,message:"agent failed to register with the workspace after retries"}:{ok:!0,message:"registering"}}}}catch(V){W.registration={ok:!0,message:`registration check skipped: ${V instanceof Error?V.message:String(V)}`}}let H=await HQ(Z.getPluginManager?.()??null),B=Object.values(W).every((V)=>V.ok)&&Object.values(H).every((V)=>V.ok);if(!B)Q.status=503;let K=J==="degraded"?G().getDegradedReasons():[],L=G().name,w={};for(let V of s.list())w[V.name]={bootState:V.getBootState(),ok:V.getBootState()==="ready",degradedReasons:V.getDegradedReasons()};let E=G().getLastFinalizeError(),x={status:B?"ok":"degraded",lifecycleState:X,bootState:J,daemon:{profile:L,bootState:J,ok:J==="ready"},profiles:w,components:W,plugins:H,degradedReasons:K,lastFinalizeError:E,timestamp:new Date().toISOString()};if(!B)G().logger.warn("health","Readiness probe failed",{components:W,plugins:H,bootState:J});return x})}var m2=0,H4=0;function G4(){return new D({name:"inflight-tracker"}).onRequest(()=>{m2+=1}).onAfterResponse(()=>{m2=Math.max(0,m2-1),H4+=1})}function B4(){return new D({prefix:"/api/stats"}).get("/inflight",()=>({inflight:Math.max(0,m2-1),totalServed:H4}))}var G0=Object.freeze(["code","code-insiders","codium","cursor","idea","pycharm","webstorm","goland","phpstorm","rubymine","clion","rider","zed","subl","vim","nvim","emacs","neovide","fleet","helix"]),GQ=new Set(G0),BQ=new Set(["--new-window","-n","--reuse-window","-r","--wait","-w","--add","--goto"]);function V4($){try{return Bun.which($)??null}catch{return null}}function L4(){return new D({prefix:"/api/editor"}).get("/allowlist",()=>({commands:[...G0]})).get("/detect",async()=>{let $=G0.map((Y)=>[Y,V4(Y)]),Z=[],Q={};for(let[Y,X]of $)if(X)Z.push(Y),Q[Y]=X;return{available:Z,paths:Q}}).post("/open",async({body:$,set:Z})=>{let{command:Q,path:Y,args:X=[]}=$;if(!GQ.has(Q))return Z.status=400,{ok:!1,error:`Command '${Q}' is not in the IDE allowlist`};for(let H of X)if(typeof H!=="string"||!BQ.has(H))return Z.status=400,{ok:!1,error:`Argument '${H}' is not in the flag allowlist`};let J;try{J=(await K4(Y,{mustExist:!0})).realPath}catch(H){return Z.status=400,{ok:!1,error:`Invalid path: ${H instanceof Error?H.message:String(H)}`}}let W=V4(Q);if(!W)return Z.status=404,{ok:!1,error:`'${Q}' is not installed or not on PATH on this agent`};try{let H=F4({owner:`editor:${Q}`,cmd:[W,...X,J],env:process.env,stdout:"ignore",stderr:"ignore",stdin:"ignore",meta:{command:Q,path:J}});return G().logger.info("editor",`Launched ${Q} on ${J}`,{pid:H.pid}),G().audit.emit("agent","editor.open",{command:Q,path:J,pid:H.pid}),{ok:!0,command:Q,resolvedPath:J,pid:H.pid}}catch(H){return Z.status=500,{ok:!1,error:`Failed to spawn editor: ${H instanceof Error?H.message:String(H)}`}}},{body:z.Object({command:z.String({minLength:1,maxLength:40}),path:z.String({minLength:1,maxLength:4096}),args:z.Optional(z.Array(z.String({maxLength:32})))})})}var N4=Symbol.for("@vibecontrols/plugin-sdk:contextProviders@1");function VQ(){let $=globalThis,Z=$[N4];if(Z)return Z;let Q=new Map;return $[N4]=Q,Q}function B0(){return Array.from(VQ().values())}function _4(){return(c()??G()).dataDir}function n(){let $=t({dir:_4()});return{ownerUserId:$.ownerUserId,workspaceId:$.workspaceId}}function g2(){return t({dir:_4()}).agentRecordId}function U4($){if(!$)return null;try{return new URL($).host}catch{return null}}async function j4($,Z){let Q=$.getPluginManager(),Y=Q?Q.getPluginDetails().map((H)=>({pluginName:H.pluginName,packageName:H.packageName,version:H.version,tags:H.tags??[]})):[],X=process.memoryUsage(),J=U4($.getTunnelHost?.()??null),W;try{W=L2(n()).map((H)=>({id:H.id,label:H.label,host:U4(H.tunnelUrl),agentRecordId:H.agentRecordId??null,permissions:H.permissions,canForward:H.permissions.includes("mesh:forward"),lastReachable:H.lastReachable??null}))}catch{W=[]}return{pluginName:"agent",description:"vibecontrols-agent runtime self-report",generatedAt:new Date().toISOString(),data:{profile:Z.profile,vibeId:Z.vibeId??null,runtime:{bunVersion:typeof Bun<"u"?Bun.version:null,nodeVersion:process.versions.node??null,platform:process.platform,arch:process.arch,pid:process.pid,uptimeSeconds:Math.round(process.uptime()),memory:{rssMB:Math.round(X.rss/1048576),heapUsedMB:Math.round(X.heapUsed/1048576)}},agent:{version:$.getAgentVersion?.()??null,profileRegistered:C2(),tunnelHost:J},plugins:{count:Y.length,items:Y},mesh:{peerCount:W.length,peers:W}}}}var KQ=2000,x4=1000;async function FQ($,Z){let Q,Y=new Promise((X,J)=>{Q=setTimeout(()=>J(Error(`timeout after ${Z}ms`)),Z)});try{return await Promise.race([$,Y])}finally{if(Q)clearTimeout(Q)}}async function O4($,Z){let Q=performance.now(),Y=$.timeoutMs??KQ;try{let X=await FQ($.getContext(Z),Y);if(!X.generatedAt)X.generatedAt=new Date().toISOString();return{ok:!0,data:X,durationMs:Math.round(performance.now()-Q)}}catch(X){return{ok:!1,error:X.message??String(X),durationMs:Math.round(performance.now()-Q)}}}class V0{deps;inflight=new Map;constructor($){this.deps=$}async aggregate($){let Z=`${$.profile}::${$.vibeId??""}`,Q=this.inflight.get(Z);if(Q&&Date.now()-Q.ts<x4)return Q.promise;let Y=this.doAggregate($).finally(()=>{setTimeout(()=>{let X=this.inflight.get(Z);if(X&&X.promise===Y)this.inflight.delete(Z)},x4).unref?.()});return this.inflight.set(Z,{ts:Date.now(),promise:Y}),Y}async selfContext($){return j4(this.deps,$)}async pluginContext($,Z){let Q=B0().find((Y)=>Y.name===$);if(!Q)return null;return O4(Q,Z)}async pluginsContext($){let Z=B0(),Q=await Promise.allSettled(Z.map((X)=>O4(X,$))),Y={};return Z.forEach((X,J)=>{let W=Q[J];if(W&&W.status==="fulfilled")Y[X.name]=W.value;else if(W&&W.status==="rejected")Y[X.name]={ok:!1,error:W.reason instanceof Error?W.reason.message:String(W.reason),durationMs:0}}),Y}async doAggregate($){let[Z,Q]=await Promise.all([this.selfContext($),this.pluginsContext($)]);return{agent:Z,plugins:Q}}}function p2($){let Z=$.vibeId;if(typeof Z!=="string")return;let Q=Z.trim();return Q.length>0&&Q.length<=128?Q:void 0}function M4($){let Z=new V0($);return new D({prefix:"/api/agent/context"}).get("/",async({params:Q,query:Y})=>{let X=Q?.profile??"default",J=p2(Y);return Z.aggregate({profile:X,vibeId:J})},{query:z.Object({vibeId:z.Optional(z.String())})}).get("/agent",async({params:Q,query:Y})=>{let X=Q?.profile??"default",J=p2(Y);return Z.selfContext({profile:X,vibeId:J})},{query:z.Object({vibeId:z.Optional(z.String())})}).get("/plugins",async({params:Q,query:Y})=>{let X=Q?.profile??"default",J=p2(Y);return Z.pluginsContext({profile:X,vibeId:J})},{query:z.Object({vibeId:z.Optional(z.String())})}).get("/plugins/:name",async({params:Q,query:Y,set:X})=>{let J=Q?.profile??"default",W=Q?.name;if(!W)return X.status=400,{error:"missing plugin name"};let H=p2(Y),B=await Z.pluginContext(W,{profile:J,vibeId:H});if(!B)return X.status=404,{error:`no context provider registered under name "${W}"`};return B},{params:z.Object({name:z.String()}),query:z.Object({vibeId:z.Optional(z.String())})})}var Z2="autoupdate",LQ=86400000,T4=300000,NQ=900000,S={timer:null,running:!1,profile:"default",lastCheckAt:null,lastCheck:null,lastUpdateAt:null,lastUpdate:null,startedAt:null};function K0(){let $=(process.env.VIBE_AUTOUPDATE??"").trim().toLowerCase();return $==="0"||$==="false"||$==="off"||$==="no"}function E4(){if(K0())return!1;try{return t().autoUpdate!==!1}catch{return!0}}function F0(){let $=Number(process.env.VIBE_AUTOUPDATE_INTERVAL_MS);if(Number.isFinite($)&&$>0)return Math.max(NQ,$);return LQ}async function L0($){let Z=G().logger;if(S.running)return{check:S.lastCheck??await C4(),update:null};S.running=!0;try{let Q=await E2();if(S.lastCheck=Q,S.lastCheckAt=new Date().toISOString(),Q.error)Z.debug(Z2,`Update check failed: ${Q.error}`);else if(Q.hasUpdate)Z.info(Z2,`New agent version available: ${Q.current} \u2192 ${Q.latest}`);let Y=$?.force||E4();if(!Q.hasUpdate||!Y)return{check:Q,update:null};Z.info(Z2,`Auto-updating ${Q.current} \u2192 ${Q.latest} (idle-gated restart)\u2026`);let X=await l2({restart:!0,name:S.profile,onLog:(J)=>Z.info(Z2,J)});if(S.lastUpdate=X,S.lastUpdateAt=new Date().toISOString(),X.ok&&X.updated)Z.info(Z2,`Auto-update applied: now ${X.current} (restart: ${X.restart}).`);else if(!X.ok)Z.warn(Z2,`Auto-update failed: ${X.error}`);return{check:Q,update:X}}catch(Q){return Z.warn(Z2,`Auto-update tick threw: ${Q instanceof Error?Q.message:String(Q)}`),{check:await C4(),update:null}}finally{S.running=!1}}async function C4(){if(S.lastCheck)return S.lastCheck;let $=await E2();return S.lastCheck=$,S.lastCheckAt=new Date().toISOString(),$}function I4($){if(S.timer)clearTimeout(S.timer);S.timer=setTimeout(()=>{L0().finally(()=>{if(S.startedAt)I4(F0())})},$),S.timer.unref?.()}function _Q($){let Z=G().logger;if(S.profile=$?.profile||process.env.VIBECONTROLS_PROFILE||"default",S.startedAt=new Date().toISOString(),K0()){Z.info(Z2,"Autoupdate disabled via VIBE_AUTOUPDATE \u2014 not scheduling.");return}Z.info(Z2,`Autoupdate scheduled (first check in ${Math.round(T4/60000)}m, then every ${Math.round(F0()/3600000)}h).`),I4(T4)}function L7(){if(S.timer)clearTimeout(S.timer),S.timer=null;S.startedAt=null}function w4($){if(b2({autoUpdate:$}),$&&!S.startedAt)_Q({profile:S.profile})}function N0(){let $=!0;try{$=t().autoUpdate!==!1}catch{}return{enabled:E4(),envKillSwitch:K0(),configEnabled:$,scheduled:!!S.startedAt,intervalMs:F0(),profile:S.profile,startedAt:S.startedAt,lastCheckAt:S.lastCheckAt,lastCheck:S.lastCheck,lastUpdateAt:S.lastUpdateAt,lastUpdate:S.lastUpdate}}import{existsSync as q4}from"fs";import{join as R4}from"path";var UQ=600000,_0=1e6;function jQ(){let $=N2(),Z=$.which("bun")??`bun${$.executableSuffix}`,Q=R4(import.meta.dir,"cli.js");if(q4(Q))return{runner:Z,prefix:[Q]};let Y=R4(import.meta.dir,"..","cli.ts");if(q4(Y))return{runner:Z,prefix:[Y]};let X=$.which("vibe");if(X)return{runner:X,prefix:[]};return null}function A4($){if($.length<=_0)return $;return $.slice(0,_0)+`
4
- \u2026[output truncated at ${_0} bytes]`}async function d2($,Z={}){let Q=jQ();if(!Q)return{ok:!1,exitCode:null,stdout:"",stderr:"Could not locate the vibe CLI to execute (no dist/cli.js, source, or PATH entry).",timedOut:!1,argv:$,command:"(unresolved)"};let Y=[...Q.prefix,...$],X=[Q.runner,...Y].join(" ");try{let J=Bun.spawn([Q.runner,...Y],{cwd:Z.cwd,env:{...process.env,VIBE_AUTO_ACCEPT:"1",CI:"1",NO_COLOR:"1",...Z.env},stdout:"pipe",stderr:"pipe"}),W=Z.timeoutMs??UQ,H=!1,B=setTimeout(()=>{H=!0;try{J.kill()}catch{}},W),[K,L,w]=await Promise.all([new Response(J.stdout).text(),new Response(J.stderr).text(),J.exited]);return clearTimeout(B),{ok:!H&&w===0,exitCode:w,stdout:A4(K),stderr:A4(L),timedOut:H,argv:$,command:X}}catch(J){return{ok:!1,exitCode:null,stdout:"",stderr:`Failed to spawn vibe CLI: ${J instanceof Error?J.message:String(J)}`,timedOut:!1,argv:$,command:X}}}async function k4(){let{Command:$}=await import("./esm-6f3dfn6v.js"),{registerCoreCommands:Z}=await import("./register-core-0d4adnqp.js"),Q=new $;Q.name("vibe").option("--json").option("--plain").option("-y, --yes").option("-p, --profile <name>");try{Z(Q)}catch{}let Y=new Set(["nuke","kill","gc","stop","rollback","deploy"]),X=[];for(let J of Q.commands){let W=J.name();if(!W||W==="help")continue;X.push({name:W,description:J.description()||"",usage:J.usage()||"",options:J.options.map((H)=>({flags:H.flags,description:H.description||""})),group:"core",destructive:Y.has(W)})}return X.sort((J,W)=>J.name.localeCompare(W.name))}import{spawn as xQ}from"child_process";import{writeFileSync as OQ,mkdirSync as MQ}from"fs";import{tmpdir as TQ}from"os";import{join as S4}from"path";var CQ="@vibecontrols/agent";function D4($){let Z=N2(),Q=Z.which("bun")??`bun${Z.executableSuffix}`,Y=Z.which("npm")??`npm${Z.executableSuffix}`,X=n2(),J=$.delayMs??3000,W=$.pids.filter((B)=>Number.isInteger(B)&&B>0),H=`// vibecontrols agent self-uninstall reaper (auto-generated)
4
+ \u2026[output truncated at ${_0} bytes]`}async function d2($,Z={}){let Q=jQ();if(!Q)return{ok:!1,exitCode:null,stdout:"",stderr:"Could not locate the vibe CLI to execute (no dist/cli.js, source, or PATH entry).",timedOut:!1,argv:$,command:"(unresolved)"};let Y=[...Q.prefix,...$],X=[Q.runner,...Y].join(" ");try{let J=Bun.spawn([Q.runner,...Y],{cwd:Z.cwd,env:{...process.env,VIBE_AUTO_ACCEPT:"1",CI:"1",NO_COLOR:"1",...Z.env},stdout:"pipe",stderr:"pipe"}),W=Z.timeoutMs??UQ,H=!1,B=setTimeout(()=>{H=!0;try{J.kill()}catch{}},W),[K,L,w]=await Promise.all([new Response(J.stdout).text(),new Response(J.stderr).text(),J.exited]);return clearTimeout(B),{ok:!H&&w===0,exitCode:w,stdout:A4(K),stderr:A4(L),timedOut:H,argv:$,command:X}}catch(J){return{ok:!1,exitCode:null,stdout:"",stderr:`Failed to spawn vibe CLI: ${J instanceof Error?J.message:String(J)}`,timedOut:!1,argv:$,command:X}}}async function k4(){let{Command:$}=await import("./esm-6f3dfn6v.js"),{registerCoreCommands:Z}=await import("./register-core-vv6pbb13.js"),Q=new $;Q.name("vibe").option("--json").option("--plain").option("-y, --yes").option("-p, --profile <name>");try{Z(Q)}catch{}let Y=new Set(["nuke","kill","gc","stop","rollback","deploy"]),X=[];for(let J of Q.commands){let W=J.name();if(!W||W==="help")continue;X.push({name:W,description:J.description()||"",usage:J.usage()||"",options:J.options.map((H)=>({flags:H.flags,description:H.description||""})),group:"core",destructive:Y.has(W)})}return X.sort((J,W)=>J.name.localeCompare(W.name))}import{spawn as xQ}from"child_process";import{writeFileSync as OQ,mkdirSync as MQ}from"fs";import{tmpdir as TQ}from"os";import{join as S4}from"path";var CQ="@vibecontrols/agent";function D4($){let Z=N2(),Q=Z.which("bun")??`bun${Z.executableSuffix}`,Y=Z.which("npm")??`npm${Z.executableSuffix}`,X=n2(),J=$.delayMs??3000,W=$.pids.filter((B)=>Number.isInteger(B)&&B>0),H=`// vibecontrols agent self-uninstall reaper (auto-generated)
5
5
  const PIDS = ${JSON.stringify(W)};
6
6
  const NPM = ${JSON.stringify(Y)};
7
7
  const BUN = ${JSON.stringify(Q)};
@@ -22,5 +22,5 @@ try { Bun.spawnSync([BUN, "remove", "-g", PKG], { stdout: "inherit", stderr: "in
22
22
  addVibecontrolsAgentFromTunnel(input: $input) { agent { id name } clientId success error }
23
23
  }`,wQ=`mutation ReportAgentMeshLink($input: ReportAgentMeshLinkInput!) {
24
24
  reportAgentMeshLink(input: $input) { id }
25
- }`,P4="VIBE_BOOTSTRAP_JSON=";function qQ($){for(let Y of $.split(/\r?\n/)){let X=Y.indexOf(P4);if(X>=0)try{return JSON.parse(Y.slice(X+P4.length))}catch{}}let Z=$.indexOf("{"),Q=$.lastIndexOf("}");if(Z>=0&&Q>Z)try{return JSON.parse($.slice(Z,Q+1))}catch{return null}return null}async function c4($,Z){let Q=(L,w,E)=>Z?.({step:L,status:w,message:E}),Y=b4($.permissions??["tunnel:read","session:list","plugin:list","diagnostics:read","mesh:forward"]);if(!Y.includes("mesh:forward"))Y.push("mesh:forward");let X=(L)=>({ok:!1,peerId:"",agentRecordId:null,tunnelUrl:null,permissions:Y,error:L}),J;try{J=o2($.target,{identityFile:$.identityFile})}catch(L){return X(L instanceof Error?L.message:String(L))}let W=$.label??J.id,H=Y.join(","),B,K='export PATH="$HOME/.bun/bin:$PATH"; ';try{if(!$.connectExisting){Q("probe","running");let O=await J.probe();if(Q("probe","completed",`os=${O.os??"?"} arch=${O.arch??"?"}`),!O.bun){if($.installBun===!1)return X("Bun is required to run the agent but is not installed, and Bun auto-install was disabled.");Q("install-bun","running");let i=await J.run(["sh","-c",`curl -fsSL https://bun.sh/install | bash && echo 'export PATH="$HOME/.bun/bin:$PATH"' >> ~/.bashrc`],{timeoutMs:300000});if(i.code!==0)return Q("install-bun","failed",i.stderr.slice(0,400)),X("Bun auto-install failed.");let _2=await J.run(["sh","-c","$HOME/.bun/bin/bun --version 2>/dev/null"],{timeoutMs:1e4});if(_2.code===0&&_2.stdout.trim())O.bun="$HOME/.bun/bin/bun",Q("install-bun","completed",_2.stdout.trim());else return X("Bun installed but the binary is not reachable.")}Q("install-agent","running");let I=$.version??"latest",h=$.registry??"https://registry.npmjs.org/";if(!/^[A-Za-z0-9._@/^~>=<-]+$/.test(I))return Q("install-agent","failed","invalid version"),X(`Invalid agent version: ${I}`);if(!/^https?:\/\/[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+$/.test(h))return Q("install-agent","failed","invalid registry"),X(`Invalid registry URL: ${h}`);let y=await J.run(["sh","-c",`${K}npm_config_registry="${h}" bun install -g @vibecontrols/agent@${I} --no-cache`],{timeoutMs:600000});if(y.code!==0)return Q("install-agent","failed",y.stderr.slice(0,400)),X(`Agent install failed (exit ${y.code}).`);if(B=(await J.run(["sh","-c",`${K}vibe --version`],{timeoutMs:15000})).stdout.trim()||void 0,Q("install-agent","completed",B),$.autostart)Q("autostart","running"),await J.run(["sh","-c",`${K}vibe autostart install`],{timeoutMs:60000}),Q("autostart","completed");if($.installPlugins?.length){Q("plugins","running");for(let i of $.installPlugins)await J.run(["sh","-c",`${K}vibe plugin install ${i}`],{timeoutMs:300000});Q("plugins","completed")}Q("start","running"),await J.run(["sh","-c",`${K}vibe start`],{timeoutMs:60000}),Q("start","completed")}Q("bootstrap","running");let L=$.expiresIn?` --expires-in ${$.expiresIn}`:"",w=W.replace(/'/g,""),E=null;for(let O=0;O<15;O++){let I=`${K}vibe peer-bootstrap --json --emit-default-key --label '${w}' --scope ${H}${L} 2>/dev/null`,h=await J.run(["sh","-c",I],{timeoutMs:15000});if(h.code===0){let y=qQ(h.stdout);if(y&&typeof y.apiKey==="string"){E=y;break}}await new Promise((y)=>setTimeout(y,2000))}if(!E)return Q("bootstrap","failed","could not obtain peer-bootstrap bundle"),X("Remote peer-bootstrap did not return a credential bundle.");Q("bootstrap","completed");let x=n(),V=String(E.id),C=String(E.apiKey),q=i2(typeof E.tunnelUrl==="string"?E.tunnelUrl:null),v=typeof E.agentRecordId==="string"?E.agentRecordId:null;if($.onboardBackend!==!1&&g.isConfigured()&&q&&typeof E.fullDefaultApiKey==="string"){Q("onboard","running");let O=5,I="no agent returned";for(let h=0;h<O;h++){try{let i=(await g.workspaceQuery(IQ,{input:{tunnelUrl:q,apiKey:E.fullDefaultApiKey,name:W}})).data?.addVibecontrolsAgentFromTunnel;if(i?.agent?.id){v=i.agent.id,I="",Q("onboard","completed",`agent ${v}`);break}I=i?.error??"no agent returned"}catch(r){I=r instanceof Error?r.message:String(r)}if(!/unreachable|resolve hostname|timed out|timeout|ECONN|network|to fetch|50[234]/i.test(I)||h===O-1)break;Q("onboard","running",`retry ${h+1}/${O-1}: ${I.slice(0,80)}`),await new Promise((r)=>setTimeout(r,3000*(h+1)))}if(I)Q("onboard","failed",I)}else Q("onboard","skipped");Q("store-creds","running"),f4({id:V,label:W,tunnelUrl:q??"",apiKey:C,permissions:Y,addedAt:new Date().toISOString(),agentRecordId:v??void 0,workspaceId:(typeof E.workspaceId==="string"?E.workspaceId:x.workspaceId)??void 0,fingerprint:V,ownerUserId:x.ownerUserId,sshTarget:J.mode==="ssh"?$.target:void 0,sshIdentityFile:$.identityFile}),Q("store-creds","completed");let N=g2();if($.onboardBackend!==!1&&g.isConfigured()&&N&&v){Q("report-link","running");try{await g.workspaceQuery(wQ,{input:{sourceAgentRecordId:N,destinationAgentRecordId:v,label:W}}),Q("report-link","completed")}catch(O){Q("report-link","failed",O instanceof Error?O.message:String(O))}}else Q("report-link","skipped");let T=await I2(V,"/api/profiles/default/agent/identity",{operation:"post-deploy-probe"});return Q("probe-peer",T.ok?"completed":"failed",T.error??void 0),{ok:!0,peerId:V,agentRecordId:v,tunnelUrl:q,permissions:Y,remoteVersion:B}}catch(L){return X(L instanceof Error?L.message:String(L))}finally{await J.close().catch(()=>{})}}var U0='export PATH="$HOME/.bun/bin:$PATH"; ';function RQ($){let Z=$.indexOf("{"),Q=$.lastIndexOf("}");if(Z>=0&&Q>Z)try{let Y=JSON.parse($.slice(Z,Q+1));if(Y.tunnelUrl)return Y.tunnelUrl;if(Y.url&&Y.url.startsWith("https"))return Y.url}catch{}return null}async function m4($,Z){let Q=(J,W,H)=>Z?.({step:J,status:W,message:H}),Y=y4($);if(!Y)return{ok:!1,peerId:$,tunnelUrl:null,error:`No peer with id ${$}`};if(!Y.sshTarget)return{ok:!1,peerId:$,tunnelUrl:null,error:"No SSH target stored for this peer \u2014 it wasn't SSH-deployed, so it can't be woken via SSH."};let X;try{X=o2(Y.sshTarget,{identityFile:Y.sshIdentityFile})}catch(J){return{ok:!1,peerId:$,tunnelUrl:null,error:J instanceof Error?J.message:String(J)}}try{Q("ssh-restart","running",Y.sshTarget);let J=await X.run(["sh","-c",`${U0}vibe restart 2>/dev/null || ${U0}vibe start`],{timeoutMs:90000});if(J.code!==0)return Q("ssh-restart","failed",J.stderr.slice(0,300)),{ok:!1,peerId:$,tunnelUrl:null,error:`Remote restart failed (exit ${J.code})`};Q("ssh-restart","completed"),Q("await-tunnel","running");let W=null;for(let H=0;H<15;H++){let B=await X.run(["sh","-c",`${U0}vibe url --json 2>/dev/null`],{timeoutMs:15000});if(B.code===0){let K=RQ(B.stdout),L=i2(K);if(L){W=L;break}}await new Promise((K)=>setTimeout(K,2000))}if(!W)return Q("await-tunnel","failed","no fresh tunnel after restart"),{ok:!1,peerId:$,tunnelUrl:null,error:"Agent restarted but no fresh tunnel came up."};return Q("await-tunnel","completed",W),u4($,{tunnelUrl:W,lastReachable:new Date().toISOString()}),Q("update","completed"),{ok:!0,peerId:$,tunnelUrl:W}}catch(J){return{ok:!1,peerId:$,tunnelUrl:null,error:J instanceof Error?J.message:String(J)}}finally{await X.close().catch(()=>{})}}var DQ=Number(process.env.VIBECONTROLS_MESH_MAX_HOPS||"8");function g4(){return(c()??G()).name}function hQ(){return(c()??G()).dataDir}function p4(){try{let Z=SQ(hQ(),"runtime.json");if(AQ(Z)){let Q=JSON.parse(kQ(Z,"utf8"));if(Q.port&&Number.isInteger(Q.port))return Q.port}}catch{}let $=Number(process.env.PORT);return Number.isInteger($)&&$>0?$:3005}function vQ($){let Z={};return $.headers.forEach((Q,Y)=>{Z[Y]=Q}),Z}function X2($,Z){let Q=m(vQ($));return n4(d4(Q),Z)}function PQ($){let{apiKey:Z,...Q}=$;return{...Q,apiKey:"[REDACTED]"}}function l4($){return typeof $==="string"&&$.startsWith("/api/")&&!$.includes("..")&&!$.includes("//")}var a2=new Map;function fQ(){let $=Date.now()-3600000;for(let[Z,Q]of a2)if(Q.completedAt&&Date.parse(Q.completedAt)<$)a2.delete(Z)}function o4(){return new D({name:"agent-mesh"}).get("/api/mesh/peers",({request:$,set:Z})=>{if(!X2($,["read"]))return Z.status=403,{error:"forbidden"};return{peers:L2(n()).map(PQ)}}).delete("/api/mesh/peers/:id",({request:$,set:Z,params:Q})=>{if(!X2($,["mutate"]))return Z.status=403,{error:"forbidden"};if(!L2(n()).some((X)=>X.id===Q.id))return Z.status=404,{error:"not found"};return{ok:i4(Q.id)}}).post("/api/mesh/peers/:id/call",async({request:$,set:Z,params:Q,body:Y})=>{if(!X2($,["mesh:forward"]))return Z.status=403,{error:"forbidden"};let X=Y;if(!l4(X.path))return Z.status=400,{error:"invalid path"};if(!L2(n()).find((H)=>H.id===Q.id))return Z.status=404,{error:"not found"};let W=await I2(Q.id,X.path,{method:X.method??"GET",body:X.body,operation:"mesh-call"});return{ok:W.ok,status:W.status,data:W.data,rotated:W.rotated,error:W.error}},{body:z.Object({method:z.Optional(z.String()),path:z.String(),body:z.Optional(z.Any())})}).post("/api/mesh/forward",async({request:$,set:Z,body:Q})=>{if(!X2($,["mesh:forward"]))return Z.status=403,{error:"forbidden"};let Y=Q;if(!Y.request||!l4(Y.request.path))return Z.status=400,{error:"invalid request"};let X=(Y._hopCount??0)+1;if(X>DQ)return Z.status=422,{error:"hop limit exceeded"};let J=n(),W=g2(),H=Y.hops??[];if(H.length===0){G().audit.emit("mesh","forward.terminal",{path:Y.request.path,method:Y.request.method??"GET"});let x=(Y.request.method??"GET").toUpperCase();try{let V=await fetch(`http://127.0.0.1:${p4()}${Y.request.path}`,{method:x,headers:{"x-agent-api-key":await j0(),...Y.request.body!==void 0?{"content-type":"application/json"}:{}},body:Y.request.body!==void 0?JSON.stringify(Y.request.body):void 0,signal:AbortSignal.timeout(60000)}),C=await V.text().catch(()=>""),q=null;try{q=C?JSON.parse(C):null}catch{q=null}return{ok:V.ok,status:V.status,data:q,text:C||null,error:V.ok?null:C||`status ${V.status}`}}catch(V){return Z.status=502,{ok:!1,status:0,error:V instanceof Error?V.message:String(V)}}}let B=H[0],K=Y._traversed??[];if(B===W||K.includes(B))return Z.status=422,{error:"cycle detected",at:B};let L=x0(B,J);if(!L)return Z.status=403,{error:"next hop not in authorized boundary"};if(!L.permissions.includes("mesh:forward"))return Z.status=403,{error:"peer lacks mesh:forward grant"};G().audit.emit("mesh","forward.hop",{nextId:B,remaining:H.length,hopCount:X});let w=encodeURIComponent(g4()),E=await I2(L.id,`/api/profiles/${w}/mesh/forward`,{method:"POST",operation:"mesh-forward",timeoutMs:60000,body:{hops:H.slice(1),request:Y.request,_traversed:[...K,W??"self"],_hopCount:X}});if(!E.ok)return Z.status=502,{ok:!1,status:E.status,error:E.error,failedAtHop:B};return E.data},{body:z.Object({hops:z.Optional(z.Array(z.String())),request:z.Object({method:z.Optional(z.String()),path:z.String(),body:z.Optional(z.Any())}),_traversed:z.Optional(z.Array(z.String())),_hopCount:z.Optional(z.Number())})}).post("/api/mesh/deploy",({request:$,set:Z,body:Q})=>{if(!X2($,["admin"]))return Z.status=403,{error:"forbidden"};fQ();let Y=Q,X=n(),J=crypto.randomUUID(),W={id:J,status:"running",steps:[],ownerUserId:X.ownerUserId,workspaceId:X.workspaceId,startedAt:new Date().toISOString()};return a2.set(J,W),c4({target:Y.target,permissions:Y.permissions,installPlugins:Y.installPlugins,autostart:Y.autostart,identityFile:Y.identityFile,label:Y.label,version:Y.version,connectExisting:Y.connectExisting},(H)=>{W.steps.push(H),Y2("mesh:deploy:progress",{jobId:J,step:H})}).then((H)=>{if(W.result=H,W.status=H.ok?"completed":"failed",!H.ok)W.error=H.error;W.completedAt=new Date().toISOString(),Y2(H.ok?"mesh:deploy:complete":"mesh:deploy:failed",{jobId:J,result:H})}).catch((H)=>{W.status="failed",W.error=H instanceof Error?H.message:String(H),W.completedAt=new Date().toISOString(),Y2("mesh:deploy:failed",{jobId:J,error:W.error})}),Z.status=202,{jobId:J,status:"running"}},{body:z.Object({target:z.String(),permissions:z.Optional(z.Array(z.String())),installPlugins:z.Optional(z.Array(z.String())),autostart:z.Optional(z.Boolean()),identityFile:z.Optional(z.String()),label:z.Optional(z.String()),version:z.Optional(z.String()),connectExisting:z.Optional(z.Boolean())})}).get("/api/mesh/deploy/jobs/:id",({request:$,set:Z,params:Q})=>{if(!X2($,["read"]))return Z.status=403,{error:"forbidden"};let Y=a2.get(Q.id),X=n();if(!Y||X.ownerUserId&&Y.ownerUserId&&Y.ownerUserId!==X.ownerUserId)return Z.status=404,{error:"not found"};return Y}).post("/api/mesh/wake",async({request:$,set:Z,body:Q})=>{if(!X2($,["admin"]))return Z.status=403,{error:"forbidden"};let Y=Q,X=x0(Y.targetAgentRecordId,n());if(!X)return Z.status=404,{ok:!1,error:"peer not in authorized boundary"};G().audit.emit("mesh","wake.start",{peerId:X.id,agentRecordId:Y.targetAgentRecordId});let J=await m4(X.id,(W)=>Y2("mesh:wake:progress",{peerId:X.id,step:W}));if(!J.ok)Z.status=502;return J},{body:z.Object({targetAgentRecordId:z.String()})}).post("/api/mesh/session",async({request:$,set:Z,body:Q})=>{if(!X2($,["mesh:forward","mutate"]))return Z.status=403,{error:"forbidden"};let Y=Q,X=Y.sessionId&&/^[A-Za-z0-9_-]{1,128}$/.test(Y.sessionId)?Y.sessionId:crypto.randomUUID(),J=encodeURIComponent(g4()),W=await j0(),H=`http://127.0.0.1:${p4()}`,B=Y.command||"bash";try{let K=await fetch(`${H}/api/profiles/${J}/sessions/create`,{method:"POST",headers:{"x-agent-api-key":W,"content-type":"application/json"},body:JSON.stringify({sessionId:X,sessionName:`vc-mesh-${X.slice(0,8)}`,command:B,provider:"TERMINAL",...Y.vibeId?{projectId:Y.vibeId}:{}}),signal:AbortSignal.timeout(20000)});if(!K.ok)return Z.status=502,{error:`session create returned ${K.status}: ${await K.text().catch(()=>"")}`};let L=await fetch(`${H}/api/profiles/${J}/sessions/${encodeURIComponent(X)}/terminal`,{method:"POST",headers:{"x-agent-api-key":W},signal:AbortSignal.timeout(20000)});if(!L.ok)return Z.status=502,{error:`terminal start returned ${L.status}: ${await L.text().catch(()=>"")}`};let w=v2(`/terminal/${X}`,600);return G().audit.emit("mesh","session.created",{sessionId:X,kind:Y.kind??"TERMINAL"}),{connectionId:X,sessionId:X,capabilityToken:w.token,expiresAt:w.expiresAt}}catch(K){return Z.status=502,{error:K instanceof Error?K.message:String(K)}}},{body:z.Object({sessionId:z.Optional(z.String()),kind:z.Optional(z.String()),cwd:z.Optional(z.String()),vibeId:z.Optional(z.String()),command:z.Optional(z.String())})})}var bQ=["/health","/api/agent/status","/api/agent/version","/api/agent/identity","/api/agent/api-key","/api/agent/tunnel","/api/agent/system","/api/agent/gateway-auth","/api/stats","/metrics","/api/profiles","/api/profile-stats"];function cQ($){return bQ.some((Z)=>$.startsWith(Z))}var yQ=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function uQ($){return $.split("/").map((Z)=>{if(!Z)return Z;if(/^\d+$/.test(Z))return":id";if(yQ.test(Z))return":id";if(Z.length>=24&&/^[A-Za-z0-9_-]+$/.test(Z))return":id";return Z}).join("/")}async function a8($){let{port:Z,host:Q,dbPath:Y,logLevel:X,corsOrigin:J}=$,W=Y??T2();try{(await import("fs")).mkdirSync(W,{recursive:!0})}catch(F){throw G().logger.error("app","Failed to create dbPath dir at boot",{dbPath:W,error:String(F)}),Error(`Cannot create dbPath ${W}: ${F instanceof Error?F.message:String(F)}`,{cause:F})}if(X)G().logger.setLevel(X);(async()=>{let{logShipper:F}=await import("./log-shipper-hjnn1d5p.js");F.init()})(),(async()=>{let F=await s4();await S2({version:F,profile:C2()})})();try{let{checkDependencies:F}=await import("./bootstrap.service-vg72w8pa.js"),M=F(),U=M.filter((R)=>R.required&&!R.installed),A=M.filter((R)=>!R.required&&!R.installed);if(U.length>0)G().logger.error("app",`Missing required system deps: ${U.map((R)=>R.name).join(", ")}. Run \`vibe setup\` to install.`);if(A.length>0)G().logger.warn("app",`Missing optional system deps: ${A.map((R)=>R.name).join(", ")}. Some plugins may fail their prereqs check.`)}catch(F){G().logger.warn("app","Boot-time dependency check failed",{error:String(F)})}try{G().audit.runRetention()}catch(F){G().logger.warn("app","Audit-log retention sweep failed",{error:String(F)})}let H=new N5;I5(H,{port:Z});let B="GET, POST, PUT, PATCH, DELETE, OPTIONS",K="Content-Type, x-agent-api-key, Authorization, x-requested-with",L=Array.isArray(J)?J:(J??"").split(",").map((F)=>F.trim()).filter(Boolean),w=new Set(["https://vibecontrols.com","https://app.vibecontrols.com","https://alphaapp.vibecontrols.com","https://burdenoff.com","https://app.burdenoff.com","https://alphaapp.burdenoff.com"]),E=(F)=>{try{let M=new URL(F);if(L.includes(F))return!0;if(L.includes("*"))return!1;return M.hostname==="localhost"||M.hostname==="127.0.0.1"||M.hostname==="0.0.0.0"||M.hostname.endsWith(".local.burdenoff.com")||w.has(M.origin)}catch{return!1}},x=null,V=null,C=null,q=null,v=!1,N=()=>[],T=null,O=null,I=null,h=5000,y=async(F,M)=>{let U=Date.now();try{await Promise.race([Promise.resolve(M()),new Promise((A,R)=>setTimeout(()=>R(Error(`shutdown phase ${F} exceeded ${h}ms`)),h))]),G().logger.info("app",`shutdown.phase ${F} complete`,{ms:Date.now()-U})}catch(A){G().logger.warn("app",`shutdown.phase ${F} failed`,{error:String(A),ms:Date.now()-U})}},r=async(F)=>{if(v)return;if(v=!0,G().logger.info("app","Agent shutdown starting",{reason:F?.reason??"shutdown"}),await y("plugins",async()=>{if(V)await V.dispatchServerStop(F)}),await y("bootstrap-tunnel",()=>C0()),await y("tracked-subprocesses",async()=>{let{killAllTracked:M}=await import("./subprocess-1nna3d3x.js");await M()}),F?.reason!=="reload")await y("db-close",async()=>{if(x)await x.close()});await y("http-listener",async()=>{try{await Promise.resolve(e.stop())}catch(M){G().logger.warn("app","Listener stop threw (already stopped or never started?)",{error:String(M)})}}),G().logger.info("app","Agent server stopped"),G().logger.close()},i=async(F,M)=>{if(G().getBootState()==="ready")return{ok:!0};if(I)return I;return I=(async()=>{G().setBootState("initializing");try{let U={...F,globalGatewayUrl:B2(F.globalGatewayUrl,"globalGatewayUrl"),workspaceGatewayUrl:B2(F.workspaceGatewayUrl,"workspaceGatewayUrl")},A=await U5(U),R=W,P=t({dir:G().dataDir}),p=P.storageAdapter??process.env.VIBE_STORAGE_ADAPTER??void 0,o=P.storageOptions,Q2=(_)=>{let j=(_ instanceof Error?_.message:String(_)).toLowerCase(),k=_&&typeof _==="object"&&"code"in _?String(_.code).toUpperCase():"";if(k==="EBUSY"||k==="EPERM"||k==="EACCES"||k==="EAGAIN"||k==="EMFILE"||k==="ENFILE"||k==="ETIMEDOUT"||k==="ECONNRESET"||k==="ECONNREFUSED"||j.includes("encryption key")||j.includes("fetch")&&j.includes("key")||j.includes("temporarily unavailable")||j.includes("resource busy"))return"transient";if(j.includes("auth tag")||j.includes("authentication tag")||j.includes("unable to authenticate data")||j.includes("bad decrypt")||j.includes("unsupported state")||j.includes("incorrect header check")||j.includes("invalid distance")||j.includes("incorrect data check")||j.includes("unexpected end of")||j.includes("unexpected token")||j.includes("json")&&(j.includes("parse")||j.includes("invalid"))||j.includes("truncated")||j.includes("malformed")||j.includes("corrupt"))return"corruption";return"unknown"},U2=()=>r4({dbPath:R,encryptionKey:A,adapterName:p,adapterOptions:o});try{x=await U2()}catch(_){let j=_,k=Q2(_),q2=[500,2000,8000];if(k==="transient"||k==="unknown"){G().logger.warn("app",`Storage open failed (${k}); will retry up to ${q2.length} times before quarantine`,{error:_ instanceof Error?_.message:String(_),path:R});for(let O2 of q2){await new Promise((f)=>setTimeout(f,O2));try{x=await U2(),j=null;break}catch(f){if(j=f,k=Q2(f),G().logger.warn("app",`Storage open retry failed (${k}) after ${O2}ms`,{error:f instanceof Error?f.message:String(f)}),k==="corruption")break}}}if(!x&&j){if(k!=="corruption"){let f=j instanceof Error?j.message:String(j);G().logger.error("app",`Storage open failed after retries with non-corruption error (${k}); refusing to quarantine valid data`,{error:f,path:R}),G().recordDegradedReason("storage",f);try{throw j}catch(G2){throw Error(`Storage open failed (${k}); agent is degraded: ${f}`,{cause:G2})}}let O2=j instanceof Error?j.message:String(j);G().logger.error("app","QUARANTINE: Storage file is corrupt \u2014 renaming and creating fresh DB",{errorClass:"corruption",error:O2,path:R});try{let f=await import("fs");if(f.existsSync(R)){let G2=new Date().toISOString().replace(/[:.]/g,"-"),q0=`${R}.broken-${G2}`;f.renameSync(R,q0),G().logger.warn("app",`Quarantined corrupt storage to ${q0} \u2014 fresh DB will be created`,{originalError:O2})}x=await U2()}catch(f){let G2=f instanceof Error?f.message:String(f);throw G().recordDegradedReason("storage",G2),Error(`Storage open failed twice (quarantine path); agent is degraded: ${G2}`,{cause:f})}}}if(!x)throw Error("Internal error: storage open recovery exited without an open database and without throwing");if(await h2({clientId:U.clientId,clientSecret:U.clientSecret,workspaceId:U.workspaceId,organizationId:U.organizationId,globalGatewayUrl:U.globalGatewayUrl,workspaceGatewayUrl:U.workspaceGatewayUrl,agentRecordId:M?.agentRecordId,scopes:M?.scopes},{dir:G().dataDir,scope:G().name}),await x.setConfig("gateway-auth:clientId",U.clientId),await x.setConfig("gateway-auth:clientSecret",U.clientSecret),await x.setConfig("gateway-auth:globalGatewayUrl",U.globalGatewayUrl),await x.setConfig("gateway-auth:workspaceGatewayUrl",U.workspaceGatewayUrl),await x.setConfig("gateway-auth:workspaceId",U.workspaceId),U.organizationId)await x.setConfig("gateway-auth:organizationId",U.organizationId);if(M?.agentRecordId)await x.setConfig("gateway-auth:agentRecordId",M.agentRecordId);H.db=x,await H.hydrateDefaultsFromDb(),V=new T5(x),await V.loadCorePlugins();try{await V.loadAll()}catch(_){G().logger.warn("app","Failed to load some external plugins",{error:String(_)})}let j2=C5(F2())??void 0,x2=process.env.VIBE_SKIP_AUTO_INSTALL==="1"||await x.getConfig("plugins:auto-install-disabled");if(x2!=="true"&&x2!==!0)try{let _=await V.ensureDefaultPlugins((j)=>G().logger.info("app",`[auto-install] ${j}`),[],j2);if(_.length>0)G().logger.info("app",`Auto-installed ${_.length} default plugin(s): ${_.map((j)=>j.packageName).join(", ")}`)}catch(_){G().logger.warn("app","Failed to auto-install default plugins",{error:String(_)})}G().logger.info("app",`Plugins loaded: ${V.getPluginDetails().length} total (${V.getPluginDetails().filter((_)=>_.isCore).length} core)`);try{let _=V.getPluginDetails(),j={loaded:_.filter((k)=>k.loaded).length,failed:_.filter((k)=>!k.loaded).length};b0(j)}catch{}let r2={async get(_,j){return await x.getPluginState(_,j)??null},async set(_,j,k){await x.setPluginState(_,j,k)},async delete(_,j){return x.deletePluginState(_,j)},async list(_){return await x.getAllPluginState(_)},async deleteAll(_){return x.deleteAllPluginState(_)}},w2=await s4();C={storage:r2,logger:G().logger,serviceRegistry:H,getProvider:(_)=>H.getProvider(_),getAgentBaseUrl:()=>process.env.AGENT_URL||`http://localhost:${Z}`,getAgentVersion:()=>w2,validateApiKey:(_)=>l(_),setCodeServerSessionValidator:(_)=>{w5=_},broadcast:Y2,workspaceQuery:async(_,j)=>g.workspaceQuery(_,j),isGatewayConfigured:()=>g.isConfigured(),getAgentRecordId:async()=>await x.getConfig("gateway-auth:agentRecordId")??null,getWorkspaceId:async()=>await x.getConfig("gateway-auth:workspaceId")??null,getConfig:async(_)=>await x.getConfig(_)??void 0,getPluginRegistry:()=>n2(),getDataDir:()=>D2(),cliContributors:new _5,audit:{emit:(_,j)=>G().audit.emit("agent",_,j??{})},telemetry:{emit:(_,j)=>{import("./telemetry-8jfdyt51.js").then(({telemetryService:k})=>k.emit(_,j??{})).catch(()=>{})}},os:N2(),iframeBridge:M5()},g.configure({globalGatewayUrl:U.globalGatewayUrl,workspaceGatewayUrl:U.workspaceGatewayUrl,clientId:U.clientId,clientSecret:U.clientSecret,workspaceId:U.workspaceId,organizationId:U.organizationId});let H2={db:x,serviceRegistry:H,pluginManager:V,broadcast:Y2,hostServices:C};H2.app=e;let w0=!1,t2=()=>{let{routes:_,getPublicPaths:j,mountPlugin:k}=$5(V,H2);if(H2.mountPlugin=k,N=j,X5(),T=_,O=O5(V),V&&w0&&C)V.dispatchServerStart(T,C).catch((q2)=>G().logger.warn("app","Re-dispatch of onServerStart after plugin reload failed",{error:String(q2)}));w0=!0};H2.rebuildPluginSurfaces=t2,t2(),q=new j5(H,V,x,e,C,r),H.registerService("agent","lifecycle",q),G().attachServices({db:x,serviceRegistry:H,pluginManager:V,lifecycle:q,hostServices:C}),F5(G(),{rebuildPluginSurfaces:t2,mountPlugin:H2.mountPlugin});try{await G().keyVault.bindApiKey(V2())}catch(_){G().logger.warn("app","Failed to bind api key into daemon keyVault",{error:String(_)})}let e2=[];try{let{failures:_}=await V.dispatchServerStart(T,C);for(let j of _)if(T0(j.plugin)||(j.packageName?T0(j.packageName):!1))e2.push(j),G().recordDegradedReason(j.plugin,j.error);else G().logger.warn("app",`Non-critical plugin ${j.plugin} failed onServerStart; continuing`,{error:j.error})}catch(_){G().logger.warn("app","Error during plugin onServerStart dispatch",{error:String(_)})}try{await V.dispatchServerReady(e,C)}catch(_){G().logger.warn("app","Error during plugin onServerReady dispatch",{error:String(_)})}if(G().clearFinalizeError(),e2.length>0)G().setBootState("degraded"),G().logger.error("app","Agent finalized but degraded \u2014 critical plugins failed",{failures:e2.map((_)=>`${_.plugin}: ${_.error}`)});else G().setBootState("ready"),G().logger.info("app","Agent finalized \u2014 state=ready"),G().audit.emit("agent","gateway-auth.configured",{workspaceId:U.workspaceId,organizationId:U.organizationId,agentRecordId:M?.agentRecordId});return(async()=>{try{if(await V.provisionDefaultPrereqs(e,C,H2.mountPlugin,j2),G().logger.info("app","Default provider prerequisites provisioned"),(H.listProvidersForType("tunnel")??[]).some((k)=>k.pluginName!=="bootstrap")){let{tryHandoverBootstrapTunnel:k}=await import("./tunnel-bootstrap-5wgt9a1h.js");if(!k())C0();H.unregisterProvider("tunnel","bootstrap"),G().logger.info("app","Bootstrap tunnel handed over to the real tunnel provider")}}catch(_){G().logger.warn("app","Plugin prerequisite provisioning failed",{error:String(_)})}})(),{ok:!0}}catch(U){G().setBootState("awaiting-config");let A=U instanceof Error?U.message:String(U);if(G().recordFinalizeError(A),G().logger.error("app","Finalize failed",{error:A}),process.env.VIBE_STRICT_KEY_FETCH==="1")G().logger.error("app","VIBE_STRICT_KEY_FETCH=1 \u2192 aborting daemon (strict mode)",{error:A}),setTimeout(()=>process.exit(1),50);return{ok:!1,error:A}}finally{I=null}})(),I},_2=A0({origin:(F)=>{let M=F.headers.get("origin");return!!M&&E(M)},credentials:!0,allowedHeaders:K.split(",").map((F)=>F.trim()),methods:B.split(",").map((F)=>F.trim()),exposeHeaders:["content-type","content-length"],maxAge:86400,preflight:!0}),q5=10485760,E0=process.env.VIBECONTROLS_MAX_BODY_BYTES,s2=E0?Number.parseInt(E0,10):NaN,R5=Number.isFinite(s2)&&s2>0?s2:q5,I0={current:null},e=new D({serve:{maxRequestBodySize:R5}}).onRequest(({request:F,set:M})=>{let A=t4(F.headers)??O0();e4({requestId:A,startedAt:new Date().toISOString()});let R=M.headers??={};R["X-Request-Id"]=A}).onRequest(({request:F})=>{try{let M=new URL(F.url).pathname,A=/^\/api\/profiles\/([^/]+)(?:\/|$)/.exec(M)?.[1],R=A?s.get(A):null;M0(R??G())}catch{M0(G())}}).onRequest(({request:F,set:M})=>{let U=new URL(F.url).pathname;if(!U.startsWith("/api/"))return;if(U==="/api/profiles"||U.startsWith("/api/profiles/"))return;if(U==="/api/profile-stats"||U.startsWith("/api/profile-stats/"))return;let A=new URL(F.url);A.pathname=`/api/profiles/default${U.slice(4)}`;try{F.headers.set("x-vc-profile-rewrite","1"),F.headers.set("x-vc-profile-rewrite-target",A.pathname)}catch{}return}).derive(()=>({requestId:Q5()??O0()})).use(_2).use(W5()).use(Y5(()=>N())).use(h0({getDb:()=>c()?.db??x})).onBeforeHandle(({request:F,set:M})=>{let U=G().getBootState();if(U==="ready")return;let A=new URL(F.url).pathname;if(cQ(A))return;return M.status=503,{error:"Agent not yet configured",message:"Agent is in '"+U+"' state. POST credentials to /api/agent/gateway-auth to finalize.",state:U}}).onAfterHandle(({request:F,set:M})=>{let U=new URL(F.url).pathname,A=U==="/health"||U.startsWith("/api/logs/stream")||U.startsWith("/ui/")||U==="/ws/events"||U==="/api/sessions/health-check"||U.startsWith("/terminal/"),R=typeof M.status==="number"?M.status:200,P=A?"debug":R>=400?"warn":"info";G().logger[P]("http",`${F.method} ${U} \u2192 ${R}`,{method:F.method,path:U,statusCode:R});try{f0(F.method,uQ(U),R)}catch{}}).use(z4({serviceRegistry:H,getDb:()=>c()?.db??x,getDbPath:()=>W,getPluginManager:()=>c()?.pluginManager??V})).use(y0()).use(o0({serviceRegistry:H,runFinalize:(F,M)=>i(F,M),getDb:()=>c()?.db??x})).use(G4()).use(B4()).use(v4({getPluginManager:()=>c()?.pluginManager??V})).use(o4()).use(L4()).use(M4({getPluginManager:()=>c()?.pluginManager??V,getTunnelHost:()=>E5()?.url??null})).use(Z4()).use(X4()).use(B5()).use(K5()).use(V5(H)).ws("/code-server/*",gQ(Z)).all("/api/profiles/:name/*",async({params:F,request:M,set:U})=>{let A=M.method!=="GET"&&M.method!=="HEAD",R=A?await M.arrayBuffer():void 0,P=await L5(F.name,M,R);if(P&&P.status!==404)return P;let p=C2(),o=F.name;if(o!==p)return U.status=404,{error:"profile-mismatch",running:p,requested:o,hint:"This daemon serves a different profile. Call GET /api/profiles to discover the right tunnel."};let Q2=new URL(M.url),U2=Q2.pathname.replace(/^\/api\/profiles\/[^/]+/,"/api"),j2=new Headers(M.headers);j2.set("x-vc-profile-rewrite","1");let x2={method:M.method,headers:j2};if(A&&R!==void 0)x2.body=R;let r2=new Request(`${Q2.origin}${U2}${Q2.search}`,x2),w2=I0.current;if(!w2)return new Response(JSON.stringify({error:"agent-not-ready"}),{status:503,headers:{"content-type":"application/json"}});return w2.handle(r2)}).all("/api/*",async({request:F})=>{if(G().getBootState()!=="ready"||!T)return new Response(JSON.stringify({error:"Agent not yet configured",state:G().getBootState(),message:"Plugin routes are unavailable until the agent reaches state=ready. POST credentials to /api/agent/gateway-auth to finalize."}),{status:503,headers:{"content-type":"application/json"}});try{let M=new URL(F.url),U=/^\/api\/plugins\/([a-z0-9-]{1,64})\/ui(?:\/.*)?$/.exec(M.pathname);if(U&&F.method==="GET"){let A=U[1];if(M2(A)){let R=M.pathname.slice(`/api/plugins/${A}/ui`.length),P=R===""||R==="/",o=F.headers.get("sec-fetch-mode")==="navigate";if(P||o){let Q2=J5(F,A);if(!Q2||!Z5(Q2,A))return new Response(x5(A,"/api/profiles/default/agent/ui-exchange-plugin"),{status:200,headers:{"content-type":"text/html; charset=utf-8","Content-Security-Policy":"frame-ancestors 'self' http://localhost:* http://127.0.0.1:* https://localhost:* https://127.0.0.1:* https://*.local.burdenoff.com https://vibecontrols.com https://*.vibecontrols.com https://burdenoff.com https://app.burdenoff.com https://alphaapp.burdenoff.com"}})}}}}catch{}return T.handle(F)}).all("/ui/*",async({request:F})=>{if(G().getBootState()!=="ready"||!O)return new Response("Plugin UI not yet available",{status:503});return O.handle(F)}).all("/code-server/*",async({request:F})=>{if(G().getBootState()!=="ready"||!T)return new Response("code-server not yet available",{status:503});let M=k0(F,V2);return T.handle(M??F)}).all("/plan/*",async({request:F})=>{if(G().getBootState()!=="ready"||!T)return new Response("plan provider not yet available",{status:503});return T.handle(F)});return I0.current=e,{app:e,async start(){e.listen({port:Z,hostname:Q}),G().logger.info("app",`Agent server listening on ${Q}:${Z}`);try{let F=(process.env.VIBECONTROLS_PROFILES??"").split(",").map((P)=>P.trim()).filter(Boolean),M=G().name,{getOrCreateProfile:U}=await import("./daemon-profile-gwdcqx0q.js"),{attachSecondaryProfile:A}=await import("./secondary-profile-attach-qk5tde9n.js"),R=process.env.VIBE_STRICT_KEY_FETCH==="1";for(let P of F){if(P===M)continue;try{let p=U(P),o=await A(p);if(o.ok)G().logger.info("app",`Secondary profile '${P}' attached (db+services online)`);else if(R)throw Error(`attachServices for secondary profile '${P}' failed: ${o.error}`);else p.recordDegradedReason("attach",o.error??"unknown"),G().logger.warn("app",`Secondary profile '${P}' is degraded (no creds / attach failed)`,{error:o.error})}catch(p){if(R)throw G().logger.error("app",`--strict-key-fetch: secondary profile '${P}' attach failed; aborting`,{error:String(p)}),setTimeout(()=>process.exit(1),50),p;G().logger.warn("app",`Failed to attach secondary profile '${P}'`,{error:String(p)})}}}catch{}return e},stop:r,finalize:i,getState:()=>G().getBootState(),getLifecycle:()=>c()?.lifecycle??q,getDb:()=>c()?.db??x,getServiceRegistry:()=>c()?.serviceRegistry??H,getPluginManager:()=>c()?.pluginManager??V,getHostServices:()=>c()?.hostServices??C}}var w5=null;function mQ($,Z){if(!$)return null;let Q=$.match(new RegExp(`(?:^|;\\s*)${Z}=([^;]*)`));return Q?Q[1]:null}var a4=z5(H5);function gQ($){let X=(J)=>typeof J==="string"?Buffer.byteLength(J):J.byteLength;return{open(J){let W=J.data,H=m(W.headers??{})??m(W.request?Object.fromEntries(W.request.headers.entries()):{}),B=W.query?.vt,K=!!B&&R2(B,"/code-server","GET"),L,w=l(H);if(!w&&!K){let C=W.headers?.cookie??W.request?.headers.get("cookie")??null,q=mQ(C,"__vibe_cs_session");if(!q||!w5?.(q)){J.close(1008,"Unauthorized");return}L=`session:${q}`}else if(w)L="api-key";else L="vt";let E=J.remoteAddress??null,x=G5(E,W.headers);if(!a4.accept(L,x,J)){G().logger.warn("code-server-ws",`code-server WS cap exceeded (key=${L}, ip=${x??"unknown"})`),J.close(1013,"too many connections");return}W._csCapKey=L,W._csRemoteIp=x;let V=G().name;fetch(`http://127.0.0.1:${$}/api/profiles/${encodeURIComponent(V)}/code-server/status`,{headers:{"x-agent-api-key":V2()}}).then((C)=>C.json()).then((C)=>{if(W._csClosed)return;let q=C;if(!q.running||!q.port){J.close(1011,"code-server not running");return}let v=W.request?.url??"/code-server/",N;try{let I=new URL(v,`http://127.0.0.1:${q.port}`);N=(I.pathname.replace(/^\/code-server\/?/,"/")||"/")+I.search}catch{N="/"}let T=new WebSocket(`ws://127.0.0.1:${q.port}${N}`),O={upstream:T,ready:!1,buffer:[],bufferBytes:0,openTimer:setTimeout(()=>{try{T.close(1011,"upstream open timeout")}catch{}try{J.close(1011,"upstream open timeout")}catch{}},1e4)};W._csBridge=O,T.addEventListener("open",()=>{clearTimeout(O.openTimer),O.ready=!0;for(let I of O.buffer)T.send(I);O.buffer.length=0,O.bufferBytes=0}),T.addEventListener("message",(I)=>{try{let h=I.data;if(h instanceof ArrayBuffer)J.send(new Uint8Array(h));else if(h instanceof Blob)h.arrayBuffer().then((y)=>{try{J.send(new Uint8Array(y))}catch{}});else J.send(h)}catch{}}),T.addEventListener("close",(I)=>{clearTimeout(O.openTimer);try{J.close(I.code||1000,I.reason||"upstream closed")}catch{}}),T.addEventListener("error",()=>{clearTimeout(O.openTimer);try{J.close(1011,"upstream error")}catch{}})}).catch(()=>{J.close(1011,"Failed to query code-server status")})},message(J,W){let H=J.data?._csBridge;if(!H)return;let B;if(typeof W==="string")B=W;else if(W instanceof ArrayBuffer)B=W;else if(W instanceof Uint8Array||Buffer.isBuffer(W)){let K=new ArrayBuffer(W.byteLength);new Uint8Array(K).set(new Uint8Array(W.buffer,W.byteOffset,W.byteLength)),B=K}else if(typeof W==="object"&&W!==null)B=JSON.stringify(W);else B=String(W);if(H.upstream&&H.ready&&H.upstream.readyState===WebSocket.OPEN)try{H.upstream.send(B)}catch{}else{let K=X(B);if(H.buffer.length>=256||H.bufferBytes+K>1048576){try{H.upstream.close(1013,"buffer limit exceeded")}catch{}try{J.close(1013,"buffer limit exceeded")}catch{}return}H.buffer.push(B),H.bufferBytes+=K}},close(J){J.data._csClosed=!0;let W=J.data?._csBridge;if(W?.openTimer)clearTimeout(W.openTimer);if(W?.upstream&&W.upstream.readyState===WebSocket.OPEN)W.upstream.close(1000,"client disconnected");let H=J.data._csCapKey,B=J.data._csRemoteIp;if(H)a4.release(H,B??null,J)}}}async function s4(){try{let{readFileSync:$}=await import("fs"),{join:Z,dirname:Q}=await import("path"),{fileURLToPath:Y}=await import("url"),X=Q(Y(import.meta.url));return JSON.parse($(Z(X,"..","package.json"),"utf8")).version||"1.0.0"}catch{return"1.0.0"}}
25
+ }`,P4="VIBE_BOOTSTRAP_JSON=";function qQ($){for(let Y of $.split(/\r?\n/)){let X=Y.indexOf(P4);if(X>=0)try{return JSON.parse(Y.slice(X+P4.length))}catch{}}let Z=$.indexOf("{"),Q=$.lastIndexOf("}");if(Z>=0&&Q>Z)try{return JSON.parse($.slice(Z,Q+1))}catch{return null}return null}async function c4($,Z){let Q=(L,w,E)=>Z?.({step:L,status:w,message:E}),Y=b4($.permissions??["tunnel:read","session:list","plugin:list","diagnostics:read","mesh:forward"]);if(!Y.includes("mesh:forward"))Y.push("mesh:forward");let X=(L)=>({ok:!1,peerId:"",agentRecordId:null,tunnelUrl:null,permissions:Y,error:L}),J;try{J=o2($.target,{identityFile:$.identityFile})}catch(L){return X(L instanceof Error?L.message:String(L))}let W=$.label??J.id,H=Y.join(","),B,K='export PATH="$HOME/.bun/bin:$PATH"; ';try{if(!$.connectExisting){Q("probe","running");let O=await J.probe();if(Q("probe","completed",`os=${O.os??"?"} arch=${O.arch??"?"}`),!O.bun){if($.installBun===!1)return X("Bun is required to run the agent but is not installed, and Bun auto-install was disabled.");Q("install-bun","running");let i=await J.run(["sh","-c",`curl -fsSL https://bun.sh/install | bash && echo 'export PATH="$HOME/.bun/bin:$PATH"' >> ~/.bashrc`],{timeoutMs:300000});if(i.code!==0)return Q("install-bun","failed",i.stderr.slice(0,400)),X("Bun auto-install failed.");let _2=await J.run(["sh","-c","$HOME/.bun/bin/bun --version 2>/dev/null"],{timeoutMs:1e4});if(_2.code===0&&_2.stdout.trim())O.bun="$HOME/.bun/bin/bun",Q("install-bun","completed",_2.stdout.trim());else return X("Bun installed but the binary is not reachable.")}Q("install-agent","running");let I=$.version??"latest",h=$.registry??"https://registry.npmjs.org/";if(!/^[A-Za-z0-9._@/^~>=<-]+$/.test(I))return Q("install-agent","failed","invalid version"),X(`Invalid agent version: ${I}`);if(!/^https?:\/\/[A-Za-z0-9._~:/?#@!$&'()*+,;=%-]+$/.test(h))return Q("install-agent","failed","invalid registry"),X(`Invalid registry URL: ${h}`);let y=await J.run(["sh","-c",`${K}npm_config_registry="${h}" bun install -g @vibecontrols/agent@${I} --no-cache`],{timeoutMs:600000});if(y.code!==0)return Q("install-agent","failed",y.stderr.slice(0,400)),X(`Agent install failed (exit ${y.code}).`);if(B=(await J.run(["sh","-c",`${K}vibe --version`],{timeoutMs:15000})).stdout.trim()||void 0,Q("install-agent","completed",B),$.autostart)Q("autostart","running"),await J.run(["sh","-c",`${K}vibe autostart install`],{timeoutMs:60000}),Q("autostart","completed");if($.installPlugins?.length){Q("plugins","running");for(let i of $.installPlugins)await J.run(["sh","-c",`${K}vibe plugin install ${i}`],{timeoutMs:300000});Q("plugins","completed")}Q("start","running"),await J.run(["sh","-c",`${K}vibe start`],{timeoutMs:60000}),Q("start","completed")}Q("bootstrap","running");let L=$.expiresIn?` --expires-in ${$.expiresIn}`:"",w=W.replace(/'/g,""),E=null;for(let O=0;O<15;O++){let I=`${K}vibe peer-bootstrap --json --emit-default-key --label '${w}' --scope ${H}${L} 2>/dev/null`,h=await J.run(["sh","-c",I],{timeoutMs:15000});if(h.code===0){let y=qQ(h.stdout);if(y&&typeof y.apiKey==="string"){E=y;break}}await new Promise((y)=>setTimeout(y,2000))}if(!E)return Q("bootstrap","failed","could not obtain peer-bootstrap bundle"),X("Remote peer-bootstrap did not return a credential bundle.");Q("bootstrap","completed");let x=n(),V=String(E.id),C=String(E.apiKey),q=i2(typeof E.tunnelUrl==="string"?E.tunnelUrl:null),v=typeof E.agentRecordId==="string"?E.agentRecordId:null;if($.onboardBackend!==!1&&g.isConfigured()&&q&&typeof E.fullDefaultApiKey==="string"){Q("onboard","running");let O=5,I="no agent returned";for(let h=0;h<O;h++){try{let i=(await g.workspaceQuery(IQ,{input:{tunnelUrl:q,apiKey:E.fullDefaultApiKey,name:W}})).data?.addVibecontrolsAgentFromTunnel;if(i?.agent?.id){v=i.agent.id,I="",Q("onboard","completed",`agent ${v}`);break}I=i?.error??"no agent returned"}catch(r){I=r instanceof Error?r.message:String(r)}if(!/unreachable|resolve hostname|timed out|timeout|ECONN|network|to fetch|50[234]/i.test(I)||h===O-1)break;Q("onboard","running",`retry ${h+1}/${O-1}: ${I.slice(0,80)}`),await new Promise((r)=>setTimeout(r,3000*(h+1)))}if(I)Q("onboard","failed",I)}else Q("onboard","skipped");Q("store-creds","running"),f4({id:V,label:W,tunnelUrl:q??"",apiKey:C,permissions:Y,addedAt:new Date().toISOString(),agentRecordId:v??void 0,workspaceId:(typeof E.workspaceId==="string"?E.workspaceId:x.workspaceId)??void 0,fingerprint:V,ownerUserId:x.ownerUserId,sshTarget:J.mode==="ssh"?$.target:void 0,sshIdentityFile:$.identityFile}),Q("store-creds","completed");let N=g2();if($.onboardBackend!==!1&&g.isConfigured()&&N&&v){Q("report-link","running");try{await g.workspaceQuery(wQ,{input:{sourceAgentRecordId:N,destinationAgentRecordId:v,label:W}}),Q("report-link","completed")}catch(O){Q("report-link","failed",O instanceof Error?O.message:String(O))}}else Q("report-link","skipped");let T=await I2(V,"/api/profiles/default/agent/identity",{operation:"post-deploy-probe"});return Q("probe-peer",T.ok?"completed":"failed",T.error??void 0),{ok:!0,peerId:V,agentRecordId:v,tunnelUrl:q,permissions:Y,remoteVersion:B}}catch(L){return X(L instanceof Error?L.message:String(L))}finally{await J.close().catch(()=>{})}}var U0='export PATH="$HOME/.bun/bin:$PATH"; ';function RQ($){let Z=$.indexOf("{"),Q=$.lastIndexOf("}");if(Z>=0&&Q>Z)try{let Y=JSON.parse($.slice(Z,Q+1));if(Y.tunnelUrl)return Y.tunnelUrl;if(Y.url&&Y.url.startsWith("https"))return Y.url}catch{}return null}async function m4($,Z){let Q=(J,W,H)=>Z?.({step:J,status:W,message:H}),Y=y4($);if(!Y)return{ok:!1,peerId:$,tunnelUrl:null,error:`No peer with id ${$}`};if(!Y.sshTarget)return{ok:!1,peerId:$,tunnelUrl:null,error:"No SSH target stored for this peer \u2014 it wasn't SSH-deployed, so it can't be woken via SSH."};let X;try{X=o2(Y.sshTarget,{identityFile:Y.sshIdentityFile})}catch(J){return{ok:!1,peerId:$,tunnelUrl:null,error:J instanceof Error?J.message:String(J)}}try{Q("ssh-restart","running",Y.sshTarget);let J=await X.run(["sh","-c",`${U0}vibe restart 2>/dev/null || ${U0}vibe start`],{timeoutMs:90000});if(J.code!==0)return Q("ssh-restart","failed",J.stderr.slice(0,300)),{ok:!1,peerId:$,tunnelUrl:null,error:`Remote restart failed (exit ${J.code})`};Q("ssh-restart","completed"),Q("await-tunnel","running");let W=null;for(let H=0;H<15;H++){let B=await X.run(["sh","-c",`${U0}vibe url --json 2>/dev/null`],{timeoutMs:15000});if(B.code===0){let K=RQ(B.stdout),L=i2(K);if(L){W=L;break}}await new Promise((K)=>setTimeout(K,2000))}if(!W)return Q("await-tunnel","failed","no fresh tunnel after restart"),{ok:!1,peerId:$,tunnelUrl:null,error:"Agent restarted but no fresh tunnel came up."};return Q("await-tunnel","completed",W),u4($,{tunnelUrl:W,lastReachable:new Date().toISOString()}),Q("update","completed"),{ok:!0,peerId:$,tunnelUrl:W}}catch(J){return{ok:!1,peerId:$,tunnelUrl:null,error:J instanceof Error?J.message:String(J)}}finally{await X.close().catch(()=>{})}}var DQ=Number(process.env.VIBECONTROLS_MESH_MAX_HOPS||"8");function g4(){return(c()??G()).name}function hQ(){return(c()??G()).dataDir}function p4(){try{let Z=SQ(hQ(),"runtime.json");if(AQ(Z)){let Q=JSON.parse(kQ(Z,"utf8"));if(Q.port&&Number.isInteger(Q.port))return Q.port}}catch{}let $=Number(process.env.PORT);return Number.isInteger($)&&$>0?$:3005}function vQ($){let Z={};return $.headers.forEach((Q,Y)=>{Z[Y]=Q}),Z}function X2($,Z){let Q=m(vQ($));return n4(d4(Q),Z)}function PQ($){let{apiKey:Z,...Q}=$;return{...Q,apiKey:"[REDACTED]"}}function l4($){return typeof $==="string"&&$.startsWith("/api/")&&!$.includes("..")&&!$.includes("//")}var a2=new Map;function fQ(){let $=Date.now()-3600000;for(let[Z,Q]of a2)if(Q.completedAt&&Date.parse(Q.completedAt)<$)a2.delete(Z)}function o4(){return new D({name:"agent-mesh"}).get("/api/mesh/peers",({request:$,set:Z})=>{if(!X2($,["read"]))return Z.status=403,{error:"forbidden"};return{peers:L2(n()).map(PQ)}}).delete("/api/mesh/peers/:id",({request:$,set:Z,params:Q})=>{if(!X2($,["mutate"]))return Z.status=403,{error:"forbidden"};if(!L2(n()).some((X)=>X.id===Q.id))return Z.status=404,{error:"not found"};return{ok:i4(Q.id)}}).post("/api/mesh/peers/:id/call",async({request:$,set:Z,params:Q,body:Y})=>{if(!X2($,["mesh:forward"]))return Z.status=403,{error:"forbidden"};let X=Y;if(!l4(X.path))return Z.status=400,{error:"invalid path"};if(!L2(n()).find((H)=>H.id===Q.id))return Z.status=404,{error:"not found"};let W=await I2(Q.id,X.path,{method:X.method??"GET",body:X.body,operation:"mesh-call"});return{ok:W.ok,status:W.status,data:W.data,rotated:W.rotated,error:W.error}},{body:z.Object({method:z.Optional(z.String()),path:z.String(),body:z.Optional(z.Any())})}).post("/api/mesh/forward",async({request:$,set:Z,body:Q})=>{if(!X2($,["mesh:forward"]))return Z.status=403,{error:"forbidden"};let Y=Q;if(!Y.request||!l4(Y.request.path))return Z.status=400,{error:"invalid request"};let X=(Y._hopCount??0)+1;if(X>DQ)return Z.status=422,{error:"hop limit exceeded"};let J=n(),W=g2(),H=Y.hops??[];if(H.length===0){G().audit.emit("mesh","forward.terminal",{path:Y.request.path,method:Y.request.method??"GET"});let x=(Y.request.method??"GET").toUpperCase();try{let V=await fetch(`http://127.0.0.1:${p4()}${Y.request.path}`,{method:x,headers:{"x-agent-api-key":await j0(),...Y.request.body!==void 0?{"content-type":"application/json"}:{}},body:Y.request.body!==void 0?JSON.stringify(Y.request.body):void 0,signal:AbortSignal.timeout(60000)}),C=await V.text().catch(()=>""),q=null;try{q=C?JSON.parse(C):null}catch{q=null}return{ok:V.ok,status:V.status,data:q,text:C||null,error:V.ok?null:C||`status ${V.status}`}}catch(V){return Z.status=502,{ok:!1,status:0,error:V instanceof Error?V.message:String(V)}}}let B=H[0],K=Y._traversed??[];if(B===W||K.includes(B))return Z.status=422,{error:"cycle detected",at:B};let L=x0(B,J);if(!L)return Z.status=403,{error:"next hop not in authorized boundary"};if(!L.permissions.includes("mesh:forward"))return Z.status=403,{error:"peer lacks mesh:forward grant"};G().audit.emit("mesh","forward.hop",{nextId:B,remaining:H.length,hopCount:X});let w=encodeURIComponent(g4()),E=await I2(L.id,`/api/profiles/${w}/mesh/forward`,{method:"POST",operation:"mesh-forward",timeoutMs:60000,body:{hops:H.slice(1),request:Y.request,_traversed:[...K,W??"self"],_hopCount:X}});if(!E.ok)return Z.status=502,{ok:!1,status:E.status,error:E.error,failedAtHop:B};return E.data},{body:z.Object({hops:z.Optional(z.Array(z.String())),request:z.Object({method:z.Optional(z.String()),path:z.String(),body:z.Optional(z.Any())}),_traversed:z.Optional(z.Array(z.String())),_hopCount:z.Optional(z.Number())})}).post("/api/mesh/deploy",({request:$,set:Z,body:Q})=>{if(!X2($,["admin"]))return Z.status=403,{error:"forbidden"};fQ();let Y=Q,X=n(),J=crypto.randomUUID(),W={id:J,status:"running",steps:[],ownerUserId:X.ownerUserId,workspaceId:X.workspaceId,startedAt:new Date().toISOString()};return a2.set(J,W),c4({target:Y.target,permissions:Y.permissions,installPlugins:Y.installPlugins,autostart:Y.autostart,identityFile:Y.identityFile,label:Y.label,version:Y.version,connectExisting:Y.connectExisting},(H)=>{W.steps.push(H),Y2("mesh:deploy:progress",{jobId:J,step:H})}).then((H)=>{if(W.result=H,W.status=H.ok?"completed":"failed",!H.ok)W.error=H.error;W.completedAt=new Date().toISOString(),Y2(H.ok?"mesh:deploy:complete":"mesh:deploy:failed",{jobId:J,result:H})}).catch((H)=>{W.status="failed",W.error=H instanceof Error?H.message:String(H),W.completedAt=new Date().toISOString(),Y2("mesh:deploy:failed",{jobId:J,error:W.error})}),Z.status=202,{jobId:J,status:"running"}},{body:z.Object({target:z.String(),permissions:z.Optional(z.Array(z.String())),installPlugins:z.Optional(z.Array(z.String())),autostart:z.Optional(z.Boolean()),identityFile:z.Optional(z.String()),label:z.Optional(z.String()),version:z.Optional(z.String()),connectExisting:z.Optional(z.Boolean())})}).get("/api/mesh/deploy/jobs/:id",({request:$,set:Z,params:Q})=>{if(!X2($,["read"]))return Z.status=403,{error:"forbidden"};let Y=a2.get(Q.id),X=n();if(!Y||X.ownerUserId&&Y.ownerUserId&&Y.ownerUserId!==X.ownerUserId)return Z.status=404,{error:"not found"};return Y}).post("/api/mesh/wake",async({request:$,set:Z,body:Q})=>{if(!X2($,["admin"]))return Z.status=403,{error:"forbidden"};let Y=Q,X=x0(Y.targetAgentRecordId,n());if(!X)return Z.status=404,{ok:!1,error:"peer not in authorized boundary"};G().audit.emit("mesh","wake.start",{peerId:X.id,agentRecordId:Y.targetAgentRecordId});let J=await m4(X.id,(W)=>Y2("mesh:wake:progress",{peerId:X.id,step:W}));if(!J.ok)Z.status=502;return J},{body:z.Object({targetAgentRecordId:z.String()})}).post("/api/mesh/session",async({request:$,set:Z,body:Q})=>{if(!X2($,["mesh:forward","mutate"]))return Z.status=403,{error:"forbidden"};let Y=Q,X=Y.sessionId&&/^[A-Za-z0-9_-]{1,128}$/.test(Y.sessionId)?Y.sessionId:crypto.randomUUID(),J=encodeURIComponent(g4()),W=await j0(),H=`http://127.0.0.1:${p4()}`,B=Y.command||"bash";try{let K=await fetch(`${H}/api/profiles/${J}/sessions/create`,{method:"POST",headers:{"x-agent-api-key":W,"content-type":"application/json"},body:JSON.stringify({sessionId:X,sessionName:`vc-mesh-${X.slice(0,8)}`,command:B,provider:"TERMINAL",...Y.vibeId?{projectId:Y.vibeId}:{}}),signal:AbortSignal.timeout(20000)});if(!K.ok)return Z.status=502,{error:`session create returned ${K.status}: ${await K.text().catch(()=>"")}`};let L=await fetch(`${H}/api/profiles/${J}/sessions/${encodeURIComponent(X)}/terminal`,{method:"POST",headers:{"x-agent-api-key":W},signal:AbortSignal.timeout(20000)});if(!L.ok)return Z.status=502,{error:`terminal start returned ${L.status}: ${await L.text().catch(()=>"")}`};let w=v2(`/terminal/${X}`,600);return G().audit.emit("mesh","session.created",{sessionId:X,kind:Y.kind??"TERMINAL"}),{connectionId:X,sessionId:X,capabilityToken:w.token,expiresAt:w.expiresAt}}catch(K){return Z.status=502,{error:K instanceof Error?K.message:String(K)}}},{body:z.Object({sessionId:z.Optional(z.String()),kind:z.Optional(z.String()),cwd:z.Optional(z.String()),vibeId:z.Optional(z.String()),command:z.Optional(z.String())})})}var bQ=["/health","/api/agent/status","/api/agent/version","/api/agent/identity","/api/agent/api-key","/api/agent/tunnel","/api/agent/system","/api/agent/gateway-auth","/api/stats","/metrics","/api/profiles","/api/profile-stats"];function cQ($){return bQ.some((Z)=>$.startsWith(Z))}var yQ=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;function uQ($){return $.split("/").map((Z)=>{if(!Z)return Z;if(/^\d+$/.test(Z))return":id";if(yQ.test(Z))return":id";if(Z.length>=24&&/^[A-Za-z0-9_-]+$/.test(Z))return":id";return Z}).join("/")}async function a8($){let{port:Z,host:Q,dbPath:Y,logLevel:X,corsOrigin:J}=$,W=Y??T2();try{(await import("fs")).mkdirSync(W,{recursive:!0})}catch(F){throw G().logger.error("app","Failed to create dbPath dir at boot",{dbPath:W,error:String(F)}),Error(`Cannot create dbPath ${W}: ${F instanceof Error?F.message:String(F)}`,{cause:F})}if(X)G().logger.setLevel(X);(async()=>{let{logShipper:F}=await import("./log-shipper-hjnn1d5p.js");F.init()})(),(async()=>{let F=await s4();await S2({version:F,profile:C2()})})();try{let{checkDependencies:F}=await import("./bootstrap.service-vg72w8pa.js"),M=F(),U=M.filter((R)=>R.required&&!R.installed),A=M.filter((R)=>!R.required&&!R.installed);if(U.length>0)G().logger.error("app",`Missing required system deps: ${U.map((R)=>R.name).join(", ")}. Run \`vibe setup\` to install.`);if(A.length>0)G().logger.warn("app",`Missing optional system deps: ${A.map((R)=>R.name).join(", ")}. Some plugins may fail their prereqs check.`)}catch(F){G().logger.warn("app","Boot-time dependency check failed",{error:String(F)})}try{G().audit.runRetention()}catch(F){G().logger.warn("app","Audit-log retention sweep failed",{error:String(F)})}let H=new N5;I5(H,{port:Z});let B="GET, POST, PUT, PATCH, DELETE, OPTIONS",K="Content-Type, x-agent-api-key, Authorization, x-requested-with",L=Array.isArray(J)?J:(J??"").split(",").map((F)=>F.trim()).filter(Boolean),w=new Set(["https://vibecontrols.com","https://app.vibecontrols.com","https://alphaapp.vibecontrols.com","https://burdenoff.com","https://app.burdenoff.com","https://alphaapp.burdenoff.com"]),E=(F)=>{try{let M=new URL(F);if(L.includes(F))return!0;if(L.includes("*"))return!1;return M.hostname==="localhost"||M.hostname==="127.0.0.1"||M.hostname==="0.0.0.0"||M.hostname.endsWith(".local.burdenoff.com")||w.has(M.origin)}catch{return!1}},x=null,V=null,C=null,q=null,v=!1,N=()=>[],T=null,O=null,I=null,h=5000,y=async(F,M)=>{let U=Date.now();try{await Promise.race([Promise.resolve(M()),new Promise((A,R)=>setTimeout(()=>R(Error(`shutdown phase ${F} exceeded ${h}ms`)),h))]),G().logger.info("app",`shutdown.phase ${F} complete`,{ms:Date.now()-U})}catch(A){G().logger.warn("app",`shutdown.phase ${F} failed`,{error:String(A),ms:Date.now()-U})}},r=async(F)=>{if(v)return;if(v=!0,G().logger.info("app","Agent shutdown starting",{reason:F?.reason??"shutdown"}),await y("plugins",async()=>{if(V)await V.dispatchServerStop(F)}),await y("bootstrap-tunnel",()=>C0()),await y("tracked-subprocesses",async()=>{let{killAllTracked:M}=await import("./subprocess-1nna3d3x.js");await M()}),F?.reason!=="reload")await y("db-close",async()=>{if(x)await x.close()});await y("http-listener",async()=>{try{await Promise.resolve(e.stop())}catch(M){G().logger.warn("app","Listener stop threw (already stopped or never started?)",{error:String(M)})}}),G().logger.info("app","Agent server stopped"),G().logger.close()},i=async(F,M)=>{if(G().getBootState()==="ready")return{ok:!0};if(I)return I;return I=(async()=>{G().setBootState("initializing");try{let U={...F,globalGatewayUrl:B2(F.globalGatewayUrl,"globalGatewayUrl"),workspaceGatewayUrl:B2(F.workspaceGatewayUrl,"workspaceGatewayUrl")},A=await U5(U),R=W,P=t({dir:G().dataDir}),p=P.storageAdapter??process.env.VIBE_STORAGE_ADAPTER??void 0,o=P.storageOptions,Q2=(_)=>{let j=(_ instanceof Error?_.message:String(_)).toLowerCase(),k=_&&typeof _==="object"&&"code"in _?String(_.code).toUpperCase():"";if(k==="EBUSY"||k==="EPERM"||k==="EACCES"||k==="EAGAIN"||k==="EMFILE"||k==="ENFILE"||k==="ETIMEDOUT"||k==="ECONNRESET"||k==="ECONNREFUSED"||j.includes("encryption key")||j.includes("fetch")&&j.includes("key")||j.includes("temporarily unavailable")||j.includes("resource busy"))return"transient";if(j.includes("auth tag")||j.includes("authentication tag")||j.includes("unable to authenticate data")||j.includes("bad decrypt")||j.includes("unsupported state")||j.includes("incorrect header check")||j.includes("invalid distance")||j.includes("incorrect data check")||j.includes("unexpected end of")||j.includes("unexpected token")||j.includes("json")&&(j.includes("parse")||j.includes("invalid"))||j.includes("truncated")||j.includes("malformed")||j.includes("corrupt"))return"corruption";return"unknown"},U2=()=>r4({dbPath:R,encryptionKey:A,adapterName:p,adapterOptions:o});try{x=await U2()}catch(_){let j=_,k=Q2(_),q2=[500,2000,8000];if(k==="transient"||k==="unknown"){G().logger.warn("app",`Storage open failed (${k}); will retry up to ${q2.length} times before quarantine`,{error:_ instanceof Error?_.message:String(_),path:R});for(let O2 of q2){await new Promise((f)=>setTimeout(f,O2));try{x=await U2(),j=null;break}catch(f){if(j=f,k=Q2(f),G().logger.warn("app",`Storage open retry failed (${k}) after ${O2}ms`,{error:f instanceof Error?f.message:String(f)}),k==="corruption")break}}}if(!x&&j){if(k!=="corruption"){let f=j instanceof Error?j.message:String(j);G().logger.error("app",`Storage open failed after retries with non-corruption error (${k}); refusing to quarantine valid data`,{error:f,path:R}),G().recordDegradedReason("storage",f);try{throw j}catch(G2){throw Error(`Storage open failed (${k}); agent is degraded: ${f}`,{cause:G2})}}let O2=j instanceof Error?j.message:String(j);G().logger.error("app","QUARANTINE: Storage file is corrupt \u2014 renaming and creating fresh DB",{errorClass:"corruption",error:O2,path:R});try{let f=await import("fs");if(f.existsSync(R)){let G2=new Date().toISOString().replace(/[:.]/g,"-"),q0=`${R}.broken-${G2}`;f.renameSync(R,q0),G().logger.warn("app",`Quarantined corrupt storage to ${q0} \u2014 fresh DB will be created`,{originalError:O2})}x=await U2()}catch(f){let G2=f instanceof Error?f.message:String(f);throw G().recordDegradedReason("storage",G2),Error(`Storage open failed twice (quarantine path); agent is degraded: ${G2}`,{cause:f})}}}if(!x)throw Error("Internal error: storage open recovery exited without an open database and without throwing");if(await h2({clientId:U.clientId,clientSecret:U.clientSecret,workspaceId:U.workspaceId,organizationId:U.organizationId,globalGatewayUrl:U.globalGatewayUrl,workspaceGatewayUrl:U.workspaceGatewayUrl,agentRecordId:M?.agentRecordId,scopes:M?.scopes},{dir:G().dataDir,scope:G().name}),await x.setConfig("gateway-auth:clientId",U.clientId),await x.setConfig("gateway-auth:clientSecret",U.clientSecret),await x.setConfig("gateway-auth:globalGatewayUrl",U.globalGatewayUrl),await x.setConfig("gateway-auth:workspaceGatewayUrl",U.workspaceGatewayUrl),await x.setConfig("gateway-auth:workspaceId",U.workspaceId),U.organizationId)await x.setConfig("gateway-auth:organizationId",U.organizationId);if(M?.agentRecordId)await x.setConfig("gateway-auth:agentRecordId",M.agentRecordId);H.db=x,await H.hydrateDefaultsFromDb(),V=new T5(x),await V.loadCorePlugins();try{await V.loadAll()}catch(_){G().logger.warn("app","Failed to load some external plugins",{error:String(_)})}let j2=C5(F2())??void 0,x2=process.env.VIBE_SKIP_AUTO_INSTALL==="1"||await x.getConfig("plugins:auto-install-disabled");if(x2!=="true"&&x2!==!0)try{let _=await V.ensureDefaultPlugins((j)=>G().logger.info("app",`[auto-install] ${j}`),[],j2);if(_.length>0)G().logger.info("app",`Auto-installed ${_.length} default plugin(s): ${_.map((j)=>j.packageName).join(", ")}`)}catch(_){G().logger.warn("app","Failed to auto-install default plugins",{error:String(_)})}G().logger.info("app",`Plugins loaded: ${V.getPluginDetails().length} total (${V.getPluginDetails().filter((_)=>_.isCore).length} core)`);try{let _=V.getPluginDetails(),j={loaded:_.filter((k)=>k.loaded).length,failed:_.filter((k)=>!k.loaded).length};b0(j)}catch{}let r2={async get(_,j){return await x.getPluginState(_,j)??null},async set(_,j,k){await x.setPluginState(_,j,k)},async delete(_,j){return x.deletePluginState(_,j)},async list(_){return await x.getAllPluginState(_)},async deleteAll(_){return x.deleteAllPluginState(_)}},w2=await s4();C={storage:r2,logger:G().logger,serviceRegistry:H,getProvider:(_)=>H.getProvider(_),getAgentBaseUrl:()=>process.env.AGENT_URL||`http://localhost:${Z}`,getAgentVersion:()=>w2,validateApiKey:(_)=>l(_),setCodeServerSessionValidator:(_)=>{w5=_},broadcast:Y2,workspaceQuery:async(_,j)=>g.workspaceQuery(_,j),isGatewayConfigured:()=>g.isConfigured(),getAgentRecordId:async()=>await x.getConfig("gateway-auth:agentRecordId")??null,getWorkspaceId:async()=>await x.getConfig("gateway-auth:workspaceId")??null,getConfig:async(_)=>await x.getConfig(_)??void 0,getPluginRegistry:()=>n2(),getDataDir:()=>D2(),cliContributors:new _5,audit:{emit:(_,j)=>G().audit.emit("agent",_,j??{})},telemetry:{emit:(_,j)=>{import("./telemetry-8jfdyt51.js").then(({telemetryService:k})=>k.emit(_,j??{})).catch(()=>{})}},os:N2(),iframeBridge:M5()},g.configure({globalGatewayUrl:U.globalGatewayUrl,workspaceGatewayUrl:U.workspaceGatewayUrl,clientId:U.clientId,clientSecret:U.clientSecret,workspaceId:U.workspaceId,organizationId:U.organizationId});let H2={db:x,serviceRegistry:H,pluginManager:V,broadcast:Y2,hostServices:C};H2.app=e;let w0=!1,t2=()=>{let{routes:_,getPublicPaths:j,mountPlugin:k}=$5(V,H2);if(H2.mountPlugin=k,N=j,X5(),T=_,O=O5(V),V&&w0&&C)V.dispatchServerStart(T,C).catch((q2)=>G().logger.warn("app","Re-dispatch of onServerStart after plugin reload failed",{error:String(q2)}));w0=!0};H2.rebuildPluginSurfaces=t2,t2(),q=new j5(H,V,x,e,C,r),H.registerService("agent","lifecycle",q),G().attachServices({db:x,serviceRegistry:H,pluginManager:V,lifecycle:q,hostServices:C}),F5(G(),{rebuildPluginSurfaces:t2,mountPlugin:H2.mountPlugin});try{await G().keyVault.bindApiKey(V2())}catch(_){G().logger.warn("app","Failed to bind api key into daemon keyVault",{error:String(_)})}let e2=[];try{let{failures:_}=await V.dispatchServerStart(T,C);for(let j of _)if(T0(j.plugin)||(j.packageName?T0(j.packageName):!1))e2.push(j),G().recordDegradedReason(j.plugin,j.error);else G().logger.warn("app",`Non-critical plugin ${j.plugin} failed onServerStart; continuing`,{error:j.error})}catch(_){G().logger.warn("app","Error during plugin onServerStart dispatch",{error:String(_)})}try{await V.dispatchServerReady(e,C)}catch(_){G().logger.warn("app","Error during plugin onServerReady dispatch",{error:String(_)})}if(G().clearFinalizeError(),e2.length>0)G().setBootState("degraded"),G().logger.error("app","Agent finalized but degraded \u2014 critical plugins failed",{failures:e2.map((_)=>`${_.plugin}: ${_.error}`)});else G().setBootState("ready"),G().logger.info("app","Agent finalized \u2014 state=ready"),G().audit.emit("agent","gateway-auth.configured",{workspaceId:U.workspaceId,organizationId:U.organizationId,agentRecordId:M?.agentRecordId});return(async()=>{try{if(await V.provisionDefaultPrereqs(e,C,H2.mountPlugin,j2),G().logger.info("app","Default provider prerequisites provisioned"),(H.listProvidersForType("tunnel")??[]).some((k)=>k.pluginName!=="bootstrap")){let{tryHandoverBootstrapTunnel:k}=await import("./tunnel-bootstrap-5wgt9a1h.js");if(!k())C0();H.unregisterProvider("tunnel","bootstrap"),G().logger.info("app","Bootstrap tunnel handed over to the real tunnel provider")}}catch(_){G().logger.warn("app","Plugin prerequisite provisioning failed",{error:String(_)})}})(),{ok:!0}}catch(U){G().setBootState("awaiting-config");let A=U instanceof Error?U.message:String(U);if(G().recordFinalizeError(A),G().logger.error("app","Finalize failed",{error:A}),process.env.VIBE_STRICT_KEY_FETCH==="1")G().logger.error("app","VIBE_STRICT_KEY_FETCH=1 \u2192 aborting daemon (strict mode)",{error:A}),setTimeout(()=>process.exit(1),50);return{ok:!1,error:A}}finally{I=null}})(),I},_2=A0({origin:(F)=>{let M=F.headers.get("origin");return!!M&&E(M)},credentials:!0,allowedHeaders:K.split(",").map((F)=>F.trim()),methods:B.split(",").map((F)=>F.trim()),exposeHeaders:["content-type","content-length"],maxAge:86400,preflight:!0}),q5=10485760,E0=process.env.VIBECONTROLS_MAX_BODY_BYTES,s2=E0?Number.parseInt(E0,10):NaN,R5=Number.isFinite(s2)&&s2>0?s2:q5,I0={current:null},e=new D({serve:{maxRequestBodySize:R5}}).onRequest(({request:F,set:M})=>{let A=t4(F.headers)??O0();e4({requestId:A,startedAt:new Date().toISOString()});let R=M.headers??={};R["X-Request-Id"]=A}).onRequest(({request:F})=>{try{let M=new URL(F.url).pathname,A=/^\/api\/profiles\/([^/]+)(?:\/|$)/.exec(M)?.[1],R=A?s.get(A):null;M0(R??G())}catch{M0(G())}}).onRequest(({request:F,set:M})=>{let U=new URL(F.url).pathname;if(!U.startsWith("/api/"))return;if(U==="/api/profiles"||U.startsWith("/api/profiles/"))return;if(U==="/api/profile-stats"||U.startsWith("/api/profile-stats/"))return;let A=new URL(F.url);A.pathname=`/api/profiles/default${U.slice(4)}`;try{F.headers.set("x-vc-profile-rewrite","1"),F.headers.set("x-vc-profile-rewrite-target",A.pathname)}catch{}return}).derive(()=>({requestId:Q5()??O0()})).use(_2).use(W5()).use(Y5(()=>N())).use(h0({getDb:()=>c()?.db??x})).onBeforeHandle(({request:F,set:M})=>{let U=G().getBootState();if(U==="ready")return;let A=new URL(F.url).pathname;if(cQ(A))return;return M.status=503,{error:"Agent not yet configured",message:"Agent is in '"+U+"' state. POST credentials to /api/agent/gateway-auth to finalize.",state:U}}).onAfterHandle(({request:F,set:M})=>{let U=new URL(F.url).pathname,A=U==="/health"||U.startsWith("/api/logs/stream")||U.startsWith("/ui/")||U==="/ws/events"||U==="/api/sessions/health-check"||U.startsWith("/terminal/"),R=typeof M.status==="number"?M.status:200,P=A?"debug":R>=400?"warn":"info";G().logger[P]("http",`${F.method} ${U} \u2192 ${R}`,{method:F.method,path:U,statusCode:R});try{f0(F.method,uQ(U),R)}catch{}}).use(z4({serviceRegistry:H,getDb:()=>c()?.db??x,getDbPath:()=>W,getPluginManager:()=>c()?.pluginManager??V})).use(y0()).use(o0({serviceRegistry:H,runFinalize:(F,M)=>i(F,M),getDb:()=>c()?.db??x})).use(G4()).use(B4()).use(v4({getPluginManager:()=>c()?.pluginManager??V})).use(o4()).use(L4()).use(M4({getPluginManager:()=>c()?.pluginManager??V,getTunnelHost:()=>E5()?.url??null})).use(Z4()).use(X4()).use(B5()).use(K5()).use(V5(H)).ws("/code-server/*",gQ(Z)).all("/api/profiles/:name/*",async({params:F,request:M,set:U})=>{let A=M.method!=="GET"&&M.method!=="HEAD",R=A?await M.arrayBuffer():void 0,P=await L5(F.name,M,R);if(P&&P.status!==404)return P;let p=C2(),o=F.name;if(o!==p)return U.status=404,{error:"profile-mismatch",running:p,requested:o,hint:"This daemon serves a different profile. Call GET /api/profiles to discover the right tunnel."};let Q2=new URL(M.url),U2=Q2.pathname.replace(/^\/api\/profiles\/[^/]+/,"/api"),j2=new Headers(M.headers);j2.set("x-vc-profile-rewrite","1");let x2={method:M.method,headers:j2};if(A&&R!==void 0)x2.body=R;let r2=new Request(`${Q2.origin}${U2}${Q2.search}`,x2),w2=I0.current;if(!w2)return new Response(JSON.stringify({error:"agent-not-ready"}),{status:503,headers:{"content-type":"application/json"}});return w2.handle(r2)}).all("/api/*",async({request:F})=>{if(G().getBootState()!=="ready"||!T)return new Response(JSON.stringify({error:"Agent not yet configured",state:G().getBootState(),message:"Plugin routes are unavailable until the agent reaches state=ready. POST credentials to /api/agent/gateway-auth to finalize."}),{status:503,headers:{"content-type":"application/json"}});try{let M=new URL(F.url),U=/^\/api\/plugins\/([a-z0-9-]{1,64})\/ui(?:\/.*)?$/.exec(M.pathname);if(U&&F.method==="GET"){let A=U[1];if(M2(A)){let R=M.pathname.slice(`/api/plugins/${A}/ui`.length),P=R===""||R==="/",o=F.headers.get("sec-fetch-mode")==="navigate";if(P||o){let Q2=J5(F,A);if(!Q2||!Z5(Q2,A))return new Response(x5(A,"/api/profiles/default/agent/ui-exchange-plugin"),{status:200,headers:{"content-type":"text/html; charset=utf-8","Content-Security-Policy":"frame-ancestors 'self' http://localhost:* http://127.0.0.1:* https://localhost:* https://127.0.0.1:* https://*.local.burdenoff.com https://vibecontrols.com https://*.vibecontrols.com https://burdenoff.com https://app.burdenoff.com https://alphaapp.burdenoff.com"}})}}}}catch{}return T.handle(F)}).all("/ui/*",async({request:F})=>{if(G().getBootState()!=="ready"||!O)return new Response("Plugin UI not yet available",{status:503});return O.handle(F)}).all("/code-server/*",async({request:F})=>{if(G().getBootState()!=="ready"||!T)return new Response("code-server not yet available",{status:503});let M=k0(F,V2);return T.handle(M??F)}).all("/plan/*",async({request:F})=>{if(G().getBootState()!=="ready"||!T)return new Response("plan provider not yet available",{status:503});return T.handle(F)});return I0.current=e,{app:e,async start(){e.listen({port:Z,hostname:Q}),G().logger.info("app",`Agent server listening on ${Q}:${Z}`);try{let F=(process.env.VIBECONTROLS_PROFILES??"").split(",").map((P)=>P.trim()).filter(Boolean),M=G().name,{getOrCreateProfile:U}=await import("./daemon-profile-gwdcqx0q.js"),{attachSecondaryProfile:A}=await import("./secondary-profile-attach-69zv112x.js"),R=process.env.VIBE_STRICT_KEY_FETCH==="1";for(let P of F){if(P===M)continue;try{let p=U(P),o=await A(p);if(o.ok)G().logger.info("app",`Secondary profile '${P}' attached (db+services online)`);else if(R)throw Error(`attachServices for secondary profile '${P}' failed: ${o.error}`);else p.recordDegradedReason("attach",o.error??"unknown"),G().logger.warn("app",`Secondary profile '${P}' is degraded (no creds / attach failed)`,{error:o.error})}catch(p){if(R)throw G().logger.error("app",`--strict-key-fetch: secondary profile '${P}' attach failed; aborting`,{error:String(p)}),setTimeout(()=>process.exit(1),50),p;G().logger.warn("app",`Failed to attach secondary profile '${P}'`,{error:String(p)})}}}catch{}return e},stop:r,finalize:i,getState:()=>G().getBootState(),getLifecycle:()=>c()?.lifecycle??q,getDb:()=>c()?.db??x,getServiceRegistry:()=>c()?.serviceRegistry??H,getPluginManager:()=>c()?.pluginManager??V,getHostServices:()=>c()?.hostServices??C}}var w5=null;function mQ($,Z){if(!$)return null;let Q=$.match(new RegExp(`(?:^|;\\s*)${Z}=([^;]*)`));return Q?Q[1]:null}var a4=z5(H5);function gQ($){let X=(J)=>typeof J==="string"?Buffer.byteLength(J):J.byteLength;return{open(J){let W=J.data,H=m(W.headers??{})??m(W.request?Object.fromEntries(W.request.headers.entries()):{}),B=W.query?.vt,K=!!B&&R2(B,"/code-server","GET"),L,w=l(H);if(!w&&!K){let C=W.headers?.cookie??W.request?.headers.get("cookie")??null,q=mQ(C,"__vibe_cs_session");if(!q||!w5?.(q)){J.close(1008,"Unauthorized");return}L=`session:${q}`}else if(w)L="api-key";else L="vt";let E=J.remoteAddress??null,x=G5(E,W.headers);if(!a4.accept(L,x,J)){G().logger.warn("code-server-ws",`code-server WS cap exceeded (key=${L}, ip=${x??"unknown"})`),J.close(1013,"too many connections");return}W._csCapKey=L,W._csRemoteIp=x;let V=G().name;fetch(`http://127.0.0.1:${$}/api/profiles/${encodeURIComponent(V)}/code-server/status`,{headers:{"x-agent-api-key":V2()}}).then((C)=>C.json()).then((C)=>{if(W._csClosed)return;let q=C;if(!q.running||!q.port){J.close(1011,"code-server not running");return}let v=W.request?.url??"/code-server/",N;try{let I=new URL(v,`http://127.0.0.1:${q.port}`);N=(I.pathname.replace(/^\/code-server\/?/,"/")||"/")+I.search}catch{N="/"}let T=new WebSocket(`ws://127.0.0.1:${q.port}${N}`),O={upstream:T,ready:!1,buffer:[],bufferBytes:0,openTimer:setTimeout(()=>{try{T.close(1011,"upstream open timeout")}catch{}try{J.close(1011,"upstream open timeout")}catch{}},1e4)};W._csBridge=O,T.addEventListener("open",()=>{clearTimeout(O.openTimer),O.ready=!0;for(let I of O.buffer)T.send(I);O.buffer.length=0,O.bufferBytes=0}),T.addEventListener("message",(I)=>{try{let h=I.data;if(h instanceof ArrayBuffer)J.send(new Uint8Array(h));else if(h instanceof Blob)h.arrayBuffer().then((y)=>{try{J.send(new Uint8Array(y))}catch{}});else J.send(h)}catch{}}),T.addEventListener("close",(I)=>{clearTimeout(O.openTimer);try{J.close(I.code||1000,I.reason||"upstream closed")}catch{}}),T.addEventListener("error",()=>{clearTimeout(O.openTimer);try{J.close(1011,"upstream error")}catch{}})}).catch(()=>{J.close(1011,"Failed to query code-server status")})},message(J,W){let H=J.data?._csBridge;if(!H)return;let B;if(typeof W==="string")B=W;else if(W instanceof ArrayBuffer)B=W;else if(W instanceof Uint8Array||Buffer.isBuffer(W)){let K=new ArrayBuffer(W.byteLength);new Uint8Array(K).set(new Uint8Array(W.buffer,W.byteOffset,W.byteLength)),B=K}else if(typeof W==="object"&&W!==null)B=JSON.stringify(W);else B=String(W);if(H.upstream&&H.ready&&H.upstream.readyState===WebSocket.OPEN)try{H.upstream.send(B)}catch{}else{let K=X(B);if(H.buffer.length>=256||H.bufferBytes+K>1048576){try{H.upstream.close(1013,"buffer limit exceeded")}catch{}try{J.close(1013,"buffer limit exceeded")}catch{}return}H.buffer.push(B),H.bufferBytes+=K}},close(J){J.data._csClosed=!0;let W=J.data?._csBridge;if(W?.openTimer)clearTimeout(W.openTimer);if(W?.upstream&&W.upstream.readyState===WebSocket.OPEN)W.upstream.close(1000,"client disconnected");let H=J.data._csCapKey,B=J.data._csRemoteIp;if(H)a4.release(H,B??null,J)}}}async function s4(){try{let{readFileSync:$}=await import("fs"),{join:Z,dirname:Q}=await import("path"),{fileURLToPath:Y}=await import("url"),X=Q(Y(import.meta.url));return JSON.parse($(Z(X,"..","package.json"),"utf8")).version||"1.0.0"}catch{return"1.0.0"}}
26
26
  export{H6 as j,g0 as k,_Q as l,L7 as m,a8 as n};
@@ -1,5 +1,5 @@
1
1
  // @bun
2
- import{Xa as QQ}from"./index-0ckffygp.js";import{Bd as ZQ,Md as k,Od as Y}from"./index-js1xn4sq.js";import{$d as b,de as d}from"./index-a4854mwz.js";import{ie as w}from"./index-c7554sg7.js";import{existsSync as U,mkdirSync as n,readdirSync as GQ,readFileSync as v,renameSync as _Q,realpathSync as t,rmSync as j,statSync as RQ,writeFileSync as g}from"fs";import{homedir as xQ}from"os";import{dirname as R,isAbsolute as EQ,join as V,relative as IQ,sep as r}from"path";import{fileURLToPath as P}from"url";import{existsSync as XQ,readFileSync as qQ}from"fs";import{dirname as A,join as BQ}from"path";import{fileURLToPath as YQ}from"url";var WQ="@vibecontrols/agent",_;function N(){if(_)return _;try{let Q=A(YQ(import.meta.url));for(let Z=0;Z<10&&Q&&Q!==A(Q);Z++){let $=BQ(Q,"package.json");if(XQ($))try{let z=JSON.parse(qQ($,"utf8"));if(z.name===WQ&&typeof z.version==="string")return _=z.version,_}catch{}Q=A(Q)}}catch{}return _??"0.0.0"}function u(){let Q=process.env.VIBECONTROLS_PLUGIN_CONTRACT_V2_ENFORCE;return Q==="1"||Q==="true"||Q==="on"}var m={storage:"rw",secrets:"rw",gateway:!0,broadcast:!0,subprocess:!0,audit:!0,telemetry:!0,singletonOnly:!1,requiresIsolation:!1},c={storage:"none",secrets:"none",gateway:!1,broadcast:!1,subprocess:!1,audit:!1,telemetry:!1,singletonOnly:!1,requiresIsolation:!1};function s(){let Q=process.env.VIBECONTROLS_STRICT_PLUGIN_CAPS;return Q==="1"||Q==="true"||Q==="on"}function o(Q,Z,$,z,H=!1){return new Proxy(Q,{get(q,X,B){if(X==="plugins"){if(!H)return;return Reflect.get(q,X,B)}if(X==="storage")return JQ(q.storage,$.storage??"none",Z,z);if(X==="broadcast"&&!$.broadcast)return E(Z,"broadcast",z);if(X==="workspaceQuery"&&!$.gateway)return E(Z,"workspaceQuery",z);if(X==="getAgentRecordId"&&!$.gateway)return E(Z,"getAgentRecordId",z);if(X==="getWorkspaceId"&&!$.gateway)return E(Z,"getWorkspaceId",z);if(X==="telemetry"){if(!$.telemetry)return;return Reflect.get(q,X,B)}return Reflect.get(q,X,B)}})}function JQ(Q,Z,$,z){if(Z==="rw")return Q;return new Proxy(Q,{get(H,q,X){let B=String(q),J=B==="set"||B==="delete"||B==="deleteAll";if(Z==="none"||Z==="read"&&J)return(...M)=>{throw z("plugin.capability.denied",{pluginName:$,surface:"storage",op:B,mode:Z}),Error(`plugin '${$}' lacks storage:${J?"rw":"read"} capability (op=${B})`)};return Reflect.get(H,q,X)}})}function E(Q,Z,$){return(...z)=>{throw $("plugin.capability.denied",{pluginName:Q,op:Z}),Error(`plugin '${Q}' lacks capability for ${Z}`)}}import{Worker as KQ}from"worker_threads";import{fileURLToPath as MQ}from"url";import{randomUUID as VQ}from"crypto";function OQ(){let Q=MQ(import.meta.url),Z=Q.lastIndexOf("/"),$=Z>=0?Q.slice(0,Z):Q,z=`${$}/plugin-worker-runtime.ts`,H=`${$}/plugin-worker-runtime.js`;if(Q.endsWith(".ts"))return z;return H}class L{worker;pending=new Map;spec;initPromise;terminated=!1;constructor(Q){this.spec=Q}async start(){if(this.initPromise)return this.initPromise;return this.initPromise=this.spawn(),this.initPromise}async spawn(){let Q=this.spec.runtimeEntry??OQ(),Z=["PATH","HOME","USERPROFILE","TMPDIR","TMP","TEMP","LANG","LC_ALL","LC_CTYPE","TZ","SystemRoot","SystemDrive","ComSpec","PATHEXT","windir"],$={};for(let H of Z){let q=process.env[H];if(typeof q==="string")$[H]=q}let z=new KQ(Q,{env:$});this.worker=z,z.on("message",(H)=>this.onMessage(H)),z.on("error",(H)=>this.onWorkerError(H instanceof Error?H:Error(String(H)))),z.on("exit",(H)=>this.onWorkerExit(H)),await this.call("init",{modulePath:this.spec.modulePath,ctxStub:{name:this.spec.ctx.name,dataDir:this.spec.ctx.dataDir}})}async dispatch(Q,Z=[]){if(this.terminated)throw Error("PluginWorkerHost terminated");if(!this.worker)await this.start();return this.call("dispatch",{method:Q,params:Z})}call(Q,Z){if(!this.worker)return Promise.reject(Error("worker not spawned"));let $=VQ();return new Promise((z,H)=>{this.pending.set($,{resolve:z,reject:H});try{this.worker?.postMessage({id:$,op:Q,args:Z})}catch(q){this.pending.delete($),H(q instanceof Error?q:Error(String(q)))}})}onMessage(Q){let Z=this.pending.get(Q.id);if(!Z)return;if(this.pending.delete(Q.id),Q.ok)Z.resolve(Q.result);else{let $=Error(Q.error?.message??"worker error");if(Q.error?.stack)$.stack=Q.error.stack;Z.reject($)}}onWorkerError(Q){for(let[,Z]of this.pending)Z.reject(Q);this.pending.clear()}onWorkerExit(Q){if(this.pending.size>0){let Z=Error(`worker exited (code=${Q}) with pending calls`);for(let[,$]of this.pending)$.reject(Z);this.pending.clear()}this.terminated=!0}async terminate(){if(this.terminated=!0,!this.worker)return;try{await this.worker.terminate()}catch{}this.worker=void 0}}var FQ=[{packageName:"@vibecontrols/vibe-plugin-storage",pluginName:"storage",label:"Storage facade",description:"Storage provider registry \u2014 owns AgentDatabase contract. Bundled with the agent; the storage meta lazy-loads the configured provider by name.",category:"storage",trusted:!0,isCore:!0,isDefault:!0,isCritical:!0,removable:!1,integrity:"sha512-E0agrBuSwO7R5z7dBA6Jb0Mq5zibhkFzvEh0lcb4N+byt25yStrDcsJqJ3bJpVdavw/OkAjB+MAC06zkTtHraQ=="},...["agent","task","config","git","plugin-mgr","log"].map((Q)=>({packageName:`@vibecontrols/vibe-plugin-${Q}`,pluginName:Q,label:`${Q} (built-in)`,description:`Built-in ${Q} plugin bundled with the agent.`,category:"core",trusted:!0,isCore:!0,removable:!1}))],CQ=[{packageName:"@vibecontrols/vibe-plugin-tunnel",pluginName:"tunnel",label:"Tunnel manager",description:"Owns TunnelProvider interface. Routes to a registered tunnel provider.",category:"tunnel",trusted:!0,isDefault:!0,isCritical:!0,cliCommand:"tunnel",apiPrefix:"/api/tunnel",integrity:"sha512-drBtmSC7rcv8lNB0Xco47Y1D0NJ9qwSct/K7lJNySSH8MwAHPFDfhHxLLmZ+F/NE854cgEE3wb+a2qN4rDXm4w=="},{packageName:"@vibecontrols/vibe-plugin-session-manager",pluginName:"session-manager",label:"Session manager",description:"Owns SessionProvider interface. Routes to a registered session backend.",category:"session",trusted:!0,isCore:!0,isDefault:!0,isCritical:!0,cliCommand:"session",apiPrefix:"/api/sessions",integrity:"sha512-HjF5jxAFwQFMLRlC7N4OMraGC9V9f1u+aGlab4Yr8EkPjbrECYbcBHtD6IwfIe+jcgYSAJMrESCHFHa3EcxyHg=="},{packageName:"@vibecontrols/vibe-plugin-ai",pluginName:"ai",label:"AI orchestration",description:"Owns AIAgentProvider interface. Prompts, contexts, sessions, dispatch, logs.",category:"ai",trusted:!0,isDefault:!0,isCritical:!0,cliCommand:"ai",apiPrefix:"/api/ai",integrity:"sha512-T8UJQ7AP/4fim7ggNuACgo9uKaoO9Ji6+DVFm8A/A7C/7uqNbeJwgbCMVUi3qIdNNhnrwzTQffF7chV8aozdMw=="},{packageName:"@vibecontrols/vibe-plugin-plan",pluginName:"plan",label:"Plan orchestration",description:"Owns PlanProvider interface. Routes plan sessions to a registered provider.",category:"plan",trusted:!0,isDefault:!1,cliCommand:"plan",apiPrefix:"/api/plan",integrity:"sha512-FDoMr2aDBIJ7mpqdWgfSyfwOYc1Q3JhsiNqIXHCMb8yThA7Y1939wlkG4JHmgyPxRj+1zwdg1/MiZYYFzne/pg=="},{packageName:"@vibecontrols/vibe-plugin-gitops",pluginName:"gitops",label:"GitOps orchestrator",description:"Owns GitOpsProvider interface. Routes repo / PR / CI / security queries to a registered provider.",category:"gitops",trusted:!0,isDefault:!1,cliCommand:"gitops",apiPrefix:"/api/gitops",integrity:"sha512-kUw3KIvznHQ2C9hz/K9vi1CWt4IHq0adHDcoJjvoaPumfJ8nXNJcPlqm0hVoZIAF38Hju1DlpXlsFWmYT7Y95Q=="},{packageName:"@vibecontrols/vibe-plugin-security",pluginName:"security",label:"Security lifecycle",description:"Security lifecycle orchestrator \u2014 owns /api/security and dispatches to per-stage providers.",category:"security",trusted:!0,isDefault:!1,cliCommand:"security",apiPrefix:"/api/security",integrity:"sha512-yvNuRIRpvKZzF03h0o9dv9im454r2qSLB61GiGiAnzKM3InjCyl/fYvwyQUDxKZCZIkHtGKBTmmAm669U1Q/+Q=="}],UQ=[{packageName:"@vibecontrols/vibe-plugin-tool-code-server",pluginName:"code-server",label:"Browser code editor",description:"Browser-based VS Code via code-server \u2014 open any Vibe in an in-browser editor.",category:"tool",trusted:!0,isDefault:!1,cliCommand:"code-server",apiPrefix:"/api/code-server"}],wQ=[{packageName:"@vibecontrols/vibe-plugin-agent-backup",pluginName:"agent-backup",label:"Agent backup",description:"Backup and restore agent state.",category:"agent",trusted:!0,isDefault:!0,integrity:"sha512-AzbuYGO66WHNbdJZsfODKJZVqLs18b8ocGPw1jnRZbs3rl1Z4JCDhWxtVuv/yiVIclPaFtEbSQz5sTZf2/TrEQ=="}],O=[...FQ,...CQ,...UQ,...wQ],jQ=[{key:"storage",label:"Storage",description:"Encrypted local state for the agent.",categories:["storage"],mandatory:!0,defaultSelected:!0},{key:"tunnel",label:"Tunnels",description:"Expose the agent for remote access + share links.",categories:["tunnel"],mandatory:!0,defaultSelected:!0},{key:"backup",label:"Backup",description:"Backup + restore agent state.",categories:["agent"],mandatory:!0,defaultSelected:!0},{key:"session",label:"Terminal sessions",description:"Long-lived terminal / AI agent sessions.",categories:["session"],mandatory:!1,defaultSelected:!0},{key:"editor",label:"Browser code editor",description:"Open any Vibe in an in-browser VS Code editor (code-server).",categories:["tool"],mandatory:!1,defaultSelected:!0},{key:"ai",label:"AI orchestration",description:"AI agent harnesses, prompts + dispatch.",categories:["ai"],mandatory:!1,defaultSelected:!0},{key:"plan",label:"Plan review",description:"Review / approve AI-proposed plans.",categories:["plan"],mandatory:!1,defaultSelected:!1},{key:"gitops",label:"GitOps",description:"Repo / PR / CI / security integration.",categories:["gitops"],mandatory:!1,defaultSelected:!1},{key:"security",label:"Security",description:"Security scanning lifecycle.",categories:["security"],mandatory:!1,defaultSelected:!1}],D=O.filter((Q)=>Q.isCore&&Q.category==="core").map((Q)=>Q.pluginName),f=O.filter((Q)=>Q.isDefault===!0);function S(Q){return f}function h(Q,Z){let $=Z instanceof Set?Z:new Set(Z),z=new Set;for(let H of jQ)if(H.mandatory||$.has(H.key))for(let q of H.categories)z.add(q);return O.filter((H)=>z.has(H.category))}var l=new Set(O.filter((Q)=>Q.trusted).map((Q)=>Q.packageName));function TQ(){let Q=O.filter(($)=>$.isCritical).flatMap(($)=>[$.packageName,$.pluginName]),Z=process.env.VIBECONTROLS_CRITICAL_PLUGINS;if(Z){let $=Z.split(",").map((z)=>z.trim()).filter(Boolean);return new Set([...Q,...$])}return new Set(Q)}function rQ(Q){return TQ().has(Q)}var pQ=O.filter((Q)=>!Q.isCore||Q.category!=="core");function iQ(Q){return O.find((Z)=>Z.packageName===Q)}function aQ(Q){return new Set}function I(Q){return Q.startsWith("@vibecontrols/vibe-plugin-")||l.has(Q)}function bQ(Q){let Z=Q.trim();if(!Z)return;if(Z.startsWith("@vibecontrols/"))return O.find((z)=>z.packageName===Z);if(Z.startsWith("vibe-plugin-"))return O.find((z)=>z.packageName===`@vibecontrols/${Z}`);let $=O.find((z)=>z.pluginName===Z);if($)return $;return O.find((z)=>z.packageName===`@vibecontrols/vibe-plugin-${Z}`)}function eQ(Q){let Z=Q.trim();if(!Z)return;let $=bQ(Z);if($)return $.packageName;if(Z.startsWith("@vibecontrols/"))return Z;if(Z.startsWith("vibe-plugin-"))return`@vibecontrols/${Z}`;return`@vibecontrols/vibe-plugin-${Z}`}function p(Q){return O.find((Z)=>Z.pluginName===Q)}function AQ(Q){return O.find((Z)=>Z.packageName===Q)}function LQ(Q,Z){if(Q.length!==Z.length)return!1;let $=0;for(let z=0;z<Q.length;z++)$|=Q.charCodeAt(z)^Z.charCodeAt(z);return $===0}async function DQ(Q,Z,$){let z=AQ(Q),H=process.env.VIBECONTROLS_REQUIRE_PLUGIN_INTEGRITY==="1";if(!z?.integrity){if(H)throw Error(`Refusing to install ${Q}: catalog has no pinned integrity and VIBECONTROLS_REQUIRE_PLUGIN_INTEGRITY=1`);return}let q=$,X;try{let J=`${Z.replace(/\/+$/,"")}/${Q.replace("/","%2F")}`,W=await fetch(J,{headers:{accept:"application/json"},signal:AbortSignal.timeout(20000)});if(!W.ok)throw Error(`registry packument fetch failed (HTTP ${W.status})`);let M=await W.json();if(q=q??M["dist-tags"]?.latest,!q)throw Error("could not resolve version from registry");if(X=M.versions?.[q]?.dist?.integrity,typeof X!=="string"||X.length===0)throw Error(`registry did not return dist.integrity for ${Q}@${q}`)}catch(B){let J=B instanceof Error?B.message:String(B);throw Error(`Pre-install integrity gate refused ${Q}: ${J}`,{cause:B})}if(!LQ(z.integrity,X)){let B=process.env.VIBECONTROLS_STRICT_PLUGIN_INTEGRITY==="1";if(I(Q)&&!B){Y().logger.warn("plugin-manager",`Integrity pin for ${Q} is stale \u2014 catalog expects ${z.integrity}, the allowlisted registry has ${X} for ${q}. Proceeding (first-party package, registry allowlisted). Re-pin plugins.config.ts to silence this.`);return}throw Error(`Pre-install integrity gate refused ${Q}: integrity mismatch for ${q}: expected ${z.integrity}, got ${X}`)}}var fQ=["https://registry.npmjs.org/","https://registry.npmjs.org"];function SQ(){let Q=process.env.VIBECONTROLS_REGISTRY_ALLOWLIST,Z=[...fQ];if(typeof Q==="string"&&Q.length>0)for(let $ of Q.split(",").map((z)=>z.trim()).filter(Boolean))Z.push($);return Z}function hQ(Q){let Z=SQ(),$;try{$=new URL(Q).origin}catch{throw Error(`Invalid plugin registry URL: ${Q}`)}for(let z of Z)try{if(new URL(z).origin===$)return}catch{}throw Error(`Plugin registry '${Q}' is not in the allow-list. Add it to VIBECONTROLS_REGISTRY_ALLOWLIST at daemon start.`)}var i="plugins.json",vQ=/^@vibecontrols\/vibe-plugin-[a-z0-9][a-z0-9-]{0,80}$/,a=/^[a-z0-9][a-z0-9-]{0,63}$/,PQ=/^\/api\/[A-Za-z0-9][A-Za-z0-9/_-]{0,127}$/,yQ=/^\/[A-Za-z0-9][A-Za-z0-9/_-]{0,159}$/,$Q=Symbol.for("vibecontrols.pluginPackageRoot");function VZ(Q){return Q[$Q]}function G(Q){let Z=Q.trim();if(!vQ.test(Z))throw Error("Plugin package must be a @vibecontrols/vibe-plugin-* package name.");if(!I(Z)&&process.env.VIBECONTROLS_ALLOW_UNTRUSTED_PLUGINS!=="1")throw Error("Plugin package is not in the trusted VibeControls catalog.");return Z}function dQ(Q,Z){let $=IQ(Q,Z);return $===""||!!$&&!$.startsWith("..")&&!EQ($)}function zQ(){return V(b(),"agent-plugins","node_modules")}function kQ(){try{let Q=zQ();return U(Q)&&GQ(Q).length>0}catch{return!1}}function y(){let Q=(process.env.VIBECONTROLS_PLUGIN_INSTALL_SCOPE??process.env.VIBECONTROLS_PLUGIN_INSTALL_MODE??"").toLowerCase();if(Q==="local")return"local";if(Q==="global")return"global";return kQ()?"local":"global"}var e="provider:default:";function NQ(Q){if(!Q||typeof Q!=="object")return!1;let Z=Q;return typeof Z.packageName==="string"&&typeof Z.version==="string"&&typeof Z.pluginName==="string"&&typeof Z.installedAt==="string"}var OZ=f;class HQ{registry=[];loaded=new Map;corePlugins=new Map;db;forcedIsolation=new Set;workerHosts=new Map;lifecycleChain=Promise.resolve();withLifecycleLock(Q){let $=this.lifecycleChain.then(Q,Q);return this.lifecycleChain=$.then(()=>{return},()=>{return}),$}async terminateWorkerHost(Q){let Z=this.workerHosts.get(Q);if(!Z)return;try{await Z.terminate()}catch($){Y().logger.warn("plugin-manager",`Failed to terminate worker for '${Q}': ${$ instanceof Error?$.message:String($)}`)}finally{this.workerHosts.delete(Q)}}async terminateAllWorkerHosts(){let Q=Array.from(this.workerHosts.keys());await Promise.all(Q.map((Z)=>this.terminateWorkerHost(Z)))}constructor(Q){this.db=Q,this.ensureDir(),this.loadRegistry();let Z=process.env.VIBE_ISOLATE_PLUGINS;if(typeof Z==="string"&&Z.length>0)this.setForcedIsolation(Z.split(",").map(($)=>$.trim()).filter(($)=>$.length>0))}setForcedIsolation(Q){this.forcedIsolation=new Set(Q.filter((Z)=>Z.length>0))}shouldIsolate(Q){if(this.forcedIsolation.has(Q.name))return!0;return Q.capabilities?.requiresIsolation===!0}getWorkerHost(Q){return this.workerHosts.get(Q)}registerWorkerHost(Q,Z){this.workerHosts.set(Q,Z)}auditSink=(Q,Z)=>{Y().logger.warn("plugin-capability",Q,Z)};static resolveEffectiveCapabilities(Q,Z){if(Q.capabilities)return Q.capabilities;return Z?m:c}wrapHostServices(Q,Z){let $=this.corePlugins.has(Q.name),z=HQ.resolveEffectiveCapabilities(Q,$),H=$||this.isTrustedLoadedPlugin(Q);return o(Z,Q.name,z,this.auditSink,H)}isTrustedLoadedPlugin(Q){for(let[Z,$]of this.loaded)if($===Q)return I(Z);return!1}acceptCapabilities(Q,Z){if(Q.capabilities?.singletonOnly===!0&&k.size()>1)return Y().logger.error("plugin-manager",`[plugin] '${Q.name}' refused to load: singletonOnly capability incompatible with multi-profile daemon (profiles=${k.size()}, source=${Z})`),!1;if(Q.capabilities)return!0;if(s())return Y().logger.error("plugin-manager",`[plugin] '${Q.name}' refused to load: missing required capabilities declaration (source=${Z})`),!1;if(Z.startsWith("core:"))Y().logger.warn("plugin-manager",`[plugin] '${Q.name}' loaded without a capabilities declaration \u2014 granting full trust (core plugin). Declare capabilities explicitly. (source=${Z})`);else Y().logger.warn("plugin-manager",`[plugin] '${Q.name}' loaded without a capabilities declaration \u2014 defaulting to EMPTY capability set (deny by default). External plugins MUST declare capabilities explicitly to access host services. (source=${Z})`);return!0}ensureDir(){let Q=b();if(!U(Q))n(Q,{recursive:!0})}loadRegistry(){let Q=V(b(),i);try{if(U(Q)){let Z=v(Q,"utf-8"),$=JSON.parse(Z);if(Array.isArray($)&&$.every(NQ))this.registry=$.filter((z)=>{try{return G(z.packageName),!0}catch(H){return Y().logger.warn("plugin-manager","Ignoring invalid plugin entry",{packageName:z.packageName,error:String(H)}),!1}});else throw Error("plugins.json has an invalid schema")}}catch(Z){Y().logger.warn("plugin-manager","Failed to load plugin registry",{path:Q,error:String(Z)}),this.registry=[]}}saveRegistry(){this.ensureDir();let Q=V(b(),i),Z=`${Q}.${process.pid}.tmp`;g(Z,`${JSON.stringify(this.registry,null,2)}
3
- `,{encoding:"utf-8",mode:384}),_Q(Z,Q)}async loadCorePlugins(){let Q=await Promise.allSettled([import("./index-5amvpjqx.js"),import("./index-0924jp9m.js"),import("./index-tgrt61qr.js"),import("./index-ebwwtwwc.js"),import("./index-ca5c245v.js"),import("./index-nrsqzcfc.js")]),Z=Y();for(let $=0;$<Q.length;$++){let z=Q[$],H=D[$];if(z.status==="fulfilled"){let q=z.value,X;try{X=this.extractPlugin(q,`core:${H}`,Z)}catch(B){Y().logger.error("plugin-manager",`Core plugin '${H}' refused to load: ${B instanceof Error?B.message:String(B)}`);continue}if(X?.name){if(!this.acceptCapabilities(X,`core:${H}`))continue;this.corePlugins.set(X.name,X),Y().logger.info("plugin-manager",`Core plugin loaded: ${X.name} v${X.version}`)}else Y().logger.warn("plugin-manager",`Core plugin '${H}' did not export a valid createPlugin(ctx) factory`)}else Y().logger.warn("plugin-manager",`Failed to load core plugin '${H}': ${z.reason}`)}Y().logger.info("plugin-manager",`Core plugins loaded: ${this.corePlugins.size}/${D.length}`)}async resolveConcreteLatest(Q,Z){try{let z=`${Z.replace(/\/+$/,"")}/${Q.replace("/","%2F")}`,H=await fetch(z,{headers:{accept:"application/json"},signal:AbortSignal.timeout(20000)});if(!H.ok)return;let X=(await H.json())["dist-tags"]?.latest;if(typeof X==="string"&&/^\d+\.\d+\.\d+/.test(X))return X}catch{}return}async install(Q,Z={}){return this.withLifecycleLock(()=>this.installLocked(Q,Z))}async installLocked(Q,Z={}){Q=G(Q);let $=Z.version?.trim()||void 0,z=Z.refreshLatest===!0||!!$;Y().logger.info("plugin-manager",`Installing ${Q}${z?"@latest (refresh)":""}...`);let H=d();if(hQ(H),await DQ(Q,H,void 0),!z)try{await import(Q),Y().logger.info("plugin-manager",`${Q} already resolvable \u2014 skipping global install`);let K=await this.importPlugin(Q),F={packageName:Q,version:K.version,pluginName:K.name,installedAt:new Date().toISOString()};return this.registry=this.registry.filter((T)=>T.packageName!==Q),this.registry.push(F),this.saveRegistry(),F}catch{}let q=d(),X=y(),B=$?$:z?await this.resolveConcreteLatest(Q,q):void 0,J=z?`${Q}@${B??"latest"}`:Q;try{if(X==="local"){let K=V(b(),"agent-plugins");if(!U(K))n(K,{recursive:!0});let F=V(K,"package.json");if(!U(F))g(F,JSON.stringify({name:"vibecontrols-agent-plugins",private:!0,version:"0.0.0",dependencies:{}},null,2)+`
2
+ import{Xa as QQ}from"./index-0ckffygp.js";import{Bd as ZQ,Md as k,Od as Y}from"./index-js1xn4sq.js";import{$d as b,de as d}from"./index-a4854mwz.js";import{ie as w}from"./index-c7554sg7.js";import{existsSync as U,mkdirSync as n,readdirSync as GQ,readFileSync as v,renameSync as _Q,realpathSync as t,rmSync as j,statSync as RQ,writeFileSync as g}from"fs";import{homedir as xQ}from"os";import{dirname as R,isAbsolute as EQ,join as V,relative as IQ,sep as r}from"path";import{fileURLToPath as P}from"url";import{existsSync as XQ,readFileSync as qQ}from"fs";import{dirname as A,join as BQ}from"path";import{fileURLToPath as YQ}from"url";var WQ="@vibecontrols/agent",_;function N(){if(_)return _;try{let Q=A(YQ(import.meta.url));for(let Z=0;Z<10&&Q&&Q!==A(Q);Z++){let $=BQ(Q,"package.json");if(XQ($))try{let z=JSON.parse(qQ($,"utf8"));if(z.name===WQ&&typeof z.version==="string")return _=z.version,_}catch{}Q=A(Q)}}catch{}return _??"0.0.0"}function u(){let Q=process.env.VIBECONTROLS_PLUGIN_CONTRACT_V2_ENFORCE;return Q==="1"||Q==="true"||Q==="on"}var m={storage:"rw",secrets:"rw",gateway:!0,broadcast:!0,subprocess:!0,audit:!0,telemetry:!0,singletonOnly:!1,requiresIsolation:!1},c={storage:"none",secrets:"none",gateway:!1,broadcast:!1,subprocess:!1,audit:!1,telemetry:!1,singletonOnly:!1,requiresIsolation:!1};function s(){let Q=process.env.VIBECONTROLS_STRICT_PLUGIN_CAPS;return Q==="1"||Q==="true"||Q==="on"}function o(Q,Z,$,z,H=!1){return new Proxy(Q,{get(q,X,B){if(X==="plugins"){if(!H)return;return Reflect.get(q,X,B)}if(X==="storage")return JQ(q.storage,$.storage??"none",Z,z);if(X==="broadcast"&&!$.broadcast)return E(Z,"broadcast",z);if(X==="workspaceQuery"&&!$.gateway)return E(Z,"workspaceQuery",z);if(X==="getAgentRecordId"&&!$.gateway)return E(Z,"getAgentRecordId",z);if(X==="getWorkspaceId"&&!$.gateway)return E(Z,"getWorkspaceId",z);if(X==="telemetry"){if(!$.telemetry)return;return Reflect.get(q,X,B)}return Reflect.get(q,X,B)}})}function JQ(Q,Z,$,z){if(Z==="rw")return Q;return new Proxy(Q,{get(H,q,X){let B=String(q),J=B==="set"||B==="delete"||B==="deleteAll";if(Z==="none"||Z==="read"&&J)return(...M)=>{throw z("plugin.capability.denied",{pluginName:$,surface:"storage",op:B,mode:Z}),Error(`plugin '${$}' lacks storage:${J?"rw":"read"} capability (op=${B})`)};return Reflect.get(H,q,X)}})}function E(Q,Z,$){return(...z)=>{throw $("plugin.capability.denied",{pluginName:Q,op:Z}),Error(`plugin '${Q}' lacks capability for ${Z}`)}}import{Worker as KQ}from"worker_threads";import{fileURLToPath as MQ}from"url";import{randomUUID as VQ}from"crypto";function OQ(){let Q=MQ(import.meta.url),Z=Q.lastIndexOf("/"),$=Z>=0?Q.slice(0,Z):Q,z=`${$}/plugin-worker-runtime.ts`,H=`${$}/plugin-worker-runtime.js`;if(Q.endsWith(".ts"))return z;return H}class L{worker;pending=new Map;spec;initPromise;terminated=!1;constructor(Q){this.spec=Q}async start(){if(this.initPromise)return this.initPromise;return this.initPromise=this.spawn(),this.initPromise}async spawn(){let Q=this.spec.runtimeEntry??OQ(),Z=["PATH","HOME","USERPROFILE","TMPDIR","TMP","TEMP","LANG","LC_ALL","LC_CTYPE","TZ","SystemRoot","SystemDrive","ComSpec","PATHEXT","windir"],$={};for(let H of Z){let q=process.env[H];if(typeof q==="string")$[H]=q}let z=new KQ(Q,{env:$});this.worker=z,z.on("message",(H)=>this.onMessage(H)),z.on("error",(H)=>this.onWorkerError(H instanceof Error?H:Error(String(H)))),z.on("exit",(H)=>this.onWorkerExit(H)),await this.call("init",{modulePath:this.spec.modulePath,ctxStub:{name:this.spec.ctx.name,dataDir:this.spec.ctx.dataDir}})}async dispatch(Q,Z=[]){if(this.terminated)throw Error("PluginWorkerHost terminated");if(!this.worker)await this.start();return this.call("dispatch",{method:Q,params:Z})}call(Q,Z){if(!this.worker)return Promise.reject(Error("worker not spawned"));let $=VQ();return new Promise((z,H)=>{this.pending.set($,{resolve:z,reject:H});try{this.worker?.postMessage({id:$,op:Q,args:Z})}catch(q){this.pending.delete($),H(q instanceof Error?q:Error(String(q)))}})}onMessage(Q){let Z=this.pending.get(Q.id);if(!Z)return;if(this.pending.delete(Q.id),Q.ok)Z.resolve(Q.result);else{let $=Error(Q.error?.message??"worker error");if(Q.error?.stack)$.stack=Q.error.stack;Z.reject($)}}onWorkerError(Q){for(let[,Z]of this.pending)Z.reject(Q);this.pending.clear()}onWorkerExit(Q){if(this.pending.size>0){let Z=Error(`worker exited (code=${Q}) with pending calls`);for(let[,$]of this.pending)$.reject(Z);this.pending.clear()}this.terminated=!0}async terminate(){if(this.terminated=!0,!this.worker)return;try{await this.worker.terminate()}catch{}this.worker=void 0}}var FQ=[{packageName:"@vibecontrols/vibe-plugin-storage",pluginName:"storage",label:"Storage facade",description:"Storage provider registry \u2014 owns AgentDatabase contract. Bundled with the agent; the storage meta lazy-loads the configured provider by name.",category:"storage",trusted:!0,isCore:!0,isDefault:!0,isCritical:!0,removable:!1,integrity:"sha512-E0agrBuSwO7R5z7dBA6Jb0Mq5zibhkFzvEh0lcb4N+byt25yStrDcsJqJ3bJpVdavw/OkAjB+MAC06zkTtHraQ=="},...["agent","task","config","git","plugin-mgr","log"].map((Q)=>({packageName:`@vibecontrols/vibe-plugin-${Q}`,pluginName:Q,label:`${Q} (built-in)`,description:`Built-in ${Q} plugin bundled with the agent.`,category:"core",trusted:!0,isCore:!0,removable:!1}))],CQ=[{packageName:"@vibecontrols/vibe-plugin-tunnel",pluginName:"tunnel",label:"Tunnel manager",description:"Owns TunnelProvider interface. Routes to a registered tunnel provider.",category:"tunnel",trusted:!0,isDefault:!0,isCritical:!0,cliCommand:"tunnel",apiPrefix:"/api/tunnel",integrity:"sha512-FFqJjvPNCAYZwMjOKt1vHiBuzd+6W9sYI6vZqls7kr3Za+m++tIueT9OV2DlpAJT8XU+fidrgsWgQi8AcjPHWQ=="},{packageName:"@vibecontrols/vibe-plugin-session-manager",pluginName:"session-manager",label:"Session manager",description:"Owns SessionProvider interface. Routes to a registered session backend.",category:"session",trusted:!0,isCore:!0,isDefault:!0,isCritical:!0,cliCommand:"session",apiPrefix:"/api/sessions",integrity:"sha512-qrbwqL+LsCihI5BR6HqFJiqI19htgfiv6w75wn1gwpEuFvggoElwJ134xLPRKH1+AEKRsbpe63pqfexLPrQIBw=="},{packageName:"@vibecontrols/vibe-plugin-ai",pluginName:"ai",label:"AI orchestration",description:"Owns AIAgentProvider interface. Prompts, contexts, sessions, dispatch, logs.",category:"ai",trusted:!0,isDefault:!0,isCritical:!0,cliCommand:"ai",apiPrefix:"/api/ai",integrity:"sha512-mIkzkzMDU38ILFa2lRsjeaJqAidtlUBWoQ3KaFxkpG88AHWUtcA6Vha/wZQ5Ns16h0g4vRKxtbOLfFSTEgRerA=="},{packageName:"@vibecontrols/vibe-plugin-plan",pluginName:"plan",label:"Plan orchestration",description:"Owns PlanProvider interface. Routes plan sessions to a registered provider.",category:"plan",trusted:!0,isDefault:!1,cliCommand:"plan",apiPrefix:"/api/plan",integrity:"sha512-SSCFLFkmAhHesLYgETeEyAZs2Gu8tDEaMMuJtMMKG5eKGQIXYJaJZnQBuXP/vKOAlLd//l8es5hPqhmiNSi4Gw=="},{packageName:"@vibecontrols/vibe-plugin-gitops",pluginName:"gitops",label:"GitOps orchestrator",description:"Owns GitOpsProvider interface. Routes repo / PR / CI / security queries to a registered provider.",category:"gitops",trusted:!0,isDefault:!1,cliCommand:"gitops",apiPrefix:"/api/gitops",integrity:"sha512-KzoSmBDgQ5mbSFxAuIyIBnC/HKwYhtXluGp06DvzQmwqOQ4vEC72PuSiVx3doWrt+Z6fZ6i6gxNzmYNpdhPLXA=="},{packageName:"@vibecontrols/vibe-plugin-security",pluginName:"security",label:"Security lifecycle",description:"Security lifecycle orchestrator \u2014 owns /api/security and dispatches to per-stage providers.",category:"security",trusted:!0,isDefault:!1,cliCommand:"security",apiPrefix:"/api/security",integrity:"sha512-K6w3tC7qnCotvnNWWdmHnjqGgCNJoPNMs8gCwWFbcNI5MmbIrUQfFQdcjwGudwryvN2+TrX12MhfhWz4p1qcMA=="}],UQ=[{packageName:"@vibecontrols/vibe-plugin-tool-code-server",pluginName:"code-server",label:"Browser code editor",description:"Browser-based VS Code via code-server \u2014 open any Vibe in an in-browser editor.",category:"tool",trusted:!0,isDefault:!1,cliCommand:"code-server",apiPrefix:"/api/code-server"}],wQ=[{packageName:"@vibecontrols/vibe-plugin-agent-backup",pluginName:"agent-backup",label:"Agent backup",description:"Backup and restore agent state.",category:"agent",trusted:!0,isDefault:!0,integrity:"sha512-KhN2Vaahtnl4IKRbaHKtlEbsuvW9dbgC2l4kkIXcme55DaSmLy5kYkiysnwyZdC4PRQu4NKM4GQLoW9hD86dRw=="}],O=[...FQ,...CQ,...UQ,...wQ],jQ=[{key:"storage",label:"Storage",description:"Encrypted local state for the agent.",categories:["storage"],mandatory:!0,defaultSelected:!0},{key:"tunnel",label:"Tunnels",description:"Expose the agent for remote access + share links.",categories:["tunnel"],mandatory:!0,defaultSelected:!0},{key:"backup",label:"Backup",description:"Backup + restore agent state.",categories:["agent"],mandatory:!0,defaultSelected:!0},{key:"session",label:"Terminal sessions",description:"Long-lived terminal / AI agent sessions.",categories:["session"],mandatory:!1,defaultSelected:!0},{key:"editor",label:"Browser code editor",description:"Open any Vibe in an in-browser VS Code editor (code-server).",categories:["tool"],mandatory:!1,defaultSelected:!0},{key:"ai",label:"AI orchestration",description:"AI agent harnesses, prompts + dispatch.",categories:["ai"],mandatory:!1,defaultSelected:!0},{key:"plan",label:"Plan review",description:"Review / approve AI-proposed plans.",categories:["plan"],mandatory:!1,defaultSelected:!1},{key:"gitops",label:"GitOps",description:"Repo / PR / CI / security integration.",categories:["gitops"],mandatory:!1,defaultSelected:!1},{key:"security",label:"Security",description:"Security scanning lifecycle.",categories:["security"],mandatory:!1,defaultSelected:!1}],D=O.filter((Q)=>Q.isCore&&Q.category==="core").map((Q)=>Q.pluginName),f=O.filter((Q)=>Q.isDefault===!0);function S(Q){return f}function h(Q,Z){let $=Z instanceof Set?Z:new Set(Z),z=new Set;for(let H of jQ)if(H.mandatory||$.has(H.key))for(let q of H.categories)z.add(q);return O.filter((H)=>z.has(H.category))}var l=new Set(O.filter((Q)=>Q.trusted).map((Q)=>Q.packageName));function TQ(){let Q=O.filter(($)=>$.isCritical).flatMap(($)=>[$.packageName,$.pluginName]),Z=process.env.VIBECONTROLS_CRITICAL_PLUGINS;if(Z){let $=Z.split(",").map((z)=>z.trim()).filter(Boolean);return new Set([...Q,...$])}return new Set(Q)}function rQ(Q){return TQ().has(Q)}var pQ=O.filter((Q)=>!Q.isCore||Q.category!=="core");function iQ(Q){return O.find((Z)=>Z.packageName===Q)}function aQ(Q){return new Set}function I(Q){return Q.startsWith("@vibecontrols/vibe-plugin-")||l.has(Q)}function bQ(Q){let Z=Q.trim();if(!Z)return;if(Z.startsWith("@vibecontrols/"))return O.find((z)=>z.packageName===Z);if(Z.startsWith("vibe-plugin-"))return O.find((z)=>z.packageName===`@vibecontrols/${Z}`);let $=O.find((z)=>z.pluginName===Z);if($)return $;return O.find((z)=>z.packageName===`@vibecontrols/vibe-plugin-${Z}`)}function eQ(Q){let Z=Q.trim();if(!Z)return;let $=bQ(Z);if($)return $.packageName;if(Z.startsWith("@vibecontrols/"))return Z;if(Z.startsWith("vibe-plugin-"))return`@vibecontrols/${Z}`;return`@vibecontrols/vibe-plugin-${Z}`}function p(Q){return O.find((Z)=>Z.pluginName===Q)}function AQ(Q){return O.find((Z)=>Z.packageName===Q)}function LQ(Q,Z){if(Q.length!==Z.length)return!1;let $=0;for(let z=0;z<Q.length;z++)$|=Q.charCodeAt(z)^Z.charCodeAt(z);return $===0}async function DQ(Q,Z,$){let z=AQ(Q),H=process.env.VIBECONTROLS_REQUIRE_PLUGIN_INTEGRITY==="1";if(!z?.integrity){if(H)throw Error(`Refusing to install ${Q}: catalog has no pinned integrity and VIBECONTROLS_REQUIRE_PLUGIN_INTEGRITY=1`);return}let q=$,X;try{let J=`${Z.replace(/\/+$/,"")}/${Q.replace("/","%2F")}`,W=await fetch(J,{headers:{accept:"application/json"},signal:AbortSignal.timeout(20000)});if(!W.ok)throw Error(`registry packument fetch failed (HTTP ${W.status})`);let M=await W.json();if(q=q??M["dist-tags"]?.latest,!q)throw Error("could not resolve version from registry");if(X=M.versions?.[q]?.dist?.integrity,typeof X!=="string"||X.length===0)throw Error(`registry did not return dist.integrity for ${Q}@${q}`)}catch(B){let J=B instanceof Error?B.message:String(B);throw Error(`Pre-install integrity gate refused ${Q}: ${J}`,{cause:B})}if(!LQ(z.integrity,X)){let B=process.env.VIBECONTROLS_STRICT_PLUGIN_INTEGRITY==="1";if(I(Q)&&!B){Y().logger.warn("plugin-manager",`Integrity pin for ${Q} is stale \u2014 catalog expects ${z.integrity}, the allowlisted registry has ${X} for ${q}. Proceeding (first-party package, registry allowlisted). Re-pin plugins.config.ts to silence this.`);return}throw Error(`Pre-install integrity gate refused ${Q}: integrity mismatch for ${q}: expected ${z.integrity}, got ${X}`)}}var fQ=["https://registry.npmjs.org/","https://registry.npmjs.org"];function SQ(){let Q=process.env.VIBECONTROLS_REGISTRY_ALLOWLIST,Z=[...fQ];if(typeof Q==="string"&&Q.length>0)for(let $ of Q.split(",").map((z)=>z.trim()).filter(Boolean))Z.push($);return Z}function hQ(Q){let Z=SQ(),$;try{$=new URL(Q).origin}catch{throw Error(`Invalid plugin registry URL: ${Q}`)}for(let z of Z)try{if(new URL(z).origin===$)return}catch{}throw Error(`Plugin registry '${Q}' is not in the allow-list. Add it to VIBECONTROLS_REGISTRY_ALLOWLIST at daemon start.`)}var i="plugins.json",vQ=/^@vibecontrols\/vibe-plugin-[a-z0-9][a-z0-9-]{0,80}$/,a=/^[a-z0-9][a-z0-9-]{0,63}$/,PQ=/^\/api\/[A-Za-z0-9][A-Za-z0-9/_-]{0,127}$/,yQ=/^\/[A-Za-z0-9][A-Za-z0-9/_-]{0,159}$/,$Q=Symbol.for("vibecontrols.pluginPackageRoot");function VZ(Q){return Q[$Q]}function G(Q){let Z=Q.trim();if(!vQ.test(Z))throw Error("Plugin package must be a @vibecontrols/vibe-plugin-* package name.");if(!I(Z)&&process.env.VIBECONTROLS_ALLOW_UNTRUSTED_PLUGINS!=="1")throw Error("Plugin package is not in the trusted VibeControls catalog.");return Z}function dQ(Q,Z){let $=IQ(Q,Z);return $===""||!!$&&!$.startsWith("..")&&!EQ($)}function zQ(){return V(b(),"agent-plugins","node_modules")}function kQ(){try{let Q=zQ();return U(Q)&&GQ(Q).length>0}catch{return!1}}function y(){let Q=(process.env.VIBECONTROLS_PLUGIN_INSTALL_SCOPE??process.env.VIBECONTROLS_PLUGIN_INSTALL_MODE??"").toLowerCase();if(Q==="local")return"local";if(Q==="global")return"global";return kQ()?"local":"global"}var e="provider:default:";function NQ(Q){if(!Q||typeof Q!=="object")return!1;let Z=Q;return typeof Z.packageName==="string"&&typeof Z.version==="string"&&typeof Z.pluginName==="string"&&typeof Z.installedAt==="string"}var OZ=f;class HQ{registry=[];loaded=new Map;corePlugins=new Map;db;forcedIsolation=new Set;workerHosts=new Map;lifecycleChain=Promise.resolve();withLifecycleLock(Q){let $=this.lifecycleChain.then(Q,Q);return this.lifecycleChain=$.then(()=>{return},()=>{return}),$}async terminateWorkerHost(Q){let Z=this.workerHosts.get(Q);if(!Z)return;try{await Z.terminate()}catch($){Y().logger.warn("plugin-manager",`Failed to terminate worker for '${Q}': ${$ instanceof Error?$.message:String($)}`)}finally{this.workerHosts.delete(Q)}}async terminateAllWorkerHosts(){let Q=Array.from(this.workerHosts.keys());await Promise.all(Q.map((Z)=>this.terminateWorkerHost(Z)))}constructor(Q){this.db=Q,this.ensureDir(),this.loadRegistry();let Z=process.env.VIBE_ISOLATE_PLUGINS;if(typeof Z==="string"&&Z.length>0)this.setForcedIsolation(Z.split(",").map(($)=>$.trim()).filter(($)=>$.length>0))}setForcedIsolation(Q){this.forcedIsolation=new Set(Q.filter((Z)=>Z.length>0))}shouldIsolate(Q){if(this.forcedIsolation.has(Q.name))return!0;return Q.capabilities?.requiresIsolation===!0}getWorkerHost(Q){return this.workerHosts.get(Q)}registerWorkerHost(Q,Z){this.workerHosts.set(Q,Z)}auditSink=(Q,Z)=>{Y().logger.warn("plugin-capability",Q,Z)};static resolveEffectiveCapabilities(Q,Z){if(Q.capabilities)return Q.capabilities;return Z?m:c}wrapHostServices(Q,Z){let $=this.corePlugins.has(Q.name),z=HQ.resolveEffectiveCapabilities(Q,$),H=$||this.isTrustedLoadedPlugin(Q);return o(Z,Q.name,z,this.auditSink,H)}isTrustedLoadedPlugin(Q){for(let[Z,$]of this.loaded)if($===Q)return I(Z);return!1}acceptCapabilities(Q,Z){if(Q.capabilities?.singletonOnly===!0&&k.size()>1)return Y().logger.error("plugin-manager",`[plugin] '${Q.name}' refused to load: singletonOnly capability incompatible with multi-profile daemon (profiles=${k.size()}, source=${Z})`),!1;if(Q.capabilities)return!0;if(s())return Y().logger.error("plugin-manager",`[plugin] '${Q.name}' refused to load: missing required capabilities declaration (source=${Z})`),!1;if(Z.startsWith("core:"))Y().logger.warn("plugin-manager",`[plugin] '${Q.name}' loaded without a capabilities declaration \u2014 granting full trust (core plugin). Declare capabilities explicitly. (source=${Z})`);else Y().logger.warn("plugin-manager",`[plugin] '${Q.name}' loaded without a capabilities declaration \u2014 defaulting to EMPTY capability set (deny by default). External plugins MUST declare capabilities explicitly to access host services. (source=${Z})`);return!0}ensureDir(){let Q=b();if(!U(Q))n(Q,{recursive:!0})}loadRegistry(){let Q=V(b(),i);try{if(U(Q)){let Z=v(Q,"utf-8"),$=JSON.parse(Z);if(Array.isArray($)&&$.every(NQ))this.registry=$.filter((z)=>{try{return G(z.packageName),!0}catch(H){return Y().logger.warn("plugin-manager","Ignoring invalid plugin entry",{packageName:z.packageName,error:String(H)}),!1}});else throw Error("plugins.json has an invalid schema")}}catch(Z){Y().logger.warn("plugin-manager","Failed to load plugin registry",{path:Q,error:String(Z)}),this.registry=[]}}saveRegistry(){this.ensureDir();let Q=V(b(),i),Z=`${Q}.${process.pid}.tmp`;g(Z,`${JSON.stringify(this.registry,null,2)}
3
+ `,{encoding:"utf-8",mode:384}),_Q(Z,Q)}async loadCorePlugins(){let Q=await Promise.allSettled([import("./index-h60rr9ca.js"),import("./index-0924jp9m.js"),import("./index-tgrt61qr.js"),import("./index-ebwwtwwc.js"),import("./index-ngrj0aqp.js"),import("./index-nrsqzcfc.js")]),Z=Y();for(let $=0;$<Q.length;$++){let z=Q[$],H=D[$];if(z.status==="fulfilled"){let q=z.value,X;try{X=this.extractPlugin(q,`core:${H}`,Z)}catch(B){Y().logger.error("plugin-manager",`Core plugin '${H}' refused to load: ${B instanceof Error?B.message:String(B)}`);continue}if(X?.name){if(!this.acceptCapabilities(X,`core:${H}`))continue;this.corePlugins.set(X.name,X),Y().logger.info("plugin-manager",`Core plugin loaded: ${X.name} v${X.version}`)}else Y().logger.warn("plugin-manager",`Core plugin '${H}' did not export a valid createPlugin(ctx) factory`)}else Y().logger.warn("plugin-manager",`Failed to load core plugin '${H}': ${z.reason}`)}Y().logger.info("plugin-manager",`Core plugins loaded: ${this.corePlugins.size}/${D.length}`)}async resolveConcreteLatest(Q,Z){try{let z=`${Z.replace(/\/+$/,"")}/${Q.replace("/","%2F")}`,H=await fetch(z,{headers:{accept:"application/json"},signal:AbortSignal.timeout(20000)});if(!H.ok)return;let X=(await H.json())["dist-tags"]?.latest;if(typeof X==="string"&&/^\d+\.\d+\.\d+/.test(X))return X}catch{}return}async install(Q,Z={}){return this.withLifecycleLock(()=>this.installLocked(Q,Z))}async installLocked(Q,Z={}){Q=G(Q);let $=Z.version?.trim()||void 0,z=Z.refreshLatest===!0||!!$;Y().logger.info("plugin-manager",`Installing ${Q}${z?"@latest (refresh)":""}...`);let H=d();if(hQ(H),await DQ(Q,H,void 0),!z)try{await import(Q),Y().logger.info("plugin-manager",`${Q} already resolvable \u2014 skipping global install`);let K=await this.importPlugin(Q),F={packageName:Q,version:K.version,pluginName:K.name,installedAt:new Date().toISOString()};return this.registry=this.registry.filter((T)=>T.packageName!==Q),this.registry.push(F),this.saveRegistry(),F}catch{}let q=d(),X=y(),B=$?$:z?await this.resolveConcreteLatest(Q,q):void 0,J=z?`${Q}@${B??"latest"}`:Q;try{if(X==="local"){let K=V(b(),"agent-plugins");if(!U(K))n(K,{recursive:!0});let F=V(K,"package.json");if(!U(F))g(F,JSON.stringify({name:"vibecontrols-agent-plugins",private:!0,version:"0.0.0",dependencies:{}},null,2)+`
4
4
  `);if(z&&B){let C=this.readInstalledVersion(V(K,"node_modules"),Q);if(C&&C!==B){Y().logger.info("plugin-manager",`Pre-clean ${Q}: on-disk v${C} != target v${B} \u2014 removing stale copy + lockfile to force fresh resolve`);try{j(V(K,"node_modules",Q),{recursive:!0,force:!0})}catch{}try{j(V(K,"bun.lock"),{force:!0}),j(V(K,"bun.lockb"),{force:!0})}catch{}}try{j(V(K,"bun.lock"),{force:!0}),j(V(K,"bun.lockb"),{force:!0})}catch{}}if(Bun.spawnSync(["bun","add",J,"--registry",q],{cwd:K,timeout:120000,stdout:"pipe",stderr:"pipe"}).exitCode!==0){let C=Bun.spawnSync(["npm","install",J,"--registry",q],{cwd:K,timeout:120000,stdout:"pipe",stderr:"pipe"});if(C.exitCode!==0)throw Error(C.stderr.toString().trim())}if(z&&B){let C=this.readInstalledVersion(V(K,"node_modules"),Q);if(C!==B){Y().logger.warn("plugin-manager",`bun kept ${Q}@${C??"missing"} after requesting ${B}; retrying with npm after removing stale local copy`);try{j(V(K,"node_modules",Q),{recursive:!0,force:!0}),j(V(K,"bun.lock"),{force:!0}),j(V(K,"bun.lockb"),{force:!0}),j(V(K,"package-lock.json"),{force:!0})}catch{}let x=Bun.spawnSync(["npm","install",J,"--registry",q,"--save-exact"],{cwd:K,timeout:120000,stdout:"pipe",stderr:"pipe"});if(x.exitCode!==0)throw Error(x.stderr.toString().trim())}}}else if(Bun.spawnSync(["bun","install","-g",J,"--registry",q],{timeout:120000,stdout:"pipe",stderr:"pipe"}).exitCode!==0){let F=Bun.spawnSync(["npm","install","-g",J,"--registry",q],{timeout:120000,stdout:"pipe",stderr:"pipe"});if(F.exitCode!==0)throw Error(F.stderr.toString().trim())}this.pluginRoots=void 0}catch(K){let F=K instanceof Error?K.message:String(K);if(z)try{await import(Q),Y().logger.warn("plugin-manager",`Could not refresh ${Q} to @latest (${F}); using the already-installed copy`),this.pluginRoots=void 0;let T=await this.importPlugin(Q),C={packageName:Q,version:T.version,pluginName:T.name,installedAt:new Date().toISOString()};return this.registry=this.registry.filter((x)=>x.packageName!==Q),this.registry.push(C),this.saveRegistry(),C}catch{}throw Error(`Failed to install ${Q}: ${F}`,{cause:K})}let W=await this.importPlugin(Q);if(z&&B&&W.version!==B)Y().logger.warn("plugin-manager",`${Q} refreshed to ${W.version} but registry latest is ${B} \u2014 a stale resolver/cache may still be in play`);if(this.corePlugins.has(W.name))Y().logger.info("plugin-manager",`External plugin '${Q}' overrides core plugin '${W.name}'`);let M={packageName:Q,version:W.version,pluginName:W.name,installedAt:new Date().toISOString()};return this.registry=this.registry.filter((K)=>K.packageName!==Q),this.registry.push(M),this.saveRegistry(),Y().logger.info("plugin-manager",`Installed ${Q}@${W.version} (${W.name})`),M}async ensureDefaultPlugins(Q,Z=[],$){let z=[],H=new Set(Z),q=$?h(process.platform,$):S(process.platform);for(let X of q){if(H.has(X.packageName)||H.has(X.pluginName)){Y().logger.info("plugin-manager",`${X.packageName} skipped by --skip-plugin`);continue}if(X.isCore&&X.category==="core"){Y().logger.info("plugin-manager",`${X.packageName} is bundled with the agent \u2014 skipping auto-install`);continue}if(this.registry.some((J)=>J.packageName===X.packageName)){Y().logger.info("plugin-manager",`${X.packageName} already installed, skipping auto-install`);continue}Q?.(`Installing ${X.label} (${X.packageName})...`);try{await this.install(X.packageName,{refreshLatest:!0}),z.push(X),Q?.(`Installed ${X.label} (${X.packageName})`)}catch(J){let W=J instanceof Error?J.message:String(J);Y().logger.error("plugin-manager",`Failed to auto-install ${X.packageName}: ${W}`),Q?.(`Failed to install ${X.label}: ${W}`)}}if(z.length>0)this.loadRegistry();return z}async installAndLoad(Q,Z,$){let z=await this.install(Q),H=this.loaded.get(z.packageName);if(H){this.registerPluginProviders(H,$);let q=this.wrapHostServices(H,$);if(H.onServerStart)await H.onServerStart(Z,q);if(H.onServerReady)await H.onServerReady(Z,q)}return z}async update(Q,Z){return this.withLifecycleLock(()=>this.updateLocked(Q,Z))}async updateLocked(Q,Z){if(Q=G(Q),Y().logger.info("plugin-manager",`Updating ${Q}${Z?`@${Z}`:""}...`),!this.registry.find((q)=>q.packageName===Q))throw Error(`Plugin ${Q} is not installed. Use 'install' first.`);let z=this.loaded.get(Q);if(z)await this.terminateWorkerHost(z.name);this.loaded.delete(Q);let H=await this.installLocked(Q,{refreshLatest:!0,version:Z});return Y().logger.info("plugin-manager",`Updated ${Q} to v${H.version}`),H}async updateAll(){let Q=[];for(let Z of[...this.registry])try{let $=await this.update(Z.packageName);Q.push({packageName:Z.packageName,success:!0,version:$.version})}catch($){Q.push({packageName:Z.packageName,success:!1,error:$ instanceof Error?$.message:String($)})}return Q}async removeAll(Q){let Z=[],$=[...this.registry];for(let z of $)try{await this.remove(z.packageName,Q),Z.push({packageName:z.packageName,success:!0})}catch(H){Z.push({packageName:z.packageName,success:!1,error:H instanceof Error?H.message:String(H)})}return Z}async remove(Q,Z){return this.withLifecycleLock(()=>this.removeLocked(Q,Z))}async removeLocked(Q,Z){Q=G(Q),Y().logger.info("plugin-manager",`Removing ${Q}...`);let $=this.loaded.get(Q);if($?.onServerStop)try{await $.onServerStop()}catch(q){Y().logger.warn("plugin-manager",`Error stopping ${Q}: ${q}`)}if($)await this.terminateWorkerHost($.name),Z?.serviceRegistry.unregisterPlugin($.name),this.loaded.delete(Q);let z=this.registry.find((q)=>q.packageName===Q);if(!$&&z)Z?.serviceRegistry.unregisterPlugin(z.pluginName);let H=V(b(),"agent-plugins");try{if(U(V(H,"package.json")))Bun.spawnSync(["bun","remove",Q],{cwd:H,timeout:60000,stdout:"pipe",stderr:"pipe"})}catch{}try{Bun.spawnSync(["bun","remove","-g",Q],{timeout:60000,stdout:"pipe",stderr:"pipe"})}catch{try{Bun.spawnSync(["npm","uninstall","-g",Q],{timeout:60000,stdout:"pipe",stderr:"pipe"})}catch{}}this.pluginRoots=void 0,this.registry=this.registry.filter((q)=>q.packageName!==Q),this.saveRegistry(),Y().logger.info("plugin-manager",`Removed ${Q}`)}async loadAll(){this.loaded.clear();let Q=[];for(let Z of this.registry)try{G(Z.packageName),await this.importPlugin(Z.packageName),Y().logger.info("plugin-manager",`Loaded ${Z.packageName} (${Z.pluginName})`)}catch($){let z=$.code;if(z==="ENOENT_PLUGIN")Y().logger.info("plugin-manager",`${Z.packageName} not present on disk \u2014 dropping from registry`),Q.push(Z.packageName);else if(z==="EPLUGIN_LEGACY_SINGLETON")Y().logger.warn("plugin-manager",`Skipping ${Z.packageName}: ${$ instanceof Error?$.message:String($)}`);else Y().logger.warn("plugin-manager",`Failed to load ${Z.packageName} \u2014 dropping from registry: ${$}`),Q.push(Z.packageName)}if(Q.length>0){this.registry=this.registry.filter((Z)=>!Q.includes(Z.packageName));try{this.saveRegistry()}catch(Z){Y().logger.warn("plugin-manager",`Failed to persist pruned registry: ${Z}`)}}}async importPlugin(Q){Q=G(Q);let Z={},$;{let H=this.getGlobalRoots(),q=!1,X=[],B=!0;for(let J of H){let W=V(J,Q);if(!U(W)){X.push({path:W,error:"directory missing"});continue}B=!1;try{$=W,Z=await import(W),q=!0;break}catch(M){X.push({path:W,error:M instanceof Error?M.message:String(M)})}try{let M=V(W,"package.json");if(!U(M)){X.push({path:M,error:"package.json missing"});continue}let K=JSON.parse(v(M,"utf8")),F=K.module??K.main??"./index.js",T=V(W,F);$=W,Z=await import(T),q=!0;break}catch(M){X.push({path:W,error:M instanceof Error?M.message:String(M)})}}if(!q)try{$=this.resolvePackageRoot(Q)??$,Z=await import(Q),q=!0}catch(J){X.push({path:`bare:${Q}`,error:J instanceof Error?J.message:String(J)})}if(!q){let J=X.map((M)=>`${M.path} (${M.error})`).join("; "),W=Error(`Cannot find module '${Q}': explicit root attempts and bare import failed: ${J||"(no roots probed)"}`);if(B&&H.length>0)W.code="ENOENT_PLUGIN";throw W}}let z=this.extractPlugin(Z,`external:${Q}`,Y());if(!z){if(this.hasLegacySingleton(Z)){let H=Error(`${Q} uses removed singleton contract; upgrade to createPlugin(ctx) factory (set VIBECONTROLS_PLUGIN_CONTRACT_V2_ENFORCE=1 to refuse strictly)`);throw H.code="EPLUGIN_LEGACY_SINGLETON",H}throw Error(`${Q} does not export a valid createPlugin(ctx) factory`)}if(this.validatePluginExport(z,Q,$),!this.acceptCapabilities(z,`external:${Q}`))throw Error(`${Q} refused to load: missing required capabilities declaration`);if($)Object.defineProperty(z,$Q,{value:$,enumerable:!1,configurable:!1});if(this.logResolvedPlugin(Q,z.version,$),this.loaded.set(Q,z),this.shouldIsolate(z)){let H=Y(),q=new L({modulePath:Q,pluginName:z.name,ctx:{name:H.name,dataDir:H.dataDir}});try{await q.start(),this.workerHosts.set(z.name,q),H.logger.info("plugin-manager",`Isolated plugin '${z.name}' running in worker_threads`)}catch(X){try{await q.terminate()}catch{}this.loaded.delete(Q);let B=X instanceof Error?X.message:String(X);throw H.logger.error("plugin-manager",`Isolation required for '${z.name}' but worker failed to start (${B}); refusing to load in host process`),Error(`Plugin '${z.name}' requires isolation but the worker failed to start: ${B}`,{cause:X})}}return z}resolvePackageRoot(Q){let Z=import.meta;if(typeof Z.resolve!=="function")return;try{let $=Z.resolve(Q);if(!$.startsWith("file:"))return;let z=R(P($));while(z&&z!==R(z)){if(U(V(z,"package.json")))return z;z=R(z)}}catch{return}return}validatePluginExport(Q,Z,$){if(!a.test(Q.name))throw Error(`${Z} exports an invalid plugin name`);if(!Q.version||Q.version.length>64)throw Error(`${Z} exports an invalid plugin version`);if(Q.description&&Q.description.length>500)throw Error(`${Z} description is too long`);if(Q.cliCommand&&!a.test(Q.cliCommand))throw Error(`${Z} exports an invalid CLI command`);if(Q.apiPrefix){if(!PQ.test(Q.apiPrefix)||Q.apiPrefix.includes("..")||Q.apiPrefix.includes("//"))throw Error(`${Z} exports an invalid API prefix`)}if(Q.publicPaths){if(Q.publicPaths.length>20)throw Error(`${Z} exports too many public paths`);for(let z of Q.publicPaths)if(!yQ.test(z)||z.includes("..")||z.includes("//"))throw Error(`${Z} exports an invalid public path`)}if(Q.dependencies&&Q.dependencies.length>20)throw Error(`${Z} exports too many dependencies`);if(Q.tags){let z=new Set(["backend","frontend","cli","provider","adapter","integration"]);if(Q.tags.length>z.size)throw Error(`${Z} exports too many tags`);for(let H of Q.tags)if(!z.has(H))throw Error(`${Z} exports an invalid tag`)}if(Q.ui){if(Q.ui.title&&Q.ui.title.length>120)throw Error(`${Z} UI title is too long`);if(Q.ui.staticDir){if(!$)throw Error(`${Z} UI staticDir requires a package root`);let z=t($),H=t(Q.ui.staticDir);if(!RQ(H).isDirectory()||!dQ(z,H))throw Error(`${Z} UI staticDir must be inside the plugin package`)}}}pluginRoots;getPluginRoots(){if(this.pluginRoots!==void 0)return this.pluginRoots;let Q=QQ(),Z=[],$=new Set,z=(q)=>{if(!q||$.has(q)||!U(q))return;$.add(q),Z.push(q)},H=process.env.VIBECONTROLS_PLUGIN_ROOTS;if(H)for(let q of H.split(Q.pathSep).map((X)=>X.trim()).filter(Boolean))z(q);if(y()==="local")z(zQ());else z(V(xQ(),".bun","install","global","node_modules")),z(Q.npmGlobalRoot());if(this.isRunningFromSource())z(this.agentOwnNodeModules());return this.pluginRoots=Z,Z}isRunningFromSource(){try{let Q=P(import.meta.url);return Q.includes(`${r}src${r}`)||Q.includes("/src/")}catch{return!1}}agentOwnNodeModules(){try{let Q=R(P(import.meta.url)),Z="";while(Q&&Q!==Z){if(U(V(Q,"package.json")))return V(Q,"node_modules");Z=Q,Q=R(Q)}}catch{}return null}getGlobalRoots(){return this.getPluginRoots()}readInstalledVersion(Q,Z){try{let $=V(Q,Z,"package.json");if(!U($))return;let z=JSON.parse(v($,"utf8"));return typeof z.version==="string"?z.version:void 0}catch{return}}logResolvedPlugin(Q,Z,$){let z=Y().logger;z.debug("plugin-manager",`Resolved ${Q}@${Z}`,{from:$??"(bare import)"});try{let H=[];for(let q of this.getPluginRoots()){let X=V(q,Q);if($&&X===$)continue;let B=this.readInstalledVersion(q,Q);if(B&&B!==Z)H.push(`${X} (v${B})`)}if(H.length>0)z.warn("plugin-manager",`${Q}: loaded v${Z} but stale duplicate copy(ies) exist at a different version \u2014 these shadow the active copy across reinstalls. Run \`vibe nuke --all\` to purge them.`,{loadedVersion:Z,loadedFrom:$??"(bare import)",shadows:H})}catch{}}extractPlugin(Q,Z,$){let z=this.findFactory(Q);if(z){let H=z($);if(!this.isVibePlugin(H))throw Error(`plugin '${Z}' createPlugin(ctx) factory returned an invalid VibePlugin`);return H}if(this.hasLegacySingleton(Q)){let H=`plugin '${Z}' uses removed singleton contract; upgrade to createPlugin(ctx) factory`;if(u())throw Error(H);Y().logger.warn("plugin-manager",H);return}return}findFactory(Q){if(typeof Q.createPlugin==="function")return Q.createPlugin;let Z=Q.default;if(Z&&typeof Z.createPlugin==="function")return Z.createPlugin;return}hasLegacySingleton(Q){if(this.isVibePlugin(Q.vibePlugin))return!0;let Z=Q.default;if(Z&&this.isVibePlugin(Z.vibePlugin))return!0;if(this.isVibePlugin(Z))return!0;return!1}isVibePlugin(Q){if(!Q||typeof Q!=="object")return!1;let Z=Q;return typeof Z.name==="string"&&typeof Z.version==="string"}registerProviders(Q,Z){this.registerPluginProviders(Q,Z)}registerPluginProviders(Q,Z){let z=p(Q.name)?.isDefault===!0,H=(q)=>{if(!z)return;Z.serviceRegistry.setProviderDefault(q,Q.name)};if(Q.providers?.tunnel){if(Z.serviceRegistry.registerProvider("tunnel",Q.providers.tunnel,Q.name),H("tunnel"),Q.tunnelDomainSuffixes)for(let q of Q.tunnelDomainSuffixes)ZQ(q)}if(Q.providers?.session)Z.serviceRegistry.registerProvider("session",Q.providers.session,Q.name),H("session");if(Q.providers?.ai)Z.serviceRegistry.registerProvider("ai",Q.providers.ai,Q.name),H("ai")}async dispatchCliSetup(Q,Z){for(let $ of this.getAllPlugins())if($.onCliSetup)try{await $.onCliSetup(Q,this.wrapHostServices($,Z))}catch(z){Y().logger.warn("plugin-manager",`onCliSetup failed for ${$.name}: ${z}`)}}async dispatchServerStart(Q,Z){let $=this.sortAllByDependencies(),z=[];for(let H of $){if(this.registerPluginProviders(H,Z),H.onServerStart){let q=Date.now();try{await H.onServerStart(Q,this.wrapHostServices(H,Z)),(async()=>{try{let{telemetryService:X}=await import("./telemetry-8jfdyt51.js");X.emit("plugin.activated",{plugin_name:H.name,version:H.version,duration_ms:Date.now()-q})}catch{}})()}catch(X){let B=X instanceof Error?X.message:String(X);Y().logger.error("plugin-manager",`onServerStart failed for ${H.name}: ${B}`),(async()=>{try{let{telemetryService:W}=await import("./telemetry-8jfdyt51.js");W.emit("plugin.failed",{plugin_name:H.name,error_class:X instanceof Error?X.constructor.name:"Error"})}catch{}})();let J=this.registry.find((W)=>W.pluginName===H.name);z.push({plugin:H.name,packageName:J?.packageName,error:B})}}this.registerPluginProviders(H,Z)}return{failures:z}}async dispatchServerReady(Q,Z){for(let $ of this.getAllPlugins())if($.onServerReady)try{await $.onServerReady(Q,this.wrapHostServices($,Z))}catch(z){Y().logger.warn("plugin-manager",`onServerReady failed for ${$.name}: ${z}`)}}async provisionDefaultPrereqs(Q,Z,$,z){let H=process.env.VIBE_SKIP_PREREQ_INSTALL==="1",q=process.platform;Y().logger.info("plugin-manager",`Provisioning default providers \u2014 agent build v${N()}, platform=${q}, pluginInstallScope=${y()}, skipInstall=${H}`);let X=(z?h(process.platform,z):S(process.platform)).map((W)=>W.packageName);if(!H)for(let W of X){if(this.loaded.has(W))continue;try{Y().logger.info("plugin-manager",`Installing default meta ${W}`),await this.install(W,{refreshLatest:!0})}catch(M){Y().logger.warn("plugin-manager",`Failed to install default meta ${W}: ${M}`)}}let B=this.buildHostPluginsFacade(Q,Z,$),J=this.attachPluginsFacade(Z,B);for(let[W,M]of this.getAllLoaded()){if(!M.provisionProviders)continue;try{await M.provisionProviders(this.wrapHostServices(M,J)),Y().logger.info("plugin-manager",`${W}: providers provisioned`)}catch(K){Y().logger.warn("plugin-manager",`${W}: provisionProviders failed: ${K}`)}}}buildHostPluginsFacade(Q,Z,$){return{install:async(z,H)=>{await this.install(z,H??{})},loadProvider:async(z)=>{await this.loadAndStartProvider(z,Q,Z,$)},runPrereqs:async(z,H)=>{let{runPluginPrereqs:q}=await import("./prereqs-runner-27x3j1md.js"),X=this.loaded.get(z);if(!X)return{satisfied:!1};let B=await q(X,z,Q,this.db??null,{skipInstall:H?.skipInstall===!0});return{satisfied:B.noProtocol?!0:B.satisfied}},electDefault:async(z,H)=>{await this.electProviderDefault(z,H,Z)},isProviderRegistered:(z,H)=>Z.serviceRegistry.listProvidersForType(z).some((q)=>q.pluginName===H),skipInstall:()=>process.env.VIBE_SKIP_PREREQ_INSTALL==="1"}}attachPluginsFacade(Q,Z){return new Proxy(Q,{get($,z,H){if(z==="plugins")return Z;return Reflect.get($,z,H)}})}async loadAndStartProvider(Q,Z,$,z){let H=this.loaded.get(Q);if(!H)H=await this.importPlugin(Q);if(H.createRoutes&&z?.(H))Y().logger.info("plugin-manager",`${Q}: mounted routes after provisioning`);this.registerPluginProviders(H,$);let q=this.wrapHostServices(H,$);if(H.onServerStart)await H.onServerStart(Z,q);if(H.onServerReady)await H.onServerReady(Z,q)}async electProviderDefault(Q,Z,$){if(!$.serviceRegistry.listProvidersForType(Q).some((H)=>H.pluginName===Z))return;try{let H=await this.getDefaultProvider(Q);if(H&&H!==Z)return;if($.serviceRegistry.setProviderDefault(Q,Z),!H)await this.setDefaultProvider(Q,Z).catch(()=>{});Y().logger.info("plugin-manager",`Elected platform-default '${Q}' provider '${Z}'`)}catch(H){Y().logger.warn("plugin-manager",`Failed to elect default '${Q}' provider '${Z}': ${H}`)}}async dispatchServerStop(Q){for(let Z of this.getAllPlugins())if(Z.onServerStop)try{await Z.onServerStop(Q)}catch($){Y().logger.warn("plugin-manager",`onServerStop failed for ${Z.name}: ${$}`)}if(Q?.reason==="shutdown")await this.terminateAllWorkerHosts()}async runPluginNuke(Q,Z,$){let z=Q?this.loaded.has(Q)?[[Q,this.loaded.get(Q)]]:[]:Array.from(this.loaded.entries()),H=[];for(let[q,X]of z){if(!X.onNuke)continue;try{let B=this.wrapHostServices(X,Z),J=await X.onNuke(B,$);H.push({plugin:q,ok:!0,reaped:J?.reaped??[],notes:J?.notes??[]}),Y().logger.info("plugin-manager",`onNuke ${$.dryRun?"(dry-run) ":""}completed for ${q}`,{reaped:J?.reaped??[]})}catch(B){let J=B instanceof Error?B.message:String(B);H.push({plugin:q,ok:!1,reaped:[],notes:[],error:J}),Y().logger.warn("plugin-manager",`onNuke failed for ${q}: ${J}`)}}return{results:H}}async reloadAll(Q,Z){await this.dispatchServerStop({reason:"reload"}),await this.terminateAllWorkerHosts();for(let $ of this.loaded.values())Z.serviceRegistry.unregisterPlugin($.name);this.loaded.clear(),this.corePlugins.clear(),this.loadRegistry(),await this.loadCorePlugins(),await this.loadAll(),await this.dispatchServerStart(Q,Z),await this.dispatchServerReady(Q,Z)}sortAllByDependencies(){let Q=this.getAllPlugins(),Z=new Map;for(let X of Q)Z.set(X.name,X);let $=new Set,z=new Set,H=[],q=(X)=>{if($.has(X))return;if(z.has(X))throw Error(`Plugin dependency cycle detected at '${X}'`);let B=Z.get(X);if(!B)return;if(z.add(X),B.dependencies)for(let J of B.dependencies){if(!Z.has(J)){Y().logger.warn("plugin-manager",`Plugin '${B.name}' depends on missing plugin '${J}'`);continue}q(J)}z.delete(X),$.add(X),H.push(B)};for(let X of Q)q(X.name);return H}sortByDependencies(){let Q=Array.from(this.loaded.entries()),Z=new Map;for(let[q,X]of Q)Z.set(X.name,q);let $=new Set,z=[],H=(q)=>{if($.has(q))return;$.add(q);let X=this.loaded.get(q);if(X?.dependencies)for(let J of X.dependencies){let W=Z.get(J);if(W&&this.loaded.has(W))H(W)}let B=this.loaded.get(q);if(B)z.push([q,B])};for(let[q]of Q)H(q);return z}getPluginByKey(Q){for(let[,Z]of this.loaded)if(Z.name===Q)return Z;return this.corePlugins.get(Q)}getAllPlugins(){let Q=new Map;for(let[Z,$]of this.corePlugins)Q.set(Z,$);for(let[,Z]of this.loaded)Q.set(Z.name,Z);return Array.from(Q.values())}getAllPluginsByTag(Q){return this.getAllPlugins().filter((Z)=>Z.tags?.includes(Q)??!1)}resolvePluginChain(Q){let Z=new Set;for(let H of this.getAllPlugins())Z.add(H.name);let $=[],z=-1;for(let H=0;H<Q.length;H++){if(Q[H].startsWith("-")){z=H;break}if(Z.has(Q[H]))$.push(Q[H]);else{z=H;break}}if(z===-1)return{chain:$,command:"",args:[]};return{chain:$,command:Q[z],args:Q.slice(z+1)}}async getDefaultProvider(Q){if(!this.db)return null;return await this.db.getConfig(`${e}${Q}`)??null}async setDefaultProvider(Q,Z){if(!this.db)throw Error("Cannot set default provider: PluginManager was constructed without a database reference");if(!this.getPluginByKey(Z))throw Error(`Plugin '${Z}' not found`);await this.db.setConfig(`${e}${Q}`,Z),Y().logger.info("plugin-manager",`Set default '${Q}' provider to '${Z}'`)}getPluginDetails(){let Q=this.getCorePluginDetails(),Z=this.getExternalPluginDetails(),$=new Map;for(let z of Q)$.set(z.pluginName,z);for(let z of Z)$.set(z.pluginName,z);return Array.from($.values())}getCorePluginDetails(){let Q=[];for(let[Z,$]of this.corePlugins)Q.push({packageName:`@vibecontrols/plugin-${Z}`,pluginName:Z,version:$.version,description:$.description,tags:$.tags,cliCommand:$.cliCommand,apiPrefix:$.apiPrefix,dependencies:$.dependencies,installedAt:"",loaded:!0,isCore:!0,hasUI:!!$.ui,uiUrl:$.ui?`/ui/${Z}`:void 0,hasCliSetup:!!$.onCliSetup,hasServerStart:!!$.onServerStart,hasServerStop:!!$.onServerStop,hasServerReady:!!$.onServerReady,hasProviders:!!($.providers?.tunnel||$.providers?.session||$.providers?.ai)});return Q}getExternalPluginDetails(){return this.registry.map((Q)=>{let Z=this.loaded.get(Q.packageName),$=p(Q.pluginName);return{packageName:Q.packageName,pluginName:Q.pluginName,version:Z?.version??Q.version,description:Z?.description,tags:Z?.tags,cliCommand:Z?.cliCommand,apiPrefix:Z?.apiPrefix,dependencies:Z?.dependencies,installedAt:Q.installedAt,loaded:!!Z,isCore:$?.isCore===!0,hasUI:!!Z?.ui,uiUrl:Z?.ui?`/ui/${Q.pluginName}`:void 0,hasCliSetup:!!Z?.onCliSetup,hasServerStart:!!Z?.onServerStart,hasServerStop:!!Z?.onServerStop,hasServerReady:!!Z?.onServerReady,hasProviders:!!(Z?.providers?.tunnel||Z?.providers?.session||Z?.providers?.ai)}})}getRegistry(){return[...this.registry]}getLoaded(Q){return this.loaded.get(Q)}getAllLoaded(){return new Map(this.loaded)}isInstalled(Q){return this.registry.some((Z)=>Z.packageName===Q)}isLoaded(Q){return this.loaded.has(Q)}}
5
5
  export{N as Da,O as Ea,jQ as Fa,D as Ga,h as Ha,l as Ia,rQ as Ja,pQ as Ka,iQ as La,aQ as Ma,I as Na,bQ as Oa,eQ as Pa,SQ as Qa,hQ as Ra,VZ as Sa,G as Ta,y as Ua,OZ as Va,HQ as Wa};
@@ -1,6 +1,6 @@
1
1
  // @bun
2
- import{d as m,e as H2}from"./index-z5s398n0.js";import{z as u}from"./index-ytgmhxsj.js";import"./index-d1xjj001.js";import"./index-a9ejdv22.js";import"./index-4wgjx8bf.js";import{Ja as Z2,Ka as $2,La as z2,Na as W2,Ta as d}from"./index-s2xpdnsj.js";import"./index-0ckffygp.js";import"./index-hvjqgb97.js";import"./index-rqq0k5fc.js";import{Rb as X2,Sb as Y2}from"./index-5dysvvjv.js";import{Ub as J,Vb as V2}from"./index-pgew6sge.js";import{jc as l,kc as t,lc as R}from"./index-8nqp3a4d.js";import{oc as N,qc as q,rc as O,sc as I,tc as S,uc as _,vc as k,wc as A,yc as i}from"./index-1mppacnx.js";import{Gc as s,Hc as G2}from"./index-thammzct.js";import{Lc as U,Nc as E,Oc as n,Pc as D}from"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import{Od as c}from"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import{ie as L}from"./index-c7554sg7.js";import{timingSafeEqual as j2}from"crypto";async function a(V,B){try{let z=Bun.spawn({cmd:["npm","view",`${V}@${B}`,"dist.integrity","--json"],stdout:"pipe",stderr:"pipe"});if(await z.exited!==0)return null;let X=(await new Response(z.stdout).text()).trim();if(!X)return null;if(X.startsWith('"'))try{let $=JSON.parse(X);return typeof $==="string"?$:null}catch{return null}return X}catch{return null}}function e(V,B){let z=Buffer.from(V),K=Buffer.from(B);if(z.length!==K.length)return!1;try{return j2(z,K)}catch{return!1}}var U2=$2.map((V)=>({packageName:V.packageName,name:V.pluginName,description:V.description,cliCommand:V.cliCommand,apiPrefix:V.apiPrefix,installed:!1,category:V.category})),y=new Map;function w(V,B){let K=(y.get(V)??Promise.resolve()).then(B,B),Q=K.then(()=>{return},()=>{return});return y.set(V,Q),Q.finally(()=>{if(y.get(V)===Q)y.delete(V)}),K}function K2(V){return y.has(V)}function Q2(V){let B=V.getPluginDetails(),z=new Set(B.map((K)=>K.packageName));return{plugins:U2.map((K)=>({...K,installed:z.has(K.packageName)}))}}function B2(V){let{pluginManager:B}=V;return new V2().get("/",()=>{let z=B.getPluginDetails();return{plugins:z,count:z.length}}).get("/available",()=>Q2(B)).get("/catalog",()=>Q2(B)).get("/contributions",({query:z})=>{let K=typeof z?.mountPoint==="string"&&z.mountPoint?z.mountPoint:null,Q=[],X=new Map;for(let $ of B.getPluginDetails())X.set($.pluginName,$.packageName);for(let $ of B.getAllPlugins()){let x=$.ui;if(!x||!x.contributions||x.contributions.length===0)continue;let Y=x.capabilities??{restPaths:[],wsTopics:[],rpcMethods:[]};for(let W of x.contributions){if(K&&W.mountPoint!==K)continue;let Z=W.meta,H=Z&&typeof Z.url==="string"?Z.url:null,F=H&&H.startsWith("/")&&!H.startsWith("//")&&!H.includes("\x00")&&!H.includes("..")?H:null;Q.push({pluginKey:$.name,pluginPackageName:X.get($.name),contribution:W,capabilities:W.capabilities??Y,url:F??`/ui/${encodeURIComponent($.name)}`})}}return{contributions:Q,count:Q.length}}).post("/install",async({body:z,set:K})=>{if(!z.packageName||typeof z.packageName!=="string")return K.status=400,{error:"Missing required field: packageName"};if(z.packageName.startsWith("@burdenoff/"))z.packageName=z.packageName.replace(/^@burdenoff\//,"@vibecontrols/");if(!W2(z.packageName))return K.status=403,{error:"Plugin package is not in the trusted VibeControls catalog"};try{let Q=d(z.packageName);if(K2(Q)){let X=Q.split("/").pop()?.replace("vibe-plugin-","");if(B.getAllPlugins().some((x)=>x.name===X))return{success:!0,message:`Plugin ${Q} is already installed`,packageName:Q,alreadyInstalled:!0};return K.status=409,{error:"Install for this package is already in progress. Wait for it to finish.",packageName:Q}}return await w(Q,async()=>{let X=Q.split("/").pop()?.replace("vibe-plugin-",""),$=X?.startsWith("ai-")?X.slice(3):void 0,x=B.getAllPlugins().find((C)=>C.name===X||C.name===$),Y=!!x,W=await B.install(Q),Z=z2(Q);if(Z?.integrity){let C=await a(Q,W.version);if(!C||!e(Z.integrity,C)){try{await B.remove(Q,V.hostServices)}catch(G){console.warn(`[plugin-mgr] integrity rollback uninstall failed for ${Q}:`,G)}return c().audit.emit("agent","plugin.install.rejected",{packageName:Q,version:W.version,reason:"integrity_mismatch",expected:Z.integrity,actual:C}),K.status=400,{error:"integrity mismatch",expected:Z.integrity,actual:C}}}else console.warn(`[plugin-mgr] plugin ${Q} has no pinned integrity \u2014 accepting npm registry's hash`);let H=B.getAllPlugins().find((C)=>C.name===W.pluginName);if(H){let C=[];if(V.mountPlugin)V.mountPlugin(H);if(V.hostServices){if(Y&&x?.onServerStop)try{await x.onServerStop()}catch(G){C.push(`onServerStop failed: ${G instanceof Error?G.message:String(G)}`)}if(B.registerProviders(H,V.hostServices),H.onServerStart&&V.app)try{await H.onServerStart(V.app,V.hostServices),B.registerProviders(H,V.hostServices)}catch(G){C.push(`onServerStart failed: ${G instanceof Error?G.message:String(G)}`)}if(H.onServerReady&&V.app)try{await H.onServerReady(V.app,V.hostServices)}catch(G){C.push(`onServerReady failed: ${G instanceof Error?G.message:String(G)}`)}}if(V.rebuildPluginSurfaces?.(),C.length>0)return K.status=500,{success:!1,message:`Plugin ${Q} installed but failed to start`,lifecycleErrors:C,restartRequired:!0}}let F;if(H&&V.app)try{F=await m(H,Q,V.app,V.db,{skipInstall:!!z.skipPrereqs})}catch(C){F=void 0,console.warn(`[plugin-mgr] prereq run failed for ${Q}:`,C)}return u(V.db),c().audit.emit("agent","plugin.installed",{packageName:Q,version:W.version,pluginName:W.pluginName,wasRunning:Y}),{success:!0,message:`Plugin ${Q} installed and loaded successfully`,prereqs:F?{satisfied:F.satisfied,missing:F.status?.missing??[],pendingSudo:F.pendingSudo,skipped:!!z.skipPrereqs}:void 0}})}catch(Q){return K.status=500,{error:"Failed to install plugin",details:String(Q)}}},{body:J.Object({packageName:J.String(),skipPrereqs:J.Optional(J.Boolean())})}).post("/prereqs/status",async({body:z,set:K})=>{if(!z.packageName)return K.status=400,{error:"Missing packageName"};let Q=z.packageName,X=B.getAllPlugins().find(($)=>$.name===Q||B.getLoaded(Q)?.name===$.name);if(!X||!V.app)return await H2(V.db,Q)??{satisfied:!0,missing:[]};try{let $=await m(X,Q,V.app,V.db,{skipInstall:!0});return{satisfied:$.satisfied,missing:$.status?.missing??[],noProtocol:$.noProtocol}}catch($){return K.status=500,{error:String($)}}},{body:J.Object({packageName:J.String()})}).post("/prereqs/install",async({body:z,set:K})=>{if(!z.packageName)return K.status=400,{error:"Missing packageName"};let Q=z.packageName,X=B.getAllPlugins().find(($)=>$.name===Q||B.getLoaded(Q)?.name===$.name);if(!X||!V.app)return K.status=404,{error:"Plugin not loaded"};try{let $=await m(X,Q,V.app,V.db,{skipInstall:!1});return{satisfied:$.satisfied,installed:$.install?.installed??[],pendingSudo:$.pendingSudo,errors:$.install?.errors??[],noProtocol:$.noProtocol}}catch($){return K.status=500,{error:String($)}}},{body:J.Object({packageName:J.String(),approveSudo:J.Optional(J.Boolean())})}).post("/prereqs/uninstall",async({body:z,set:K})=>{if(!z.packageName)return K.status=400,{error:"Missing packageName"};let Q=z.packageName,X=B.getAllPlugins().find((W)=>W.name===Q);if(!X||!X.apiPrefix||!V.app)return K.status=404,{error:"Plugin not loaded"};let $=V.app.handle;if(typeof $!=="function")return K.status=500,{error:"App handle unavailable"};let x=`${X.apiPrefix.replace(/\/+$/,"")}/prereqs/uninstall`,Y=await $.call(V.app,new Request(`http://agent.local${x}`,{method:"POST",headers:{"x-vc-profile-rewrite":"1",[X2]:Y2()}}));if(Y.status===404)return K.status=404,{error:"Plugin has no prereqs/uninstall endpoint"};return Y.json()},{body:J.Object({packageName:J.String()})}).post("/nuke",async({body:z,set:K})=>{if(!V.hostServices)return K.status=503,{error:"hostServices unavailable"};let Q=V.hostServices.getDataDir?.();return{ok:!0,...await B.runPluginNuke(z.packageName,V.hostServices,{agentDir:Q,dryRun:!!z.dryRun})}},{body:J.Object({packageName:J.Optional(J.String()),dryRun:J.Optional(J.Boolean())})}).post("/remove",async({body:z,set:K})=>{if(!z.packageName||typeof z.packageName!=="string")return K.status=400,{error:"Missing required field: packageName"};if(z.packageName.startsWith("@burdenoff/"))z.packageName=z.packageName.replace(/^@burdenoff\//,"@vibecontrols/");if(Z2(z.packageName))return{success:!0,message:`Plugin ${z.packageName} is critical and cannot be removed; treating remove as a no-op.`,skipped:!0};try{let Q=d(z.packageName);return await w(Q,async()=>{return await B.remove(Q,V.hostServices),V.rebuildPluginSurfaces?.(),u(V.db),c().audit.emit("agent","plugin.removed",{packageName:Q}),{success:!0,message:`Plugin ${Q} removed successfully`}})}catch(Q){return K.status=500,{error:"Failed to remove plugin",details:String(Q)}}},{body:J.Object({packageName:J.String()})}).post("/update",async({body:z,set:K})=>{if(!z.packageName||typeof z.packageName!=="string")return K.status=400,{error:"Missing required field: packageName"};let Q=typeof z.version==="string"&&z.version.trim()?z.version.trim():void 0;if(Q&&!/^[0-9][0-9A-Za-z.+-]{0,63}$/.test(Q))return K.status=400,{error:`Invalid version "${Q}"`};try{let X=d(z.packageName);return await w(X,async()=>{let $=B.getLoaded(X);if($?.onServerStop)await $.onServerStop({reason:"reload"});if($&&V.hostServices)V.hostServices.serviceRegistry.unregisterPlugin($.name);let x=await B.update(X,Q),Y=B.getLoaded(X);if(Y&&V.hostServices){if(B.registerProviders(Y,V.hostServices),Y.onServerStart&&V.app)await Y.onServerStart(V.app,V.hostServices),B.registerProviders(Y,V.hostServices);if(Y.onServerReady&&V.app)await Y.onServerReady(V.app,V.hostServices)}return V.rebuildPluginSurfaces?.(),u(V.db),{success:!0,message:`Plugin ${X} updated to v${x.version}`,version:x.version}})}catch(X){return K.status=500,{error:"Failed to update plugin",details:String(X)}}},{body:J.Object({packageName:J.String(),version:J.Optional(J.String())})}).post("/update-all",async({set:z})=>{try{let K=await w("*",()=>B.updateAll());return{success:!0,results:K,message:`Updated ${K.filter((Q)=>Q.success).length}/${K.length} plugin(s)`}}catch(K){return z.status=500,{error:"Failed to update all plugins",details:String(K)}}}).post("/remove-all",async({set:z})=>{try{let K=await w("*",async()=>{let Q=await B.removeAll(V.hostServices);return V.rebuildPluginSurfaces?.(),Q});return{success:!0,results:K,message:`Removed ${K.filter((Q)=>Q.success).length}/${K.length} plugin(s)`}}catch(K){return z.status=500,{error:"Failed to remove all plugins",details:String(K)}}}).post("/reload",async({set:z})=>{try{if(!V.app||!V.hostServices)return z.status=503,{error:"Plugin lifecycle services are not ready"};let K=await w("*",async()=>{return await B.reloadAll(V.app,V.hostServices),V.rebuildPluginSurfaces?.(),B.getPluginDetails()});return{success:!0,plugins:K,message:`Reloaded ${K.length} plugin(s)`}}catch(K){return z.status=500,{error:"Failed to reload plugins",details:String(K)}}}).post("/:name/reload",async({params:z,set:K})=>{if(!V.app||!V.hostServices)return K.status=503,{error:"Plugin lifecycle services are not ready"};let Q=z.name,X=B.getAllPlugins().find((Y)=>Y.name===Q);if(!X)return K.status=404,{error:`Plugin "${Q}" not found`};let x=B.getPluginDetails().find((Y)=>Y.pluginName===Q)?.packageName??`core:${Q}`;if(K2(x))return K.status=409,{error:"Plugin lifecycle in progress; try again shortly",packageName:x};try{return await w(x,async()=>{if(X.onServerStop)try{await X.onServerStop({reason:"reload"})}catch(Y){console.warn(`[plugin-mgr] onServerStop during reload of ${Q}:`,Y)}if(V.hostServices)V.hostServices.serviceRegistry.unregisterPlugin(X.name);if(B.registerProviders(X,V.hostServices),X.onServerStart)await X.onServerStart(V.app,V.hostServices),B.registerProviders(X,V.hostServices);if(X.onServerReady)await X.onServerReady(V.app,V.hostServices);return V.rebuildPluginSurfaces?.(),{success:!0,message:`Plugin ${Q} reloaded`,version:X.version}})}catch(Y){return K.status=500,{error:"Failed to reload plugin",details:String(Y)}}},{params:J.Object({name:J.String()})})}import{mkdirSync as o,writeFileSync as v,existsSync as x2}from"fs";import{isAbsolute as D2,join as T,relative as h2,resolve as g}from"path";var h="http://localhost:3005",A2=/^[a-z0-9][a-z0-9-]{0,63}$/,v2=new Set(["backend","frontend","cli","provider","adapter","integration"]);function C2(V,B){let z=h2(V,B);if(z.startsWith("..")||D2(z))throw Error("Plugin scaffold path escapes the selected directory.")}function M(V){return JSON.stringify(V)}function J2(V){let B=V.command("plugin").description("Manage plugins");B.command("list").description("List installed plugins").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON").option("--plain","Force plain text output").action(async(K)=>{try{let Q={...V.opts(),...K},X=U(K),$=encodeURIComponent(E(Q)),x=async()=>{try{return(await n(X,`/api/profiles/${$}/plugins`)).plugins||[]}catch{S("Agent not reachable. Attempting local plugin registry...");let{PluginManager:Z}=await import("./plugin-system-cwznxqx5.js");return new Z().getPluginDetails()||[]}},Y=(Z)=>Z.status??(Z.loaded===!0||Z.enabled===!0?"enabled":"disabled"),W=(Z)=>Z.pluginName||Z.name||Z.packageName||Z.package||"-";await t({mode:l(Q),fetchData:x,plain:(Z)=>{if(!Z.length){_("No plugins installed.");return}k("Installed Plugins"),i(Z.map((H)=>({Name:W(H),Version:H.version||"-",Status:Y(H),Description:H.description||"-"})))},interactive:async(Z)=>{if(!Z.length){k("Installed Plugins"),_("No plugins installed.");return}let H=Z.map((F)=>{let C=W(F),G=Y(F),b=[`${N.bold(C)} ${G==="enabled"?N.green(G):N.dim(G)}`,"",` Version: ${F.version||"-"}`,` Description: ${F.description||"-"}`];if(F.tags&&Array.isArray(F.tags))b.push(` Tags: ${F.tags.join(", ")}`);if(F.cliCommand)b.push(` CLI command: vibe ${F.cliCommand}`);return{id:C,label:C,hint:G,detail:b.join(`
3
- `)}});await s({title:`vibe plugin \u2014 ${Z.length} installed`,rows:H,footer:"\u2191/\u2193 navigate \xB7 q to quit"})},json:(Z)=>Z.map((H)=>({name:W(H),version:H.version??null,status:Y(H),description:H.description??null,tags:H.tags??null,cliCommand:H.cliCommand??null}))})}catch(Q){q(O(Q))}}),B.command("install").description("Install a plugin").argument("<package>","NPM package name to install").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--skip-prereqs","Skip running the plugin's prereqs/install",!1).option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));try{let Y=await D($,`/api/profiles/${x}/plugins/install`,{packageName:K,skipPrereqs:!!Q.skipPrereqs});if(R(X,{ok:!0,action:"install",package:K,version:Y?.version??null,prereqs:Y?.prereqs??null}))return;if(I(`Plugin "${K}" installed.`),Y?.version)A("Version",Y.version);if(Y?.prereqs){let W=Y.prereqs;if(W.skipped)S(`Prerequisite install skipped. Run \`vibe plugin prereqs ${K} install\` later.`);else if(!W.satisfied)S(`Prerequisites not yet satisfied: ${(W.missing||[]).map((Z)=>Z.name).join(", ")||"(unknown)"}`);if((W.pendingSudo||[]).length>0){S(`${W.pendingSudo.length} command(s) need sudo. Run them and re-check with \`vibe plugin prereqs ${K} status\`:`);for(let Z of W.pendingSudo)A(` ${Z.name}`,Z.command)}}}catch{S("Agent not reachable. Attempting local install...");try{let{PluginManager:Y}=await import("./plugin-system-cwznxqx5.js");if(await new Y().install(K),R(X,{ok:!0,action:"install",package:K,local:!0}))return;I(`Plugin "${K}" installed locally.`)}catch(Y){q(`Could not install plugin via agent or locally: ${O(Y)}`)}}}catch(X){q(O(X))}}),B.command("remove").description("Remove a plugin").argument("<package>","NPM package name to remove").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));try{if(await D($,`/api/profiles/${x}/plugins/remove`,{packageName:K}),R(X,{ok:!0,action:"remove",package:K}))return;I(`Plugin "${K}" removed.`)}catch{S("Agent not reachable. Attempting local removal...");try{let{PluginManager:Y}=await import("./plugin-system-cwznxqx5.js");if(await new Y().remove(K),R(X,{ok:!0,action:"remove",package:K,local:!0}))return;I(`Plugin "${K}" removed locally.`)}catch(Y){q(`Could not remove plugin via agent or locally: ${O(Y)}`)}}}catch(X){q(O(X))}}),B.command("update").description("Update a plugin (or all plugins with --all)").argument("[package]","NPM package name to update").option("--all","Update all installed plugins",!1).option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));if(Q.all){_("Updating all plugins...");try{let Y=await D($,`/api/profiles/${x}/plugins/update-all`,{}),W=Y?.results||[];if(R(X,{ok:!0,action:"update-all",results:W}))return;for(let Z of W)if(Z.success)I(`Updated ${Z.packageName}${Z.version?` to v${Z.version}`:""}`);else S(`Failed to update ${Z.packageName}: ${Z.error}`);I(Y?.message||"Done.")}catch{S("Agent not reachable. Attempting local update...");try{let{PluginManager:Y}=await import("./plugin-system-cwznxqx5.js"),Z=await new Y().updateAll();if(R(X,{ok:!0,action:"update-all",results:Z,local:!0}))return;for(let H of Z)if(H.success)I(`Updated ${H.packageName}${H.version?` to v${H.version}`:""}`);else S(`Failed to update ${H.packageName}: ${H.error}`)}catch(Y){q(`Could not update plugins: ${O(Y)}`)}}}else if(K){_(`Updating ${K}...`);try{let Y=await D($,`/api/profiles/${x}/plugins/update`,{packageName:K});if(R(X,{ok:!0,action:"update",package:K,version:Y?.version??null,message:Y?.message??null}))return;I(Y?.message||`Plugin "${K}" updated.`)}catch{S("Agent not reachable. Attempting local update...");try{let{PluginManager:Y}=await import("./plugin-system-cwznxqx5.js"),Z=await new Y().update(K);if(R(X,{ok:!0,action:"update",package:K,version:Z.version,local:!0}))return;I(`Plugin "${K}" updated to v${Z.version}.`)}catch(Y){q(`Could not update plugin: ${O(Y)}`)}}}else q("Provide a package name to update, or use --all to update all plugins.")}catch(X){q(O(X))}}),B.command("uninstall").description("Uninstall a plugin (or all plugins with --all)").argument("[package]","NPM package name to uninstall").option("--all","Uninstall all external plugins",!1).option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));if(Q.all){_("Uninstalling all plugins...");try{let Y=await D($,`/api/profiles/${x}/plugins/remove-all`,{}),W=Y?.results||[];if(R(X,{ok:!0,action:"uninstall-all",results:W}))return;for(let Z of W)if(Z.success)I(`Removed ${Z.packageName}`);else S(`Failed to remove ${Z.packageName}: ${Z.error}`);I(Y?.message||"Done.")}catch{S("Agent not reachable. Attempting local removal...");try{let{PluginManager:Y}=await import("./plugin-system-cwznxqx5.js"),Z=await new Y().removeAll();if(R(X,{ok:!0,action:"uninstall-all",results:Z,local:!0}))return;for(let H of Z)if(H.success)I(`Removed ${H.packageName}`);else S(`Failed to remove ${H.packageName}: ${H.error}`)}catch(Y){q(`Could not uninstall plugins: ${O(Y)}`)}}}else if(K)try{if(await D($,`/api/profiles/${x}/plugins/remove`,{packageName:K}),R(X,{ok:!0,action:"uninstall",package:K}))return;I(`Plugin "${K}" uninstalled.`)}catch{S("Agent not reachable. Attempting local removal...");try{let{PluginManager:Y}=await import("./plugin-system-cwznxqx5.js");if(await new Y().remove(K),R(X,{ok:!0,action:"uninstall",package:K,local:!0}))return;I(`Plugin "${K}" uninstalled locally.`)}catch(Y){q(`Could not uninstall plugin: ${O(Y)}`)}}else q("Provide a package name to uninstall, or use --all to uninstall all plugins.")}catch(X){q(O(X))}}),B.command("reload").description("Reload all plugins").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K)=>{try{let Q={...V.opts(),...K},X=U(K),$=encodeURIComponent(E(Q));if(await D(X,`/api/profiles/${$}/plugins/reload`,{}),R(Q,{ok:!0,action:"reload"}))return;I("Plugins reloaded.")}catch(Q){q(O(Q))}}),B.command("available").description("Show available plugins").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON").option("--plain","Force plain text output").action(async(K)=>{try{let Q={...V.opts(),...K},X=U(K),$=encodeURIComponent(E(Q)),x=async()=>{return(await n(X,`/api/profiles/${$}/plugins/available`)).plugins||[]},Y=(Z)=>Z.name||Z.package||"-",W=(Z)=>Z.version||Z.latestVersion||"-";await t({mode:l(Q),fetchData:x,plain:(Z)=>{if(!Z||Z.length===0){_("No available plugins found.");return}k("Available Plugins"),i(Z.map((H)=>({Name:Y(H),Version:W(H),Description:H.description||"-"})))},interactive:async(Z)=>{if(!Z||Z.length===0){k("Available Plugins"),_("No available plugins found.");return}let H=Z.map((F)=>{let C=Y(F),G=[N.bold(C),"",` Version: ${W(F)}`,` Description: ${F.description||"-"}`];return{id:C,label:C,hint:W(F),detail:G.join(`
2
+ import{d as m,e as H2}from"./index-z5s398n0.js";import{z as u}from"./index-btt96dhd.js";import"./index-d1xjj001.js";import"./index-dxtnaa3g.js";import"./index-4wgjx8bf.js";import{Ja as Z2,Ka as $2,La as z2,Na as W2,Ta as d}from"./index-kmkhjf1c.js";import"./index-0ckffygp.js";import"./index-hvjqgb97.js";import"./index-rqq0k5fc.js";import{Rb as X2,Sb as Y2}from"./index-5dysvvjv.js";import{Ub as J,Vb as V2}from"./index-pgew6sge.js";import{jc as l,kc as t,lc as R}from"./index-8nqp3a4d.js";import{oc as N,qc as q,rc as O,sc as I,tc as S,uc as _,vc as k,wc as A,yc as i}from"./index-1mppacnx.js";import{Gc as s,Hc as G2}from"./index-thammzct.js";import{Lc as U,Nc as E,Oc as n,Pc as D}from"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import{Od as c}from"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import{ie as L}from"./index-c7554sg7.js";import{timingSafeEqual as j2}from"crypto";async function a(V,B){try{let z=Bun.spawn({cmd:["npm","view",`${V}@${B}`,"dist.integrity","--json"],stdout:"pipe",stderr:"pipe"});if(await z.exited!==0)return null;let X=(await new Response(z.stdout).text()).trim();if(!X)return null;if(X.startsWith('"'))try{let $=JSON.parse(X);return typeof $==="string"?$:null}catch{return null}return X}catch{return null}}function e(V,B){let z=Buffer.from(V),K=Buffer.from(B);if(z.length!==K.length)return!1;try{return j2(z,K)}catch{return!1}}var U2=$2.map((V)=>({packageName:V.packageName,name:V.pluginName,description:V.description,cliCommand:V.cliCommand,apiPrefix:V.apiPrefix,installed:!1,category:V.category})),y=new Map;function w(V,B){let K=(y.get(V)??Promise.resolve()).then(B,B),Q=K.then(()=>{return},()=>{return});return y.set(V,Q),Q.finally(()=>{if(y.get(V)===Q)y.delete(V)}),K}function K2(V){return y.has(V)}function Q2(V){let B=V.getPluginDetails(),z=new Set(B.map((K)=>K.packageName));return{plugins:U2.map((K)=>({...K,installed:z.has(K.packageName)}))}}function B2(V){let{pluginManager:B}=V;return new V2().get("/",()=>{let z=B.getPluginDetails();return{plugins:z,count:z.length}}).get("/available",()=>Q2(B)).get("/catalog",()=>Q2(B)).get("/contributions",({query:z})=>{let K=typeof z?.mountPoint==="string"&&z.mountPoint?z.mountPoint:null,Q=[],X=new Map;for(let $ of B.getPluginDetails())X.set($.pluginName,$.packageName);for(let $ of B.getAllPlugins()){let x=$.ui;if(!x||!x.contributions||x.contributions.length===0)continue;let Y=x.capabilities??{restPaths:[],wsTopics:[],rpcMethods:[]};for(let W of x.contributions){if(K&&W.mountPoint!==K)continue;let Z=W.meta,H=Z&&typeof Z.url==="string"?Z.url:null,F=H&&H.startsWith("/")&&!H.startsWith("//")&&!H.includes("\x00")&&!H.includes("..")?H:null;Q.push({pluginKey:$.name,pluginPackageName:X.get($.name),contribution:W,capabilities:W.capabilities??Y,url:F??`/ui/${encodeURIComponent($.name)}`})}}return{contributions:Q,count:Q.length}}).post("/install",async({body:z,set:K})=>{if(!z.packageName||typeof z.packageName!=="string")return K.status=400,{error:"Missing required field: packageName"};if(z.packageName.startsWith("@burdenoff/"))z.packageName=z.packageName.replace(/^@burdenoff\//,"@vibecontrols/");if(!W2(z.packageName))return K.status=403,{error:"Plugin package is not in the trusted VibeControls catalog"};try{let Q=d(z.packageName);if(K2(Q)){let X=Q.split("/").pop()?.replace("vibe-plugin-","");if(B.getAllPlugins().some((x)=>x.name===X))return{success:!0,message:`Plugin ${Q} is already installed`,packageName:Q,alreadyInstalled:!0};return K.status=409,{error:"Install for this package is already in progress. Wait for it to finish.",packageName:Q}}return await w(Q,async()=>{let X=Q.split("/").pop()?.replace("vibe-plugin-",""),$=X?.startsWith("ai-")?X.slice(3):void 0,x=B.getAllPlugins().find((C)=>C.name===X||C.name===$),Y=!!x,W=await B.install(Q),Z=z2(Q);if(Z?.integrity){let C=await a(Q,W.version);if(!C||!e(Z.integrity,C)){try{await B.remove(Q,V.hostServices)}catch(G){console.warn(`[plugin-mgr] integrity rollback uninstall failed for ${Q}:`,G)}return c().audit.emit("agent","plugin.install.rejected",{packageName:Q,version:W.version,reason:"integrity_mismatch",expected:Z.integrity,actual:C}),K.status=400,{error:"integrity mismatch",expected:Z.integrity,actual:C}}}else console.warn(`[plugin-mgr] plugin ${Q} has no pinned integrity \u2014 accepting npm registry's hash`);let H=B.getAllPlugins().find((C)=>C.name===W.pluginName);if(H){let C=[];if(V.mountPlugin)V.mountPlugin(H);if(V.hostServices){if(Y&&x?.onServerStop)try{await x.onServerStop()}catch(G){C.push(`onServerStop failed: ${G instanceof Error?G.message:String(G)}`)}if(B.registerProviders(H,V.hostServices),H.onServerStart&&V.app)try{await H.onServerStart(V.app,V.hostServices),B.registerProviders(H,V.hostServices)}catch(G){C.push(`onServerStart failed: ${G instanceof Error?G.message:String(G)}`)}if(H.onServerReady&&V.app)try{await H.onServerReady(V.app,V.hostServices)}catch(G){C.push(`onServerReady failed: ${G instanceof Error?G.message:String(G)}`)}}if(V.rebuildPluginSurfaces?.(),C.length>0)return K.status=500,{success:!1,message:`Plugin ${Q} installed but failed to start`,lifecycleErrors:C,restartRequired:!0}}let F;if(H&&V.app)try{F=await m(H,Q,V.app,V.db,{skipInstall:!!z.skipPrereqs})}catch(C){F=void 0,console.warn(`[plugin-mgr] prereq run failed for ${Q}:`,C)}return u(V.db),c().audit.emit("agent","plugin.installed",{packageName:Q,version:W.version,pluginName:W.pluginName,wasRunning:Y}),{success:!0,message:`Plugin ${Q} installed and loaded successfully`,prereqs:F?{satisfied:F.satisfied,missing:F.status?.missing??[],pendingSudo:F.pendingSudo,skipped:!!z.skipPrereqs}:void 0}})}catch(Q){return K.status=500,{error:"Failed to install plugin",details:String(Q)}}},{body:J.Object({packageName:J.String(),skipPrereqs:J.Optional(J.Boolean())})}).post("/prereqs/status",async({body:z,set:K})=>{if(!z.packageName)return K.status=400,{error:"Missing packageName"};let Q=z.packageName,X=B.getAllPlugins().find(($)=>$.name===Q||B.getLoaded(Q)?.name===$.name);if(!X||!V.app)return await H2(V.db,Q)??{satisfied:!0,missing:[]};try{let $=await m(X,Q,V.app,V.db,{skipInstall:!0});return{satisfied:$.satisfied,missing:$.status?.missing??[],noProtocol:$.noProtocol}}catch($){return K.status=500,{error:String($)}}},{body:J.Object({packageName:J.String()})}).post("/prereqs/install",async({body:z,set:K})=>{if(!z.packageName)return K.status=400,{error:"Missing packageName"};let Q=z.packageName,X=B.getAllPlugins().find(($)=>$.name===Q||B.getLoaded(Q)?.name===$.name);if(!X||!V.app)return K.status=404,{error:"Plugin not loaded"};try{let $=await m(X,Q,V.app,V.db,{skipInstall:!1});return{satisfied:$.satisfied,installed:$.install?.installed??[],pendingSudo:$.pendingSudo,errors:$.install?.errors??[],noProtocol:$.noProtocol}}catch($){return K.status=500,{error:String($)}}},{body:J.Object({packageName:J.String(),approveSudo:J.Optional(J.Boolean())})}).post("/prereqs/uninstall",async({body:z,set:K})=>{if(!z.packageName)return K.status=400,{error:"Missing packageName"};let Q=z.packageName,X=B.getAllPlugins().find((W)=>W.name===Q);if(!X||!X.apiPrefix||!V.app)return K.status=404,{error:"Plugin not loaded"};let $=V.app.handle;if(typeof $!=="function")return K.status=500,{error:"App handle unavailable"};let x=`${X.apiPrefix.replace(/\/+$/,"")}/prereqs/uninstall`,Y=await $.call(V.app,new Request(`http://agent.local${x}`,{method:"POST",headers:{"x-vc-profile-rewrite":"1",[X2]:Y2()}}));if(Y.status===404)return K.status=404,{error:"Plugin has no prereqs/uninstall endpoint"};return Y.json()},{body:J.Object({packageName:J.String()})}).post("/nuke",async({body:z,set:K})=>{if(!V.hostServices)return K.status=503,{error:"hostServices unavailable"};let Q=V.hostServices.getDataDir?.();return{ok:!0,...await B.runPluginNuke(z.packageName,V.hostServices,{agentDir:Q,dryRun:!!z.dryRun})}},{body:J.Object({packageName:J.Optional(J.String()),dryRun:J.Optional(J.Boolean())})}).post("/remove",async({body:z,set:K})=>{if(!z.packageName||typeof z.packageName!=="string")return K.status=400,{error:"Missing required field: packageName"};if(z.packageName.startsWith("@burdenoff/"))z.packageName=z.packageName.replace(/^@burdenoff\//,"@vibecontrols/");if(Z2(z.packageName))return{success:!0,message:`Plugin ${z.packageName} is critical and cannot be removed; treating remove as a no-op.`,skipped:!0};try{let Q=d(z.packageName);return await w(Q,async()=>{return await B.remove(Q,V.hostServices),V.rebuildPluginSurfaces?.(),u(V.db),c().audit.emit("agent","plugin.removed",{packageName:Q}),{success:!0,message:`Plugin ${Q} removed successfully`}})}catch(Q){return K.status=500,{error:"Failed to remove plugin",details:String(Q)}}},{body:J.Object({packageName:J.String()})}).post("/update",async({body:z,set:K})=>{if(!z.packageName||typeof z.packageName!=="string")return K.status=400,{error:"Missing required field: packageName"};let Q=typeof z.version==="string"&&z.version.trim()?z.version.trim():void 0;if(Q&&!/^[0-9][0-9A-Za-z.+-]{0,63}$/.test(Q))return K.status=400,{error:`Invalid version "${Q}"`};try{let X=d(z.packageName);return await w(X,async()=>{let $=B.getLoaded(X);if($?.onServerStop)await $.onServerStop({reason:"reload"});if($&&V.hostServices)V.hostServices.serviceRegistry.unregisterPlugin($.name);let x=await B.update(X,Q),Y=B.getLoaded(X);if(Y&&V.hostServices){if(B.registerProviders(Y,V.hostServices),Y.onServerStart&&V.app)await Y.onServerStart(V.app,V.hostServices),B.registerProviders(Y,V.hostServices);if(Y.onServerReady&&V.app)await Y.onServerReady(V.app,V.hostServices)}return V.rebuildPluginSurfaces?.(),u(V.db),{success:!0,message:`Plugin ${X} updated to v${x.version}`,version:x.version}})}catch(X){return K.status=500,{error:"Failed to update plugin",details:String(X)}}},{body:J.Object({packageName:J.String(),version:J.Optional(J.String())})}).post("/update-all",async({set:z})=>{try{let K=await w("*",()=>B.updateAll());return{success:!0,results:K,message:`Updated ${K.filter((Q)=>Q.success).length}/${K.length} plugin(s)`}}catch(K){return z.status=500,{error:"Failed to update all plugins",details:String(K)}}}).post("/remove-all",async({set:z})=>{try{let K=await w("*",async()=>{let Q=await B.removeAll(V.hostServices);return V.rebuildPluginSurfaces?.(),Q});return{success:!0,results:K,message:`Removed ${K.filter((Q)=>Q.success).length}/${K.length} plugin(s)`}}catch(K){return z.status=500,{error:"Failed to remove all plugins",details:String(K)}}}).post("/reload",async({set:z})=>{try{if(!V.app||!V.hostServices)return z.status=503,{error:"Plugin lifecycle services are not ready"};let K=await w("*",async()=>{return await B.reloadAll(V.app,V.hostServices),V.rebuildPluginSurfaces?.(),B.getPluginDetails()});return{success:!0,plugins:K,message:`Reloaded ${K.length} plugin(s)`}}catch(K){return z.status=500,{error:"Failed to reload plugins",details:String(K)}}}).post("/:name/reload",async({params:z,set:K})=>{if(!V.app||!V.hostServices)return K.status=503,{error:"Plugin lifecycle services are not ready"};let Q=z.name,X=B.getAllPlugins().find((Y)=>Y.name===Q);if(!X)return K.status=404,{error:`Plugin "${Q}" not found`};let x=B.getPluginDetails().find((Y)=>Y.pluginName===Q)?.packageName??`core:${Q}`;if(K2(x))return K.status=409,{error:"Plugin lifecycle in progress; try again shortly",packageName:x};try{return await w(x,async()=>{if(X.onServerStop)try{await X.onServerStop({reason:"reload"})}catch(Y){console.warn(`[plugin-mgr] onServerStop during reload of ${Q}:`,Y)}if(V.hostServices)V.hostServices.serviceRegistry.unregisterPlugin(X.name);if(B.registerProviders(X,V.hostServices),X.onServerStart)await X.onServerStart(V.app,V.hostServices),B.registerProviders(X,V.hostServices);if(X.onServerReady)await X.onServerReady(V.app,V.hostServices);return V.rebuildPluginSurfaces?.(),{success:!0,message:`Plugin ${Q} reloaded`,version:X.version}})}catch(Y){return K.status=500,{error:"Failed to reload plugin",details:String(Y)}}},{params:J.Object({name:J.String()})})}import{mkdirSync as o,writeFileSync as v,existsSync as x2}from"fs";import{isAbsolute as D2,join as T,relative as h2,resolve as g}from"path";var h="http://localhost:3005",A2=/^[a-z0-9][a-z0-9-]{0,63}$/,v2=new Set(["backend","frontend","cli","provider","adapter","integration"]);function C2(V,B){let z=h2(V,B);if(z.startsWith("..")||D2(z))throw Error("Plugin scaffold path escapes the selected directory.")}function M(V){return JSON.stringify(V)}function J2(V){let B=V.command("plugin").description("Manage plugins");B.command("list").description("List installed plugins").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON").option("--plain","Force plain text output").action(async(K)=>{try{let Q={...V.opts(),...K},X=U(K),$=encodeURIComponent(E(Q)),x=async()=>{try{return(await n(X,`/api/profiles/${$}/plugins`)).plugins||[]}catch{S("Agent not reachable. Attempting local plugin registry...");let{PluginManager:Z}=await import("./plugin-system-8hfz23sx.js");return new Z().getPluginDetails()||[]}},Y=(Z)=>Z.status??(Z.loaded===!0||Z.enabled===!0?"enabled":"disabled"),W=(Z)=>Z.pluginName||Z.name||Z.packageName||Z.package||"-";await t({mode:l(Q),fetchData:x,plain:(Z)=>{if(!Z.length){_("No plugins installed.");return}k("Installed Plugins"),i(Z.map((H)=>({Name:W(H),Version:H.version||"-",Status:Y(H),Description:H.description||"-"})))},interactive:async(Z)=>{if(!Z.length){k("Installed Plugins"),_("No plugins installed.");return}let H=Z.map((F)=>{let C=W(F),G=Y(F),b=[`${N.bold(C)} ${G==="enabled"?N.green(G):N.dim(G)}`,"",` Version: ${F.version||"-"}`,` Description: ${F.description||"-"}`];if(F.tags&&Array.isArray(F.tags))b.push(` Tags: ${F.tags.join(", ")}`);if(F.cliCommand)b.push(` CLI command: vibe ${F.cliCommand}`);return{id:C,label:C,hint:G,detail:b.join(`
3
+ `)}});await s({title:`vibe plugin \u2014 ${Z.length} installed`,rows:H,footer:"\u2191/\u2193 navigate \xB7 q to quit"})},json:(Z)=>Z.map((H)=>({name:W(H),version:H.version??null,status:Y(H),description:H.description??null,tags:H.tags??null,cliCommand:H.cliCommand??null}))})}catch(Q){q(O(Q))}}),B.command("install").description("Install a plugin").argument("<package>","NPM package name to install").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--skip-prereqs","Skip running the plugin's prereqs/install",!1).option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));try{let Y=await D($,`/api/profiles/${x}/plugins/install`,{packageName:K,skipPrereqs:!!Q.skipPrereqs});if(R(X,{ok:!0,action:"install",package:K,version:Y?.version??null,prereqs:Y?.prereqs??null}))return;if(I(`Plugin "${K}" installed.`),Y?.version)A("Version",Y.version);if(Y?.prereqs){let W=Y.prereqs;if(W.skipped)S(`Prerequisite install skipped. Run \`vibe plugin prereqs ${K} install\` later.`);else if(!W.satisfied)S(`Prerequisites not yet satisfied: ${(W.missing||[]).map((Z)=>Z.name).join(", ")||"(unknown)"}`);if((W.pendingSudo||[]).length>0){S(`${W.pendingSudo.length} command(s) need sudo. Run them and re-check with \`vibe plugin prereqs ${K} status\`:`);for(let Z of W.pendingSudo)A(` ${Z.name}`,Z.command)}}}catch{S("Agent not reachable. Attempting local install...");try{let{PluginManager:Y}=await import("./plugin-system-8hfz23sx.js");if(await new Y().install(K),R(X,{ok:!0,action:"install",package:K,local:!0}))return;I(`Plugin "${K}" installed locally.`)}catch(Y){q(`Could not install plugin via agent or locally: ${O(Y)}`)}}}catch(X){q(O(X))}}),B.command("remove").description("Remove a plugin").argument("<package>","NPM package name to remove").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));try{if(await D($,`/api/profiles/${x}/plugins/remove`,{packageName:K}),R(X,{ok:!0,action:"remove",package:K}))return;I(`Plugin "${K}" removed.`)}catch{S("Agent not reachable. Attempting local removal...");try{let{PluginManager:Y}=await import("./plugin-system-8hfz23sx.js");if(await new Y().remove(K),R(X,{ok:!0,action:"remove",package:K,local:!0}))return;I(`Plugin "${K}" removed locally.`)}catch(Y){q(`Could not remove plugin via agent or locally: ${O(Y)}`)}}}catch(X){q(O(X))}}),B.command("update").description("Update a plugin (or all plugins with --all)").argument("[package]","NPM package name to update").option("--all","Update all installed plugins",!1).option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));if(Q.all){_("Updating all plugins...");try{let Y=await D($,`/api/profiles/${x}/plugins/update-all`,{}),W=Y?.results||[];if(R(X,{ok:!0,action:"update-all",results:W}))return;for(let Z of W)if(Z.success)I(`Updated ${Z.packageName}${Z.version?` to v${Z.version}`:""}`);else S(`Failed to update ${Z.packageName}: ${Z.error}`);I(Y?.message||"Done.")}catch{S("Agent not reachable. Attempting local update...");try{let{PluginManager:Y}=await import("./plugin-system-8hfz23sx.js"),Z=await new Y().updateAll();if(R(X,{ok:!0,action:"update-all",results:Z,local:!0}))return;for(let H of Z)if(H.success)I(`Updated ${H.packageName}${H.version?` to v${H.version}`:""}`);else S(`Failed to update ${H.packageName}: ${H.error}`)}catch(Y){q(`Could not update plugins: ${O(Y)}`)}}}else if(K){_(`Updating ${K}...`);try{let Y=await D($,`/api/profiles/${x}/plugins/update`,{packageName:K});if(R(X,{ok:!0,action:"update",package:K,version:Y?.version??null,message:Y?.message??null}))return;I(Y?.message||`Plugin "${K}" updated.`)}catch{S("Agent not reachable. Attempting local update...");try{let{PluginManager:Y}=await import("./plugin-system-8hfz23sx.js"),Z=await new Y().update(K);if(R(X,{ok:!0,action:"update",package:K,version:Z.version,local:!0}))return;I(`Plugin "${K}" updated to v${Z.version}.`)}catch(Y){q(`Could not update plugin: ${O(Y)}`)}}}else q("Provide a package name to update, or use --all to update all plugins.")}catch(X){q(O(X))}}),B.command("uninstall").description("Uninstall a plugin (or all plugins with --all)").argument("[package]","NPM package name to uninstall").option("--all","Uninstall all external plugins",!1).option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=U(Q),x=encodeURIComponent(E(X));if(Q.all){_("Uninstalling all plugins...");try{let Y=await D($,`/api/profiles/${x}/plugins/remove-all`,{}),W=Y?.results||[];if(R(X,{ok:!0,action:"uninstall-all",results:W}))return;for(let Z of W)if(Z.success)I(`Removed ${Z.packageName}`);else S(`Failed to remove ${Z.packageName}: ${Z.error}`);I(Y?.message||"Done.")}catch{S("Agent not reachable. Attempting local removal...");try{let{PluginManager:Y}=await import("./plugin-system-8hfz23sx.js"),Z=await new Y().removeAll();if(R(X,{ok:!0,action:"uninstall-all",results:Z,local:!0}))return;for(let H of Z)if(H.success)I(`Removed ${H.packageName}`);else S(`Failed to remove ${H.packageName}: ${H.error}`)}catch(Y){q(`Could not uninstall plugins: ${O(Y)}`)}}}else if(K)try{if(await D($,`/api/profiles/${x}/plugins/remove`,{packageName:K}),R(X,{ok:!0,action:"uninstall",package:K}))return;I(`Plugin "${K}" uninstalled.`)}catch{S("Agent not reachable. Attempting local removal...");try{let{PluginManager:Y}=await import("./plugin-system-8hfz23sx.js");if(await new Y().remove(K),R(X,{ok:!0,action:"uninstall",package:K,local:!0}))return;I(`Plugin "${K}" uninstalled locally.`)}catch(Y){q(`Could not uninstall plugin: ${O(Y)}`)}}else q("Provide a package name to uninstall, or use --all to uninstall all plugins.")}catch(X){q(O(X))}}),B.command("reload").description("Reload all plugins").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K)=>{try{let Q={...V.opts(),...K},X=U(K),$=encodeURIComponent(E(Q));if(await D(X,`/api/profiles/${$}/plugins/reload`,{}),R(Q,{ok:!0,action:"reload"}))return;I("Plugins reloaded.")}catch(Q){q(O(Q))}}),B.command("available").description("Show available plugins").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON").option("--plain","Force plain text output").action(async(K)=>{try{let Q={...V.opts(),...K},X=U(K),$=encodeURIComponent(E(Q)),x=async()=>{return(await n(X,`/api/profiles/${$}/plugins/available`)).plugins||[]},Y=(Z)=>Z.name||Z.package||"-",W=(Z)=>Z.version||Z.latestVersion||"-";await t({mode:l(Q),fetchData:x,plain:(Z)=>{if(!Z||Z.length===0){_("No available plugins found.");return}k("Available Plugins"),i(Z.map((H)=>({Name:Y(H),Version:W(H),Description:H.description||"-"})))},interactive:async(Z)=>{if(!Z||Z.length===0){k("Available Plugins"),_("No available plugins found.");return}let H=Z.map((F)=>{let C=Y(F),G=[N.bold(C),"",` Version: ${W(F)}`,` Description: ${F.description||"-"}`];return{id:C,label:C,hint:W(F),detail:G.join(`
4
4
  `)}});await s({title:`vibe plugin available \u2014 ${Z.length} plugin(s)`,rows:H,footer:"\u2191/\u2193 navigate \xB7 q to quit"})},json:(Z)=>Z.map((H)=>({name:Y(H),version:W(H),description:H.description??null}))})}catch(Q){q(O(Q))}});let z=B.command("prereqs").description("Inspect or run a plugin's prerequisite-install protocol").argument("<package>","NPM package name (or short plugin name)");z.command("status",{isDefault:!0}).description("Show the plugin's prereq status").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON").option("--plain","Force plain text output").action(async(K,Q)=>{let X=Q.parent?.args?.[0];if(!X){q("Missing plugin package argument.");return}try{let $={...V.opts(),...K},x=U(K),Y=async()=>D(x,"/api/plugins/prereqs/status",{packageName:X});await t({mode:l($),fetchData:Y,plain:(W)=>{if(A("Plugin",X),A("Satisfied",W?.satisfied?"yes":"no"),Array.isArray(W?.missing)&&W.missing.length>0)A("Missing",W.missing.map((Z)=>Z.name).join(", "))},interactive:async(W)=>{let Z=[`Plugin: ${X}`,`Satisfied: ${W?.satisfied?"yes":"no"}`];if(Array.isArray(W?.missing)&&W.missing.length>0)Z.push(`Missing: ${W.missing.map((H)=>H.name).join(", ")}`);await G2({title:`Prereqs: ${X}`,body:Z.join(`
5
5
  `),footer:"q / Esc to quit"})},json:(W)=>({plugin:X,satisfied:!!W?.satisfied,missing:Array.isArray(W?.missing)?W.missing:[],pendingSudo:Array.isArray(W?.pendingSudo)?W.pendingSudo:[]})})}catch($){q(`Could not read prereq status: ${O($)}`)}}),z.command("install").description("Run the plugin's prerequisite install endpoint").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--approve-sudo","Auto-approve sudo commands the plugin returns",!1).option("--json","Emit JSON result").action(async(K,Q)=>{let X=Q.parent?.args?.[0];if(!X){q("Missing plugin package argument.");return}try{let $={...V.opts(),...K},x=U(K),Y=await D(x,"/api/plugins/prereqs/install",{packageName:X,approveSudo:!!K.approveSudo});if(R($,{ok:!0,action:"prereqs-install",plugin:X,satisfied:!!Y?.satisfied,pendingSudo:Y?.pendingSudo??[]}))return;if(Y?.satisfied)I(`Prerequisites satisfied for ${X}.`);else S(`Prerequisites still missing for ${X}.`);if(Array.isArray(Y?.pendingSudo)&&Y.pendingSudo.length>0){S(`${Y.pendingSudo.length} command(s) require sudo:`);for(let W of Y.pendingSudo)A(` ${W.name}`,W.command)}}catch($){q(`Prereq install failed: ${O($)}`)}}),z.command("uninstall").description("Run the plugin's prerequisite uninstall endpoint (if supported)").option("--agent-url <url>","Agent URL",h).option("--profile <name>","Target a specific profile by name").option("--json","Emit JSON result").action(async(K,Q)=>{let X=Q.parent?.args?.[0];if(!X){q("Missing plugin package argument.");return}try{let $={...V.opts(),...K},x=U(K);if(await D(x,"/api/plugins/prereqs/uninstall",{packageName:X}),R($,{ok:!0,action:"prereqs-uninstall",plugin:X}))return;I(`Prereq uninstall completed for ${X}.`)}catch($){S(`Prereq uninstall not supported or failed: ${O($)}`)}}),B.command("create").description("Scaffold a new plugin project").argument("<name>",'Plugin name (e.g. "docker" \u2192 vibe-plugin-docker)').option("-d, --dir <directory>","Parent directory",".").option("--tag <tag>","Plugin tag (backend, frontend, cli, provider, adapter, integration)","backend").option("--with-ui","Include a companion UI plugin scaffold",!1).option("--json","Emit JSON result").action(async(K,Q)=>{try{let X={...V.opts(),...Q},$=K.startsWith("vibe-plugin-")?K.slice(12):K;if(!A2.test($)){q("Plugin name must use lowercase letters, numbers, and dashes only.");return}let x=Q.tag;if(!v2.has(x)){q("Invalid plugin tag.");return}let Y=`vibe-plugin-${$}`,W=g(Q.dir),Z=g(W,Y);if(C2(W,Z),x2(Z)){q(`Directory "${Z}" already exists.`);return}_(`Scaffolding ${Y}...`),o(T(Z,"src"),{recursive:!0}),o(T(Z,"dist"),{recursive:!0});let H=`VibeControls plugin: ${$}`,F={name:`@vibecontrols/${Y}`,version:"0.1.0",main:"./dist/index.js",type:"module",engines:{bun:">=1.3.0"},scripts:{build:"bun build ./src/index.ts --outdir ./dist --target bun",lint:"eslint ./src",format:"bunx prettier . --write","format:check":"bunx prettier . --check","type:check":"tsc --noEmit",clean:"rimraf dist",prebuild:"bun run clean",prepublishOnly:"bun run build",sanity:"bun run format:check && bun run lint && bun run type:check && bun run build"},keywords:["vibecontrols","vibe","vibe-plugin",$,"bun"],author:{name:"Your Name",email:"you@example.com"},license:"SEE LICENSE IN LICENSE",description:H,devDependencies:{"@types/bun":"^1.2.16","bun-types":"^1.3.9",commander:"^14.0.3",eslint:"^9.30.1",prettier:"^3.6.2",rimraf:"^6.0.1",typescript:"^5.8.3","typescript-eslint":"^8.56.0"},peerDependencies:{"@vibecontrols/agent":">=2.0.0"},peerDependenciesMeta:{"@vibecontrols/agent":{optional:!0}},publishConfig:{access:"public",registry:"https://registry.npmjs.org/"},files:["dist/**/*","README.md","LICENSE"]};v(T(Z,"package.json"),JSON.stringify(F,null,2)+`
6
6
  `);let C={compilerOptions:{target:"ES2022",module:"ES2022",moduleResolution:"bundler",types:["bun-types"],strict:!0,esModuleInterop:!0,skipLibCheck:!0,outDir:"./dist",rootDir:"./src",declaration:!0,sourceMap:!0},include:["src/**/*.ts"],exclude:["node_modules","dist"]};v(T(Z,"tsconfig.json"),JSON.stringify(C,null,2)+`
@@ -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-kmkhjf1c.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(`
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
- import{j as o,k as r,l as t,m as e,n as XQ}from"./index-qzwphe3q.js";import"./index-5wpck4aw.js";import{t as QQ}from"./index-rv6h14n8.js";import"./index-ytgmhxsj.js";import"./index-6jzsthh9.js";import"./index-1zf3r23y.js";import"./index-rw9x93zb.js";import"./index-nmk7cbj5.js";import"./index-a9ejdv22.js";import"./index-4wgjx8bf.js";import{Da as a}from"./index-s2xpdnsj.js";import"./index-0ckffygp.js";import"./index-rc79x8fw.js";import{bb as W}from"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-hvjqgb97.js";import{Ib as s,Jb as i}from"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-b6x6a4xp.js";import{Sc as p,Tc as v,od as C,ud as l,vd as n}from"./index-h74va4wd.js";import{Od as q}from"./index-js1xn4sq.js";import{$d as S,Yd as D,be as g,ce as M}from"./index-a4854mwz.js";import"./index-4qq083yd.js";import{ie as B}from"./index-c7554sg7.js";import{isAbsolute as MQ}from"path";import{existsSync as V,mkdirSync as y,readFileSync as _Q,readdirSync as P,renameSync as BQ,unlinkSync as DQ,writeFileSync as f}from"fs";import{dirname as d,join as F}from"path";var GQ=".secrets-migrated-v1",IQ=["static-api-key","clientId","clientSecret"];function WQ(Q,H){return`${Q}:${H}`}function c(){return F(M(),GQ)}function TQ(){let Q=c();y(d(Q),{recursive:!0}),f(Q,`${new Date().toISOString()}
3
+ import{j as o,k as r,l as t,m as e,n as XQ}from"./index-hwtd3ank.js";import"./index-5wpck4aw.js";import{t as QQ}from"./index-rv6h14n8.js";import"./index-btt96dhd.js";import"./index-6jzsthh9.js";import"./index-cjbfremy.js";import"./index-rw9x93zb.js";import"./index-pk3ejfc4.js";import"./index-dxtnaa3g.js";import"./index-4wgjx8bf.js";import{Da as a}from"./index-kmkhjf1c.js";import"./index-0ckffygp.js";import"./index-rc79x8fw.js";import{bb as W}from"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-hvjqgb97.js";import{Ib as s,Jb as i}from"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-b6x6a4xp.js";import{Sc as p,Tc as v,od as C,ud as l,vd as n}from"./index-h74va4wd.js";import{Od as q}from"./index-js1xn4sq.js";import{$d as S,Yd as D,be as g,ce as M}from"./index-a4854mwz.js";import"./index-4qq083yd.js";import{ie as B}from"./index-c7554sg7.js";import{isAbsolute as MQ}from"path";import{existsSync as V,mkdirSync as y,readFileSync as _Q,readdirSync as P,renameSync as BQ,unlinkSync as DQ,writeFileSync as f}from"fs";import{dirname as d,join as F}from"path";var GQ=".secrets-migrated-v1",IQ=["static-api-key","clientId","clientSecret"];function WQ(Q,H){return`${Q}:${H}`}function c(){return F(M(),GQ)}function TQ(){let Q=c();y(d(Q),{recursive:!0}),f(Q,`${new Date().toISOString()}
4
4
  `,{mode:384})}function JQ(Q){if(!V(Q))return null;try{let H=_Q(Q,"utf8"),X=JSON.parse(H);if(X&&typeof X==="object"&&!Array.isArray(X))return X}catch{}return null}function VQ(Q,H){y(d(Q),{recursive:!0});let X=`${Q}.${process.pid}.tmp`;f(X,`${JSON.stringify(H,null,2)}
5
5
  `,{mode:384}),BQ(X,Q)}function FQ(){let Q=M(),H=F(Q,"agents");if(!V(H))return[];let X=[],L;try{L=P(H)}catch{return[]}for(let Y of L){let z=F(H,Y,"config.json");if(!V(z))continue;X.push({path:z,scope:Y})}return X}function jQ(){let Q=M(),H=F(Q,"profiles");if(!V(H))return[];let X=[],L;try{L=P(H)}catch{return[]}for(let Y of L){if(!Y.endsWith(".json"))continue;X.push({path:F(H,Y),scope:Y.slice(0,-5)})}return X}async function KQ(Q,H){let X=JQ(Q);if(!X)return 0;let L=0;for(let Y of IQ){let z=X[Y];if(typeof z!=="string"||z.length===0)continue;let _=WQ(H,Y);try{await v(_,z),delete X[Y],L++,q().logger.info("secrets-migrator","migrated field",{path:Q,scope:H,key:Y})}catch(G){q().logger.warn("secrets-migrator","failed to migrate field",{path:Q,scope:H,key:Y,error:String(G)})}}if(L>0)VQ(Q,X);return L}async function m(){let Q={alreadyMigrated:!1,fieldsMoved:0,filesUpdated:0};if(V(c()))return Q.alreadyMigrated=!0,Q;let H=[...FQ(),...jQ()];for(let X of H){let L;try{L=await KQ(X.path,X.scope)}catch(Y){q().logger.warn("secrets-migrator","skipping target after error",{path:X.path,error:String(Y)});continue}if(L>0)Q.fieldsMoved+=L,Q.filesUpdated++}try{TQ()}catch(X){q().logger.warn("secrets-migrator","failed to drop migration marker",{error:String(X)})}if(Q.fieldsMoved>0)q().logger.info("secrets-migrator","migration complete",{fieldsMoved:Q.fieldsMoved,filesUpdated:Q.filesUpdated});return Q}{let Q=JSON.parse.bind(JSON);JSON.parse=(L,Y)=>{try{return Q(L,Y)}catch(z){if(typeof L==="string"&&L.endsWith("}}"))try{return Q(L.slice(0,-1),Y)}catch{}throw z}};let X=globalThis.Request?.prototype;if(X&&typeof X.json==="function"){let L=X.json;X.json=async function(){let z=await this.text();if(!z)return;try{return Q(z)}catch{if(z.endsWith("}}"))try{return Q(z.slice(0,-1))}catch{}let _=new Request("http://shim/",{method:"POST",body:z});return L.call(_)}}}}QQ();l();if(!process.env.VIBECONTROLS_DATA_DIR)process.env.VIBECONTROLS_DATA_DIR=S();if(typeof Bun>"u")console.error("ERROR: VibeControls Agent requires Bun runtime."),console.error("Install Bun: https://bun.sh"),process.exit(1);function UQ(Q){if(Q==="default")return 3005;let H=2166136261;for(let X=0;X<Q.length;X++)H=Math.imul(H^Q.charCodeAt(X),16777619);return 3100+Math.abs(H)%300}var E=(()=>{try{return D()}catch{return"default"}})(),A=Number.parseInt(process.env.PORT||String(UQ(E)),10),U=Number.isInteger(A)&&A>0?A:3005,R=process.env.HOST||"0.0.0.0",RQ=(()=>{let Q=process.env.DB_PATH;if(!Q)return;if(MQ(Q))return Q;console.warn(`[boot] Ignoring relative DB_PATH=${Q} (cwd=${process.cwd()}). Use an absolute path or unset to fall back to ${g()}.`);return})(),x=process.env.AGENT_API_KEY||void 0,CQ=process.env.LOG_LEVEL||"info",EQ=process.env.CORS_ORIGIN||void 0;async function wQ(){try{await m()}catch($){q().logger.warn("server","secrets migration encountered an error",{error:String($)})}let Q=C()["static-api-key"],H=(()=>{try{return D()}catch{return"default"}})(),X=Q??await p(`${H}:static-api-key`),L=!x&&!X;await s(),await n();let Y=process.env.VIBE_CLIENT_ID,z=process.env.VIBE_CLIENT_SECRET,_=process.env.VIBE_GLOBAL_GATEWAY_URL,G=process.env.VIBE_WORKSPACE_GATEWAY_URL,b=process.env.VIBE_WORKSPACE_ID,ZQ=!!Y&&!!z&&!!_&&!!G&&!!b;q().logger.info("server","Starting VibeControls Agent...",{runtime:"bun",bunVersion:Bun.version,port:U,host:R,env:"production"});try{let $=C(),Z=$["telemetry.enabled"]===!0||$["telemetry.enabled"]==="true";W.init({persisted:Z});let N=Date.now();W.emit("agent.started",{version:process.env.npm_package_version??"unknown",profile:E,platform:process.platform}),process.__vibe_started_at=N}catch{}let j=Math.max(1,Number.parseInt(process.env.VIBECONTROLS_AGENT_BOOT_RETRIES??"10",10)||10),$Q=($)=>{let Z=String($?.message??$).toLowerCase();return Z.includes("syntax")||Z.includes("cannot find module")||Z.includes("module not found")||Z.includes("typeerror")||Z.includes("config schema")||Z.includes("invalid config")||Z.includes("corrupt")||Z.includes("eaccess")||Z.includes("eperm")},O=null,I=0;while(!O){I++;try{O=await XQ({port:U,host:R,dbPath:RQ,apiKey:x,logLevel:CQ,corsOrigin:EQ}),await O.start();try{let $=await import("fs"),Z=`${S()}/runtime.json`;$.writeFileSync(Z,JSON.stringify({pid:process.pid,port:U,host:R,profile:E,startedAt:new Date().toISOString(),version:a()},null,2));let N=()=>{try{if($.existsSync(Z))$.unlinkSync(Z)}catch{}};process.once("SIGTERM",N),process.once("SIGINT",N),process.once("exit",N)}catch($){q().logger.warn("server","Could not write runtime.json",{error:String($)})}}catch($){let Z=$Q($);if(q().logger.error("server","Failed to start agent server",{attempt:I,maxBootAttempts:j,fatal:Z,error:String($)}),Z||I>=j)console.error(`\u274C Failed to start VibeControls Agent (attempt ${I}/${j}, fatal=${Z}):`,$),process.exit(1);let N=Math.min(30000,1000*2**Math.min(5,I-1)),J=Math.floor(Math.random()*500),K=N+J;console.warn(`\u26A0\uFE0F Agent boot attempt ${I}/${j} failed (transient), retrying in ${Math.round(K/1000)}s...`),await new Promise((k)=>setTimeout(k,K)),O=null}}let h=O.getServiceRegistry().getProvider("tunnel"),T=null;if(h?.getActiveTunnelUrl)for(let $=0;$<30;$++){if(T=await h.getActiveTunnelUrl(),T)break;await new Promise((Z)=>setTimeout(Z,1000))}if(!T){let{sanitizeEnvSuffix:$}=await import("./tunnel-bootstrap-5wgt9a1h.js"),{getVibecontrolsProfile:Z}=await import("./path-utils-hxdyv2zn.js"),N=$(Z());T=process.env[`AGENT_TUNNEL_URL_${N}`]??process.env.AGENT_TUNNEL_URL??null}let HQ=C(),LQ=x||i()||HQ["static-api-key"]||"",w=q().getBootState(),YQ=w==="ready"?null:o();if(w==="ready")r();kQ({port:U,host:R,tunnelUrl:T,apiKey:LQ,revealApiKey:L||process.env.AGENT_PRINT_API_KEY==="1",state:w,pairingToken:YQ});try{t({profile:E})}catch($){q().logger.warn("server","Could not start autoupdate",{error:String($)})}let{existsSync:NQ,unlinkSync:qQ}=await import("fs"),{tmpdir:zQ}=await import("os"),{join:OQ}=await import("path"),u=async($)=>{q().logger.info("server",`Received ${$}, shutting down...`),e();try{let N=process.__vibe_started_at??Date.now();W.emit("agent.stopped",{uptime_s:Math.round((Date.now()-N)/1000),reason:$}),await W.flush(),W.stop()}catch{}let Z=O.getLifecycle();if($==="SIGTERM"){let N=OQ(zQ(),`.boff-vibecontrols-kill-${process.pid}`);if(NQ(N)){try{qQ(N)}catch{}if(q().logger.info("server","Kill-intent flag detected \u2014 full shutdown"),Z)await Z.kill();else await O.stop({reason:"shutdown"}),process.exit(0)}else if(q().logger.info("server","No kill flag \u2014 treating as hot-reload (soft stop)"),Z)await Z.softStop();else await O.stop({reason:"reload"})}else if(Z)await Z.kill();else await O.stop({reason:"shutdown"}),process.exit(0)};if(process.on("SIGINT",()=>u("SIGINT")),process.on("SIGTERM",()=>u("SIGTERM")),ZQ){let $=(()=>{let Z=process.env.VIBECONTROLS_FINALIZE_TIMEOUT_MS,N=Z?Number.parseInt(Z,10):NaN;return Number.isFinite(N)&&N>0?N:300000})();q().logger.info("server",`VIBE_* env vars detected \u2014 running inline finalize (timeout ${Math.round($/1000)}s)`),(async()=>{let Z={clientId:Y,clientSecret:z,workspaceId:b,globalGatewayUrl:_,workspaceGatewayUrl:G};try{let N=await Promise.race([O.finalize(Z),new Promise((J)=>setTimeout(()=>J({ok:!1,error:`inline finalize timed out after ${Math.round($/1000)}s`}),$))]);if(!N.ok){q().logger.warn("server","Inline finalize failed \u2014 agent stays awaiting-config. Background retry worker will keep trying.",{error:N.error});let{startFinalizeRetryWorker:J}=await import("./finalize-retry-worker-dvykrzed.js"),{setFinalizeRetryHandle:K}=await import("./finalize-retry-handle-registry-xnm9kxry.js"),k=J({trigger:()=>O.finalize(Z)});K(k)}}catch(N){q().logger.error("server","Inline finalize threw",{error:String(N)})}})()}else q().logger.info("server","Agent is awaiting gateway credentials. Add it on the VibeControls platform using the tunnel URL and API key shown above.")}function kQ(Q){let X=(G)=>("\u2551 "+G).padEnd(65)+"\u2551",L="\u2560"+"\u2550".repeat(64)+"\u2563",Y="\u2554"+"\u2550".repeat(64)+"\u2557",z="\u255A"+"\u2550".repeat(64)+"\u255D",_=Q.revealApiKey?Q.apiKey:Q.apiKey?`${Q.apiKey.substring(0,8)}****${Q.apiKey.substring(Q.apiKey.length-4)}`:"(none)";if(console.log(""),console.log(Y),console.log(X("VibeControls Agent")),console.log(L),console.log(X(`State: ${Q.state}`)),console.log(X(`Agent URL: http://${Q.host}:${Q.port}`)),console.log(X(`API Key: ${_}`)),console.log(X(`Tunnel URL: ${Q.tunnelUrl??"(none)"}`)),Q.pairingToken)console.log(X(`Pairing: ${Q.pairingToken}`)),console.log(X(" (send as x-pairing-token on bootstrap)"));if(console.log(L),console.log(X(`Health: http://localhost:${Q.port}/health`)),console.log(X(`Status: http://localhost:${Q.port}/api/agent/status`)),console.log(z),!Q.revealApiKey)console.log(" (Set AGENT_PRINT_API_KEY=1 to print the API key in full.)");console.log("")}wQ();
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{Ga as a,Ia as b,Qa as c,Ra as d,Sa as e,Ta as f,Ua as g,Va as h,Wa as i}from"./index-s2xpdnsj.js";import"./index-0ckffygp.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{f as validatePluginPackageName,c as getRegistryAllowlist,e as getPluginPackageRoot,g as getInstallScope,d as assertRegistryAllowed,b as TRUSTED_PACKAGES,i as PluginManager,h as DEFAULT_PLUGINS,a as CORE_PLUGIN_NAMES};
2
+ import{Ga as a,Ia as b,Qa as c,Ra as d,Sa as e,Ta as f,Ua as g,Va as h,Wa as i}from"./index-kmkhjf1c.js";import"./index-0ckffygp.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{f as validatePluginPackageName,c as getRegistryAllowlist,e as getPluginPackageRoot,g as getInstallScope,d as assertRegistryAllowed,b as TRUSTED_PACKAGES,i as PluginManager,h as DEFAULT_PLUGINS,a as CORE_PLUGIN_NAMES};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{J as a}from"./index-aq81xmn0.js";import"./index-d1xjj001.js";import"./index-b5dhmybd.js";import"./index-e1bw1bwr.js";import"./index-1zf3r23y.js";import"./index-rw9x93zb.js";import"./index-nmk7cbj5.js";import"./index-4wgjx8bf.js";import"./index-s2xpdnsj.js";import"./index-0ckffygp.js";import"./index-rc79x8fw.js";import"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-8nqp3a4d.js";import"./index-1mppacnx.js";import"./index-thammzct.js";import"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{a as registerCoreCommands};
2
+ import{J as a}from"./index-9430ndf7.js";import"./index-d1xjj001.js";import"./index-b5dhmybd.js";import"./index-e1bw1bwr.js";import"./index-cjbfremy.js";import"./index-rw9x93zb.js";import"./index-pk3ejfc4.js";import"./index-4wgjx8bf.js";import"./index-kmkhjf1c.js";import"./index-0ckffygp.js";import"./index-rc79x8fw.js";import"./index-ydc0tk17.js";import"./index-52cp759f.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-8nqp3a4d.js";import"./index-1mppacnx.js";import"./index-thammzct.js";import"./index-b6x6a4xp.js";import"./index-h74va4wd.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{a as registerCoreCommands};
@@ -1,2 +1,2 @@
1
1
  // @bun
2
- import{x as a}from"./index-ytgmhxsj.js";import"./index-a9ejdv22.js";import"./index-4wgjx8bf.js";import"./index-s2xpdnsj.js";import"./index-0ckffygp.js";import"./index-hvjqgb97.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-h74va4wd.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{a as attachSecondaryProfile};
2
+ import{x as a}from"./index-btt96dhd.js";import"./index-dxtnaa3g.js";import"./index-4wgjx8bf.js";import"./index-kmkhjf1c.js";import"./index-0ckffygp.js";import"./index-hvjqgb97.js";import"./index-rqq0k5fc.js";import"./index-5dysvvjv.js";import"./index-pgew6sge.js";import"./index-h74va4wd.js";import"./index-js1xn4sq.js";import"./index-a4854mwz.js";import"./index-4qq083yd.js";import"./index-c7554sg7.js";export{a as attachSecondaryProfile};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibecontrols/agent",
3
- "version": "2026.602.4",
3
+ "version": "2026.602.5",
4
4
  "main": "./dist/index.js",
5
5
  "type": "module",
6
6
  "bin": {