@agensis/agensis-agent 0.1.30 → 0.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/bin/agensis.mjs +52 -40
  2. package/package.json +1 -1
package/bin/agensis.mjs CHANGED
@@ -1,25 +1,8 @@
1
1
  #!/usr/bin/env node
2
- var hn=Object.defineProperty;var gn=(e,t)=>()=>(e&&(t=e(e=0)),t);var yn=(e,t)=>{for(var n in t)hn(e,n,{get:t[n],enumerable:!0})};var nt={};yn(nt,{createE2bProvider:()=>Tn});function Ae(e){return`'${String(e).replace(/'/g,"'\\''")}'`}function Tn({apiKey:e,anthropicApiKey:t,gitToken:n="",repoUrl:r="",template:s=""}={}){if(!e)throw new Error("E2B_API_KEY is not set on the daemon host.");if(!r)throw new Error("Sandbox needs a repo URL (set sandbox_config.repoUrl or the agent's repo).");return{async ensureEnv(){let o={apiKey:e,envs:t?{ANTHROPIC_API_KEY:t}:{}},i;try{({Sandbox:i}=await import("e2b"))}catch(u){if(u&&(u.code==="ERR_MODULE_NOT_FOUND"||u.code==="MODULE_NOT_FOUND"||/Cannot find package 'e2b'/.test(String(u&&u.message)))){let a=Number(String(process.versions.node).split(".")[0])||0,l=a<20||a===21?` Sandbox mode needs Node >=20.18.1 (<21 or >=22); you have ${process.versions.node}. Upgrade Node, then run \`npm i e2b\` in the daemon.`:" Run `npm i e2b` in the daemon to enable Sandbox mode.";throw new Error(`Sandbox execution requires the optional 'e2b' package, which is not installed.${l}`)}throw u}let c=s?await i.create(s,o):await i.create(o);return await c.commands.run("bash -lc 'command -v claude >/dev/null || npm i -g @anthropic-ai/claude-code'"),{sbx:c,dir:Nn}},async putRepo(o){let i=n?r.replace(/^https:\/\//,`https://x-access-token:${n}@`):r;try{let c=await o.sbx.commands.run(`git clone ${Ae(i)} ${Ae(o.dir)}`);if(c&&typeof c.exitCode=="number"&&c.exitCode!==0)throw new Error(`git clone failed: ${c.stderr||`exit ${c.exitCode}`}`)}catch(c){if(c&&String(c.message||"").startsWith("git clone failed:"))throw c;let u=c&&(c.stderr||c.exitCode!=null)?c.stderr||`exit ${c.exitCode}`:String(c?.message||c);throw new Error(`git clone failed: ${u}`)}},async exec(o,{cmd:i,args:c=[],env:u={},onData:a}){let l=`${i} ${c.map(Ae).join(" ")}`,h={cwd:o.dir,envs:{...u,IS_SANDBOX:"1",AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS:"1"},onStdout:E=>{try{a?.(E)}catch{}}};try{let E=await o.sbx.commands.run(l,h);return{status:E.exitCode,stdout:E.stdout||"",stderr:E.stderr||"",error:null}}catch(E){return E&&typeof E.exitCode=="number"?{status:E.exitCode,stdout:E.stdout||"",stderr:E.stderr||"",error:null}:{status:null,stdout:"",stderr:String(E?.message||E),error:E}}},async getResult(o){try{return{patch:(await o.sbx.commands.run("git add -A && git diff --cached",{cwd:o.dir})).stdout||""}}catch(i){return{patch:i&&i.stdout||""}}},async destroy(o){await o.sbx.kill()}}}var Nn,rt=gn(()=>{Nn="/home/user/repo"});import Y from"node:process";import le from"node:fs";import de from"node:path";import me from"node:os";import Cr from"node:crypto";import A from"node:process";import ue from"ws";import{spawn as Sn}from"node:child_process";function qe(e){let t=Math.max(0,Math.round(e/1e3)),n=Math.floor(t/60),r=t%60;return n>0?`${n}m ${r}s`:`${r}s`}var wn=50*1024*1024;function ie(e){let{cmd:t,args:n=[],env:r={},cwd:s,timeoutMs:o=0,label:i="working",heartbeatMs:c=15e3,input:u="",now:a=Date.now,log:l=console,signal:h,onData:E}=e||{};return new Promise(w=>{if(h?.aborted){w({status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")});return}let g;try{let p=n.some(x=>x==="--dangerously-skip-permissions"),k=typeof process.getuid=="function"&&process.getuid()===0,D={...process.env,...r};delete D.AGENSIS_TOKEN,delete D.ANTHROPIC_API_KEY,delete D.ANTHROPIC_AUTH_TOKEN,p&&k&&(D.IS_SANDBOX="1"),g=Sn(t,n,{cwd:s,detached:!0,env:D})}catch(p){w({status:null,stdout:"",stderr:"",error:p});return}u?g.stdin?.end(String(u)):g.stdin?.end();let v="",S="";g.stdout?.setEncoding("utf8"),g.stderr?.setEncoding("utf8");let f=(p,k)=>p.length>=wn?p:p+k;g.stdout?.on("data",p=>{if(v=f(v,p),E)try{E(p)}catch{}}),g.stderr?.on("data",p=>S=f(S,p));let _=a(),I=c>0?setInterval(()=>{l.log(` \u2026 still ${i} (${qe(a()-_)}) \u2014 Ctrl+C to cancel`)},c):null;I?.unref&&I.unref();let C=p=>{if(g.pid!=null)try{process.kill(-g.pid,p)}catch{try{g.kill(p)}catch{}}},T=!1,P=o>0?setTimeout(()=>{T=!0,C("SIGKILL")},o):null;P?.unref&&P.unref();let m=!1,y=null,M=()=>{m=!0,C("SIGTERM"),y=setTimeout(()=>C("SIGKILL"),3e3),y?.unref&&y.unref()};h&&h.addEventListener("abort",M,{once:!0});let d=(p,k)=>{I&&clearInterval(I),P&&clearTimeout(P),y&&clearTimeout(y),h&&h.removeEventListener("abort",M),w({status:p,stdout:v,stderr:S,aborted:m,error:k||(m?new Error("cancelled"):T?new Error(`timed out after ${qe(o)}`):null)})};g.on("error",p=>d(null,p)),g.on("close",p=>d(p,null))})}import{spawn as bn}from"node:child_process";var Xe=10*60*1e3;function Ve(e={}){let t={...process.env,...e};return delete t.AGENSIS_TOKEN,delete t.ANTHROPIC_API_KEY,delete t.ANTHROPIC_AUTH_TOKEN,t}var ke=class{#e=[];#t=[];#n=!1;push(t){if(this.#n)return;let n=this.#t.shift();n?n({value:t,done:!1}):this.#e.push(t)}close(){this.#n=!0;for(let t of this.#t.splice(0))t({value:void 0,done:!0})}[Symbol.asyncIterator](){return{next:()=>this.#e.length?Promise.resolve({value:this.#e.shift(),done:!1}):this.#n?Promise.resolve({value:void 0,done:!0}):new Promise(t=>this.#t.push(t))}}};function Qe(){let e=new Map;return(t,n)=>{let r=(e.get(t)||Promise.resolve()).then(n,n);return e.set(t,r.catch(()=>{})),r}}var _n=["mcp__agensis"];function vn(e){return e==="yolo"?{permissionMode:"bypassPermissions",allowDangerouslySkipPermissions:!0}:e==="accept_edits"?{permissionMode:"acceptEdits"}:{permissionMode:"default"}}function En(e){if(!e||e.type!=="content_block_delta")return"";let t=e.delta;return t&&t.type==="text_delta"&&typeof t.text=="string"?t.text:""}function kn(e){return`${JSON.stringify({type:"stream_event",event:{type:"content_block_delta",delta:{type:"text_delta",text:e}}})}
3
- `}function In(e){return`${JSON.stringify({type:"result",result:e})}
4
- `}function An(e){return`${JSON.stringify({type:"agensis_step",step:e})}
5
- `}function Cn(e){return`${JSON.stringify({type:"agensis_segment",segment:e})}
6
- `}var xn=["file_path","path","pattern","command","description","prompt"],Ye=120;function Ie(e){if(!e||typeof e!="object")return"";for(let t of xn){let n=e[t];if(typeof n!="string")continue;let r=n.replace(/\s+/g," ").trim();if(r)return r.length>Ye?`${r.slice(0,Ye)}\u2026`:r}return""}function Ze(e){return JSON.stringify({cwd:e.cwd||"",model:e.model||"",permissionMode:e.permissionMode||"default",hostFolders:[...e.hostFolders||[]].sort(),leanCli:!!e.leanCli,mcpUrl:e.mcp?.url||"",mcpToken:e.mcp?.env?.AGENSIS_MCP_TOKEN||""})}function et({queryFn:e,idleCloseMs:t=Xe}={}){let n=new Map,r=Qe(),s=(u,a,l)=>{let h=n.get(u);if(!(!h||a&&h!==a))if(n.delete(u),clearTimeout(h.idleTimer),h.closed=!0,h.queue.close(),l&&h.activeTurn&&h.activeTurn.finish(l),typeof h.query.close=="function")try{h.query.close()}catch{}else Promise.resolve(h.query.return?.()).catch(()=>{})},o=u=>{let a=n.get(u);a&&(clearTimeout(a.idleTimer),a.idleTimer=setTimeout(()=>s(u),t),a.idleTimer.unref?.())},i=async(u,a)=>{let l=n.get(u),h=Ze(a);if(l&&l.fingerprint===h&&!l.closed)return l;l&&s(u,l),e||(e=(await import("@anthropic-ai/claude-agent-sdk")).query);let E=new ke,w=vn(a.permissionMode),g=a.leanCli&&a.mcp?{agensis:{type:"http",url:a.mcp.url,headers:{Authorization:"Bearer ${AGENSIS_MCP_TOKEN}"}}}:void 0,v=e({prompt:E,options:{cwd:a.cwd,model:a.model,...w,allowedTools:_n,additionalDirectories:a.hostFolders&&a.hostFolders.length?a.hostFolders:void 0,mcpServers:g,strictMcpConfig:a.leanCli?!0:void 0,settingSources:a.leanCli?[]:void 0,persistSession:a.leanCli?!1:void 0,includePartialMessages:!0,env:Ve(a.mcp?.env)}});return l={query:v,queue:E,sessionId:"",idleTimer:null,activeTurn:null,closed:!1,terminalError:null,fingerprint:h},n.set(u,l),l.pump=(async()=>{let S=null;try{for await(let f of v){f.session_id&&(l.sessionId=f.session_id);let _=l.activeTurn;if(_){if(f.type==="stream_event"){let I=En(f.event);I&&(_.streamed+=I,_.onData?.(kn(I)))}else if(f.type==="result")if(f.subtype==="success"){let I=f.result==null?_.text:String(f.result);_.onData?.(In(I)),_.finish({status:0,stdout:I,stderr:"",error:null})}else{let I=Array.isArray(f.errors)?f.errors.filter(Boolean).join(`
7
- `):f.result,C=new Error(I||`claude-agent-sdk result error: ${f.subtype}`);_.finish({status:1,stdout:_.text,stderr:C.message,error:C})}else if(f.type==="assistant"){let I=f.message?.content;if(Array.isArray(I)){let C=I.filter(T=>T&&T.type==="text"&&typeof T.text=="string").map(T=>T.text).join("");C&&(_.onData?.(Cn({text:C})),_.flushed+=_.streamed,_.streamed="");for(let T of I)!T||T.type!=="tool_use"||!T.name||_.onData?.(An({kind:"tool",name:String(T.name),detail:Ie(T.input)}))}}}}S=new Error("claude-agent-sdk connection closed")}catch(f){S=f}finally{l.closed=!0,l.terminalError=S,clearTimeout(l.idleTimer),l.queue.close(),n.get(u)===l&&n.delete(u),l.activeTurn&&l.activeTurn.finish({status:null,stdout:l.activeTurn.text,stderr:String(S?.message||S||""),error:S})}})(),l};return{run:u=>r(u.sessionKey||"default",async()=>{let{sessionKey:a="default",prompt:l,signal:h,onData:E,timeoutMs:w=0}=u;if(h?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let g;try{g=await i(a,u)}catch(S){return{status:null,stdout:"",stderr:"",error:S}}if(g.closed){let S=g.terminalError||new Error("claude-agent-sdk connection closed");return{status:null,stdout:"",stderr:String(S.message||S),error:S}}clearTimeout(g.idleTimer);let v=await new Promise(S=>{let f=!1,_=null,I={streamed:"",flushed:"",get text(){return this.flushed+this.streamed},onData:E,finish(T){f||(f=!0,g.activeTurn===I&&(g.activeTurn=null),h&&h.removeEventListener("abort",C),_&&clearTimeout(_),S(T))}},C=()=>{let T={status:null,stdout:I.text,stderr:"",aborted:!0,error:new Error("cancelled")};Promise.resolve(g.query.interrupt?.()).catch(()=>{}),s(a,g,T)};g.activeTurn=I,h&&h.addEventListener("abort",C,{once:!0}),w>0&&(_=setTimeout(()=>{let T=new Error(`timed out after ${w}ms`);Promise.resolve(g.query.interrupt?.()).catch(()=>{}),s(a,g,{status:null,stdout:I.text,stderr:T.message,error:T})},w),_.unref?.()),g.queue.push({type:"user",message:{role:"user",content:l},parent_tool_use_id:null,session_id:g.sessionId})});return n.get(a)===g&&o(a),v}),shutdown:()=>{for(let u of[...n.keys()])s(u)}}}function Mn(e){let t=1,n="",r=new Map,s=new Set;e.stdout.setEncoding("utf8"),e.stdout.on("data",i=>{n+=i;let c;for(;(c=n.indexOf(`
8
- `))>=0;){let u=n.slice(0,c);if(n=n.slice(c+1),!u.trim())continue;let a;try{a=JSON.parse(u)}catch{continue}if(a.id!==void 0&&r.has(a.id)){let{resolve:l,reject:h}=r.get(a.id);r.delete(a.id),a.error?h(new Error(a.error.message||"codex app-server error")):l(a.result)}else if(a.method)for(let l of s)l(a.method,a.params,a.id)}});let o=i=>{for(let{reject:c}of r.values())c(i);r.clear()};return e.on("exit",()=>o(new Error("codex app-server exited"))),e.on("error",i=>o(i)),{request(i,c){let u=t++;return new Promise((a,l)=>{r.set(u,{resolve:a,reject:l}),e.stdin.write(`${JSON.stringify({id:u,method:i,params:c})}
9
- `)})},notify(i,c){e.stdin.write(`${JSON.stringify({method:i,params:c})}
10
- `)},respond(i,c){e.stdin.write(`${JSON.stringify({id:i,result:c})}
11
- `)},respondError(i,c){e.stdin.write(`${JSON.stringify({id:i,error:{code:-32601,message:c}})}
12
- `)},onMessage(i){return s.add(i),()=>s.delete(i)}}}function On(e){return e==="yolo"?{approvalPolicy:"never",sandbox:"danger-full-access"}:{}}function tt({spawnFn:e=bn,idleCloseMs:t=Xe}={}){let n=new Map,r=Qe(),s=u=>{let a=n.get(u);if(a){n.delete(u),clearTimeout(a.idleTimer);try{a.child.kill("SIGTERM")}catch{}}},o=u=>{let a=n.get(u);a&&(clearTimeout(a.idleTimer),a.idleTimer=setTimeout(()=>s(u),t),a.idleTimer.unref?.())},i=async(u,a)=>{let l=n.get(u),h=Ze(a);if(l&&l.fingerprint===h)return l;l&&s(u);let E=e("codex",["app-server"],{cwd:a.cwd,env:Ve(a.mcp?.env),stdio:["pipe","pipe","pipe"]}),w=Mn(E);await w.request("initialize",{clientInfo:{name:"agensis-agent",version:a.clientVersion||"unknown"}}),w.notify("initialized");let g=a.leanCli&&a.mcp?{mcp_servers:{agensis:{url:a.mcp.url,bearer_token_env_var:"AGENSIS_MCP_TOKEN"}}}:void 0,v=await w.request("thread/start",{cwd:a.cwd,ephemeral:a.leanCli||void 0,model:a.model,config:g,...On(a.permissionMode)}),S={child:E,rpc:w,threadId:v.thread.id,fingerprint:h,idleTimer:null};return n.set(u,S),S};return{run:u=>r(u.sessionKey||"default",async()=>{let{sessionKey:a="default",prompt:l,signal:h,onData:E,timeoutMs:w=0}=u;if(h?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let g;try{g=await i(a,u)}catch(C){return{status:null,stdout:"",stderr:"",error:C}}let v="",S="",f=null,_=!1,I=await new Promise(C=>{let T=!1,P=p=>{T||(T=!0,d(),C(p))},m=g.rpc.onMessage((p,k,D)=>{if(D!==void 0){if(p==="item/commandExecution/requestApproval"){let x=u.permissionMode==="yolo"?"acceptForSession":"decline";g.rpc.respond(D,{decision:x})}else if(p==="item/fileChange/requestApproval"){let x=u.permissionMode==="yolo"||u.permissionMode==="accept_edits"?"acceptForSession":"decline";g.rpc.respond(D,{decision:x})}else g.rpc.respondError(D,`Agensis daemon cannot handle Codex request ${p}`);return}if(!(!k||k.threadId!==g.threadId)){if(p==="turn/started"){f=k.turn?.id??f;return}if(!(f&&k.turnId&&k.turnId!==f)){if(p==="item/agentMessage/delta")v+=k.delta||"",E?.(k.delta||"");else if(p==="item/completed"&&k.item?.type==="agentMessage")S=k.item.text||S;else if(p==="turn/completed"){let x=k.turn?.status==="failed"||k.turn?.error;P({status:x?1:0,stdout:S||v,stderr:x?String(k.turn?.error?.message||k.turn?.error||""):"",error:x?new Error(String(k.turn?.error?.message||k.turn?.error||"codex turn failed")):null})}}}}),y=()=>{_=!0,g.rpc.request("turn/interrupt",{threadId:g.threadId}).catch(()=>{});let p={status:null,stdout:v,stderr:"",aborted:!0,error:new Error("cancelled")};P(p),s(a)};h&&h.addEventListener("abort",y,{once:!0});let M=w>0?setTimeout(()=>{let p=new Error(`timed out after ${w}ms`);g.rpc.request("turn/interrupt",{threadId:g.threadId}).catch(()=>{}),P({status:null,stdout:v,stderr:p.message,error:p}),s(a)},w):null;M?.unref?.();function d(){m(),h&&h.removeEventListener("abort",y),M&&clearTimeout(M)}g.rpc.request("turn/start",{threadId:g.threadId,input:[{type:"text",text:l}]}).then(p=>{f=p?.turn?.id||f}).catch(p=>P({status:null,stdout:"",stderr:"",error:p}))});return _||o(a),I}),shutdown:()=>{for(let u of[...n.keys()])s(u)}}}function st({run:e=ie}={}){return{run:t=>e(t)}}var $n=null,Bn=null,ot=new Set;function Dn(e){let t=String(e&&e.message||e||"");return/Cannot find module|ERR_MODULE_NOT_FOUND|ENOENT|command not found/i.test(t)}function Pn(e,{local:t,pooled:n,log:r=console}={}){let s=t||st(),o=n||(e==="claude"?$n||=et():e==="codex"?Bn||=tt():null);return o?{async run(i){if(ot.has(e))return s.run(i);let c=await o.run(i);return c.error&&Dn(c.error)?(ot.add(e),r.log?.(`[executor] ${e} fast connection unavailable (${c.error.message}); falling back to subprocess mode for this and future jobs.`),s.run(i)):c}}:s}function Rn(e){return{async run({cmd:t,args:n=[],env:r={},onData:s,signal:o,job:i}){let c=null;try{c=await e.ensureEnv({job:i,signal:o}),await e.putRepo(c,{job:i,signal:o});let u=await e.exec(c,{cmd:t,args:n,env:r,onData:s,signal:o}),a=await e.getResult(c,{job:i}).catch(()=>({})),l=a&&a.patch?String(a.patch).trim():"",h=l?`${u.stdout||""}
13
-
14
- \`\`\`diff
15
- ${l}
16
- \`\`\``:u.stdout||"";return{status:u.status,stdout:h,stderr:u.stderr||"",error:u.error||null}}catch(u){return{status:null,stdout:"",stderr:"",error:u}}finally{if(c)try{await e.destroy(c)}catch{}}}}}function it(e,{makeProvider:t,family:n}={}){return(e&&e.agent&&e.agent.run_mode)==="sandbox"?Rn((t||Ln)(e)):n==="claude"||n==="codex"?Pn(n):st()}function Ln(e){let t=e.agent&&e.agent.sandbox_provider||"e2b",n=e.agent&&e.agent.sandbox_config||{};if(t!=="e2b")throw new Error(`Sandbox provider "${t}" is not available yet (only e2b is wired).`);return Fn({apiKey:process.env.E2B_API_KEY,anthropicApiKey:process.env.ANTHROPIC_API_KEY,gitToken:process.env.GIT_TOKEN||"",repoUrl:e.repoUrl||e.agent&&e.agent.repo_url||n.repoUrl||"",template:n.template||""})}function Un(e=process.versions.node){let[t,n,r]=String(e).split(".").map(s=>Number(s)||0);return t===21?!1:t>=22?!0:t!==20?!1:n>18?!0:n<18?!1:r>=1}function Fn(e){let t=null,n=async()=>{if(!t){if(!Un())throw new Error(`Sandbox execution requires Node >=20.18.1 (you have ${process.versions.node}). Upgrade Node to use Sandbox agents; Built-in and Remote daemon modes still work on Node 18.`);t=(await Promise.resolve().then(()=>(rt(),nt))).createE2bProvider(e)}return t};return{ensureEnv:async r=>(await n()).ensureEnv(r),putRepo:async(r,s)=>(await n()).putRepo(r,s),exec:async(r,s)=>(await n()).exec(r,s),getResult:async(r,s)=>(await n()).getResult(r,s),destroy:async r=>(await n()).destroy(r)}}function at(e={}){let{runJob:t}=e,n=Math.max(1,Number(e.concurrency)||1),r=new Map,s=0,o=[];function i(S){let f=r.get(S);return f||(f={queued:[],active:null},r.set(S,f)),f}function c(S){if(S==null)return!1;for(let f of r.values())if(f.active&&!f.active.cancelled&&f.active.job.key===S||f.queued.some(_=>_.key===S))return!0;return!1}function u(){for(let[S,f]of r){if(s>=n)break;if(f.active||f.queued.length===0)continue;let _=f.queued.shift(),I=new AbortController;f.active={job:_,controller:I,cancelled:!1},s+=1,Promise.resolve().then(()=>I.signal.aborted?void 0:t(_,{signal:I.signal})).catch(()=>{}).finally(()=>{f.active=null,s-=1,f.queued.length===0&&!f.active&&r.delete(S),u(),a()})}}function a(){if(s>0)return;for(let f of r.values())if(f.queued.length)return;let S=o;o=[];for(let f of S)f()}function l(S){if(S&&S.key!=null&&c(S.key))return{accepted:!1,deduped:!0,position:0,startedImmediately:!1};let f=S&&S.lane!=null?String(S.lane):"",_=i(f),I=!_.active&&_.queued.length===0&&s<n;_.queued.push(S);let C=_.queued.length+(_.active?1:0);return u(),{accepted:!0,deduped:!1,position:C,startedImmediately:I}}function h(S,f){let _=!1;for(let[I,C]of r)f!=null&&I!==String(f)||C.active&&(C.active.cancelled=!0,C.active.controller.abort(S||"cancelled"),_=!0);return _}function E(S,f){if(S==null)return!1;let _=!1;for(let[I,C]of[...r]){C.active?.job?.key===S&&(C.active.cancelled=!0,C.active.controller.abort(f||"cancelled"),_=!0);let T=C.queued.length;C.queued=C.queued.filter(P=>P.key!==S),C.queued.length!==T&&(_=!0),!C.active&&C.queued.length===0&&r.delete(I)}return a(),_}function w(){let S=0;for(let f of r.values())S+=f.queued.length;return S}function g(){return s}function v(){return s===0&&w()===0?Promise.resolve():new Promise(S=>o.push(S))}return{enqueue:l,cancel:E,cancelActive:h,has:c,size:w,active:g,idle:v}}import ft from"node:crypto";import jn from"node:http";import pt from"node:os";import X from"node:process";var ct=8787,Ce="claude-haiku-4-5",Gn=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/,Hn=100,Jn=new Set(["say","wave","hush","open","choose"]),ye="x-agensis-bridge-secret";function Kn(){return`cbs_${ft.randomBytes(24).toString("base64url")}`}function zn(e){let t=e?.headers||{},n=String(t[ye]||t[ye.toLowerCase()]||"").trim();if(n)return n;let s=String(t.authorization||t.Authorization||"").trim().match(/^Bearer\s+(.+)$/i);return s?s[1].trim():""}function Wn(e,t){let n=String(t||""),r=zn(e);if(!n||!r)return!1;let s=Buffer.from(r),o=Buffer.from(n);return s.length!==o.length?!1:ft.timingSafeEqual(s,o)}function qn(e={},t={}){let n=String(t.authSecret||"").trim();if(n)return n;let r=String(e.cursorBuddyBridgeSecret||"").trim();if(r)return r;let s=String(X.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim();return s||Kn()}function Yn(e,t){return e==="OPTIONS"||e==="GET"&&t==="/cursorbuddy/health"}function j(e,t,n){e.writeHead(t,{"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST, OPTIONS","access-control-allow-headers":"content-type, authorization, x-agensis-bridge-secret"}),e.end(JSON.stringify(n))}function ut(e){e.writeHead(200,{"content-type":"text/event-stream; charset=utf-8","cache-control":"no-store, no-transform",connection:"keep-alive","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST, OPTIONS","access-control-allow-headers":"content-type, authorization, x-agensis-bridge-secret","x-accel-buffering":"no"})}function H(e,t){e.write(`data: ${typeof t=="string"?t:JSON.stringify(t)}
17
-
18
- `)}function ae(e){return new Promise((t,n)=>{let r="";e.on("data",s=>{r+=s,r.length>256*1024&&(n(new Error("request body is too large")),e.destroy())}),e.on("error",n),e.on("end",()=>t(r))})}function Xn(e){let t=[],n="",r="",s=!1;for(let o of String(e||"")){if(s){n+=o,s=!1;continue}if(o==="\\"){s=!0;continue}if(r){o===r?r="":n+=o;continue}if(o==='"'||o==="'"){r=o;continue}if(/\s/.test(o)){n&&(t.push(n),n="");continue}n+=o}if(n&&t.push(n),!t.length)throw new Error("coding command is empty");return{cmd:t[0],args:t.slice(1)}}function Vn(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function he(e,t){return e.some(n=>n===t||String(n).startsWith(`${t}=`))}function lt(e,t){let n=[];t&&n.push("CursorBuddy local runtime context:",JSON.stringify(t,null,2),"");for(let r of Array.isArray(e)?e:[]){let s=String(r?.role||"user"),o=String(r?.content||"");o.trim()&&n.push(`${s.toUpperCase()}:
19
- ${o}`)}return n.join(`
20
-
21
- `).trim()||"Say that the local Agensis runtime is connected."}function dt(e){let t=String(e||"").trim();if(!t)return"";try{let n=JSON.parse(t);if(typeof n?.result=="string")return n.result;if(typeof n?.message=="string")return n.message;if(typeof n?.content=="string")return n.content}catch{}return t}function Qn(e){let t=Array.isArray(e?.messages)?e.messages:[];for(let n=t.length-1;n>=0;n-=1){let r=t[n];if(String(r?.role||"user")!=="user")continue;let s=String(r?.content||"").trim();if(s)return s}return""}function Zn(e,t=280){let n=Qn(e).replace(/\s+/g," ").trim();if(!n)return"";if(n.length<=t)return n;let r=[/\b(tell me (?:a )?joke)\b/i,/\b(make (?:him|the buddy|cursorbuddy|avatar) wave|wave(?: hello)?|say hi|say hello)\b/i,/\b(what site|which site|what page|where am i|where are you|current url)\b/i,/\b(are you connected|connected|working|online|there)\b/i,/\b(show|guide|tour|walk|around|sections?|features?|important|highlight|what can i do|what should i do|help me)\b/i,/\b(open|show|bring up|get back|display)\b.{0,80}\b(prompt|bubble|dialog|panel|options|menu)\b/i,/\b(hide|hush|close|dismiss|clear|stop|cancel|be quiet)\b.{0,80}\b(bubble|prompt|dialog|panel|options|menu)?\b/i,/^(hi|hello|hey|yo|sup)\b/i];for(let s of r){let o=n.match(s);if(o?.[0])return o[0].trim()}return n.slice(-t).trim()}function er(e){let t=Zn(e);if(!t)return null;if(/\b(?:him|the buddy|cursorbuddy|cursor buddy|avatar|buddy|pet|character)\b/i.test(t)&&/\bwave(?: hello)?\b/i.test(t))return{content:"Waving now.",command:{action:"wave",text:"Hi. How can I help?",source:"chat"}};let r=t.match(/^(?:say|speak)\s+(.{1,180})$/i)||t.match(/\b(?:make|tell)\s+(?:him|the buddy|cursorbuddy|avatar)\s+(?:say|speak)\s+(.{1,180})$/i);return r?.[1]?{content:"Saying it now.",command:{action:"say",text:r[1].trim(),source:"chat"}}:/^(stop|cancel|dismiss|close|hide|hush|be quiet)\b/i.test(t)?{content:"Closed.",command:{action:"hush",source:"chat"}}:/\b(open|show)\b.*\b(options|chat|bubble|prompt)\b/i.test(t)?{content:"Opening options.",command:{action:"open",text:"What should I help with?",source:"chat"}}:null}function tr(e){let t=String(e||"").trim();return t?/\s/.test(t)||t.startsWith("-")?!0:/^(claude|codex|node|npm|bun|python|python3|sh|bash|zsh)(?:$|\.)/.test(t):!1}function ht(e,t){let n=String(e||"").trim();return!n||tr(n)?t:n}function gt(e){let t=String(e||"").trim();return!t||t==="haiku-4.5"||t==="claude-haiku-4.5"?Ce:t}function xe(e={}){return gt(e.cursorBuddyModel||X.env.AGENSIS_CURSORBUDDY_MODEL||Ce)}function mt(e,t,n,r={}){let{cmd:s,args:o}=Xn(e.codingCmd||"claude -p"),i=[...o],c=gt(ht(n,xe(e))),u="",a=!1;return Vn(s)?(c&&!he(i,"--model")&&i.push("--model",c),r.stream===!0&&!he(i,"--output-format")?(i.push("--output-format","stream-json","--include-partial-messages"),he(i,"--verbose")||i.push("--verbose"),a=!0):(he(i,"--output-format")||i.push("--output-format","json"),a=i.some(h=>String(h).includes("stream-json"))),u=t):i.push(t),{cmd:s,args:i,model:c,stdin:u,streamJson:a}}function nr(e=()=>{}){let t="",n="",r=!1,s="",o=null,i=a=>{a&&e(a)},c=a=>{if(!a||typeof a!="object")return;let l=a.event&&a.event.delta||a.delta;if(l&&l.type==="text_delta"&&typeof l.text=="string"){r=!0,n+=l.text,i(l.text);return}if(a.type==="result"&&typeof a.result=="string"){o=a.result;return}if(a.type==="assistant"&&a.message&&Array.isArray(a.message.content)){let h=a.message.content.filter(E=>E&&E.type==="text"&&typeof E.text=="string").map(E=>E.text).join("");h&&(s+=h)}},u=a=>{let l=String(a).trim();if(l)try{c(JSON.parse(l))}catch{}};return{feed(a){t+=String(a||"");let l;for(;(l=t.indexOf(`
22
- `))>=0;)u(t.slice(0,l)),t=t.slice(l+1)},end(){t&&(u(t),t="")},get live(){return r?n:s},get result(){return o??(r?n:s)}}}function te(e,t,n,r=null){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:t,choices:[{index:0,delta:n?{content:n}:{},finish_reason:r}]}}function ge(e){return`http://127.0.0.1:${e}`}function rr(e={},t={}){return String(t.agensisUrl||t.baseUrl||e.url||X.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function or(e){return String(e||"").slice(0,18)}function U(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function sr(e={},t={},n={}){let r=U(e.metadata)||{},s=U(e.page)||U(r.page)||{},o=U(e.client)||U(r.client)||{},i=U(r.runtime)||{},c=U(e.manifest)||U(r.manifest)||null;return{url:String(e.url||s.url||r.websiteSource||e.websiteSource||"").slice(0,2048),title:String(e.title||s.title||"").slice(0,300),surface:String(e.surface||i.surface||t.surface||"").slice(0,80),instanceId:String(e.instanceId||i.instanceId||"").slice(0,140),workspaceId:String(t.workspaceId||e.workspaceId||n.workspace||"").slice(0,120),agentId:String(t.agentId||e.agentId||n.agent||"").slice(0,120),runtime:{...i,local:!0,connected:!0,connection:t},page:s,client:o,project:U(e.project)||U(r.project)||null,manifest:c,selection:U(e.selection)||null,updatedAt:new Date().toISOString()}}function ir(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function ar(e,t={},n=globalThis.fetch){let r=String(t.key||"").trim();if(!Gn.test(r))throw new Error("Connection key format is invalid. Create a fresh CursorBuddy key first.");if(typeof n!="function")throw new Error("This Node.js runtime does not provide fetch; use a current Node.js release.");let s=rr(e,t),o=await n(`${s}/backend/cursorbuddy/connection-keys/claim`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({key:r,baseUrl:s,host:pt.hostname(),cwd:t.cwd||e.cwd||X.cwd(),name:t.name||e.name||e.handle||"CursorBuddy runtime",surface:t.surface||"browser_extension",scope:t.scope||"machine",runtimeKind:t.runtimeKind||"agensis-cli-local-bridge",version:t.version||e.version||X.env.npm_package_version||"",permissionMode:t.permissionMode||e.permissionMode,model:t.model||e.model,metadata:U(t.metadata)||null,websiteSource:t.websiteSource||t.metadata?.websiteSource||"",page:U(t.page)||U(t.metadata?.page)||null,client:U(t.client)||U(t.metadata?.client)||null,manifest:U(t.manifest)||U(t.metadata?.manifest)||null})}),i=await o.json().catch(()=>({}));if(!o.ok)throw new Error(ir(o,i));return{key:r,baseUrl:s,data:i?.data||i}}async function yt(e,t={}){let n=Number(t.port??e.cursorBuddyPort??X.env.AGENSIS_CURSORBUDDY_PORT??ct),r=qn(e,t),s=new Date().toISOString(),o=[],i=[],c=new Set,u=t.fetchImpl||globalThis.fetch,a=1,l=null,h=n,E=null,w=(m,y={})=>{let M={ts:new Date().toISOString(),event:m,detail:y};return o.push(M),o.length>200&&o.shift(),t.log?.(`CursorBuddy local bridge: ${m}${Object.keys(y).length?` ${JSON.stringify(y)}`:""}`),M},g=()=>({connected:!!e.cursorBuddyRuntime,mode:e.cursorBuddyRuntime?"agensis-cli":"agensis-cli-unclaimed",agentId:e.agent,workspaceId:e.workspace,agensisUrl:e.url,handle:e.handle,name:e.name,cwd:e.cwd,updatedAt:new Date().toISOString()}),v=()=>{if(typeof t.connectionProvider!="function")return null;try{let m=t.connectionProvider();return!m||typeof m!="object"||Array.isArray(m)?null:{...g(),...m,connected:m.connected===!0}}catch{return null}},S=()=>{let m=v();return m?.connected===!1?m:E?{...g(),...m||{},...E,connected:!0,updatedAt:m?.updatedAt||E.updatedAt}:m||g()};function f(m={}){if(!m||typeof m!="object"||Array.isArray(m))return null;let y=String(m.action||m.type||"").trim().toLowerCase();if(!Jn.has(y))return null;let M={id:a++,ts:new Date().toISOString(),action:y,text:String(m.text||m.say||m.message||"").slice(0,1200),label:String(m.label||"").slice(0,80),value:String(m.value||m.prompt||"").slice(0,1200),holdMs:Number.isFinite(m.holdMs)?Math.max(0,Math.min(6e4,m.holdMs)):void 0,source:String(m.source||"agensis-daemon").slice(0,80)};return m.options&&Array.isArray(m.options)&&(M.options=m.options.map(d=>({label:String(d?.label||"").slice(0,80),value:String(d?.value||d?.task||"").slice(0,1200)})).filter(d=>d.label).slice(0,6)),M}function _(m){for(i.push(m);i.length>Hn;)i.shift();w("control",{id:m.id,action:m.action,chars:m.text.length});for(let y of[...c])try{H(y,{type:"command",command:m})}catch{c.delete(y)}return m}function I(m){let y=er(m);if(y){let M=f(y.command);return M&&(_(M),w("chat_control",{id:M.id,action:M.action})),{content:y.content,model:"cursorbuddy-local-control",fast:!0}}return null}async function C(m){let y=I(m);if(y)return y;let M=lt(m?.messages,l),d=mt(e,M,m?.model),p=await ie({cmd:d.cmd,args:d.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:d.stdin});if(p.error||p.status!==0)throw new Error(p.error?.message||String(p.stderr||"").trim()||`Command exited with status ${p.status}`);return{content:dt(p.stdout||p.stderr),model:d.model}}async function T(m,y){let M=`agensis-cursorbuddy-${Date.now()}`,d=I(m);if(d){let $=d.model||"cursorbuddy-local-control";return H(y,te(M,$,d.content)),H(y,te(M,$,"","stop")),H(y,"[DONE]"),w("chat_fast",{chars:d.content.length,model:$}),{content:d.content,model:$,fast:!0}}let p=lt(m?.messages,l),k=mt(e,p,m?.model,{stream:!0}),D="",x=$=>{$&&(D+=$,H(y,te(M,k.model||e.model,$)))},N=k.streamJson?nr(x):null,b=await ie({cmd:k.cmd,args:k.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:k.stdin,onData:$=>{if(N)N.feed($);else{let F=String($||"");D+=F,H(y,te(M,k.model||e.model,F))}}});if(N){N.end();let $=N.result||"";!D&&$?x($):D=$||D}if(b.error||b.status!==0){let $=b.error?.message||String(b.stderr||"").trim()||`Command exited with status ${b.status}`;throw new Error($)}let O=N?D:dt(D||b.stdout||b.stderr);return!N&&O&&O!==D&&(H(y,te(M,k.model||e.model,O)),D=O),H(y,te(M,k.model||e.model,"","stop")),H(y,"[DONE]"),{content:D||O,model:k.model}}let P=jn.createServer(async(m,y)=>{if(y.setHeader("access-control-allow-origin","*"),y.setHeader("access-control-allow-methods","GET, POST, OPTIONS"),y.setHeader("access-control-allow-headers","content-type, authorization, x-agensis-bridge-secret"),m.method==="OPTIONS"){y.writeHead(204),y.end();return}let M=new URL(m.url||"/",ge(h||ct));if(!Yn(m.method,M.pathname)&&!Wn(m,r)){j(y,401,{ok:!1,error:"Authentication required",code:"bridge_auth_required"});return}if(m.method==="GET"&&M.pathname==="/cursorbuddy/health"){let d=ge(h);j(y,200,{ok:!0,runtime:"agensis-cli",backend:e.codingCmd,model:xe(e),daemonModel:e.model,port:h,host:pt.hostname(),pid:X.pid,bootedAt:s,authRequired:!0,authHeader:ye,stream:!0,streaming:!0,supportsStreaming:!0,chatStream:!0,capabilities:{chatStream:!0,controlStream:!0,fastAvatarReplies:!1,nativeCursorBuddyControl:!0},latestControlId:i.at(-1)?.id||0,connection:S(),context:l,endpoints:{chat:`${d}/v1/chat/completions`,chatStream:`${d}/v1/chat/completions`,edit:`${d}/cursorbuddy/edit`,context:`${d}/cursorbuddy/context`,control:`${d}/cursorbuddy/control`,controlStream:`${d}/cursorbuddy/control/stream`,logs:`${d}/cursorbuddy/logs`}});return}if(m.method==="GET"&&M.pathname==="/cursorbuddy/logs"){j(y,200,{ok:!0,events:o.slice(-100)});return}if(m.method==="GET"&&M.pathname==="/cursorbuddy/context"){j(y,200,{ok:!0,context:l});return}if(m.method==="GET"&&M.pathname==="/cursorbuddy/control"){let d=Number(M.searchParams.get("after")||0),p=i.filter(k=>k.id>d);j(y,200,{ok:!0,commands:p,latestId:i.at(-1)?.id||0});return}if(m.method==="GET"&&M.pathname==="/cursorbuddy/control/stream"){let d=Number(M.searchParams.get("after")||0);ut(y),c.add(y),H(y,{type:"ready",latestId:i.at(-1)?.id||0});for(let k of i.filter(D=>D.id>d))H(y,{type:"command",command:k});let p=setInterval(()=>{try{H(y,{type:"ping",ts:new Date().toISOString()})}catch{c.delete(y),clearInterval(p)}},15e3);p.unref&&p.unref(),m.on("close",()=>{c.delete(y),clearInterval(p)});return}if(m.method==="POST"&&M.pathname==="/cursorbuddy/control"){try{let d=JSON.parse(await ae(m)||"{}"),p=f(d);if(!p){j(y,400,{ok:!1,error:"unsupported CursorBuddy control command"});return}let k=_(p);j(y,200,{ok:!0,command:k})}catch(d){w("control_error",{error:String(d?.message||d)}),j(y,400,{ok:!1,error:String(d?.message||d)})}return}if(m.method==="POST"&&M.pathname==="/cursorbuddy/context"){try{let d=JSON.parse(await ae(m)||"{}");l={url:String(d.url||"").slice(0,2048),title:String(d.title||"").slice(0,300),surface:String(d.surface||"").slice(0,80),instanceId:String(d.instanceId||"").slice(0,140),workspaceId:String(d.workspaceId||e.workspace||"").slice(0,120),agentId:String(d.agentId||e.agent||"").slice(0,120),runtime:d.runtime&&typeof d.runtime=="object"?d.runtime:null,page:d.page&&typeof d.page=="object"?d.page:null,client:d.client&&typeof d.client=="object"?d.client:null,project:d.project&&typeof d.project=="object"?d.project:null,manifest:d.manifest&&typeof d.manifest=="object"?d.manifest:null,selection:d.selection&&typeof d.selection=="object"?d.selection:null,updatedAt:new Date().toISOString()},w("context",{url:l.url,surface:l.surface,instanceId:l.instanceId}),j(y,200,{ok:!0,context:l})}catch(d){w("context_error",{error:String(d?.message||d)}),j(y,400,{ok:!1,error:String(d?.message||d)})}return}if(m.method==="POST"&&M.pathname==="/cursorbuddy/connect"){try{let d=JSON.parse(await ae(m)||"{}"),p=await ar(e,d,u),k=p.data||{};E={connected:!0,mode:"agensis-claimed",keyId:or(p.key),agentId:String(k.agentId||k.agent?.id||e.agent||""),workspaceId:String(k.workspaceId||k.workspace_id||k.agent?.workspace_id||e.workspace||""),agensisUrl:p.baseUrl,handle:String(k.handle||k.agent?.handle||e.handle||""),name:String(k.agent?.name||d.name||e.name||"CursorBuddy runtime"),cwd:String(d.cwd||e.cwd||X.cwd()),surface:String(d.surface||"browser_extension"),command:String(k.command||k.localCommand||""),updatedAt:new Date().toISOString()},l=sr(d,E,e),w("connect",{mode:E.mode,keyId:E.keyId,agentId:E.agentId,workspaceId:E.workspaceId,url:l.url}),j(y,200,{ok:!0,connection:E,claim:k})}catch(d){w("connect_error",{error:String(d?.message||d)}),j(y,400,{ok:!1,error:String(d?.message||d)})}return}if(m.method==="POST"&&M.pathname==="/cursorbuddy/edit"){try{let d=JSON.parse(await ae(m)||"{}"),p=[{role:"system",content:"You are the local CursorBuddy edit agent. The user selected a DOM element in their own site. Use the payload to inspect and change the local checkout, then report what changed."},{role:"user",content:JSON.stringify(d,null,2)}];w("edit_request",{selector:d?.target?.selector||""});let k=await C({messages:p,model:d?.model});w("edit_done",{chars:k.content.length}),j(y,200,{ok:!0,backend:e.codingCmd,cwd:e.cwd,content:k.content})}catch(d){w("edit_error",{error:String(d?.message||d)}),j(y,500,{ok:!1,error:String(d?.message||d)})}return}if(m.method==="POST"&&M.pathname.endsWith("/chat/completions")){try{let d=JSON.parse(await ae(m)||"{}");if(w("chat_request",{messages:Array.isArray(d.messages)?d.messages.length:0,model:ht(d.model,xe(e))}),d.stream===!0){ut(y);let k=await T(d,y);w("chat_done",{chars:k.content.length,stream:!0,fast:k.fast===!0}),y.end();return}let p=await C(d);w("chat_done",{chars:p.content.length,fast:p.fast===!0}),j(y,200,{id:`agensis-cursorbuddy-${Date.now()}`,object:"chat.completion",model:p.model||d.model||e.model,choices:[{index:0,message:{role:"assistant",content:p.content},finish_reason:"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}catch(d){w("chat_error",{error:String(d?.message||d)}),j(y,500,{error:{message:String(d?.message||d)}})}return}y.writeHead(404),y.end("CursorBuddy local bridge")});return await new Promise((m,y)=>{P.once("error",y),P.listen(n,"127.0.0.1",()=>{h=P.address().port,P.off("error",y),m()})}),w("listening",{url:`${ge(h)}/cursorbuddy/health`}),{port:h,url:ge(h),secret:r,authHeader:ye,close(){return new Promise(m=>P.close(()=>m()))},getContext(){return l}}}import ne from"node:fs/promises";import cr from"node:os";import J from"node:path";var St=200,wt=256*1024,ur=2,lr=new Set([".md",".markdown",".txt"]);function dr(e){return String(e||"").replace(/[^a-zA-Z0-9]/g,"-")}function Me({cwd:e,memoryDir:t,homedir:n=cr.homedir()}={}){let r=String(t||"").trim();if(r)return r.startsWith("~")?J.join(n,r.slice(1)):J.resolve(r);let s=String(e||"").trim();return s?J.join(n,".claude","projects",dr(s),"memory"):null}async function Oe(e){if(!e)return null;try{let t=await ne.realpath(e);return(await ne.stat(t)).isDirectory()?t:null}catch{return null}}async function mr(e,t){if(!e)throw new Error("memory root unavailable");let n=J.isAbsolute(String(t))?String(t):J.join(e,String(t)),r=await ne.realpath(n),s=e.endsWith(J.sep)?e:e+J.sep;if(r!==e&&!r.startsWith(s))throw new Error(`path escapes memory root: ${t}`);return r}function fr(e){let t=J.basename(e).toLowerCase();return t==="memory.md"?"index":t==="claude.md"?"instructions":"memory"}async function Ne(e,t,n,r){if(n>ur||r.length>=St)return;let s;try{s=await ne.readdir(t,{withFileTypes:!0})}catch{return}for(let o of s){if(r.length>=St)break;if(o.name.startsWith("."))continue;let i=J.join(t,o.name);if(o.isDirectory())await Ne(e,i,n+1,r);else if(o.isFile()&&lr.has(J.extname(o.name).toLowerCase())){let c=J.relative(e,i);r.push({path:c,kind:fr(c)})}}}async function pr(e){let t=await Oe(e);if(!t)return[];let n=[];return await Ne(t,t,0,n),n.sort((r,s)=>r.kind==="index"?-1:s.kind==="index"?1:r.path.localeCompare(s.path)),n}async function hr(e,t){let n=await Oe(e),r=await mr(n,t),s=await ne.readFile(r),o=s.length>wt;return{content:s.subarray(0,wt).toString("utf8"),byteSize:s.length,truncated:o}}async function bt(e){let t=await Oe(e);if(!t)return"";let n=[];await Ne(t,t,0,n),n.sort((s,o)=>s.path.localeCompare(o.path));let r=[];for(let s of n)try{let o=await ne.stat(J.join(t,s.path));r.push(`${s.path}:${o.size}:${Math.floor(o.mtimeMs)}`)}catch{}return r.join("|")}async function _t(e){let t=await pr(e),n=[];for(let r of t)try{let{content:s,byteSize:o}=await hr(e,r.path);n.push({path:r.path,kind:r.kind,content:s,byteSize:o})}catch{}return n}import vt from"node:fs";import re from"node:path";import Et from"node:os";function gr(e){try{return vt.statSync(e).isDirectory()}catch{return!1}}function Te(e){try{return vt.readdirSync(e,{withFileTypes:!0})}catch{return[]}}function kt({home:e=Et.homedir(),cwd:t=process.cwd()}={}){let n=[e&&re.join(e,".claude","commands"),t&&re.join(t,".claude","commands")].filter(Boolean),r=new Set,s=[],o=(i,c)=>{if(!i)return;let u=c?`${c}:${i}`:i;r.has(u)||(r.add(u),s.push({name:i,parent:c||null}))};for(let i of n)for(let c of Te(i)){if(c.name.startsWith("."))continue;if(c.name.endsWith(".md")){o(c.name.slice(0,-3),null);continue}let u=re.join(i,c.name);if(c.isDirectory()||c.isSymbolicLink()&&gr(u))for(let a of Te(u))a.name.startsWith(".")||a.name.endsWith(".md")&&o(a.name.slice(0,-3),c.name)}return s}function It({home:e=Et.homedir(),cwd:t=process.cwd()}={}){let n=[e&&re.join(e,".claude","skills"),e&&re.join(e,".codex","skills"),t&&re.join(t,".claude","skills")].filter(Boolean),r=new Set;for(let s of n)for(let o of Te(s))o.name.startsWith(".")||(o.name.endsWith(".md")?r.add(o.name.slice(0,-3)):(o.isDirectory()||o.isSymbolicLink())&&r.add(o.name));return[...r].sort()}import{readFile as yr}from"node:fs/promises";var Sr=new Set(["127.0.0.1","localhost","::1","[::1]"]);function At(e,t,n){let r=Number(e);return Number.isFinite(r)?Math.max(1,Math.min(n,Math.trunc(r))):t}function wr(e,t){if(!e||typeof e!="object"||e.shared===!1)return null;let n=String(e.id||e.upstreamModel||`model-${t+1}`).trim();if(!n)return null;if(!/^[a-zA-Z0-9._:@/-]+$/.test(n))throw new Error(`Shared model id '${n}' may only contain letters, numbers, dot, underscore, colon, at, slash, or dash.`);let r=new URL(String(e.baseUrl||"http://127.0.0.1:11434/v1"));if(!Sr.has(r.hostname))throw new Error(`Shared model '${n}' must use a loopback endpoint.`);if(!["http:","https:"].includes(r.protocol))throw new Error(`Shared model '${n}' must use an HTTP endpoint.`);return{id:n.slice(0,160),name:String(e.name||n).trim().slice(0,160)||n,provider:String(e.provider||"local").trim().slice(0,80)||"local",protocol:"openai-chat",baseUrl:r.toString().replace(/\/$/,""),upstreamModel:String(e.upstreamModel||n).trim().slice(0,200)||n,apiKeyEnv:String(e.apiKeyEnv||"").trim().slice(0,120),capabilities:[...new Set((Array.isArray(e.capabilities)?e.capabilities:["text","streaming"]).map(s=>String(s||"").trim().toLowerCase()).filter(Boolean))].slice(0,16),...e.contextWindow?{contextWindow:At(e.contextWindow,void 0,1e7)}:{},maxConcurrency:At(e.maxConcurrency,1,64),shared:!0}}async function Ct(e){if(!e)return[];let t=JSON.parse(await yr(e,"utf8")),n=Array.isArray(t)?t:t?.models;if(!Array.isArray(n))throw new Error("Shared model config must contain a models array.");return n.slice(0,32).map(wr).filter(Boolean)}function xt(e){return(Array.isArray(e)?e:[]).filter(t=>t?.shared).map(t=>({id:t.id,name:t.name,provider:t.provider,protocol:t.protocol,upstreamModel:t.upstreamModel,capabilities:[...t.capabilities],...t.contextWindow?{contextWindow:t.contextWindow}:{},maxConcurrency:t.maxConcurrency,shared:!0}))}async function Mt({models:e,request:t,send:n,signal:r,fetchImpl:s=fetch,env:o=process.env}){let i=String(t?.requestId||"").trim();if(!i)throw new Error("Inference requestId is required.");let c=(Array.isArray(e)?e:[]).find(f=>f.id===t?.model);if(!c)throw new Error(`Shared model '${t?.model||""}' is not available.`);let u={"content-type":"application/json"},a=c.apiKeyEnv?o[c.apiKeyEnv]:"";a&&(u.authorization=`Bearer ${a}`),n({action:"agent_inference_started",requestId:i,model:c.id});let{requestId:l,model:h,type:E,action:w,...g}=t,v=await s(`${c.baseUrl}/chat/completions`,{method:"POST",headers:u,body:JSON.stringify({...g,model:c.upstreamModel,stream:t.stream===!0}),signal:r});if(!v.ok){let f=await v.text().catch(()=>"");throw new Error(f||`Local model returned HTTP ${v.status}.`)}if(t.stream===!0){if(!v.body)throw new Error("Local model returned an empty stream.");let f=v.body.getReader(),_=new TextDecoder,I="",C,T=y=>{let M=y.trim();if(!M.startsWith("data:"))return!1;let d=M.slice(5).trim();if(!d)return!1;if(d==="[DONE]")return!0;try{let p=JSON.parse(d);p?.usage&&(C=p.usage),n({action:"agent_inference_delta",requestId:i,model:c.id,chunk:p})}catch{}return!1},P=!1;for(;!P;){let{done:y,value:M}=await f.read();I+=_.decode(M||new Uint8Array,{stream:!y});let d=I.split(/\r?\n/);I=y?"":d.pop()||"";for(let p of d)if(T(p)){P=!0;break}if(y)break}I&&T(I);let m={action:"agent_inference_result",requestId:i,model:c.id,...C?{usage:C}:{}};return n(m),m}let S=await v.json();return n({action:"agent_inference_result",requestId:i,model:c.id,response:S}),S}import Ot from"node:fs";import z from"node:fs/promises";import br from"node:os";import K from"node:path";var $t="status.json",Bt="heartbeat.json",$e="heartbeat.md",_r="agent.json",vr="soul.md",Er=16*1024,kr=`# Heartbeat
2
+ var Kn=Object.defineProperty;var be=(e,t)=>()=>(e&&(t=e(e=0)),t);var ht=(e,t)=>{for(var n in t)Kn(e,n,{get:t[n],enumerable:!0})};var kt={};ht(kt,{createE2bProvider:()=>cr});function Be(e){return`'${String(e).replace(/'/g,"'\\''")}'`}function cr({apiKey:e,anthropicApiKey:t,gitToken:n="",repoUrl:r="",template:s=""}={}){if(!e)throw new Error("E2B_API_KEY is not set on the daemon host.");if(!r)throw new Error("Sandbox needs a repo URL (set sandbox_config.repoUrl or the agent's repo).");return{async ensureEnv(){let o={apiKey:e,envs:t?{ANTHROPIC_API_KEY:t}:{}},i;try{({Sandbox:i}=await import("e2b"))}catch(u){if(u&&(u.code==="ERR_MODULE_NOT_FOUND"||u.code==="MODULE_NOT_FOUND"||/Cannot find package 'e2b'/.test(String(u&&u.message)))){let a=Number(String(process.versions.node).split(".")[0])||0,l=a<20||a===21?` Sandbox mode needs Node >=20.18.1 (<21 or >=22); you have ${process.versions.node}. Upgrade Node, then run \`npm i e2b\` in the daemon.`:" Run `npm i e2b` in the daemon to enable Sandbox mode.";throw new Error(`Sandbox execution requires the optional 'e2b' package, which is not installed.${l}`)}throw u}let c=s?await i.create(s,o):await i.create(o);return await c.commands.run("bash -lc 'command -v claude >/dev/null || npm i -g @anthropic-ai/claude-code'"),{sbx:c,dir:ar}},async putRepo(o){let i=n?r.replace(/^https:\/\//,`https://x-access-token:${n}@`):r;try{let c=await o.sbx.commands.run(`git clone ${Be(i)} ${Be(o.dir)}`);if(c&&typeof c.exitCode=="number"&&c.exitCode!==0)throw new Error(`git clone failed: ${c.stderr||`exit ${c.exitCode}`}`)}catch(c){if(c&&String(c.message||"").startsWith("git clone failed:"))throw c;let u=c&&(c.stderr||c.exitCode!=null)?c.stderr||`exit ${c.exitCode}`:String(c?.message||c);throw new Error(`git clone failed: ${u}`)}},async exec(o,{cmd:i,args:c=[],env:u={},onData:a}){let l=`${i} ${c.map(Be).join(" ")}`,g={cwd:o.dir,envs:{...u,IS_SANDBOX:"1",AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS:"1"},onStdout:w=>{try{a?.(w)}catch{}}};try{let w=await o.sbx.commands.run(l,g);return{status:w.exitCode,stdout:w.stdout||"",stderr:w.stderr||"",error:null}}catch(w){return w&&typeof w.exitCode=="number"?{status:w.exitCode,stdout:w.stdout||"",stderr:w.stderr||"",error:null}:{status:null,stdout:"",stderr:String(w?.message||w),error:w}}},async getResult(o){try{return{patch:(await o.sbx.commands.run("git add -A && git diff --cached",{cwd:o.dir})).stdout||""}}catch(i){return{patch:i&&i.stdout||""}}},async destroy(o){await o.sbx.kill()}}}var ar,At=be(()=>{ar="/home/user/repo"});import Qt from"node:fs";import G from"node:fs/promises";import Vr from"node:os";import H from"node:path";function Zt(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/\.{2,}/g,".").replace(/^[.-]+/,"").slice(0,96)||t}function q({workspace:e,agent:t,homedir:n=Vr.homedir()}={}){return H.join(n,".agensis",Zt(e,"workspace"),Zt(t,"agent"))}function rn(e){return H.join(q(e),en)}function on(e){return H.join(q(e),He)}async function ke(e){let t=q(e);try{return await G.mkdir(t,{recursive:!0}),t}catch{return null}}async function de(e,t){let n=`${e}.tmp-${process.pid}`;try{return await G.writeFile(n,t),await G.rename(n,e),!0}catch{try{await G.rm(n,{force:!0})}catch{}return!1}}async function Je(e,t){if(!t||typeof t!="object")return!1;let n=await ke(e);if(!n)return!1;let r={id:t.id??e.agent??"",workspace:t.workspace_id??e.workspace??"",name:t.name??e.name??"",handle:t.handle??e.handle??"",model:t.model??e.model??"",permissionMode:t.permissionMode??t.permission_mode??e.permissionMode??"",description:t.description??"",instructions:t.instructions??"",systemPrompt:t.system_prompt??t.systemPrompt??"",tools:Array.isArray(t.tools)?t.tools:[],skills:Array.isArray(t.skills)?t.skills:[],memoryDir:t.memory_dir??t.memoryDir??"",version:Number(t.version||0),updatedAt:new Date().toISOString()},s=await de(H.join(n,Qr),`${JSON.stringify(r,null,2)}
3
+ `),o=String(t.soul??""),i=await de(H.join(n,Zr),o);return s&&i}async function sn(e,t={}){let n=await ke(e);return n?de(H.join(n,tn),cn(e,t)):!1}function an(e,t={}){let n=q(e);try{return Qt.mkdirSync(n,{recursive:!0}),Qt.writeFileSync(H.join(n,tn),cn(e,t)),!0}catch{return!1}}function cn(e,t){let n=Date.now(),r={ts:n,iso:new Date(n).toISOString(),status:t.status||(t.busy?"busy":"online"),busy:!!t.busy,active:Number(t.active||0),queueSize:Number(t.queueSize||0),connected:!!t.connected,model:e.model||"",permissionMode:e.permissionMode||"",handle:e.handle||"",agent:e.agent||"",workspace:e.workspace||"",pid:process.pid,heartbeatMs:e.heartbeatMs,...t.agentStatus?{agentStatus:t.agentStatus}:{},...t.agentNote?{agentNote:t.agentNote}:{}};return`${JSON.stringify(r,null,2)}
4
+ `}async function qe(e){let t=H.join(q(e),en),n;try{let c=await G.stat(t);if(!c.isFile()||c.size>io)return null;n=await G.readFile(t,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;let s=Ge(r.status),o=Ge(r.note??r.message);if(!s&&!o)return null;let i={};return s&&(i.status=s),o&&(i.note=o),r.ts!=null&&Number.isFinite(Number(r.ts))&&(i.ts=Number(r.ts)),i}function Ge(e){return e==null?"":String(e).trim().replace(/\s+/g," ").slice(0,ao)}function Ke(e){return H.join(q(e),Xr)}async function un(e){let t=Ke(e),n;try{let i=await G.stat(t);if(!i.isFile()||i.size>co)return null;n=await G.readFile(t,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;let s={};for(let i of uo){let c=i==="description"&&r.description==null?r.profile:r[i];typeof c!="string"||!c.trim()||(s[i]=c.trim())}let o=mo(r.voice,r.attitude);return o&&(s.voice=o),Object.keys(s).length>0?s:null}function mo(e,t){let n=e&&typeof e=="object"&&!Array.isArray(e)?e:{},r={};for(let s of lo){let o=n[s];typeof o=="string"&&o.trim()?r[s]=o.trim():s==="speed"&&typeof o=="number"&&Number.isFinite(o)&&(r.speed=o)}return!r.emotion&&!r.attitude&&typeof t=="string"&&t.trim()&&(r.attitude=t.trim()),Object.keys(r).length>0?r:null}function ln(e){return H.join(q(e),eo)}function fo(e){return H.join(q(e),nn)}async function dn(e){let t=ln(e),n;try{let c=await G.stat(t);if(!c.isFile()||c.size>to)return null;n=await G.readFile(t,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;let s=String(r.targetVersion||"").trim();if(!ro.test(s))return null;let o={targetVersion:s},i=Ge(r.note);return i&&(o.note=i),typeof r.requestedAt=="string"&&(o.requestedAt=r.requestedAt),o}async function mn(e){try{return await G.rm(ln(e),{force:!0}),!0}catch{return!1}}async function Ae(e){let t=fo(e),n;try{let r=await G.stat(t);if(!r.isFile()||r.size>no)return null;n=await G.readFile(t,"utf8")}catch{return null}try{let r=JSON.parse(n);return r&&typeof r=="object"&&!Array.isArray(r)?r:null}catch{return null}}async function ee(e,t={}){let n=await ke(e);if(!n)return!1;let r={...t,updatedAt:new Date().toISOString()};return de(H.join(n,nn),`${JSON.stringify(r,null,2)}
5
+ `)}async function fn(e){let t=await ke(e);if(!t)return!1;let n=H.join(t,He);try{return await G.access(n),!0}catch{}return de(n,so)}async function pn(e){let t=H.join(q(e),He);try{let n=await G.stat(t);return!n.isFile()||n.size>oo?null:(await G.readFile(t,"utf8")).trim()||null}catch{return null}}var en,Xr,tn,He,Qr,Zr,eo,nn,to,no,ro,oo,so,io,ao,co,uo,lo,Ie=be(()=>{en="status.json",Xr="identity.json",tn="heartbeat.json",He="heartbeat.md",Qr="agent.json",Zr="soul.md",eo="update-request.json",nn="update.json",to=4*1024,no=16*1024,ro=/^[a-zA-Z0-9._+-]{1,64}$/,oo=16*1024,so=`# Heartbeat
23
6
 
24
7
  This file tells you what to do on each heartbeat \u2014 the recurring "still here, still
25
8
  working" moment. Edit it freely; the daemon reads it but never overwrites your edits.
@@ -32,36 +15,56 @@ On each heartbeat:
32
15
  - If you've finished and there's nothing to do, a short idle note is fine.
33
16
 
34
17
  Add your own recurring checks below.
35
- `,Ir=8*1024,Ar=400;function Nt(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/\.{2,}/g,".").replace(/^[.-]+/,"").slice(0,96)||t}function oe({workspace:e,agent:t,homedir:n=br.homedir()}={}){return K.join(n,".agensis",Nt(e,"workspace"),Nt(t,"agent"))}function Dt(e){return K.join(oe(e),$t)}function Pt(e){return K.join(oe(e),$e)}async function Be(e){let t=oe(e);try{return await z.mkdir(t,{recursive:!0}),t}catch{return null}}async function Se(e,t){let n=`${e}.tmp-${process.pid}`;try{return await z.writeFile(n,t),await z.rename(n,e),!0}catch{try{await z.rm(n,{force:!0})}catch{}return!1}}async function De(e,t){if(!t||typeof t!="object")return!1;let n=await Be(e);if(!n)return!1;let r={id:t.id??e.agent??"",workspace:t.workspace_id??e.workspace??"",name:t.name??e.name??"",handle:t.handle??e.handle??"",model:t.model??e.model??"",permissionMode:t.permissionMode??t.permission_mode??e.permissionMode??"",description:t.description??"",instructions:t.instructions??"",systemPrompt:t.system_prompt??t.systemPrompt??"",tools:Array.isArray(t.tools)?t.tools:[],skills:Array.isArray(t.skills)?t.skills:[],memoryDir:t.memory_dir??t.memoryDir??"",version:Number(t.version||0),updatedAt:new Date().toISOString()},s=await Se(K.join(n,_r),`${JSON.stringify(r,null,2)}
36
- `),o=String(t.soul??""),i=await Se(K.join(n,vr),o);return s&&i}async function Rt(e,t={}){let n=await Be(e);return n?Se(K.join(n,Bt),Ut(e,t)):!1}function Lt(e,t={}){let n=oe(e);try{return Ot.mkdirSync(n,{recursive:!0}),Ot.writeFileSync(K.join(n,Bt),Ut(e,t)),!0}catch{return!1}}function Ut(e,t){let n=Date.now(),r={ts:n,iso:new Date(n).toISOString(),status:t.status||(t.busy?"busy":"online"),busy:!!t.busy,active:Number(t.active||0),queueSize:Number(t.queueSize||0),connected:!!t.connected,model:e.model||"",permissionMode:e.permissionMode||"",handle:e.handle||"",agent:e.agent||"",workspace:e.workspace||"",pid:process.pid,heartbeatMs:e.heartbeatMs,...t.agentStatus?{agentStatus:t.agentStatus}:{},...t.agentNote?{agentNote:t.agentNote}:{}};return`${JSON.stringify(r,null,2)}
37
- `}async function Pe(e){let t=K.join(oe(e),$t),n;try{let c=await z.stat(t);if(!c.isFile()||c.size>Ir)return null;n=await z.readFile(t,"utf8")}catch{return null}let r;try{r=JSON.parse(n)}catch{return null}if(!r||typeof r!="object"||Array.isArray(r))return null;let s=Tt(r.status),o=Tt(r.note??r.message);if(!s&&!o)return null;let i={};return s&&(i.status=s),o&&(i.note=o),r.ts!=null&&Number.isFinite(Number(r.ts))&&(i.ts=Number(r.ts)),i}function Tt(e){return e==null?"":String(e).trim().replace(/\s+/g," ").slice(0,Ar)}async function Ft(e){let t=await Be(e);if(!t)return!1;let n=K.join(t,$e);try{return await z.access(n),!0}catch{}return Se(n,kr)}async function jt(e){let t=K.join(oe(e),$e);try{let n=await z.stat(t);return!n.isFile()||n.size>Er?null:(await z.readFile(t,"utf8")).trim()||null}catch{return null}}var xr=30*60*1e3,Mr=15*1e3,Gt=2,Or=10*1024,Nr="claude-opus-4-8",Z="0.1.30";async function we(e={}){let t=Tr(e);t.sharedModels=t.share?await Ct(t.sharedModelsFile):[];let n=!1,r=null,s=null,o=null,i=null,c=0,u=null,a=null,l="",h=null,E=!1,w=null,g=new Map,v=null,S={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"},f=new Map,_=new Map,I=[],C=()=>S,T=()=>({connected:E&&!!t.cursorBuddyRuntime,mode:t.cursorBuddyRuntime?"agensis-cli":"agensis-cli-unclaimed",agentId:w?.agentId||w?.agent_id||t.agent,workspaceId:w?.workspaceId||w?.workspace_id||t.workspace,agensisUrl:t.url,handle:w?.handle||t.handle,name:w?.name||t.name,cwd:t.cwd,updatedAt:new Date().toISOString()}),P=()=>{v||!t.lanListener||(v=new ue.Server({port:0}),v.on("listening",()=>{let{port:x}=v.address();S={transport:"ws",listening:!0,addrs:no(x),auth:"hub-pairwise"},B(`Agent-mesh LAN listener on port ${x}`),ce(r,t,C())}),v.on("connection",x=>{let N=!1,b=setTimeout(()=>{if(!N)try{x.close(1008,"peer auth required")}catch{}},5e3);x.once("message",O=>{clearTimeout(b);let $=Le(O),F=$?.type==="peer_auth"?f.get($.ticket):null;if(!F||F.fromAgentId!==$.fromAgentId||Date.now()>F.exp){try{x.close(1008,"invalid ticket")}catch{}return}f.delete($.ticket),N=!0,x.on("message",G=>{let R=Le(G);R?.type==="agent_job"&&R.job?.id&&a.enqueue({...R.job,key:R.job.id,lane:Ht(R.job),ws:r}).accepted&&B(`Queued peer-handoff job ${R.job.id} from ${$.fromAgentId}`)})})}),v.on("error",x=>B(`LAN listener error: ${x?.message||x}`)))},m=()=>{if(v){try{v.close()}catch{}v=null}S={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"}},y=x=>new Promise((N,b)=>{if(!L(r,{action:"peer_ticket_request",targetAgentId:x})){b(new Error("hub socket not open"));return}let O=_.get(x)||[];O.push({resolve:N,reject:b}),_.set(x,O),setTimeout(()=>{let $=_.get(x)||[],F=$.findIndex(G=>G.resolve===N);F>=0&&($.splice(F,1),b(new Error("peer ticket request timed out")))},1e4)}),M=()=>new Promise((x,N)=>{if(!L(r,{action:"peer_list_request"})){N(new Error("hub socket not open"));return}I.push(x),setTimeout(()=>{let b=I.indexOf(x);b>=0&&(I.splice(b,1),x([]))},1e4)}),d=async(x,N)=>{let b=null;try{let $=(await M()).find(R=>R.agentId===x&&R.reach?.listening&&R.reach.addrs?.length);if(!$)return!1;let F=await y(x),G=F.peer?.addrs?.[0]||$.reach.addrs[0];return!G?.host||!G?.port?!1:(b=new ue(`ws://${G.host}:${G.port}`),await new Promise((R,Ee)=>{b.once("open",R),b.once("error",Ee),setTimeout(()=>Ee(new Error("peer connect timed out")),5e3)}),L(b,{type:"peer_auth",ticket:F.ticket,fromAgentId:t.agent}),L(b,{type:"agent_job",job:N}),!0)}catch(O){return B(`Peer handoff to ${x} failed, falling back to hub relay: ${O?.message||O}`),!1}finally{try{b?.close()}catch{}}},p=()=>{n=!0,Wt(g),s&&clearTimeout(s),o&&clearInterval(o),i&&clearInterval(i),h&&(h.close().catch(()=>{}),h=null),m(),Lt(t,{status:"stopped",connected:!1});try{r?.close()}catch{}u&&u()};if(a=at({concurrency:t.once?1:t.maxConcurrency,runJob:async(x,N)=>{await Wr(t,x,N),t.once&&p()}}),t.cursorBuddyBridge)try{h=await yt(t,{port:t.cursorBuddyPort,authSecret:t.cursorBuddyBridgeSecret||void 0,log:B,connectionProvider:T}),h?.secret&&(t.cursorBuddyBridgeSecret=h.secret)}catch(x){if(io(x)){let N=await ao(t.cursorBuddyPort);if(N?.ok){let b=N.pid?` pid ${N.pid}`:"";B(`CursorBuddy local bridge already running on http://127.0.0.1:${t.cursorBuddyPort}${b}`)}else B(`CursorBuddy local bridge port ${t.cursorBuddyPort} is in use but did not answer health`)}else B(`CursorBuddy local bridge unavailable: ${x?.message||x}`);h=null}A.once("SIGINT",p),A.once("SIGTERM",p);let k=()=>{if(n)return;let x=Br(t.url,t.token,t);l="",B(`Connecting to ${x.replace(t.token,"redacted")}`),r=new ue(x),r.on("open",()=>{E=!1,w=null,B(`Connected. Registering @${t.handle||"agent"} from ${t.cwd}`),L(r,{type:"auth",token:t.token}),L(r,{action:"agent_register",workspaceId:t.workspace,agentId:t.agent,handle:t.handle,name:t.name,host:me.hostname(),cwd:t.cwd,metadata:{codingCmd:t.codingCmd,model:t.model,permissionMode:t.permissionMode,permissionFlags:Ge(t.permissionMode),once:t.once,runtime:"agensis",version:Z}}),o=setInterval(()=>{Promise.all([Zt(t,C()).catch(()=>null),Pe(t).catch(()=>null)]).then(([N,b])=>{L(r,{action:"agent_heartbeat",...N?{capabilitiesHash:N.capabilitiesHash,memoryHash:N.memoryHash}:{},metadata:Re(t,a,b,qt(t)?h?.getContext?.():null,g)})})},t.heartbeatMs),o.unref&&o.unref()}),r.on("message",N=>{let b=Le(N);if(b){if(b.type==="agent_registered"){E=!0,w=b.connection||b.agent||null,Jt(t,b.agent),B(`Registered as ${b.connection?.name||t.name} on ${b.connection?.host||me.hostname()}`),t.onRegistered&&Promise.resolve(t.onRegistered(t,b)).catch(O=>{B(`Profile save failed: ${O?.message||O}`)}),De(t,b.agent).catch(()=>{}),Ft(t).catch(()=>{}),zt(r,t),P(),ce(r,t,C());return}if(b.type==="agent_config"){Jt(t,b.agent),B(`Updated config for @${t.handle||"agent"}: model=${t.model}, permission=${t.permissionMode}`),De(t,b.agent).catch(()=>{});return}if(b.type==="agent_memory_refresh"){zt(r,t),ce(r,t,C());return}if(b.type==="agent_capabilities_refresh"){ce(r,t,C());return}if(b.type==="agent_inference_cancel"){g.get(String(b.requestId||""))?.abort();return}if(b.type==="agent_job_cancel"){let O=String(b.jobId||"");O&&a.cancel(O,b.reason||"Cancelled by Agensis")&&B(`Cancelled job ${O}`);return}if(b.type==="agent_inference_request"&&b.requestId){let O=String(b.requestId),$=t.sharedModels.find(R=>R.id===b.model),F=[...g.values()].filter(R=>R.model===b.model).length;if(!$){L(r,{action:"agent_inference_error",requestId:O,error:`Shared model '${b.model||""}' is not available.`});return}if(F>=$.maxConcurrency){L(r,{action:"agent_inference_error",requestId:O,error:"Shared model is at capacity.",code:"capacity_exhausted"});return}let G=new AbortController;g.set(O,{abort:()=>G.abort(),model:$.id}),L(r,{action:"agent_heartbeat",metadata:Re(t,a,null,null,g)}),Mt({models:t.sharedModels,request:b,signal:G.signal,send:R=>L(r,R)}).catch(R=>{L(r,{action:"agent_inference_error",requestId:O,error:G.signal.aborted?"Inference cancelled.":R?.message||String(R),code:G.signal.aborted?"cancelled":"inference_failed"})}).finally(()=>{g.delete(O),L(r,{action:"agent_heartbeat",metadata:Re(t,a,null,null,g)})});return}if(b.type==="peer_ticket"){let O=b.peer?.agentId,$=_.get(O)||[],F=$.shift();$.length?_.set(O,$):_.delete(O),F&&F.resolve(b);return}if(b.type==="peer_ticket_grant"){f.set(b.ticket,{fromAgentId:b.fromAgentId,exp:b.exp});return}if(b.type==="peer_list"){let O=I.shift();O&&O(Array.isArray(b.peers)?b.peers:[]);return}if(b.type==="agent_reach_disable"){m(),ce(r,t,C());return}if(b.type==="error"){B(`Server rejected request: ${b.message||"unknown error"}`);return}if(b.type==="agent_disabled"){E=!1,w=null,B(`Agent disabled by Agensis: ${b.reason||"deactivated"}`),p();return}if(b.type==="agent_job"&&b.job?.id){let O=a.enqueue({...b.job,key:b.job.id,lane:Ht(b.job),ws:r});O.accepted&&(c+=1,B(`Queued job ${b.job.id} at position ${O.position}`),t.once&&a.idle().then(()=>p()))}}}),r.on("close",(N,b)=>{Wt(g),E=!1,w=null;let O=String(b||"");if(B(`Socket closed (${N||"no-code"}${O?`: ${O}`:""})`),o&&(clearInterval(o),o=null),N===1008&&/agent deactivated|authentication failed/i.test(O)){B("Stopping daemon because Agensis rejected this agent connection."),p();return}if(l==="ECONNREFUSED"&&Pr(t.url)){B("Local agent backend is not running on 127.0.0.1:3142."),B("Start it in another terminal with: npm run backend"),B("Then rerun this connect command."),p();return}t.once&&c>0&&a.active()===0&&a.size()===0&&p(),!(n||t.once)&&(s=setTimeout(k,2e3),s.unref&&s.unref())}),r.on("error",N=>{l=N?.code||"",B(`Socket error: ${N?.message||N}`)})},D=async()=>{let x=await Pe(t).catch(()=>null);await Rt(t,{busy:a.active()>0,active:a.active(),queueSize:a.size(),connected:r?.readyState===ue.OPEN,agentStatus:x?.status,agentNote:x?.note}).catch(()=>{})};D(),i=setInterval(()=>{D()},t.heartbeatMs),i.unref&&i.unref(),k(),await new Promise(x=>{let N=setInterval(async()=>{t.once&&c>0&&a.active()===0&&a.size()===0&&p(),n&&p()},500);u=()=>{clearInterval(N),x()}}),u=null,A.off("SIGINT",p),A.off("SIGTERM",p)}function Tr(e){let t=$r(e.cursorBuddyBridge),n=e.noCoding===!0||A.env.AGENSIS_NO_CODING==="1",s=!se(e.fullCliContext,se(A.env.AGENSIS_FULL_CLI_CONTEXT,!1))&&se(e.leanCli,!0),o={url:String(e.url||e.baseUrl||A.env.AGENSIS_URL||"").trim(),token:String(e.token||A.env.AGENSIS_TOKEN||"").trim(),workspace:String(e.workspace||e.workspaceId||A.env.AGENSIS_WORKSPACE||A.env.AGENSIS_WORKSPACE_ID||"").trim(),agent:String(e.agent||e.agentId||A.env.AGENSIS_AGENT||A.env.AGENSIS_AGENT_ID||"").trim(),handle:nn(e.handle||A.env.AGENSIS_HANDLE||e.name||A.env.AGENSIS_NAME||"agent"),name:String(e.name||A.env.AGENSIS_NAME||e.handle||A.env.AGENSIS_HANDLE||"agensis Agent").trim(),cwd:String(e.cwd||A.env.AGENSIS_CWD||A.cwd()).trim(),codingCmd:n?"":String(e.codingCmd||A.env.AGENSIS_CODING_CMD||A.env.CODING_CMD||"claude -p").trim(),model:je(e.model||A.env.AGENSIS_MODEL||A.env.CLAUDE_MODEL||""),permissionMode:be(e.permissionMode||e.permission_mode||e.permission||A.env.AGENSIS_PERMISSION_MODE||"default"),timeoutMs:Number(e.timeoutMs||A.env.AGENSIS_TIMEOUT_MS||xr),heartbeatMs:Number(e.heartbeatMs||A.env.AGENSIS_HEARTBEAT_MS||Mr),maxConcurrency:Math.max(1,Number(e.maxConcurrency||A.env.AGENSIS_MAX_CONCURRENCY||Gt)||Gt),once:!!(e.once||A.env.AGENSIS_ONCE==="1"),exitOnOnce:!!e.exitOnOnce,onRegistered:typeof e.onRegistered=="function"?e.onRegistered:null,primaryDaemon:!!(e.primaryDaemon||A.env.AGENSIS_PRIMARY_DAEMON==="1"),cursorBuddyRuntime:!!(e.cursorBuddyRuntime||A.env.AGENSIS_CURSORBUDDY_RUNTIME==="1"),cursorBuddyBridge:t,cursorBuddyPort:Number(e.cursorBuddyPort||A.env.AGENSIS_CURSORBUDDY_PORT||8787),cursorBuddyBridgeSecret:String(e.cursorBuddyBridgeSecret||A.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),cursorBuddyModel:String(e.cursorBuddyModel||A.env.AGENSIS_CURSORBUDDY_MODEL||"haiku-4.5").trim(),lanListener:!!(e.lanListener||e.lan||A.env.AGENSIS_LAN==="1"),share:!!(e.share||A.env.AGENSIS_SHARE==="1"),sharedModelsFile:String(e.sharedModelsFile||A.env.AGENSIS_SHARED_MODELS_FILE||"").trim(),noCoding:n,leanCli:s,fastConnection:se(e.fastConnection,se(A.env.AGENSIS_FAST_CONNECTION,!0)),syncMemory:se(e.syncMemory,A.env.AGENSIS_SYNC_MEMORY==="1"),hostFolders:Vt(e.hostFolders??e.host_folders??A.env.AGENSIS_HOST_FOLDERS)};o.sharedModelsFile&&!de.isAbsolute(o.sharedModelsFile)&&(o.sharedModelsFile=de.resolve(o.cwd,o.sharedModelsFile));let i=[];if(o.url||i.push("--url"),o.token||i.push("--token"),o.workspace||i.push("--workspace"),o.agent||i.push("--agent"),o.share&&!o.sharedModelsFile&&i.push("--shared-models-file"),i.length)throw new Error(`Missing required option(s): ${i.join(", ")}`);return o}function se(e,t){return e==null||e===""?t:typeof e=="boolean"?e:!/^(0|false|off|no)$/i.test(String(e).trim())}function $r(e){let t=A.env.AGENSIS_CURSORBUDDY_BRIDGE;return t!==void 0&&t!==""?!/^(0|false|off|no)$/i.test(String(t).trim()):e==null||e===""?!1:typeof e=="boolean"?e:!/^(0|false|off|no)$/i.test(String(e).trim())}function Br(e,t,n={}){let r=Fe(e);return r.protocol=r.protocol==="https:"?"wss:":"ws:",r.pathname="/backend/ws",r.search="",n.workspace&&r.searchParams.set("workspaceId",n.workspace),n.agent&&r.searchParams.set("agentId",n.agent),r.toString()}function Fe(e){let t=new URL(e);return Dr(t)&&(t.protocol="http:",t.hostname="127.0.0.1",t.port="3142"),t}function Dr(e){if(!(e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="0.0.0.0")||e.port==="3142")return!1;if(e.port==="5173"||e.port==="8888")return!0;let t=Number(e.port||0);return t>=49152&&t<=65535}function Pr(e){try{let t=Fe(e);return(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="0.0.0.0")&&t.port==="3142"}catch{return!1}}function Ht(e){let t=String(e?.sessionId||""),n=String(e?.threadParentId||"");return`${t}::${n}`}var Rr=/\b(cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\b/i,Lr=[/\b(?:make|have|tell)\s+(?:the\s+)?(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\s+(?:say|speak)\s+(.+)$/i];function Ur(e){return String(e||"").trim().replace(/^[`"'“”‘’]+|[`"'“”‘’?.!]+$/g,"").trim().slice(0,1200)}function Fr(e){for(let t of Lr){let n=String(e||"").match(t),r=Ur(n?.[1]||"");if(r)return r}return""}function jr(e){let t=String(e||"").replace(/\s+/g," ").trim();if(!t)return"";let n=/latest user message\s*:\s*/gi,r=null,s=null;for(;r=n.exec(t);)s=r;if(!s)return"";let o=t.slice(s.index+s[0].length).trim(),i=o.search(/\b(Return a useful response|Conversation context follows|Previous user|Previous assistant|Diagnostic notes|System prompt|Developer message)\b/i);return(i>=0?o.slice(0,i):o).trim().replace(/^["'“”‘’]+|["'“”‘’]+$/g,"").trim()}function Gr(e){let t=String(e||"").replace(/\s+/g," ").trim(),r=jr(t)||t;if(!r)return"";if(r.length<=500)return r;let s=[/\b(?:can you\s+)?(?:make|have|tell)\s+(?:the\s+)?(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\s+(?:wave|waves|waving|say|speak)\b.{0,160}/i,/\b(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\b.{0,120}\b(?:wave|waves|waving|say|speak|open|show|hide|hush|close|dismiss|clear)\b.{0,160}/i,/\b(?:wave|open|show|hide|hush|close|dismiss|clear)\b.{0,120}\b(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy|bubble|prompt|dialog|panel|options|menu)\b/i,/\b(?:say|speak)\s+[`"'“”‘’]?.{1,180}/i];for(let o of s){let i=r.match(o);if(i?.[0])return i[0].trim()}return""}function Hr(e){let t=Gr(e);if(!t)return null;let n=/^(open|show|hide|hush|close|dismiss)\b/i.test(t),r=Rr.test(t);if(!n&&!r)return null;let s="agensis-native-control";if(/\b(hide|hush|close|dismiss|clear)\b.*\b(bubble|prompt|dialog|panel|options|menu)\b/i.test(t)||/^hush\b/i.test(t))return{action:"hush",source:s};if(/\b(open|show|bring up|get back|display)\b.*\b(prompt|bubble|dialog|panel|options|menu)\b/i.test(t)||/^open\b/i.test(t))return{action:"open",source:s};let o=Fr(t);return o&&r?{action:"say",text:o,source:s}:r&&/\b(wave|waves|waving)\b/i.test(t)?{action:"wave",text:o,source:s}:null}async function Jr(e,t){let r=`http://127.0.0.1:${Number(e.cursorBuddyPort||8787)}/cursorbuddy/control`,s=String(e.cursorBuddyBridgeSecret||A.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),o={"content-type":"application/json"};s&&(o.authorization=`Bearer ${s}`,o["x-agensis-bridge-secret"]=s);let i=await fetch(r,{method:"POST",headers:o,body:JSON.stringify(t)}),c=null;try{c=await i.json()}catch{c=null}if(!i.ok||c?.ok===!1)throw new Error(c?.error||`CursorBuddy control failed with HTTP ${i.status}`);return c}function Kr(e){return e.action==="wave"?"Sent CursorBuddy a wave command.":e.action==="say"?`Sent CursorBuddy speech: ${e.text||""}`.trim():e.action==="open"?"Opened CursorBuddy's prompt.":e.action==="hush"?"Dismissed CursorBuddy's bubble.":e.action==="choose"?"Sent CursorBuddy options.":"Sent CursorBuddy control command."}function qt(e={}){return e.cursorBuddyBridge===!1?!1:!!(e.cursorBuddyRuntime||e.primaryDaemon)}async function zr(e,t,n,r){let s="cursorbuddy-control",o="native",i=[],c=(l="")=>{L(t.ws,{action:"agent_job_delta",jobId:t.id,content:l,elapsedMs:Date.now()-r,model:s,permissionMode:o,permissionFlags:i})};c("");let u="",a="";try{await Jr(e,n),u=Kr(n),c(u)}catch(l){a=String(l?.message||l),u=`CursorBuddy control failed: ${a}`,c(u)}L(t.ws,{action:"agent_job_result",jobId:t.id,response:u,error:a,elapsedMs:Date.now()-r,model:s,permissionMode:o,permissionFlags:i}),B(`Finished native CursorBuddy ${n.action} job ${t.id} in ${Math.round((Date.now()-r)/1e3)}s`)}async function Wr(e,t,{signal:n}){let r=Date.now();B(`Starting job ${t.id}`);let s=Hr(t.prompt);if(s&&qt(e)){await zr(e,t,s,r),e.once&&(B("One-shot CursorBuddy control job complete; exiting."),setTimeout(()=>A.exit(0),150));return}let o=Xr(e,t),i=await qr(e,t),c="",u="",a=0,l=(m="")=>{L(t.ws,{action:"agent_job_delta",jobId:t.id,content:m,elapsedMs:Date.now()-r,model:o.model,permissionMode:o.permissionMode,permissionFlags:o.permissionFlags})},h=m=>{L(t.ws,{action:"agent_job_step",jobId:t.id,kind:m.kind,name:m.name,detail:m.detail,elapsedMs:Date.now()-r})},E=m=>{L(t.ws,{action:"agent_job_segment",jobId:t.id,text:m.text,elapsedMs:Date.now()-r})};l("");let w=o.streamJson?Vr({onStep:h,onSegment:E}):null,g=setInterval(()=>l(c),1e3);g.unref&&g.unref();let v=!/[\\/]/.test(o.cmd),S=e.fastConnection&&v?en(o.cmd)?"claude":tn(o.cmd)?"codex":null:null,_=await it(t,{family:S}).run({cmd:o.cmd,args:[...o.args,i],env:o.env,cwd:t.cwd||e.cwd,timeoutMs:e.timeoutMs,heartbeatMs:e.heartbeatMs,label:"agent job",signal:n,job:t,prompt:i,model:o.model,permissionMode:o.permissionMode,hostFolders:Qt(e,t),leanCli:e.leanCli,mcp:e.leanCli?Ue(e):null,sessionKey:`${t.workspaceId||e.workspace||""}:${e.agent||e.handle||""}`,clientVersion:Z,onData:m=>{w?(w.feed(m),c=w.live):(c+=String(m||""),u=so(`${u}
38
- ${m}`));let y=Date.now();y-a>150&&(a=y,l(c))}});clearInterval(g),w&&(w.end(),c=w.live,l(c));let I=String(_.stdout||"").trim(),C=String(_.stderr||"").trim(),T=_.error?_.error.message:_.status===0?"":C||`Command exited with status ${_.status}`,P=w?w.result||(T?"":C):I||(T?"":C)||u||"";L(t.ws,{action:"agent_job_result",jobId:t.id,response:P,error:T,elapsedMs:Date.now()-r,model:o.model,permissionMode:o.permissionMode,permissionFlags:o.permissionFlags}),B(`Finished job ${t.id} in ${Math.round((Date.now()-r)/1e3)}s`),e.once&&(B("One-shot job complete; exiting."),setTimeout(()=>A.exit(0),150))}async function qr(e,t){let n=t.agent||{},r=Array.isArray(n.skills)?n.skills.join(", "):String(n.skills||""),s=Array.isArray(n.tools)?n.tools.join(", "):String(n.tools||""),o=Yt(e,t),i=Xt(e,t),c=await jt(e).catch(()=>null),u=c?`Heartbeat (recurring instructions \u2014 edit at ${Pt(e)}):
18
+ `,io=8*1024,ao=400;co=16*1024,uo=["name","avatar","accent_color","description","soul"],lo=["cartesia_voice_id","voice_id","id","speed","emotion","attitude"]});import{spawn as _s,execFile as vs}from"node:child_process";import it from"node:fs";import we from"node:fs/promises";import Es from"node:os";import ce from"node:path";import{promisify as ks}from"node:util";function ct({homedir:e=Es.homedir()}={}){return ce.join(e,".agensis","versions")}function Oe(e,t){return ce.join(e,t)}function ut(e){return ce.join(e,Is)}function ae(e){return ce.join(e,"node_modules",at,"bin","agensis.mjs")}async function Un(e,t){await we.mkdir(ce.dirname(e),{recursive:!0}),await we.rm(e,{force:!0}),await we.symlink(t,e)}async function lt({root:e,version:t,log:n=()=>{}}){let r=Oe(e,t),s=ae(r);if(it.existsSync(s))return n(`[self-update] ${t} already installed at ${r}`),r;if(await we.mkdir(r,{recursive:!0}),n(`[self-update] installing ${at}@${t} into ${r}`),await As("npm",["install","--prefix",r,`${at}@${t}`,"--no-audit","--no-fund","--no-save","--omit=dev"]),!it.existsSync(s))throw new Error(`npm install reported success but ${s} is missing`);return r}function dt({entry:e,profileName:t,extraArgs:n=[],env:r=process.env}){let s=["connect","--profile",t,...n],o=_s(process.execPath,[e,...s],{detached:!0,stdio:"inherit",env:r});return o.unref(),o}async function mt(e,{graceMs:t=5e3}={}){return!e||e.exitCode!==null||e.killed||await new Promise(n=>{let r=!1,s=()=>{r||(r=!0,clearTimeout(o),n())},o=setTimeout(()=>{try{e.kill("SIGKILL")}catch{}},t);o.unref?.(),e.once("exit",s);try{e.kill("SIGTERM")}catch{s()}}),!0}async function ft({config:e,pid:t,timeoutMs:n=Fn}){let r=ce.join(q(e),"heartbeat.json"),s=Date.now()+n;for(;Date.now()<s;){try{let o=await we.readFile(r,"utf8"),i=JSON.parse(o);if(Number.isFinite(i.ts)&&Date.now()-i.ts<=Cs&&i.connected&&(t==null||i.pid===t))return!0}catch{}await new Promise(o=>setTimeout(o,xs))}return!1}async function jn({config:e,targetVersion:t,currentVersion:n,root:r=ct({}),profileName:s="default",runningChild:o=null,installFn:i=lt,spawnFn:c=dt,stopFn:u=mt,healthCheckFn:a=ft,healthTimeoutMs:l=Fn,log:g=()=>{}}={}){let w=await Ae(e)||{},f=n||w.currentVersion||null,h=ut(r),_={version:t,startedAt:new Date().toISOString()};if(t===f){let d={currentVersion:f,previousVersion:w.previousVersion||null,lastAttempt:{..._,result:"noop_already_current"}};return await ee(e,d),{...d,child:o}}let S;try{S=await i({root:r,version:t,log:g})}catch(d){let b={currentVersion:f,previousVersion:w.previousVersion||null,lastAttempt:{..._,result:"install_failed",error:String(d?.message||d)}};return await ee(e,b),{...b,child:o}}o&&await u(o),await Un(h,S);let p=ae(S),v=c({entry:p,profileName:s});if(await a({config:e,pid:v.pid,timeoutMs:l})){let d={currentVersion:t,previousVersion:f,lastAttempt:{..._,result:"ok"}};return await ee(e,d),{...d,child:v}}g(`[self-update] ${t} failed its health check within ${l}ms \u2014 rolling back to ${f||"(no known previous version)"}`),await u(v);let A=!1,T=null;if(f){let d=Oe(r,f);it.existsSync(ae(d))&&(await Un(h,d),T=c({entry:ae(d),profileName:s}),A=!0)}let B={currentVersion:A?f:w.currentVersion||f,previousVersion:f,lastAttempt:{..._,result:A?"rolled_back":"failed_no_fallback"}};return await ee(e,B),{...B,child:T}}var As,at,Is,Fn,xs,Cs,Gn=be(()=>{Ie();As=ks(vs),at="@agensis/agensis-agent",Is="current",Fn=3e4,xs=1e3,Cs=1e4});var Jn={};ht(Jn,{runSupervisor:()=>$s});import Ms from"node:fs";import pt from"node:fs/promises";import Ts from"node:path";async function Ns({root:e,runningVersion:t,installFn:n,log:r}){let s=ut(e);if(Ms.existsSync(s))return;r(`[supervise] no current version linked yet \u2014 adopting the running version ${t}`);let o=await n({root:e,version:t,log:r});await pt.mkdir(Ts.dirname(s),{recursive:!0}),await pt.rm(s,{force:!0}),await pt.symlink(o,s)}async function $s({config:e,runningVersion:t,profileName:n="default",pollIntervalMs:r=Os,root:s=ct({}),log:o=w=>process.stdout.write(`${w}
19
+ `),signal:i,installFn:c=lt,spawnFn:u=dt,stopFn:a=mt,healthCheckFn:l=ft,maxIterations:g=1/0}={}){if(!e?.workspace||!e?.agent)throw new Error("supervise requires a resolved profile with workspace + agent (run `agensis setup`/`agensis connect` first).");await Ns({root:s,runningVersion:t,installFn:c,log:o});let w=await Ae(e);w?.currentVersion||(w={currentVersion:t,previousVersion:null,lastAttempt:null},await ee(e,w));let f=null,h=!1,_=0,S=()=>{let k=Oe(s,w.currentVersion);return f=u({entry:ae(k),profileName:n}),f.on?.("exit",(A,T)=>{if(h)return;o(`[supervise] daemon (version ${w.currentVersion}) exited (code=${A} signal=${T}); respawning`);let B=Hn[Math.min(_,Hn.length-1)];_+=1,setTimeout(()=>{h||S()},B).unref?.()}),f.on?.("spawn",()=>{_=0}),f};S();let p=async()=>{h=!0,f&&await a(f)};i?.addEventListener("abort",()=>{p()}),process.once("SIGTERM",()=>{p().then(()=>process.exit(0))}),process.once("SIGINT",()=>{p().then(()=>process.exit(0))});let v=0;for(;!h&&!i?.aborted&&v<g&&(v+=1,await new Promise(T=>setTimeout(T,r)),!(h||i?.aborted));){let k=await dn(e);if(!k||k.targetVersion===w.currentVersion)continue;o(`[supervise] update requested: ${w.currentVersion} -> ${k.targetVersion}${k.note?` (${k.note})`:""}`);let A=await jn({config:e,targetVersion:k.targetVersion,currentVersion:w.currentVersion,root:s,profileName:n,runningChild:f,installFn:c,spawnFn:u,stopFn:a,healthCheckFn:l,log:o});await mn(e),w=A,f=A.child||f,_=0,o(`[supervise] update attempt "${k.targetVersion}" -> ${A.lastAttempt?.result} (running ${A.currentVersion})`)}return{state:w,child:f}}var Os,Hn,qn=be(()=>{Gn();Ie();Os=5e3,Hn=[1e3,5e3,15e3,3e4]});import V from"node:process";import pe from"node:fs";import he from"node:path";import ge from"node:os";import po from"node:crypto";import x from"node:process";import fe from"ws";import{spawn as zn}from"node:child_process";function gt(e){let t=Math.max(0,Math.round(e/1e3)),n=Math.floor(t/60),r=t%60;return n>0?`${n}m ${r}s`:`${r}s`}var Wn=50*1024*1024;function ue(e){let{cmd:t,args:n=[],env:r={},cwd:s,timeoutMs:o=0,label:i="working",heartbeatMs:c=15e3,input:u="",now:a=Date.now,log:l=console,signal:g,onData:w}=e||{};return new Promise(f=>{if(g?.aborted){f({status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")});return}let h;try{let y=n.some(C=>C==="--dangerously-skip-permissions"),I=typeof process.getuid=="function"&&process.getuid()===0,R={...process.env,...r};delete R.AGENSIS_TOKEN,delete R.ANTHROPIC_API_KEY,delete R.ANTHROPIC_AUTH_TOKEN,y&&I&&(R.IS_SANDBOX="1"),h=zn(t,n,{cwd:s,detached:!0,env:R})}catch(y){f({status:null,stdout:"",stderr:"",error:y});return}u?h.stdin?.end(String(u)):h.stdin?.end();let _="",S="";h.stdout?.setEncoding("utf8"),h.stderr?.setEncoding("utf8");let p=(y,I)=>y.length>=Wn?y:y+I;h.stdout?.on("data",y=>{if(_=p(_,y),w)try{w(y)}catch{}}),h.stderr?.on("data",y=>S=p(S,y));let v=a(),k=c>0?setInterval(()=>{l.log(` \u2026 still ${i} (${gt(a()-v)}) \u2014 Ctrl+C to cancel`)},c):null;k?.unref&&k.unref();let A=y=>{if(h.pid!=null)try{process.kill(-h.pid,y)}catch{try{h.kill(y)}catch{}}},T=!1,B=o>0?setTimeout(()=>{T=!0,A("SIGKILL")},o):null;B?.unref&&B.unref();let d=!1,b=null,M=()=>{d=!0,A("SIGTERM"),b=setTimeout(()=>A("SIGKILL"),3e3),b?.unref&&b.unref()};g&&g.addEventListener("abort",M,{once:!0});let m=(y,I)=>{k&&clearInterval(k),B&&clearTimeout(B),b&&clearTimeout(b),g&&g.removeEventListener("abort",M),f({status:y,stdout:_,stderr:S,aborted:d,error:I||(d?new Error("cancelled"):T?new Error(`timed out after ${gt(o)}`):null)})};h.on("error",y=>m(null,y)),h.on("close",y=>m(y,null))})}import{spawn as Yn}from"node:child_process";var St=10*60*1e3;function wt(e={}){let t={...process.env,...e};return delete t.AGENSIS_TOKEN,delete t.ANTHROPIC_API_KEY,delete t.ANTHROPIC_AUTH_TOKEN,t}var $e=class{#e=[];#t=[];#n=!1;push(t){if(this.#n)return;let n=this.#t.shift();n?n({value:t,done:!1}):this.#e.push(t)}close(){this.#n=!0;for(let t of this.#t.splice(0))t({value:void 0,done:!0})}[Symbol.asyncIterator](){return{next:()=>this.#e.length?Promise.resolve({value:this.#e.shift(),done:!1}):this.#n?Promise.resolve({value:void 0,done:!0}):new Promise(t=>this.#t.push(t))}}};function bt(){let e=new Map;return(t,n)=>{let r=(e.get(t)||Promise.resolve()).then(n,n);return e.set(t,r.catch(()=>{})),r}}var Vn=["mcp__agensis"],Xn=["Grep","Glob"];function Qn(e){return e==="yolo"?{permissionMode:"bypassPermissions",allowDangerouslySkipPermissions:!0}:e==="accept_edits"?{permissionMode:"acceptEdits"}:{permissionMode:"default"}}function Zn(e){if(!e||e.type!=="content_block_delta")return"";let t=e.delta;return t&&t.type==="text_delta"&&typeof t.text=="string"?t.text:""}function er(e){return`${JSON.stringify({type:"stream_event",event:{type:"content_block_delta",delta:{type:"text_delta",text:e}}})}
20
+ `}function tr(e){return`${JSON.stringify({type:"result",result:e})}
21
+ `}function nr(e){return`${JSON.stringify({type:"agensis_step",step:e})}
22
+ `}function rr(e){return`${JSON.stringify({type:"agensis_segment",segment:e})}
23
+ `}var or=["file_path","path","pattern","command","description","prompt"],yt=120;function De(e){if(!e||typeof e!="object")return"";for(let t of or){let n=e[t];if(typeof n!="string")continue;let r=n.replace(/\s+/g," ").trim();if(r)return r.length>yt?`${r.slice(0,yt)}\u2026`:r}return""}function _t(e){return JSON.stringify({cwd:e.cwd||"",model:e.model||"",permissionMode:e.permissionMode||"default",hostFolders:[...e.hostFolders||[]].sort(),leanCli:!!e.leanCli,mcpUrl:e.mcp?.url||"",mcpToken:e.mcp?.env?.AGENSIS_MCP_TOKEN||""})}function vt({queryFn:e,idleCloseMs:t=St}={}){let n=new Map,r=bt(),s=(u,a,l)=>{let g=n.get(u);if(!(!g||a&&g!==a))if(n.delete(u),clearTimeout(g.idleTimer),g.closed=!0,g.queue.close(),l&&g.activeTurn&&g.activeTurn.finish(l),typeof g.query.close=="function")try{g.query.close()}catch{}else Promise.resolve(g.query.return?.()).catch(()=>{})},o=u=>{let a=n.get(u);a&&(clearTimeout(a.idleTimer),a.idleTimer=setTimeout(()=>s(u),t),a.idleTimer.unref?.())},i=async(u,a)=>{let l=n.get(u),g=_t(a);if(l&&l.fingerprint===g&&!l.closed)return l;l&&s(u,l),e||(e=(await import("@anthropic-ai/claude-agent-sdk")).query);let w=new $e,f=Qn(a.permissionMode),h=a.leanCli&&a.mcp?{agensis:{type:"http",url:a.mcp.url,headers:{Authorization:"Bearer ${AGENSIS_MCP_TOKEN}"}}}:void 0,_=e({prompt:w,options:{cwd:a.cwd,model:a.model,...f,allowedTools:[...Vn,...Xn],additionalDirectories:a.hostFolders&&a.hostFolders.length?a.hostFolders:void 0,mcpServers:h,strictMcpConfig:a.leanCli?!0:void 0,settingSources:a.leanCli?[]:void 0,persistSession:a.leanCli?!1:void 0,includePartialMessages:!0,env:wt(a.mcp?.env)}});return l={query:_,queue:w,sessionId:"",idleTimer:null,activeTurn:null,closed:!1,terminalError:null,fingerprint:g},n.set(u,l),l.pump=(async()=>{let S=null;try{for await(let p of _){p.session_id&&(l.sessionId=p.session_id);let v=l.activeTurn;if(v){if(p.type==="stream_event"){let k=Zn(p.event);k&&(v.streamed+=k,v.onData?.(er(k)))}else if(p.type==="result")if(p.subtype==="success"){let k=p.result==null?v.text:String(p.result);v.onData?.(tr(k)),v.finish({status:0,stdout:k,stderr:"",error:null})}else{let k=Array.isArray(p.errors)?p.errors.filter(Boolean).join(`
24
+ `):p.result,A=new Error(k||`claude-agent-sdk result error: ${p.subtype}`);v.finish({status:1,stdout:v.text,stderr:A.message,error:A})}else if(p.type==="assistant"){let k=p.message?.content;if(Array.isArray(k)){let A=k.filter(T=>T&&T.type==="text"&&typeof T.text=="string").map(T=>T.text).join("");A&&(v.onData?.(rr({text:A})),v.flushed+=v.streamed,v.streamed="");for(let T of k)!T||T.type!=="tool_use"||!T.name||v.onData?.(nr({kind:"tool",name:String(T.name),detail:De(T.input)}))}}}}S=new Error("claude-agent-sdk connection closed")}catch(p){S=p}finally{l.closed=!0,l.terminalError=S,clearTimeout(l.idleTimer),l.queue.close(),n.get(u)===l&&n.delete(u),l.activeTurn&&l.activeTurn.finish({status:null,stdout:l.activeTurn.text,stderr:String(S?.message||S||""),error:S})}})(),l};return{run:u=>r(u.sessionKey||"default",async()=>{let{sessionKey:a="default",prompt:l,signal:g,onData:w,timeoutMs:f=0}=u;if(g?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let h;try{h=await i(a,u)}catch(S){return{status:null,stdout:"",stderr:"",error:S}}if(h.closed){let S=h.terminalError||new Error("claude-agent-sdk connection closed");return{status:null,stdout:"",stderr:String(S.message||S),error:S}}clearTimeout(h.idleTimer);let _=await new Promise(S=>{let p=!1,v=null,k={streamed:"",flushed:"",get text(){return this.flushed+this.streamed},onData:w,finish(T){p||(p=!0,h.activeTurn===k&&(h.activeTurn=null),g&&g.removeEventListener("abort",A),v&&clearTimeout(v),S(T))}},A=()=>{let T={status:null,stdout:k.text,stderr:"",aborted:!0,error:new Error("cancelled")};Promise.resolve(h.query.interrupt?.()).catch(()=>{}),s(a,h,T)};h.activeTurn=k,g&&g.addEventListener("abort",A,{once:!0}),f>0&&(v=setTimeout(()=>{let T=new Error(`timed out after ${f}ms`);Promise.resolve(h.query.interrupt?.()).catch(()=>{}),s(a,h,{status:null,stdout:k.text,stderr:T.message,error:T})},f),v.unref?.()),h.queue.push({type:"user",message:{role:"user",content:l},parent_tool_use_id:null,session_id:h.sessionId})});return n.get(a)===h&&o(a),_}),shutdown:()=>{for(let u of[...n.keys()])s(u)}}}function sr(e){let t=1,n="",r=new Map,s=new Set;e.stdout.setEncoding("utf8"),e.stdout.on("data",i=>{n+=i;let c;for(;(c=n.indexOf(`
25
+ `))>=0;){let u=n.slice(0,c);if(n=n.slice(c+1),!u.trim())continue;let a;try{a=JSON.parse(u)}catch{continue}if(a.id!==void 0&&r.has(a.id)){let{resolve:l,reject:g}=r.get(a.id);r.delete(a.id),a.error?g(new Error(a.error.message||"codex app-server error")):l(a.result)}else if(a.method)for(let l of s)l(a.method,a.params,a.id)}});let o=i=>{for(let{reject:c}of r.values())c(i);r.clear()};return e.on("exit",()=>o(new Error("codex app-server exited"))),e.on("error",i=>o(i)),{request(i,c){let u=t++;return new Promise((a,l)=>{r.set(u,{resolve:a,reject:l}),e.stdin.write(`${JSON.stringify({id:u,method:i,params:c})}
26
+ `)})},notify(i,c){e.stdin.write(`${JSON.stringify({method:i,params:c})}
27
+ `)},respond(i,c){e.stdin.write(`${JSON.stringify({id:i,result:c})}
28
+ `)},respondError(i,c){e.stdin.write(`${JSON.stringify({id:i,error:{code:-32601,message:c}})}
29
+ `)},onMessage(i){return s.add(i),()=>s.delete(i)}}}function ir(e){return e==="yolo"?{approvalPolicy:"never",sandbox:"danger-full-access"}:{}}function Et({spawnFn:e=Yn,idleCloseMs:t=St}={}){let n=new Map,r=bt(),s=u=>{let a=n.get(u);if(a){n.delete(u),clearTimeout(a.idleTimer);try{a.child.kill("SIGTERM")}catch{}}},o=u=>{let a=n.get(u);a&&(clearTimeout(a.idleTimer),a.idleTimer=setTimeout(()=>s(u),t),a.idleTimer.unref?.())},i=async(u,a)=>{let l=n.get(u),g=_t(a);if(l&&l.fingerprint===g)return l;l&&s(u);let w=e("codex",["app-server"],{cwd:a.cwd,env:wt(a.mcp?.env),stdio:["pipe","pipe","pipe"]}),f=sr(w);await f.request("initialize",{clientInfo:{name:"agensis-agent",version:a.clientVersion||"unknown"}}),f.notify("initialized");let h=a.leanCli&&a.mcp?{mcp_servers:{agensis:{url:a.mcp.url,bearer_token_env_var:"AGENSIS_MCP_TOKEN"}}}:void 0,_=await f.request("thread/start",{cwd:a.cwd,ephemeral:a.leanCli||void 0,model:a.model,config:h,...ir(a.permissionMode)}),S={child:w,rpc:f,threadId:_.thread.id,fingerprint:g,idleTimer:null};return n.set(u,S),S};return{run:u=>r(u.sessionKey||"default",async()=>{let{sessionKey:a="default",prompt:l,signal:g,onData:w,timeoutMs:f=0}=u;if(g?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let h;try{h=await i(a,u)}catch(A){return{status:null,stdout:"",stderr:"",error:A}}let _="",S="",p=null,v=!1,k=await new Promise(A=>{let T=!1,B=y=>{T||(T=!0,m(),A(y))},d=h.rpc.onMessage((y,I,R)=>{if(R!==void 0){if(y==="item/commandExecution/requestApproval"){let C=u.permissionMode==="yolo"?"acceptForSession":"decline";h.rpc.respond(R,{decision:C})}else if(y==="item/fileChange/requestApproval"){let C=u.permissionMode==="yolo"||u.permissionMode==="accept_edits"?"acceptForSession":"decline";h.rpc.respond(R,{decision:C})}else h.rpc.respondError(R,`Agensis daemon cannot handle Codex request ${y}`);return}if(!(!I||I.threadId!==h.threadId)){if(y==="turn/started"){p=I.turn?.id??p;return}if(!(p&&I.turnId&&I.turnId!==p)){if(y==="item/agentMessage/delta")_+=I.delta||"",w?.(I.delta||"");else if(y==="item/completed"&&I.item?.type==="agentMessage")S=I.item.text||S;else if(y==="turn/completed"){let C=I.turn?.status==="failed"||I.turn?.error;B({status:C?1:0,stdout:S||_,stderr:C?String(I.turn?.error?.message||I.turn?.error||""):"",error:C?new Error(String(I.turn?.error?.message||I.turn?.error||"codex turn failed")):null})}}}}),b=()=>{v=!0,h.rpc.request("turn/interrupt",{threadId:h.threadId}).catch(()=>{});let y={status:null,stdout:_,stderr:"",aborted:!0,error:new Error("cancelled")};B(y),s(a)};g&&g.addEventListener("abort",b,{once:!0});let M=f>0?setTimeout(()=>{let y=new Error(`timed out after ${f}ms`);h.rpc.request("turn/interrupt",{threadId:h.threadId}).catch(()=>{}),B({status:null,stdout:_,stderr:y.message,error:y}),s(a)},f):null;M?.unref?.();function m(){d(),g&&g.removeEventListener("abort",b),M&&clearTimeout(M)}h.rpc.request("turn/start",{threadId:h.threadId,input:[{type:"text",text:l}]}).then(y=>{p=y?.turn?.id||p}).catch(y=>B({status:null,stdout:"",stderr:"",error:y}))});return v||o(a),k}),shutdown:()=>{for(let u of[...n.keys()])s(u)}}}function xt({run:e=ue}={}){return{run:t=>e(t)}}var ur=null,lr=null,It=new Set;function dr(e){let t=String(e&&e.message||e||"");return/Cannot find module|ERR_MODULE_NOT_FOUND|ENOENT|command not found/i.test(t)}function mr(e,{local:t,pooled:n,log:r=console}={}){let s=t||xt(),o=n||(e==="claude"?ur||=vt():e==="codex"?lr||=Et():null);return o?{async run(i){if(It.has(e))return s.run(i);let c=await o.run(i);return c.error&&dr(c.error)?(It.add(e),r.log?.(`[executor] ${e} fast connection unavailable (${c.error.message}); falling back to subprocess mode for this and future jobs.`),s.run(i)):c}}:s}function fr(e){return{async run({cmd:t,args:n=[],env:r={},onData:s,signal:o,job:i}){let c=null;try{c=await e.ensureEnv({job:i,signal:o}),await e.putRepo(c,{job:i,signal:o});let u=await e.exec(c,{cmd:t,args:n,env:r,onData:s,signal:o}),a=await e.getResult(c,{job:i}).catch(()=>({})),l=a&&a.patch?String(a.patch).trim():"",g=l?`${u.stdout||""}
30
+
31
+ \`\`\`diff
32
+ ${l}
33
+ \`\`\``:u.stdout||"";return{status:u.status,stdout:g,stderr:u.stderr||"",error:u.error||null}}catch(u){return{status:null,stdout:"",stderr:"",error:u}}finally{if(c)try{await e.destroy(c)}catch{}}}}}function Ct(e,{makeProvider:t,family:n}={}){return(e&&e.agent&&e.agent.run_mode)==="sandbox"?fr((t||pr)(e)):n==="claude"||n==="codex"?mr(n):xt()}function pr(e){let t=e.agent&&e.agent.sandbox_provider||"e2b",n=e.agent&&e.agent.sandbox_config||{};if(t!=="e2b")throw new Error(`Sandbox provider "${t}" is not available yet (only e2b is wired).`);return gr({apiKey:process.env.E2B_API_KEY,anthropicApiKey:process.env.ANTHROPIC_API_KEY,gitToken:process.env.GIT_TOKEN||"",repoUrl:e.repoUrl||e.agent&&e.agent.repo_url||n.repoUrl||"",template:n.template||""})}function hr(e=process.versions.node){let[t,n,r]=String(e).split(".").map(s=>Number(s)||0);return t===21?!1:t>=22?!0:t!==20?!1:n>18?!0:n<18?!1:r>=1}function gr(e){let t=null,n=async()=>{if(!t){if(!hr())throw new Error(`Sandbox execution requires Node >=20.18.1 (you have ${process.versions.node}). Upgrade Node to use Sandbox agents; Built-in and Remote daemon modes still work on Node 18.`);t=(await Promise.resolve().then(()=>(At(),kt))).createE2bProvider(e)}return t};return{ensureEnv:async r=>(await n()).ensureEnv(r),putRepo:async(r,s)=>(await n()).putRepo(r,s),exec:async(r,s)=>(await n()).exec(r,s),getResult:async(r,s)=>(await n()).getResult(r,s),destroy:async r=>(await n()).destroy(r)}}function Mt(e={}){let{runJob:t}=e,n=Math.max(1,Number(e.concurrency)||1),r=new Map,s=0,o=[];function i(S){let p=r.get(S);return p||(p={queued:[],active:null},r.set(S,p)),p}function c(S){if(S==null)return!1;for(let p of r.values())if(p.active&&!p.active.cancelled&&p.active.job.key===S||p.queued.some(v=>v.key===S))return!0;return!1}function u(){for(let[S,p]of r){if(s>=n)break;if(p.active||p.queued.length===0)continue;let v=p.queued.shift(),k=new AbortController;p.active={job:v,controller:k,cancelled:!1},s+=1,Promise.resolve().then(()=>k.signal.aborted?void 0:t(v,{signal:k.signal})).catch(()=>{}).finally(()=>{p.active=null,s-=1,p.queued.length===0&&!p.active&&r.delete(S),u(),a()})}}function a(){if(s>0)return;for(let p of r.values())if(p.queued.length)return;let S=o;o=[];for(let p of S)p()}function l(S){if(S&&S.key!=null&&c(S.key))return{accepted:!1,deduped:!0,position:0,startedImmediately:!1};let p=S&&S.lane!=null?String(S.lane):"",v=i(p),k=!v.active&&v.queued.length===0&&s<n;v.queued.push(S);let A=v.queued.length+(v.active?1:0);return u(),{accepted:!0,deduped:!1,position:A,startedImmediately:k}}function g(S,p){let v=!1;for(let[k,A]of r)p!=null&&k!==String(p)||A.active&&(A.active.cancelled=!0,A.active.controller.abort(S||"cancelled"),v=!0);return v}function w(S,p){if(S==null)return!1;let v=!1;for(let[k,A]of[...r]){A.active?.job?.key===S&&(A.active.cancelled=!0,A.active.controller.abort(p||"cancelled"),v=!0);let T=A.queued.length;A.queued=A.queued.filter(B=>B.key!==S),A.queued.length!==T&&(v=!0),!A.active&&A.queued.length===0&&r.delete(k)}return a(),v}function f(){let S=0;for(let p of r.values())S+=p.queued.length;return S}function h(){return s}function _(){return s===0&&f()===0?Promise.resolve():new Promise(S=>o.push(S))}return{enqueue:l,cancel:w,cancelActive:g,has:c,size:f,active:h,idle:_}}import Bt from"node:crypto";import yr from"node:http";import Rt from"node:os";import X from"node:process";var Tt=8787,Re="claude-haiku-4-5",Sr=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/,wr=100,br=new Set(["say","wave","hush","open","choose"]),Ee="x-agensis-bridge-secret";function _r(){return`cbs_${Bt.randomBytes(24).toString("base64url")}`}function vr(e){let t=e?.headers||{},n=String(t[Ee]||t[Ee.toLowerCase()]||"").trim();if(n)return n;let s=String(t.authorization||t.Authorization||"").trim().match(/^Bearer\s+(.+)$/i);return s?s[1].trim():""}function Er(e,t){let n=String(t||""),r=vr(e);if(!n||!r)return!1;let s=Buffer.from(r),o=Buffer.from(n);return s.length!==o.length?!1:Bt.timingSafeEqual(s,o)}function kr(e={},t={}){let n=String(t.authSecret||"").trim();if(n)return n;let r=String(e.cursorBuddyBridgeSecret||"").trim();if(r)return r;let s=String(X.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim();return s||_r()}function Ar(e,t){return e==="OPTIONS"||e==="GET"&&t==="/cursorbuddy/health"}function j(e,t,n){e.writeHead(t,{"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST, OPTIONS","access-control-allow-headers":"content-type, authorization, x-agensis-bridge-secret"}),e.end(JSON.stringify(n))}function Ot(e){e.writeHead(200,{"content-type":"text/event-stream; charset=utf-8","cache-control":"no-store, no-transform",connection:"keep-alive","access-control-allow-origin":"*","access-control-allow-methods":"GET, POST, OPTIONS","access-control-allow-headers":"content-type, authorization, x-agensis-bridge-secret","x-accel-buffering":"no"})}function K(e,t){e.write(`data: ${typeof t=="string"?t:JSON.stringify(t)}
34
+
35
+ `)}function le(e){return new Promise((t,n)=>{let r="";e.on("data",s=>{r+=s,r.length>256*1024&&(n(new Error("request body is too large")),e.destroy())}),e.on("error",n),e.on("end",()=>t(r))})}function Ir(e){let t=[],n="",r="",s=!1;for(let o of String(e||"")){if(s){n+=o,s=!1;continue}if(o==="\\"){s=!0;continue}if(r){o===r?r="":n+=o;continue}if(o==='"'||o==="'"){r=o;continue}if(/\s/.test(o)){n&&(t.push(n),n="");continue}n+=o}if(n&&t.push(n),!t.length)throw new Error("coding command is empty");return{cmd:t[0],args:t.slice(1)}}function xr(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function _e(e,t){return e.some(n=>n===t||String(n).startsWith(`${t}=`))}function Nt(e,t){let n=[];t&&n.push("CursorBuddy local runtime context:",JSON.stringify(t,null,2),"");for(let r of Array.isArray(e)?e:[]){let s=String(r?.role||"user"),o=String(r?.content||"");o.trim()&&n.push(`${s.toUpperCase()}:
36
+ ${o}`)}return n.join(`
37
+
38
+ `).trim()||"Say that the local Agensis runtime is connected."}function $t(e){let t=String(e||"").trim();if(!t)return"";try{let n=JSON.parse(t);if(typeof n?.result=="string")return n.result;if(typeof n?.message=="string")return n.message;if(typeof n?.content=="string")return n.content}catch{}return t}function Cr(e){let t=Array.isArray(e?.messages)?e.messages:[];for(let n=t.length-1;n>=0;n-=1){let r=t[n];if(String(r?.role||"user")!=="user")continue;let s=String(r?.content||"").trim();if(s)return s}return""}function Mr(e,t=280){let n=Cr(e).replace(/\s+/g," ").trim();if(!n)return"";if(n.length<=t)return n;let r=[/\b(tell me (?:a )?joke)\b/i,/\b(make (?:him|the buddy|cursorbuddy|avatar) wave|wave(?: hello)?|say hi|say hello)\b/i,/\b(what site|which site|what page|where am i|where are you|current url)\b/i,/\b(are you connected|connected|working|online|there)\b/i,/\b(show|guide|tour|walk|around|sections?|features?|important|highlight|what can i do|what should i do|help me)\b/i,/\b(open|show|bring up|get back|display)\b.{0,80}\b(prompt|bubble|dialog|panel|options|menu)\b/i,/\b(hide|hush|close|dismiss|clear|stop|cancel|be quiet)\b.{0,80}\b(bubble|prompt|dialog|panel|options|menu)?\b/i,/^(hi|hello|hey|yo|sup)\b/i];for(let s of r){let o=n.match(s);if(o?.[0])return o[0].trim()}return n.slice(-t).trim()}function Tr(e){let t=Mr(e);if(!t)return null;if(/\b(?:him|the buddy|cursorbuddy|cursor buddy|avatar|buddy|pet|character)\b/i.test(t)&&/\bwave(?: hello)?\b/i.test(t))return{content:"Waving now.",command:{action:"wave",text:"Hi. How can I help?",source:"chat"}};let r=t.match(/^(?:say|speak)\s+(.{1,180})$/i)||t.match(/\b(?:make|tell)\s+(?:him|the buddy|cursorbuddy|avatar)\s+(?:say|speak)\s+(.{1,180})$/i);return r?.[1]?{content:"Saying it now.",command:{action:"say",text:r[1].trim(),source:"chat"}}:/^(stop|cancel|dismiss|close|hide|hush|be quiet)\b/i.test(t)?{content:"Closed.",command:{action:"hush",source:"chat"}}:/\b(open|show)\b.*\b(options|chat|bubble|prompt)\b/i.test(t)?{content:"Opening options.",command:{action:"open",text:"What should I help with?",source:"chat"}}:null}function Or(e){let t=String(e||"").trim();return t?/\s/.test(t)||t.startsWith("-")?!0:/^(claude|codex|node|npm|bun|python|python3|sh|bash|zsh)(?:$|\.)/.test(t):!1}function Pt(e,t){let n=String(e||"").trim();return!n||Or(n)?t:n}function Lt(e){let t=String(e||"").trim();return!t||t==="haiku-4.5"||t==="claude-haiku-4.5"?Re:t}function Pe(e={}){return Lt(e.cursorBuddyModel||X.env.AGENSIS_CURSORBUDDY_MODEL||Re)}function Dt(e,t,n,r={}){let{cmd:s,args:o}=Ir(e.codingCmd||"claude -p"),i=[...o],c=Lt(Pt(n,Pe(e))),u="",a=!1;return xr(s)?(c&&!_e(i,"--model")&&i.push("--model",c),r.stream===!0&&!_e(i,"--output-format")?(i.push("--output-format","stream-json","--include-partial-messages"),_e(i,"--verbose")||i.push("--verbose"),a=!0):(_e(i,"--output-format")||i.push("--output-format","json"),a=i.some(g=>String(g).includes("stream-json"))),u=t):i.push(t),{cmd:s,args:i,model:c,stdin:u,streamJson:a}}function Nr(e=()=>{}){let t="",n="",r=!1,s="",o=null,i=a=>{a&&e(a)},c=a=>{if(!a||typeof a!="object")return;let l=a.event&&a.event.delta||a.delta;if(l&&l.type==="text_delta"&&typeof l.text=="string"){r=!0,n+=l.text,i(l.text);return}if(a.type==="result"&&typeof a.result=="string"){o=a.result;return}if(a.type==="assistant"&&a.message&&Array.isArray(a.message.content)){let g=a.message.content.filter(w=>w&&w.type==="text"&&typeof w.text=="string").map(w=>w.text).join("");g&&(s+=g)}},u=a=>{let l=String(a).trim();if(l)try{c(JSON.parse(l))}catch{}};return{feed(a){t+=String(a||"");let l;for(;(l=t.indexOf(`
39
+ `))>=0;)u(t.slice(0,l)),t=t.slice(l+1)},end(){t&&(u(t),t="")},get live(){return r?n:s},get result(){return o??(r?n:s)}}}function re(e,t,n,r=null){return{id:e,object:"chat.completion.chunk",created:Math.floor(Date.now()/1e3),model:t,choices:[{index:0,delta:n?{content:n}:{},finish_reason:r}]}}function ve(e){return`http://127.0.0.1:${e}`}function $r(e={},t={}){return String(t.agensisUrl||t.baseUrl||e.url||X.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function Dr(e){return String(e||"").slice(0,18)}function U(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Br(e={},t={},n={}){let r=U(e.metadata)||{},s=U(e.page)||U(r.page)||{},o=U(e.client)||U(r.client)||{},i=U(r.runtime)||{},c=U(e.manifest)||U(r.manifest)||null;return{url:String(e.url||s.url||r.websiteSource||e.websiteSource||"").slice(0,2048),title:String(e.title||s.title||"").slice(0,300),surface:String(e.surface||i.surface||t.surface||"").slice(0,80),instanceId:String(e.instanceId||i.instanceId||"").slice(0,140),workspaceId:String(t.workspaceId||e.workspaceId||n.workspace||"").slice(0,120),agentId:String(t.agentId||e.agentId||n.agent||"").slice(0,120),runtime:{...i,local:!0,connected:!0,connection:t},page:s,client:o,project:U(e.project)||U(r.project)||null,manifest:c,selection:U(e.selection)||null,updatedAt:new Date().toISOString()}}function Rr(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function Pr(e,t={},n=globalThis.fetch){let r=String(t.key||"").trim();if(!Sr.test(r))throw new Error("Connection key format is invalid. Create a fresh CursorBuddy key first.");if(typeof n!="function")throw new Error("This Node.js runtime does not provide fetch; use a current Node.js release.");let s=$r(e,t),o=await n(`${s}/backend/cursorbuddy/connection-keys/claim`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({key:r,baseUrl:s,host:Rt.hostname(),cwd:t.cwd||e.cwd||X.cwd(),name:t.name||e.name||e.handle||"CursorBuddy runtime",surface:t.surface||"browser_extension",scope:t.scope||"machine",runtimeKind:t.runtimeKind||"agensis-cli-local-bridge",version:t.version||e.version||X.env.npm_package_version||"",permissionMode:t.permissionMode||e.permissionMode,model:t.model||e.model,metadata:U(t.metadata)||null,websiteSource:t.websiteSource||t.metadata?.websiteSource||"",page:U(t.page)||U(t.metadata?.page)||null,client:U(t.client)||U(t.metadata?.client)||null,manifest:U(t.manifest)||U(t.metadata?.manifest)||null})}),i=await o.json().catch(()=>({}));if(!o.ok)throw new Error(Rr(o,i));return{key:r,baseUrl:s,data:i?.data||i}}async function Ut(e,t={}){let n=Number(t.port??e.cursorBuddyPort??X.env.AGENSIS_CURSORBUDDY_PORT??Tt),r=kr(e,t),s=new Date().toISOString(),o=[],i=[],c=new Set,u=t.fetchImpl||globalThis.fetch,a=1,l=null,g=n,w=null,f=(d,b={})=>{let M={ts:new Date().toISOString(),event:d,detail:b};return o.push(M),o.length>200&&o.shift(),t.log?.(`CursorBuddy local bridge: ${d}${Object.keys(b).length?` ${JSON.stringify(b)}`:""}`),M},h=()=>({connected:!!e.cursorBuddyRuntime,mode:e.cursorBuddyRuntime?"agensis-cli":"agensis-cli-unclaimed",agentId:e.agent,workspaceId:e.workspace,agensisUrl:e.url,handle:e.handle,name:e.name,cwd:e.cwd,updatedAt:new Date().toISOString()}),_=()=>{if(typeof t.connectionProvider!="function")return null;try{let d=t.connectionProvider();return!d||typeof d!="object"||Array.isArray(d)?null:{...h(),...d,connected:d.connected===!0}}catch{return null}},S=()=>{let d=_();return d?.connected===!1?d:w?{...h(),...d||{},...w,connected:!0,updatedAt:d?.updatedAt||w.updatedAt}:d||h()};function p(d={}){if(!d||typeof d!="object"||Array.isArray(d))return null;let b=String(d.action||d.type||"").trim().toLowerCase();if(!br.has(b))return null;let M={id:a++,ts:new Date().toISOString(),action:b,text:String(d.text||d.say||d.message||"").slice(0,1200),label:String(d.label||"").slice(0,80),value:String(d.value||d.prompt||"").slice(0,1200),holdMs:Number.isFinite(d.holdMs)?Math.max(0,Math.min(6e4,d.holdMs)):void 0,source:String(d.source||"agensis-daemon").slice(0,80)};return d.options&&Array.isArray(d.options)&&(M.options=d.options.map(m=>({label:String(m?.label||"").slice(0,80),value:String(m?.value||m?.task||"").slice(0,1200)})).filter(m=>m.label).slice(0,6)),M}function v(d){for(i.push(d);i.length>wr;)i.shift();f("control",{id:d.id,action:d.action,chars:d.text.length});for(let b of[...c])try{K(b,{type:"command",command:d})}catch{c.delete(b)}return d}function k(d){let b=Tr(d);if(b){let M=p(b.command);return M&&(v(M),f("chat_control",{id:M.id,action:M.action})),{content:b.content,model:"cursorbuddy-local-control",fast:!0}}return null}async function A(d){let b=k(d);if(b)return b;let M=Nt(d?.messages,l),m=Dt(e,M,d?.model),y=await ue({cmd:m.cmd,args:m.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:m.stdin});if(y.error||y.status!==0)throw new Error(y.error?.message||String(y.stderr||"").trim()||`Command exited with status ${y.status}`);return{content:$t(y.stdout||y.stderr),model:m.model}}async function T(d,b){let M=`agensis-cursorbuddy-${Date.now()}`,m=k(d);if(m){let $=m.model||"cursorbuddy-local-control";return K(b,re(M,$,m.content)),K(b,re(M,$,"","stop")),K(b,"[DONE]"),f("chat_fast",{chars:m.content.length,model:$}),{content:m.content,model:$,fast:!0}}let y=Nt(d?.messages,l),I=Dt(e,y,d?.model,{stream:!0}),R="",C=$=>{$&&(R+=$,K(b,re(M,I.model||e.model,$)))},N=I.streamJson?Nr(C):null,E=await ue({cmd:I.cmd,args:I.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:I.stdin,onData:$=>{if(N)N.feed($);else{let F=String($||"");R+=F,K(b,re(M,I.model||e.model,F))}}});if(N){N.end();let $=N.result||"";!R&&$?C($):R=$||R}if(E.error||E.status!==0){let $=E.error?.message||String(E.stderr||"").trim()||`Command exited with status ${E.status}`;throw new Error($)}let O=N?R:$t(R||E.stdout||E.stderr);return!N&&O&&O!==R&&(K(b,re(M,I.model||e.model,O)),R=O),K(b,re(M,I.model||e.model,"","stop")),K(b,"[DONE]"),{content:R||O,model:I.model}}let B=yr.createServer(async(d,b)=>{if(b.setHeader("access-control-allow-origin","*"),b.setHeader("access-control-allow-methods","GET, POST, OPTIONS"),b.setHeader("access-control-allow-headers","content-type, authorization, x-agensis-bridge-secret"),d.method==="OPTIONS"){b.writeHead(204),b.end();return}let M=new URL(d.url||"/",ve(g||Tt));if(!Ar(d.method,M.pathname)&&!Er(d,r)){j(b,401,{ok:!1,error:"Authentication required",code:"bridge_auth_required"});return}if(d.method==="GET"&&M.pathname==="/cursorbuddy/health"){let m=ve(g);j(b,200,{ok:!0,runtime:"agensis-cli",backend:e.codingCmd,model:Pe(e),daemonModel:e.model,port:g,host:Rt.hostname(),pid:X.pid,bootedAt:s,authRequired:!0,authHeader:Ee,stream:!0,streaming:!0,supportsStreaming:!0,chatStream:!0,capabilities:{chatStream:!0,controlStream:!0,fastAvatarReplies:!1,nativeCursorBuddyControl:!0},latestControlId:i.at(-1)?.id||0,connection:S(),context:l,endpoints:{chat:`${m}/v1/chat/completions`,chatStream:`${m}/v1/chat/completions`,edit:`${m}/cursorbuddy/edit`,context:`${m}/cursorbuddy/context`,control:`${m}/cursorbuddy/control`,controlStream:`${m}/cursorbuddy/control/stream`,logs:`${m}/cursorbuddy/logs`}});return}if(d.method==="GET"&&M.pathname==="/cursorbuddy/logs"){j(b,200,{ok:!0,events:o.slice(-100)});return}if(d.method==="GET"&&M.pathname==="/cursorbuddy/context"){j(b,200,{ok:!0,context:l});return}if(d.method==="GET"&&M.pathname==="/cursorbuddy/control"){let m=Number(M.searchParams.get("after")||0),y=i.filter(I=>I.id>m);j(b,200,{ok:!0,commands:y,latestId:i.at(-1)?.id||0});return}if(d.method==="GET"&&M.pathname==="/cursorbuddy/control/stream"){let m=Number(M.searchParams.get("after")||0);Ot(b),c.add(b),K(b,{type:"ready",latestId:i.at(-1)?.id||0});for(let I of i.filter(R=>R.id>m))K(b,{type:"command",command:I});let y=setInterval(()=>{try{K(b,{type:"ping",ts:new Date().toISOString()})}catch{c.delete(b),clearInterval(y)}},15e3);y.unref&&y.unref(),d.on("close",()=>{c.delete(b),clearInterval(y)});return}if(d.method==="POST"&&M.pathname==="/cursorbuddy/control"){try{let m=JSON.parse(await le(d)||"{}"),y=p(m);if(!y){j(b,400,{ok:!1,error:"unsupported CursorBuddy control command"});return}let I=v(y);j(b,200,{ok:!0,command:I})}catch(m){f("control_error",{error:String(m?.message||m)}),j(b,400,{ok:!1,error:String(m?.message||m)})}return}if(d.method==="POST"&&M.pathname==="/cursorbuddy/context"){try{let m=JSON.parse(await le(d)||"{}");l={url:String(m.url||"").slice(0,2048),title:String(m.title||"").slice(0,300),surface:String(m.surface||"").slice(0,80),instanceId:String(m.instanceId||"").slice(0,140),workspaceId:String(m.workspaceId||e.workspace||"").slice(0,120),agentId:String(m.agentId||e.agent||"").slice(0,120),runtime:m.runtime&&typeof m.runtime=="object"?m.runtime:null,page:m.page&&typeof m.page=="object"?m.page:null,client:m.client&&typeof m.client=="object"?m.client:null,project:m.project&&typeof m.project=="object"?m.project:null,manifest:m.manifest&&typeof m.manifest=="object"?m.manifest:null,selection:m.selection&&typeof m.selection=="object"?m.selection:null,updatedAt:new Date().toISOString()},f("context",{url:l.url,surface:l.surface,instanceId:l.instanceId}),j(b,200,{ok:!0,context:l})}catch(m){f("context_error",{error:String(m?.message||m)}),j(b,400,{ok:!1,error:String(m?.message||m)})}return}if(d.method==="POST"&&M.pathname==="/cursorbuddy/connect"){try{let m=JSON.parse(await le(d)||"{}"),y=await Pr(e,m,u),I=y.data||{};w={connected:!0,mode:"agensis-claimed",keyId:Dr(y.key),agentId:String(I.agentId||I.agent?.id||e.agent||""),workspaceId:String(I.workspaceId||I.workspace_id||I.agent?.workspace_id||e.workspace||""),agensisUrl:y.baseUrl,handle:String(I.handle||I.agent?.handle||e.handle||""),name:String(I.agent?.name||m.name||e.name||"CursorBuddy runtime"),cwd:String(m.cwd||e.cwd||X.cwd()),surface:String(m.surface||"browser_extension"),command:String(I.command||I.localCommand||""),updatedAt:new Date().toISOString()},l=Br(m,w,e),f("connect",{mode:w.mode,keyId:w.keyId,agentId:w.agentId,workspaceId:w.workspaceId,url:l.url}),j(b,200,{ok:!0,connection:w,claim:I})}catch(m){f("connect_error",{error:String(m?.message||m)}),j(b,400,{ok:!1,error:String(m?.message||m)})}return}if(d.method==="POST"&&M.pathname==="/cursorbuddy/edit"){try{let m=JSON.parse(await le(d)||"{}"),y=[{role:"system",content:"You are the local CursorBuddy edit agent. The user selected a DOM element in their own site. Use the payload to inspect and change the local checkout, then report what changed."},{role:"user",content:JSON.stringify(m,null,2)}];f("edit_request",{selector:m?.target?.selector||""});let I=await A({messages:y,model:m?.model});f("edit_done",{chars:I.content.length}),j(b,200,{ok:!0,backend:e.codingCmd,cwd:e.cwd,content:I.content})}catch(m){f("edit_error",{error:String(m?.message||m)}),j(b,500,{ok:!1,error:String(m?.message||m)})}return}if(d.method==="POST"&&M.pathname.endsWith("/chat/completions")){try{let m=JSON.parse(await le(d)||"{}");if(f("chat_request",{messages:Array.isArray(m.messages)?m.messages.length:0,model:Pt(m.model,Pe(e))}),m.stream===!0){Ot(b);let I=await T(m,b);f("chat_done",{chars:I.content.length,stream:!0,fast:I.fast===!0}),b.end();return}let y=await A(m);f("chat_done",{chars:y.content.length,fast:y.fast===!0}),j(b,200,{id:`agensis-cursorbuddy-${Date.now()}`,object:"chat.completion",model:y.model||m.model||e.model,choices:[{index:0,message:{role:"assistant",content:y.content},finish_reason:"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}catch(m){f("chat_error",{error:String(m?.message||m)}),j(b,500,{error:{message:String(m?.message||m)}})}return}b.writeHead(404),b.end("CursorBuddy local bridge")});return await new Promise((d,b)=>{B.once("error",b),B.listen(n,"127.0.0.1",()=>{g=B.address().port,B.off("error",b),d()})}),f("listening",{url:`${ve(g)}/cursorbuddy/health`}),{port:g,url:ve(g),secret:r,authHeader:Ee,close(){return new Promise(d=>B.close(()=>d()))},getContext(){return l}}}import oe from"node:fs/promises";import Lr from"node:os";import z from"node:path";var Ft=200,jt=256*1024,Ur=2,Fr=new Set([".md",".markdown",".txt"]);function jr(e){return String(e||"").replace(/[^a-zA-Z0-9]/g,"-")}function Le({cwd:e,memoryDir:t,homedir:n=Lr.homedir()}={}){let r=String(t||"").trim();if(r)return r.startsWith("~")?z.join(n,r.slice(1)):z.resolve(r);let s=String(e||"").trim();return s?z.join(n,".claude","projects",jr(s),"memory"):null}async function Ue(e){if(!e)return null;try{let t=await oe.realpath(e);return(await oe.stat(t)).isDirectory()?t:null}catch{return null}}async function Gr(e,t){if(!e)throw new Error("memory root unavailable");let n=z.isAbsolute(String(t))?String(t):z.join(e,String(t)),r=await oe.realpath(n),s=e.endsWith(z.sep)?e:e+z.sep;if(r!==e&&!r.startsWith(s))throw new Error(`path escapes memory root: ${t}`);return r}function Hr(e){let t=z.basename(e).toLowerCase();return t==="memory.md"?"index":t==="claude.md"?"instructions":"memory"}async function Fe(e,t,n,r){if(n>Ur||r.length>=Ft)return;let s;try{s=await oe.readdir(t,{withFileTypes:!0})}catch{return}for(let o of s){if(r.length>=Ft)break;if(o.name.startsWith("."))continue;let i=z.join(t,o.name);if(o.isDirectory())await Fe(e,i,n+1,r);else if(o.isFile()&&Fr.has(z.extname(o.name).toLowerCase())){let c=z.relative(e,i);r.push({path:c,kind:Hr(c)})}}}async function Jr(e){let t=await Ue(e);if(!t)return[];let n=[];return await Fe(t,t,0,n),n.sort((r,s)=>r.kind==="index"?-1:s.kind==="index"?1:r.path.localeCompare(s.path)),n}async function qr(e,t){let n=await Ue(e),r=await Gr(n,t),s=await oe.readFile(r),o=s.length>jt;return{content:s.subarray(0,jt).toString("utf8"),byteSize:s.length,truncated:o}}async function Gt(e){let t=await Ue(e);if(!t)return"";let n=[];await Fe(t,t,0,n),n.sort((s,o)=>s.path.localeCompare(o.path));let r=[];for(let s of n)try{let o=await oe.stat(z.join(t,s.path));r.push(`${s.path}:${o.size}:${Math.floor(o.mtimeMs)}`)}catch{}return r.join("|")}async function Ht(e){let t=await Jr(e),n=[];for(let r of t)try{let{content:s,byteSize:o}=await qr(e,r.path);n.push({path:r.path,kind:r.kind,content:s,byteSize:o})}catch{}return n}import Jt from"node:fs";import se from"node:path";import qt from"node:os";function Kr(e){try{return Jt.statSync(e).isDirectory()}catch{return!1}}function je(e){try{return Jt.readdirSync(e,{withFileTypes:!0})}catch{return[]}}function Kt({home:e=qt.homedir(),cwd:t=process.cwd()}={}){let n=[e&&se.join(e,".claude","commands"),t&&se.join(t,".claude","commands")].filter(Boolean),r=new Set,s=[],o=(i,c)=>{if(!i)return;let u=c?`${c}:${i}`:i;r.has(u)||(r.add(u),s.push({name:i,parent:c||null}))};for(let i of n)for(let c of je(i)){if(c.name.startsWith("."))continue;if(c.name.endsWith(".md")){o(c.name.slice(0,-3),null);continue}let u=se.join(i,c.name);if(c.isDirectory()||c.isSymbolicLink()&&Kr(u))for(let a of je(u))a.name.startsWith(".")||a.name.endsWith(".md")&&o(a.name.slice(0,-3),c.name)}return s}function zt({home:e=qt.homedir(),cwd:t=process.cwd()}={}){let n=[e&&se.join(e,".claude","skills"),e&&se.join(e,".codex","skills"),t&&se.join(t,".claude","skills")].filter(Boolean),r=new Set;for(let s of n)for(let o of je(s))o.name.startsWith(".")||(o.name.endsWith(".md")?r.add(o.name.slice(0,-3)):(o.isDirectory()||o.isSymbolicLink())&&r.add(o.name));return[...r].sort()}import{readFile as zr}from"node:fs/promises";var Wr=new Set(["127.0.0.1","localhost","::1","[::1]"]);function Wt(e,t,n){let r=Number(e);return Number.isFinite(r)?Math.max(1,Math.min(n,Math.trunc(r))):t}function Yr(e,t){if(!e||typeof e!="object"||e.shared===!1)return null;let n=String(e.id||e.upstreamModel||`model-${t+1}`).trim();if(!n)return null;if(!/^[a-zA-Z0-9._:@/-]+$/.test(n))throw new Error(`Shared model id '${n}' may only contain letters, numbers, dot, underscore, colon, at, slash, or dash.`);let r=new URL(String(e.baseUrl||"http://127.0.0.1:11434/v1"));if(!Wr.has(r.hostname))throw new Error(`Shared model '${n}' must use a loopback endpoint.`);if(!["http:","https:"].includes(r.protocol))throw new Error(`Shared model '${n}' must use an HTTP endpoint.`);return{id:n.slice(0,160),name:String(e.name||n).trim().slice(0,160)||n,provider:String(e.provider||"local").trim().slice(0,80)||"local",protocol:"openai-chat",baseUrl:r.toString().replace(/\/$/,""),upstreamModel:String(e.upstreamModel||n).trim().slice(0,200)||n,apiKeyEnv:String(e.apiKeyEnv||"").trim().slice(0,120),capabilities:[...new Set((Array.isArray(e.capabilities)?e.capabilities:["text","streaming"]).map(s=>String(s||"").trim().toLowerCase()).filter(Boolean))].slice(0,16),...e.contextWindow?{contextWindow:Wt(e.contextWindow,void 0,1e7)}:{},maxConcurrency:Wt(e.maxConcurrency,1,64),shared:!0}}async function Yt(e){if(!e)return[];let t=JSON.parse(await zr(e,"utf8")),n=Array.isArray(t)?t:t?.models;if(!Array.isArray(n))throw new Error("Shared model config must contain a models array.");return n.slice(0,32).map(Yr).filter(Boolean)}function Vt(e){return(Array.isArray(e)?e:[]).filter(t=>t?.shared).map(t=>({id:t.id,name:t.name,provider:t.provider,protocol:t.protocol,upstreamModel:t.upstreamModel,capabilities:[...t.capabilities],...t.contextWindow?{contextWindow:t.contextWindow}:{},maxConcurrency:t.maxConcurrency,shared:!0}))}async function Xt({models:e,request:t,send:n,signal:r,fetchImpl:s=fetch,env:o=process.env}){let i=String(t?.requestId||"").trim();if(!i)throw new Error("Inference requestId is required.");let c=(Array.isArray(e)?e:[]).find(p=>p.id===t?.model);if(!c)throw new Error(`Shared model '${t?.model||""}' is not available.`);let u={"content-type":"application/json"},a=c.apiKeyEnv?o[c.apiKeyEnv]:"";a&&(u.authorization=`Bearer ${a}`),n({action:"agent_inference_started",requestId:i,model:c.id});let{requestId:l,model:g,type:w,action:f,...h}=t,_=await s(`${c.baseUrl}/chat/completions`,{method:"POST",headers:u,body:JSON.stringify({...h,model:c.upstreamModel,stream:t.stream===!0}),signal:r});if(!_.ok){let p=await _.text().catch(()=>"");throw new Error(p||`Local model returned HTTP ${_.status}.`)}if(t.stream===!0){if(!_.body)throw new Error("Local model returned an empty stream.");let p=_.body.getReader(),v=new TextDecoder,k="",A,T=b=>{let M=b.trim();if(!M.startsWith("data:"))return!1;let m=M.slice(5).trim();if(!m)return!1;if(m==="[DONE]")return!0;try{let y=JSON.parse(m);y?.usage&&(A=y.usage),n({action:"agent_inference_delta",requestId:i,model:c.id,chunk:y})}catch{}return!1},B=!1;for(;!B;){let{done:b,value:M}=await p.read();k+=v.decode(M||new Uint8Array,{stream:!b});let m=k.split(/\r?\n/);k=b?"":m.pop()||"";for(let y of m)if(T(y)){B=!0;break}if(b)break}k&&T(k);let d={action:"agent_inference_result",requestId:i,model:c.id,...A?{usage:A}:{}};return n(d),d}let S=await _.json();return n({action:"agent_inference_result",requestId:i,model:c.id,response:S}),S}Ie();var ho=30*60*1e3,go=15*1e3,hn=2,yo=10*1024,So="claude-opus-4-8",Q="0.1.31";async function xe(e={}){let t=wo(e);t.sharedModels=t.share?await Yt(t.sharedModelsFile):[];let n=!1,r=null,s=null,o=null,i=null,c=0,u=null,a=null,l="",g=null,w=!1,f=null,h=new Map,_=null,S={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"},p=new Map,v=new Map,k=[],A=()=>S,T=()=>({connected:w&&!!t.cursorBuddyRuntime,mode:t.cursorBuddyRuntime?"agensis-cli":"agensis-cli-unclaimed",agentId:f?.agentId||f?.agent_id||t.agent,workspaceId:f?.workspaceId||f?.workspace_id||t.workspace,agensisUrl:t.url,handle:f?.handle||t.handle,name:f?.name||t.name,cwd:t.cwd,updatedAt:new Date().toISOString()}),B=()=>{_||!t.lanListener||(_=new fe.Server({port:0}),_.on("listening",()=>{let{port:C}=_.address();S={transport:"ws",listening:!0,addrs:Jo(C),auth:"hub-pairwise"},D(`Agent-mesh LAN listener on port ${C}`),me(r,t,A())}),_.on("connection",C=>{let N=!1,E=setTimeout(()=>{if(!N)try{C.close(1008,"peer auth required")}catch{}},5e3);C.once("message",O=>{clearTimeout(E);let $=We(O),F=$?.type==="peer_auth"?p.get($.ticket):null;if(!F||F.fromAgentId!==$.fromAgentId||Date.now()>F.exp){try{C.close(1008,"invalid ticket")}catch{}return}p.delete($.ticket),N=!0,C.on("message",J=>{let P=We(J);P?.type==="agent_job"&&P.job?.id&&a.enqueue({...P.job,key:P.job.id,lane:gn(P.job),ws:r}).accepted&&D(`Queued peer-handoff job ${P.job.id} from ${$.fromAgentId}`)})})}),_.on("error",C=>D(`LAN listener error: ${C?.message||C}`)))},d=()=>{if(_){try{_.close()}catch{}_=null}S={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"}},b=C=>new Promise((N,E)=>{if(!L(r,{action:"peer_ticket_request",targetAgentId:C})){E(new Error("hub socket not open"));return}let O=v.get(C)||[];O.push({resolve:N,reject:E}),v.set(C,O),setTimeout(()=>{let $=v.get(C)||[],F=$.findIndex(J=>J.resolve===N);F>=0&&($.splice(F,1),E(new Error("peer ticket request timed out")))},1e4)}),M=()=>new Promise((C,N)=>{if(!L(r,{action:"peer_list_request"})){N(new Error("hub socket not open"));return}k.push(C),setTimeout(()=>{let E=k.indexOf(C);E>=0&&(k.splice(E,1),C([]))},1e4)}),m=async(C,N)=>{let E=null;try{let $=(await M()).find(P=>P.agentId===C&&P.reach?.listening&&P.reach.addrs?.length);if(!$)return!1;let F=await b(C),J=F.peer?.addrs?.[0]||$.reach.addrs[0];return!J?.host||!J?.port?!1:(E=new fe(`ws://${J.host}:${J.port}`),await new Promise((P,Ne)=>{E.once("open",P),E.once("error",Ne),setTimeout(()=>Ne(new Error("peer connect timed out")),5e3)}),L(E,{type:"peer_auth",ticket:F.ticket,fromAgentId:t.agent}),L(E,{type:"agent_job",job:N}),!0)}catch(O){return D(`Peer handoff to ${C} failed, falling back to hub relay: ${O?.message||O}`),!1}finally{try{E?.close()}catch{}}},y=()=>{n=!0,bn(h),s&&clearTimeout(s),o&&clearInterval(o),i&&clearInterval(i),g&&(g.close().catch(()=>{}),g=null),d(),an(t,{status:"stopped",connected:!1});try{r?.close()}catch{}u&&u()};if(a=Mt({concurrency:t.once?1:t.maxConcurrency,runJob:async(C,N)=>{await Do(t,C,N),t.once&&y()}}),t.cursorBuddyBridge)try{g=await Ut(t,{port:t.cursorBuddyPort,authSecret:t.cursorBuddyBridgeSecret||void 0,log:D,connectionProvider:T}),g?.secret&&(t.cursorBuddyBridgeSecret=g.secret)}catch(C){if(Wo(C)){let N=await Yo(t.cursorBuddyPort);if(N?.ok){let E=N.pid?` pid ${N.pid}`:"";D(`CursorBuddy local bridge already running on http://127.0.0.1:${t.cursorBuddyPort}${E}`)}else D(`CursorBuddy local bridge port ${t.cursorBuddyPort} is in use but did not answer health`)}else D(`CursorBuddy local bridge unavailable: ${C?.message||C}`);g=null}x.once("SIGINT",y),x.once("SIGTERM",y);let I=()=>{if(n)return;let C=_o(t.url,t.token,t);l="",D(`Connecting to ${C.replace(t.token,"redacted")}`),r=new fe(C),r.on("open",async()=>{w=!1,f=null,D(`Connected. Registering @${t.handle||"agent"} from ${t.cwd}`),L(r,{type:"auth",token:t.token});let N=await un(t);L(r,{action:"agent_register",workspaceId:t.workspace,agentId:t.agent,handle:t.handle,name:t.name,host:ge.hostname(),cwd:t.cwd,...N?{identity:N}:{},metadata:{codingCmd:t.codingCmd,model:t.model,permissionMode:t.permissionMode,permissionFlags:Qe(t.permissionMode),once:t.once,runtime:"agensis",version:Q}}),o=setInterval(()=>{Promise.all([In(t,A()).catch(()=>null),qe(t).catch(()=>null)]).then(([E,O])=>{L(r,{action:"agent_heartbeat",...E?{capabilitiesHash:E.capabilitiesHash,memoryHash:E.memoryHash}:{},metadata:ze(t,a,O,_n(t)?g?.getContext?.():null,h)})})},t.heartbeatMs),o.unref&&o.unref()}),r.on("message",N=>{let E=We(N);if(E){if(E.type==="agent_registered"){w=!0,f=E.connection||E.agent||null,yn(t,E.agent),D(`Registered as ${E.connection?.name||t.name} on ${E.connection?.host||ge.hostname()}`),t.onRegistered&&Promise.resolve(t.onRegistered(t,E)).catch(O=>{D(`Profile save failed: ${O?.message||O}`)}),Je(t,E.agent).catch(()=>{}),fn(t).catch(()=>{}),wn(r,t),B(),me(r,t,A());return}if(E.type==="agent_config"){yn(t,E.agent),D(`Updated config for @${t.handle||"agent"}: model=${t.model}, permission=${t.permissionMode}`),Je(t,E.agent).catch(()=>{});return}if(E.type==="agent_memory_refresh"){wn(r,t),me(r,t,A());return}if(E.type==="agent_capabilities_refresh"){me(r,t,A());return}if(E.type==="agent_inference_cancel"){h.get(String(E.requestId||""))?.abort();return}if(E.type==="agent_job_cancel"){let O=String(E.jobId||"");O&&a.cancel(O,E.reason||"Cancelled by Agensis")&&D(`Cancelled job ${O}`);return}if(E.type==="agent_inference_request"&&E.requestId){let O=String(E.requestId),$=t.sharedModels.find(P=>P.id===E.model),F=[...h.values()].filter(P=>P.model===E.model).length;if(!$){L(r,{action:"agent_inference_error",requestId:O,error:`Shared model '${E.model||""}' is not available.`});return}if(F>=$.maxConcurrency){L(r,{action:"agent_inference_error",requestId:O,error:"Shared model is at capacity.",code:"capacity_exhausted"});return}let J=new AbortController;h.set(O,{abort:()=>J.abort(),model:$.id}),L(r,{action:"agent_heartbeat",metadata:ze(t,a,null,null,h)}),Xt({models:t.sharedModels,request:E,signal:J.signal,send:P=>L(r,P)}).catch(P=>{L(r,{action:"agent_inference_error",requestId:O,error:J.signal.aborted?"Inference cancelled.":P?.message||String(P),code:J.signal.aborted?"cancelled":"inference_failed"})}).finally(()=>{h.delete(O),L(r,{action:"agent_heartbeat",metadata:ze(t,a,null,null,h)})});return}if(E.type==="peer_ticket"){let O=E.peer?.agentId,$=v.get(O)||[],F=$.shift();$.length?v.set(O,$):v.delete(O),F&&F.resolve(E);return}if(E.type==="peer_ticket_grant"){p.set(E.ticket,{fromAgentId:E.fromAgentId,exp:E.exp});return}if(E.type==="peer_list"){let O=k.shift();O&&O(Array.isArray(E.peers)?E.peers:[]);return}if(E.type==="agent_reach_disable"){d(),me(r,t,A());return}if(E.type==="error"){D(`Server rejected request: ${E.message||"unknown error"}`);return}if(E.type==="agent_disabled"){w=!1,f=null,D(`Agent disabled by Agensis: ${E.reason||"deactivated"}`),y();return}if(E.type==="agent_job"&&E.job?.id){let O=a.enqueue({...E.job,key:E.job.id,lane:gn(E.job),ws:r});O.accepted&&(c+=1,D(`Queued job ${E.job.id} at position ${O.position}`),t.once&&a.idle().then(()=>y()))}}}),r.on("close",(N,E)=>{bn(h),w=!1,f=null;let O=String(E||"");if(D(`Socket closed (${N||"no-code"}${O?`: ${O}`:""})`),o&&(clearInterval(o),o=null),N===1008&&/agent deactivated|authentication failed/i.test(O)){D("Stopping daemon because Agensis rejected this agent connection."),y();return}if(l==="ECONNREFUSED"&&Eo(t.url)){D("Local agent backend is not running on 127.0.0.1:3142."),D("Start it in another terminal with: npm run backend"),D("Then rerun this connect command."),y();return}t.once&&c>0&&a.active()===0&&a.size()===0&&y(),!(n||t.once)&&(s=setTimeout(I,2e3),s.unref&&s.unref())}),r.on("error",N=>{l=N?.code||"",D(`Socket error: ${N?.message||N}`)})},R=async()=>{let C=await qe(t).catch(()=>null);await sn(t,{busy:a.active()>0,active:a.active(),queueSize:a.size(),connected:r?.readyState===fe.OPEN,agentStatus:C?.status,agentNote:C?.note}).catch(()=>{})};R(),i=setInterval(()=>{R()},t.heartbeatMs),i.unref&&i.unref(),I(),await new Promise(C=>{let N=setInterval(async()=>{t.once&&c>0&&a.active()===0&&a.size()===0&&y(),n&&y()},500);u=()=>{clearInterval(N),C()}}),u=null,x.off("SIGINT",y),x.off("SIGTERM",y)}function wo(e){let t=bo(e.cursorBuddyBridge),n=e.noCoding===!0||x.env.AGENSIS_NO_CODING==="1",s=!ie(e.fullCliContext,ie(x.env.AGENSIS_FULL_CLI_CONTEXT,!1))&&ie(e.leanCli,!0),o={url:String(e.url||e.baseUrl||x.env.AGENSIS_URL||"").trim(),token:String(e.token||x.env.AGENSIS_TOKEN||"").trim(),workspace:String(e.workspace||e.workspaceId||x.env.AGENSIS_WORKSPACE||x.env.AGENSIS_WORKSPACE_ID||"").trim(),agent:String(e.agent||e.agentId||x.env.AGENSIS_AGENT||x.env.AGENSIS_AGENT_ID||"").trim(),handle:Mn(e.handle||x.env.AGENSIS_HANDLE||e.name||x.env.AGENSIS_NAME||"agent"),name:String(e.name||x.env.AGENSIS_NAME||e.handle||x.env.AGENSIS_HANDLE||"agensis Agent").trim(),cwd:String(e.cwd||x.env.AGENSIS_CWD||x.cwd()).trim(),codingCmd:n?"":String(e.codingCmd||x.env.AGENSIS_CODING_CMD||x.env.CODING_CMD||"claude -p").trim(),model:Xe(e.model||x.env.AGENSIS_MODEL||x.env.CLAUDE_MODEL||""),permissionMode:Ce(e.permissionMode||e.permission_mode||e.permission||x.env.AGENSIS_PERMISSION_MODE||"default"),timeoutMs:Number(e.timeoutMs||x.env.AGENSIS_TIMEOUT_MS||ho),heartbeatMs:Number(e.heartbeatMs||x.env.AGENSIS_HEARTBEAT_MS||go),maxConcurrency:Math.max(1,Number(e.maxConcurrency||x.env.AGENSIS_MAX_CONCURRENCY||hn)||hn),once:!!(e.once||x.env.AGENSIS_ONCE==="1"),exitOnOnce:!!e.exitOnOnce,onRegistered:typeof e.onRegistered=="function"?e.onRegistered:null,primaryDaemon:!!(e.primaryDaemon||x.env.AGENSIS_PRIMARY_DAEMON==="1"),cursorBuddyRuntime:!!(e.cursorBuddyRuntime||x.env.AGENSIS_CURSORBUDDY_RUNTIME==="1"),cursorBuddyBridge:t,cursorBuddyPort:Number(e.cursorBuddyPort||x.env.AGENSIS_CURSORBUDDY_PORT||8787),cursorBuddyBridgeSecret:String(e.cursorBuddyBridgeSecret||x.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),cursorBuddyModel:String(e.cursorBuddyModel||x.env.AGENSIS_CURSORBUDDY_MODEL||"haiku-4.5").trim(),lanListener:!!(e.lanListener||e.lan||x.env.AGENSIS_LAN==="1"),share:!!(e.share||x.env.AGENSIS_SHARE==="1"),sharedModelsFile:String(e.sharedModelsFile||x.env.AGENSIS_SHARED_MODELS_FILE||"").trim(),noCoding:n,leanCli:s,fastConnection:ie(e.fastConnection,ie(x.env.AGENSIS_FAST_CONNECTION,!0)),syncMemory:ie(e.syncMemory,x.env.AGENSIS_SYNC_MEMORY==="1"),hostFolders:kn(e.hostFolders??e.host_folders??x.env.AGENSIS_HOST_FOLDERS)};o.sharedModelsFile&&!he.isAbsolute(o.sharedModelsFile)&&(o.sharedModelsFile=he.resolve(o.cwd,o.sharedModelsFile));let i=[];if(o.url||i.push("--url"),o.token||i.push("--token"),o.workspace||i.push("--workspace"),o.agent||i.push("--agent"),o.share&&!o.sharedModelsFile&&i.push("--shared-models-file"),i.length)throw new Error(`Missing required option(s): ${i.join(", ")}`);return o}function ie(e,t){return e==null||e===""?t:typeof e=="boolean"?e:!/^(0|false|off|no)$/i.test(String(e).trim())}function bo(e){let t=x.env.AGENSIS_CURSORBUDDY_BRIDGE;return t!==void 0&&t!==""?!/^(0|false|off|no)$/i.test(String(t).trim()):e==null||e===""?!1:typeof e=="boolean"?e:!/^(0|false|off|no)$/i.test(String(e).trim())}function _o(e,t,n={}){let r=Ve(e);return r.protocol=r.protocol==="https:"?"wss:":"ws:",r.pathname="/backend/ws",r.search="",n.workspace&&r.searchParams.set("workspaceId",n.workspace),n.agent&&r.searchParams.set("agentId",n.agent),r.toString()}function Ve(e){let t=new URL(e);return vo(t)&&(t.protocol="http:",t.hostname="127.0.0.1",t.port="3142"),t}function vo(e){if(!(e.hostname==="localhost"||e.hostname==="127.0.0.1"||e.hostname==="0.0.0.0")||e.port==="3142")return!1;if(e.port==="5173"||e.port==="8888")return!0;let t=Number(e.port||0);return t>=49152&&t<=65535}function Eo(e){try{let t=Ve(e);return(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="0.0.0.0")&&t.port==="3142"}catch{return!1}}function gn(e){let t=String(e?.sessionId||""),n=String(e?.threadParentId||"");return`${t}::${n}`}var ko=/\b(cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\b/i,Ao=[/\b(?:make|have|tell)\s+(?:the\s+)?(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\s+(?:say|speak)\s+(.+)$/i];function Io(e){return String(e||"").trim().replace(/^[`"'“”‘’]+|[`"'“”‘’?.!]+$/g,"").trim().slice(0,1200)}function xo(e){for(let t of Ao){let n=String(e||"").match(t),r=Io(n?.[1]||"");if(r)return r}return""}function Co(e){let t=String(e||"").replace(/\s+/g," ").trim();if(!t)return"";let n=/latest user message\s*:\s*/gi,r=null,s=null;for(;r=n.exec(t);)s=r;if(!s)return"";let o=t.slice(s.index+s[0].length).trim(),i=o.search(/\b(Return a useful response|Conversation context follows|Previous user|Previous assistant|Diagnostic notes|System prompt|Developer message)\b/i);return(i>=0?o.slice(0,i):o).trim().replace(/^["'“”‘’]+|["'“”‘’]+$/g,"").trim()}function Mo(e){let t=String(e||"").replace(/\s+/g," ").trim(),r=Co(t)||t;if(!r)return"";if(r.length<=500)return r;let s=[/\b(?:can you\s+)?(?:make|have|tell)\s+(?:the\s+)?(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\s+(?:wave|waves|waving|say|speak)\b.{0,160}/i,/\b(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\b.{0,120}\b(?:wave|waves|waving|say|speak|open|show|hide|hush|close|dismiss|clear)\b.{0,160}/i,/\b(?:wave|open|show|hide|hush|close|dismiss|clear)\b.{0,120}\b(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy|bubble|prompt|dialog|panel|options|menu)\b/i,/\b(?:say|speak)\s+[`"'“”‘’]?.{1,180}/i];for(let o of s){let i=r.match(o);if(i?.[0])return i[0].trim()}return""}function To(e){let t=Mo(e);if(!t)return null;let n=/^(open|show|hide|hush|close|dismiss)\b/i.test(t),r=ko.test(t);if(!n&&!r)return null;let s="agensis-native-control";if(/\b(hide|hush|close|dismiss|clear)\b.*\b(bubble|prompt|dialog|panel|options|menu)\b/i.test(t)||/^hush\b/i.test(t))return{action:"hush",source:s};if(/\b(open|show|bring up|get back|display)\b.*\b(prompt|bubble|dialog|panel|options|menu)\b/i.test(t)||/^open\b/i.test(t))return{action:"open",source:s};let o=xo(t);return o&&r?{action:"say",text:o,source:s}:r&&/\b(wave|waves|waving)\b/i.test(t)?{action:"wave",text:o,source:s}:null}async function Oo(e,t){let r=`http://127.0.0.1:${Number(e.cursorBuddyPort||8787)}/cursorbuddy/control`,s=String(e.cursorBuddyBridgeSecret||x.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),o={"content-type":"application/json"};s&&(o.authorization=`Bearer ${s}`,o["x-agensis-bridge-secret"]=s);let i=await fetch(r,{method:"POST",headers:o,body:JSON.stringify(t)}),c=null;try{c=await i.json()}catch{c=null}if(!i.ok||c?.ok===!1)throw new Error(c?.error||`CursorBuddy control failed with HTTP ${i.status}`);return c}function No(e){return e.action==="wave"?"Sent CursorBuddy a wave command.":e.action==="say"?`Sent CursorBuddy speech: ${e.text||""}`.trim():e.action==="open"?"Opened CursorBuddy's prompt.":e.action==="hush"?"Dismissed CursorBuddy's bubble.":e.action==="choose"?"Sent CursorBuddy options.":"Sent CursorBuddy control command."}function _n(e={}){return e.cursorBuddyBridge===!1?!1:!!(e.cursorBuddyRuntime||e.primaryDaemon)}async function $o(e,t,n,r){let s="cursorbuddy-control",o="native",i=[],c=(l="")=>{L(t.ws,{action:"agent_job_delta",jobId:t.id,content:l,elapsedMs:Date.now()-r,model:s,permissionMode:o,permissionFlags:i})};c("");let u="",a="";try{await Oo(e,n),u=No(n),c(u)}catch(l){a=String(l?.message||l),u=`CursorBuddy control failed: ${a}`,c(u)}L(t.ws,{action:"agent_job_result",jobId:t.id,response:u,error:a,elapsedMs:Date.now()-r,model:s,permissionMode:o,permissionFlags:i}),D(`Finished native CursorBuddy ${n.action} job ${t.id} in ${Math.round((Date.now()-r)/1e3)}s`)}async function Do(e,t,{signal:n}){let r=Date.now();D(`Starting job ${t.id}`);let s=To(t.prompt);if(s&&_n(e)){await $o(e,t,s,r),e.once&&(D("One-shot CursorBuddy control job complete; exiting."),setTimeout(()=>x.exit(0),150));return}let o=Po(e,t),i=await Bo(e,t),c="",u="",a=0,l=(d="")=>{L(t.ws,{action:"agent_job_delta",jobId:t.id,content:d,elapsedMs:Date.now()-r,model:o.model,permissionMode:o.permissionMode,permissionFlags:o.permissionFlags})},g=d=>{L(t.ws,{action:"agent_job_step",jobId:t.id,kind:d.kind,name:d.name,detail:d.detail,elapsedMs:Date.now()-r})},w=d=>{L(t.ws,{action:"agent_job_segment",jobId:t.id,text:d.text,elapsedMs:Date.now()-r})};l("");let f=o.streamJson?Lo({onStep:g,onSegment:w}):null,h=setInterval(()=>l(c),1e3);h.unref&&h.unref();let _=!/[\\/]/.test(o.cmd),S=e.fastConnection&&_?xn(o.cmd)?"claude":Cn(o.cmd)?"codex":null:null,v=await Ct(t,{family:S}).run({cmd:o.cmd,args:[...o.args,i],env:o.env,cwd:t.cwd||e.cwd,timeoutMs:e.timeoutMs,heartbeatMs:e.heartbeatMs,label:"agent job",signal:n,job:t,prompt:i,model:o.model,permissionMode:o.permissionMode,hostFolders:An(e,t),leanCli:e.leanCli,mcp:e.leanCli?Ye(e):null,sessionKey:`${t.workspaceId||e.workspace||""}:${e.agent||e.handle||""}`,clientVersion:Q,onData:d=>{f?(f.feed(d),c=f.live):(c+=String(d||""),u=zo(`${u}
40
+ ${d}`));let b=Date.now();b-a>150&&(a=b,l(c))}});clearInterval(h),f&&(f.end(),c=f.live,l(c));let k=String(v.stdout||"").trim(),A=String(v.stderr||"").trim(),T=v.error?v.error.message:v.status===0?"":A||`Command exited with status ${v.status}`,B=f?f.result||(T?"":A):k||(T?"":A)||u||"";L(t.ws,{action:"agent_job_result",jobId:t.id,response:B,error:T,elapsedMs:Date.now()-r,model:o.model,permissionMode:o.permissionMode,permissionFlags:o.permissionFlags}),D(`Finished job ${t.id} in ${Math.round((Date.now()-r)/1e3)}s`),e.once&&(D("One-shot job complete; exiting."),setTimeout(()=>x.exit(0),150))}async function Bo(e,t){let n=t.agent||{},r=Array.isArray(n.skills)?n.skills.join(", "):String(n.skills||""),s=Array.isArray(n.tools)?n.tools.join(", "):String(n.tools||""),o=vn(e,t),i=En(e,t),c=await pn(e).catch(()=>null),u=c?`Heartbeat (recurring instructions \u2014 edit at ${on(e)}):
39
41
  ${c}`:"",l=["You are running as a local agensis workspace agent daemon.",`Workspace: ${t.workspaceId||e.workspace}`,`Channel session: ${t.sessionId||""}`,`Agent: ${n.name||e.name} (@${n.handle||e.handle})`,`Requested model: ${o}`,`Permission mode: ${i}`,n.description?`Description:
40
42
  ${n.description}`:"",n.soul?`Soul:
41
43
  ${n.soul}`:"",n.system_prompt?`System instructions:
42
44
  ${n.system_prompt}`:"",n.instructions?`Additional instructions:
43
45
  ${n.instructions}`:"",s?`Enabled tools:
44
46
  ${s}`:"",r?`Enabled skills:
45
- ${r}`:"",'Thread widgets: this chat has a right-side widget rail the human watches. When you work a multi-step task here, surface it: call create_thread_item (kind "todo", "plan", or "blocker") with the Channel session id above to post your plan steps and to-dos, mark them done with update_thread_item as you finish, and raise a "blocker" when you need the human to answer something (read their reply from the item response via list_thread_items). Keep it to a few real items, not every micro-step; skip it for quick one-off replies.',`Status file: you can report your own working status by overwriting the JSON file at ${Dt(e)} with e.g. {"status":"working","note":"short summary of what you're doing"}. Your daemon reads it on its next heartbeat (~${Math.round((e.heartbeatMs||15e3)/1e3)}s) and surfaces it on your agent card. Optional and best-effort \u2014 overwrite the whole file, keep note under ~200 chars, and there's no need to clear it.`,u,"User message:",String(t.prompt||""),"Identity boundary: answer as the workspace agent named above. Do not adopt the identity of any browser, desktop, avatar, pet, widget, or UI surface.","Respond with a clear channel-ready result. Use markdown for structure \u2014 bullets, headers, and code blocks where appropriate. If you changed files, summarize the files and verification. If you cannot complete it, say exactly why."].filter(Boolean).join(`
47
+ ${r}`:"",'Thread widgets: this chat has a right-side widget rail the human watches. When you work a multi-step task here, surface it: call create_thread_item (kind "todo", "plan", or "blocker") with the Channel session id above to post your plan steps and to-dos, mark them done with update_thread_item as you finish, and raise a "blocker" when you need the human to answer something (read their reply from the item response via list_thread_items). Keep it to a few real items, not every micro-step; skip it for quick one-off replies.',`Status file: you can report your own working status by overwriting the JSON file at ${rn(e)} with e.g. {"status":"working","note":"short summary of what you're doing"}. Your daemon reads it on its next heartbeat (~${Math.round((e.heartbeatMs||15e3)/1e3)}s) and surfaces it on your agent card. Optional and best-effort \u2014 overwrite the whole file, keep note under ~200 chars, and there's no need to clear it.`,`Identity file: you can declare how you appear \u2014 avatar, description, soul, and voice ({"cartesia_voice_id","speed","emotion"}) \u2014 by writing JSON to ${Ke(e)}, e.g. {"avatar":"FX","description":"...","voice":{"emotion":"calm"}}. Your daemon sends it the next time it connects; anything a human has set in the app always wins, and "name" only applies to brand-new agents.`,u,"User message:",String(t.prompt||""),"Identity boundary: answer as the workspace agent named above. Do not adopt the identity of any browser, desktop, avatar, pet, widget, or UI surface.","Respond with a clear channel-ready result. Use markdown for structure \u2014 bullets, headers, and code blocks where appropriate. If you changed files, summarize the files and verification. If you cannot complete it, say exactly why."].filter(Boolean).join(`
46
48
 
47
- `);return e.leanCli?Yr(l,Or):l}function Yr(e,t){let n=String(e||"");if(Buffer.byteLength(n,"utf8")<=t)return n;let r=`[... older or optional Agensis context omitted ...]
49
+ `);return e.leanCli?Ro(l,yo):l}function Ro(e,t){let n=String(e||"");if(Buffer.byteLength(n,"utf8")<=t)return n;let r=`[... older or optional Agensis context omitted ...]
48
50
 
49
- `,s=Math.max(0,t-Buffer.byteLength(r,"utf8")),o=[...n],i=0,c=o.length;for(;i<c;){let u=Math.ceil((i+c)/2),a=o.slice(o.length-u).join("");Buffer.byteLength(a,"utf8")<=s?i=u:c=u-1}return r+o.slice(o.length-i).join("")}function Xr(e,t){let{cmd:n,args:r}=oo(e.codingCmd),s=Yt(e,t),o=Xt(e,t),i=ro(r),c=Ge(o),u=Qt(e,t);if(en(n)){let a=[...i];s&&a.push("--model",s);let l;if(e.leanCli){let g=Ue(e);a.push("--no-session-persistence","--safe-mode","--mcp-config",JSON.stringify({mcpServers:{agensis:{type:"http",url:g.url,headers:{Authorization:"Bearer ${AGENSIS_MCP_TOKEN}"}}}}),"--strict-mcp-config"),l=g.env}if(o==="accept_edits"&&a.push("--permission-mode","acceptEdits"),o==="yolo"){let g=t&&t.agent&&t.agent.run_mode==="sandbox",v=typeof A.getuid=="function"&&A.getuid()===0,S=g||Qr(),f=A.env.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1";S||!v||f?a.push("--dangerously-skip-permissions"):(c=[],B("running as root with no sandbox detected: dropping --dangerously-skip-permissions (Claude rejects it as root). Set AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS=1 if this host really is sandboxed."))}let h=i.some(g=>g==="--output-format"||String(g).startsWith("--output-format=")),E=i.includes("-p")||i.includes("--print"),w=!1;!h&&E?(a.push("--output-format","stream-json","--include-partial-messages"),i.includes("--verbose")||a.push("--verbose"),w=!0):h&&(w=i.some(g=>/stream-json/.test(String(g))));for(let g of u)a.push("--add-dir",g);return{cmd:n,args:a,model:s,permissionMode:o,permissionFlags:c,streamJson:w,env:l}}if(tn(n)){let a=[...i];s&&a.push("--model",s);let l;if(e.leanCli&&i.includes("exec")){let h=Ue(e);a.push("--ephemeral","--ignore-user-config","--ignore-rules","--disable","plugins","--disable","memories","--disable","hooks","--disable","skill_search","-c","project_doc_max_bytes=0","-c",`mcp_servers.agensis.url=${JSON.stringify(h.url)}`,"-c",'mcp_servers.agensis.bearer_token_env_var="AGENSIS_MCP_TOKEN"'),l=h.env}return o==="yolo"&&a.push("--sandbox","danger-full-access","--ask-for-approval","never"),{cmd:n,args:a,model:s,permissionMode:o,permissionFlags:c,env:l}}return{cmd:n,args:r,model:s,permissionMode:o,permissionFlags:c}}function Ue(e){let t=Fe(e.url);return t.pathname="/backend/mcp",t.search="",t.hash="",{url:t.toString(),env:{AGENSIS_MCP_TOKEN:e.token}}}function Vr({onStep:e,onSegment:t}={}){let n="",r="",s=!1,o="",i="",c=null,u=!1,a=!1,l=new Set,h=v=>{if(!(typeof e!="function"||!v.name))try{e(v)}catch{}},E=v=>{if(typeof t=="function"){i+=s?r:o,r="",o="";try{t(v)}catch{}}},w=v=>{if(!v||typeof v!="object")return;if(v.type==="agensis_step"){let f=v.step;f&&typeof f=="object"&&(u=!0,h({kind:f.kind||"tool",name:String(f.name||""),detail:String(f.detail||"")}));return}if(v.type==="agensis_segment"){let f=v.segment;f&&typeof f=="object"&&(a=!0,E({text:String(f.text||"")}));return}let S=v.event&&v.event.delta||v.delta;if(S&&S.type==="text_delta"&&typeof S.text=="string"){s=!0,r+=S.text;return}if(v.type==="result"&&typeof v.result=="string"){c=v.result;return}if(v.type==="assistant"&&v.message&&Array.isArray(v.message.content)){let f=v.message.content.filter(_=>_&&_.type==="text"&&typeof _.text=="string").map(_=>_.text).join("");if(f&&(o+=f),f&&!a&&E({text:f}),!u)for(let _ of v.message.content){if(!_||_.type!=="tool_use")continue;let I=typeof _.id=="string"?_.id:"";if(I){if(l.has(I))continue;l.add(I)}h({kind:"tool",name:String(_.name||""),detail:Ie(_.input)})}}},g=v=>{let S=String(v).trim();if(S)try{w(JSON.parse(S))}catch{}};return{feed(v){n+=String(v||"");let S;for(;(S=n.indexOf(`
50
- `))>=0;)g(n.slice(0,S)),n=n.slice(S+1)},end(){n&&(g(n),n="")},get live(){return s?r:o},get result(){return c??i+(s?r:o)}}}function Yt(e,t){return je(t?.agent?.model||t?.model||e.model)}function je(e){let t=String(e||"").trim();return!t||t==="auto"||t==="claude-fable-5"?Nr:t}function Xt(e,t){return be(t?.agent?.permissionMode||t?.agent?.permission_mode||t?.permissionMode||t?.permission_mode||e.permissionMode)}function be(e){let t=String(e||"").trim().toLowerCase().replace(/[-\s]+/g,"_");return["yolo","no_sandbox","danger","danger_full_access","dangerously_skip_permissions"].includes(t)?"yolo":["accept_edits","acceptedits","auto_approve","auto_approve_edits"].includes(t)?"accept_edits":"default"}function Ge(e){return be(e)==="yolo"?["--no-sandbox","--yolo"]:[]}function Vt(e){let t=Array.isArray(e)?e:String(e||"").split(/[,\n]/),n=new Set,r=[];for(let s of t){let o=String(s||"").trim();!o||n.has(o)||(n.add(o),r.push(o))}return r}function Qt(e,t){let n=t?.agent?.metadata?.host_folders??t?.agent?.hostFolders??t?.hostFolders??t?.host_folders,r=Vt(n);return r.length>0?r:e.hostFolders||[]}var Q;function Qr(){if(Q!==void 0)return Q;let e=A.env;if(e.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1"||e.AGENSIS_SANDBOX_HOST==="1"||e.IS_SANDBOX==="1")return Q=!0;if(e.AGENSIS_NO_SANDBOX_AUTODETECT==="1")return Q=!1;try{if(le.existsSync("/.dockerenv")||le.existsSync("/run/.containerenv"))return Q=!0}catch{}try{let t=le.readFileSync("/proc/1/cgroup","utf8");if(/docker|kubepods|containerd|lxc|podman/i.test(t))return Q=!0}catch{}return Q=!1}function Re(e,t,n,r=null,s=null){let o={busy:t.active()>0,queueSize:t.size(),cwd:e.cwd,model:e.model,permissionMode:e.permissionMode,permissionFlags:Ge(e.permissionMode),daemon:{runtime:"agensis-cli",version:Z,pid:A.pid,node:A.version,platform:A.platform,arch:A.arch,host:me.hostname(),cwd:e.cwd}};if(s instanceof Map){let i={};for(let c of s.values()){let u=String(c?.model||"");u&&(i[u]=(i[u]||0)+1)}o.activeInferenceByModel=i}return r&&typeof r=="object"&&(o.cursorBuddy=Zr(r)),n?.status&&(o.agentStatus=n.status),n?.note&&(o.agentNote=n.note),(n?.status||n?.note)&&(o.agentStatusAt=new Date().toISOString()),o}function Zr(e={}){let t=e.client&&typeof e.client=="object"?e.client:{},n=e.page&&typeof e.page=="object"?e.page:{},r=e.runtime&&typeof e.runtime=="object"?e.runtime:{},s=e.manifest&&typeof e.manifest=="object"?e.manifest:{},o=e.project&&typeof e.project=="object"?e.project:{};return{surface:String(e.surface||"").slice(0,80),instanceId:String(e.instanceId||"").slice(0,140),url:String(e.url||"").slice(0,2048),title:String(e.title||"").slice(0,300),origin:String(n.origin||"").slice(0,300),hostname:String(n.hostname||"").slice(0,200),pathname:String(n.pathname||"").slice(0,500),visibilityState:String(n.visibilityState||"").slice(0,40),focused:n.focused===!0,userAgent:String(t.userAgent||"").slice(0,500),platform:String(t.platform||"").slice(0,120),language:String(t.language||"").slice(0,80),viewport:t.viewport&&typeof t.viewport=="object"?{width:Number(t.viewport.width)||0,height:Number(t.viewport.height)||0,devicePixelRatio:Number(t.viewport.devicePixelRatio)||0}:null,runtimeMarker:String(r.marker||"").slice(0,120),extensionMarker:String(r.extensionMarker||"").slice(0,120),manifest:{name:String(s.name||"").slice(0,120),version:String(s.version||"").slice(0,80),source:String(s.source||"").slice(0,500)},project:{name:String(o.name||"").slice(0,120),root:String(o.root||"").slice(0,500),agent:String(o.agent||"").slice(0,80)},updatedAt:String(e.updatedAt||"").slice(0,80)}}function Jt(e,t){if(!t||typeof t!="object")return;t.name&&(e.name=String(t.name).trim()||e.name),(t.handle||t.name)&&(e.handle=nn(t.handle||t.name||e.handle)),t.model&&(e.model=je(t.model));let n=t.permissionMode||t.permission_mode;n&&(e.permissionMode=be(n)),(t.memory_dir!==void 0||t.memoryDir!==void 0)&&(e.memoryDir=String(t.memory_dir??t.memoryDir??"").trim())}function eo(){let e=["claude","codex","gh","node","npm","python3","git","fly","vercel"],t=(A.env.PATH||"").split(de.delimiter).filter(Boolean);return e.filter(n=>t.some(r=>{try{return le.existsSync(de.join(r,n))}catch{return!1}}))}function to(){try{let e=le.readFileSync(de.join(me.homedir(),".claude.json"),"utf8"),n=JSON.parse(e)?.mcpServers;if(n&&typeof n=="object")return Object.keys(n).sort()}catch{}return[]}function Kt(e){return Cr.createHash("sha1").update(String(e)).digest("hex").slice(0,16)}async function Zt(e,t=null){let n=It({cwd:e.cwd}),r=kt({cwd:e.cwd}),s=eo(),o=to(),i=e.syncMemory&&Me({cwd:e.cwd,memoryDir:e.memoryDir})||null,c=xt(e.sharedModels),u=Kt(JSON.stringify({skills:n,commands:r,clis:s,mcpServers:o,memoryRoot:i,sharedModels:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null})),a=Kt(await bt(i));return{skills:n,commands:r,clis:s,mcpServers:o,memoryRoot:i,sharedModels:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null,capabilitiesHash:u,memoryHash:a}}async function ce(e,t,n=null){try{let r=await Zt(t,n);L(e,{action:"agent_capabilities_sync",workspaceId:t.workspace,agentId:t.agent,skills:r.skills,commands:r.commands,clis:r.clis,mcpServers:r.mcpServers,sharedModels:r.sharedModels,codingRoute:r.codingRoute,shared:r.shared,memoryRoot:r.memoryRoot,reach:r.reach||void 0,hash:r.capabilitiesHash,memoryHash:r.memoryHash}),B(`Capabilities synced \u2014 skills:${r.skills.length} commands:${r.commands.length} clis:${r.clis.length} mcp:${r.mcpServers.length}`)}catch(r){B(`Capabilities sync skipped: ${r?.message||r}`)}}function no(e){let t=me.networkInterfaces(),n=[];for(let r of Object.values(t))for(let s of r||[])s.family==="IPv4"&&!s.internal&&n.push({host:s.address,port:e,scope:"lan"});return n.slice(0,4)}async function zt(e,t){try{if(!t.syncMemory)return;let n=Me({cwd:t.cwd,memoryDir:t.memoryDir});if(!n)return;let r=await _t(n);L(e,{action:"agent_memory_sync",workspaceId:t.workspace,agentId:t.agent,root:n,files:r}),B(`Synced ${r.length} memory file${r.length===1?"":"s"} from ${n}`)}catch(n){B(`Memory sync skipped: ${n?.message||n}`)}}function ro(e){let t=new Set(["--model","-m","--permission-mode","--sandbox","--ask-for-approval","--approval-policy"]),n=new Set(["--dangerously-skip-permissions","--no-sandbox","--yolo","--accept-edits"]),r=[];for(let s=0;s<e.length;s+=1){let o=e[s],[i]=String(o).split("=",1);if(!n.has(o)){if(t.has(i)){String(o).includes("=")||(s+=1);continue}r.push(o)}}return r}function en(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function tn(e){return/(^|\/)codex(?:$|\.)/.test(String(e||""))}function oo(e){let t=[],n="",r="",s=!1;for(let o of e){if(s){n+=o,s=!1;continue}if(o==="\\"){s=!0;continue}if(r){o===r?r="":n+=o;continue}if(o==='"'||o==="'"){r=o;continue}if(/\s/.test(o)){n&&(t.push(n),n="");continue}n+=o}if(n&&t.push(n),!t.length)throw new Error("coding command is empty");return{cmd:t[0],args:t.slice(1)}}function Le(e){try{return JSON.parse(String(e))}catch{return null}}function L(e,t){return!e||e.readyState!==ue.OPEN?!1:(e.send(JSON.stringify(t)),!0)}function so(e){return String(e||"").split(/\r?\n/).map(t=>t.trim()).filter(Boolean).slice(-1)[0]||""}function nn(e){return String(e||"").trim().toLowerCase().replace(/^@+/,"").replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}function io(e){return e?.code==="EADDRINUSE"||/\bEADDRINUSE\b/.test(String(e?.message||e))}async function ao(e){let t=new AbortController,n=setTimeout(()=>t.abort(),700);try{let r=await fetch(`http://127.0.0.1:${Number(e||8787)}/cursorbuddy/health`,{cache:"no-store",signal:t.signal}),s=await r.json().catch(()=>({}));return!r.ok||!s?.ok?null:s}catch{return null}finally{clearTimeout(n)}}function B(e){A.stderr.write(`[agensis] ${e}
51
- `)}function Wt(e){if(e instanceof Map)for(let t of e.values())try{t?.abort?.()}catch{}}import co from"node:crypto";import fe from"node:fs/promises";import uo from"node:os";import rn from"node:path";var ee="default",on=2,lo=/^[a-zA-Z0-9_.-]{1,64}$/,mo=["url","token","workspace","agent","handle","name","cwd","codingCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","fullCliContext","syncMemory","lanListener","primaryDaemon","cursorBuddyBridge","cursorBuddyPort","hostFolders"];function W(e=ee){let t=String(e||ee).trim();if(!lo.test(t))throw new Error("Daemon profile names may only contain letters, numbers, dot, dash, and underscore.");return t}function sn(e=ee,t={}){let n=t.homedir||uo.homedir();return rn.join(n,".agensis","daemon-profiles",`${W(e)}.json`)}function He(e={}){let t={};for(let n of mo){let r=e[n];r!=null&&r!==""&&(t[n]=r)}return t}function V(e,t,n=[]){for(let r of t)if(String(e?.[r]||"").trim())return!0;for(let r of n)if(String(process.env[r]||"").trim())return!0;return!1}function an(e={}){return!!(V(e,["url","baseUrl"],["AGENSIS_URL"])||V(e,["token"],["AGENSIS_TOKEN"])||V(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])||V(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}function Je(e={}){return!!(V(e,["url","baseUrl"],["AGENSIS_URL"])&&V(e,["token"],["AGENSIS_TOKEN"])&&V(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])&&V(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}async function cn(e=ee,t={}){let n=sn(e,t),r;try{r=await fe.readFile(n,"utf8")}catch(c){if(c?.code==="ENOENT")return null;throw c}let s;try{s=JSON.parse(r)}catch(c){throw new Error(`Daemon profile "${W(e)}" is unreadable: ${c?.message||c}`)}let o=s?.config;if(!o?.url||!o?.token||!o?.workspace||!o?.agent)return null;let i=He(o);return Number(s.version||1)<on&&Number(i.maxConcurrency)===8&&(i.maxConcurrency=2),i}async function _e(e=ee,t={},n={}){let r=He(t);if(!r.url||!r.token||!r.workspace||!r.agent)return null;let s=sn(e,n),o=rn.dirname(s);await fe.mkdir(o,{recursive:!0,mode:448});let i=`${s}.${process.pid}.${Date.now()}.tmp`,c={version:on,savedAt:new Date().toISOString(),profile:W(e),tokenHash:co.createHash("sha256").update(r.token).digest("hex"),config:r};return await fe.writeFile(i,`${JSON.stringify(c,null,2)}
52
- `,{mode:384}),await fe.rename(i,s),await fe.chmod(s,384).catch(()=>{}),s}function un(e,t={}){let n={...e,...He(t),command:"connect"};return t.fullCliContext===!0&&(n.leanCli=!1),t.codingCmd!==void 0&&t.noCoding===void 0&&(n.noCoding=!1),t.cursorBuddyBridge===void 0&&!n.primaryDaemon&&(n.cursorBuddyBridge=!1),t.once!==void 0&&(n.once=t.once),t.exitOnOnce!==void 0&&(n.exitOnOnce=t.exitOnOnce),n}function ln(e=ee){let t=W(e);return[`No saved Agensis daemon profile found for "${t}".`,"","To connect the main agent once:","1. Run: agensis setup","2. Sign in or create an account in the browser.","3. Approve this machine as your primary local agent.","","Manual fallback: open Agensis > AI Agents, copy a connection command,","and run that full agensis connect command from the repo folder.","","After the daemon registers successfully, this CLI saves the profile locally.",`Then restart it with: agensis connect${t===ee?"":` --profile ${t}`}`].join(`
53
- `)}import fo from"node:crypto";import pe from"node:fs/promises";import dn from"node:os";import Ke from"node:path";import ze from"node:process";var po=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/;function ho(e={}){return String(e.url||e.baseUrl||ze.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function mn(e,t={}){let n=t.homedir||dn.homedir(),r=fo.createHash("sha256").update(String(e)).digest("hex");return Ke.join(n,".agensis","cursorbuddy","connection-keys",`${r}.json`)}function go(){return new Error("Missing or invalid --key. Create a CursorBuddy connection key in Agensis first.")}function We(e){let t=String(e||"").trim();if(!po.test(t))throw go();return t}function yo(e,t,n,r){let s=t?.token,o=t?.workspaceId||t?.workspace_id||t?.agent?.workspace_id,i=t?.agentId||t?.agent?.id;if(!s||!o||!i)throw new Error("CursorBuddy key claim did not return a complete daemon connection payload");let{key:c,subcommand:u,...a}=e;return{...a,command:"connect",url:t.baseUrl||n,token:s,workspace:o,agent:i,handle:t.handle||e.handle,name:t.agent?.name||e.name||"CursorBuddy runtime",model:t.model||e.model,permissionMode:t.permissionMode||t.permission_mode||e.permissionMode,cwd:e.cwd||r,cursorBuddyRuntime:!0}}async function So(e,t={}){We(e);let n=mn(e,t),r;try{r=await pe.readFile(n,"utf8")}catch(i){if(i?.code==="ENOENT")return null;throw i}let s;try{s=JSON.parse(r)}catch(i){throw new Error(`Cached CursorBuddy daemon config is unreadable: ${i?.message||i}`)}let o=s?.daemonArgs;return!o?.token||!o?.workspace||!o?.agent||!o?.url?null:o}async function wo(e,t,n={}){if(We(e),!t?.token||!t?.workspace||!t?.agent||!t?.url)return;let r=mn(e,n),s=Ke.dirname(r);await pe.mkdir(s,{recursive:!0,mode:448});let o=`${r}.${ze.pid}.${Date.now()}.tmp`,i={version:1,savedAt:new Date().toISOString(),keyHash:Ke.basename(r,".json"),daemonArgs:t};await pe.writeFile(o,`${JSON.stringify(i,null,2)}
54
- `,{mode:384}),await pe.rename(o,r),await pe.chmod(r,384).catch(()=>{})}function bo(e,t,n){let r={...e,command:"connect"};for(let s of["cwd","codingCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","lanListener","once"])t[s]!==void 0&&(r[s]=t[s]);return t.codingCmd!==void 0&&t.noCoding===void 0&&(r.noCoding=!1),r.cwd||(r.cwd=n),r.cursorBuddyRuntime=!0,r}function _o(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function vo(e){return e.json().catch(()=>({}))}async function fn(e,t={}){let n=We(e?.key),r=ho(e),s=t.fetchImpl||globalThis.fetch;if(typeof s!="function")throw new Error("This Node.js runtime does not provide fetch; use a current Node.js release.");let o=t.cwd||ze.cwd(),i=t.hostname||dn.hostname(),c=t.version||Z,u={homedir:t.homedir},a=await s(`${r}/backend/cursorbuddy/connection-keys/claim`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({key:n,baseUrl:r,host:i,cwd:e.cwd||o,name:e.name,surface:e.surface||"local_cli",scope:e.scope||"machine",runtimeKind:"agensis-cli",version:c,permissionMode:e.permissionMode,model:e.model})}),l=await vo(a);if(!a.ok){let E=_o(a,l);if(a.status===409||/already been claimed/i.test(E)){let w=await So(n,u);if(w)return bo(w,e,o);throw new Error(`${E}. No cached daemon config was found on this machine; create a new CursorBuddy key in Agensis or run the full copied agensis connect command.`)}throw new Error(E)}let h=yo(e,l?.data||l,r,o);return await wo(n,h,u),h}import Eo from"node:crypto";import ko from"node:http";import Io from"node:os";import q from"node:process";import{spawn as Ao}from"node:child_process";var Co="https://agensis.io",xo=10*60*1e3;function ve(e,t,n){e.writeHead(t,{"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"content-type"}),e.end(JSON.stringify(n))}function Mo(e){return new Promise((t,n)=>{let r="";e.on("data",s=>{r+=s,r.length>128*1024&&(n(new Error("setup callback body is too large")),e.destroy())}),e.on("error",n),e.on("end",()=>t(r))})}function Oo(e){let t=String(e||q.env.AGENSIS_URL||Co).trim(),n=new URL(t);if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error("Agensis setup URL must be http or https.");return n.search="",n.hash="",n.toString().replace(/\/+$/,"")}function No(e){let t=q.platform==="darwin"?"open":q.platform==="win32"?"cmd":"xdg-open",n=q.platform==="win32"?["/c","start","",e]:[e],r=Ao(t,n,{detached:!0,stdio:"ignore"});r.on("error",()=>{}),r.unref()}function To(e){let t=e?.daemonArgs||e?.data?.daemonArgs||e?.data||{},r=["url","token","workspace","agent"].filter(s=>!String(t[s]||"").trim());if(r.length)throw new Error(`Setup callback did not include ${r.join(", ")}`);return{...t,command:"connect"}}function $o(e,t,n){let r=new URL(Oo(e.url||e.baseUrl));return r.searchParams.set("source","agensis-cli"),r.searchParams.set("referrer","agensis-cli"),r.searchParams.set("intent","setup"),r.searchParams.set("callback",t),r.searchParams.set("state",n),r.searchParams.set("profile",W(e.profile||"default")),r.searchParams.set("host",Io.hostname()),r.searchParams.set("cwd",String(e.cwd||q.cwd())),e.handle&&r.searchParams.set("handle",String(e.handle)),e.name&&r.searchParams.set("name",String(e.name)),r.toString()}async function pn(e={}){let t=W(e.profile||"default"),n=Eo.randomBytes(24).toString("base64url"),r=Number(e.setupTimeoutMs||q.env.AGENSIS_SETUP_TIMEOUT_MS||xo),s,o=new Promise((a,l)=>{let h=setTimeout(()=>l(new Error("Agensis setup timed out waiting for browser login.")),r);h.unref&&h.unref(),s=ko.createServer(async(E,w)=>{if(w.setHeader("access-control-allow-origin","*"),w.setHeader("access-control-allow-methods","POST, OPTIONS"),w.setHeader("access-control-allow-headers","content-type"),E.method==="OPTIONS"){w.writeHead(204),w.end();return}if(E.method!=="POST"||E.url!=="/agensis/setup-callback"){ve(w,404,{ok:!1,error:"Unknown Agensis setup callback route"});return}try{let g=JSON.parse(await Mo(E)||"{}");if(g?.state!==n){ve(w,403,{ok:!1,error:"Setup state did not match"});return}let v={...To(g),primaryDaemon:!0,cursorBuddyBridge:e.cursorBuddyBridge!==!1};await _e(t,v),clearTimeout(h),ve(w,200,{ok:!0,profile:t}),a(v)}catch(g){ve(w,400,{ok:!1,error:String(g?.message||g)})}}),s.once("error",l)});await new Promise((a,l)=>{s.listen(0,"127.0.0.1",h=>h?l(h):a())});let{port:i}=s.address(),c=`http://127.0.0.1:${i}/agensis/setup-callback`,u=$o(e,c,n);q.stdout.write(`[agensis] Opening Agensis to sign in and connect this machine.
55
- `),q.stdout.write(`[agensis] If the browser did not open, visit:
51
+ `,s=Math.max(0,t-Buffer.byteLength(r,"utf8")),o=[...n],i=0,c=o.length;for(;i<c;){let u=Math.ceil((i+c)/2),a=o.slice(o.length-u).join("");Buffer.byteLength(a,"utf8")<=s?i=u:c=u-1}return r+o.slice(o.length-i).join("")}function Po(e,t){let{cmd:n,args:r}=Ko(e.codingCmd),s=vn(e,t),o=En(e,t),i=qo(r),c=Qe(o),u=An(e,t);if(xn(n)){let a=[...i];s&&a.push("--model",s);let l;if(e.leanCli){let h=Ye(e);a.push("--no-session-persistence","--safe-mode","--mcp-config",JSON.stringify({mcpServers:{agensis:{type:"http",url:h.url,headers:{Authorization:"Bearer ${AGENSIS_MCP_TOKEN}"}}}}),"--strict-mcp-config"),l=h.env}if(o==="accept_edits"&&a.push("--permission-mode","acceptEdits"),o==="yolo"){let h=t&&t.agent&&t.agent.run_mode==="sandbox",_=typeof x.getuid=="function"&&x.getuid()===0,S=h||Fo(),p=x.env.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1";S||!_||p?a.push("--dangerously-skip-permissions"):(c=[],D("running as root with no sandbox detected: dropping --dangerously-skip-permissions (Claude rejects it as root). Set AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS=1 if this host really is sandboxed."))}let g=i.some(h=>h==="--output-format"||String(h).startsWith("--output-format=")),w=i.includes("-p")||i.includes("--print"),f=!1;!g&&w?(a.push("--output-format","stream-json","--include-partial-messages"),i.includes("--verbose")||a.push("--verbose"),f=!0):g&&(f=i.some(h=>/stream-json/.test(String(h))));for(let h of u)a.push("--add-dir",h);return{cmd:n,args:a,model:s,permissionMode:o,permissionFlags:c,streamJson:f,env:l}}if(Cn(n)){let a=[...i];s&&a.push("--model",s);let l;if(e.leanCli&&i.includes("exec")){let g=Ye(e);a.push("--ephemeral","--ignore-user-config","--ignore-rules","--disable","plugins","--disable","memories","--disable","hooks","--disable","skill_search","-c","project_doc_max_bytes=0","-c",`mcp_servers.agensis.url=${JSON.stringify(g.url)}`,"-c",'mcp_servers.agensis.bearer_token_env_var="AGENSIS_MCP_TOKEN"'),l=g.env}return o==="yolo"&&a.push("--sandbox","danger-full-access","--ask-for-approval","never"),{cmd:n,args:a,model:s,permissionMode:o,permissionFlags:c,env:l}}return{cmd:n,args:r,model:s,permissionMode:o,permissionFlags:c}}function Ye(e){let t=Ve(e.url);return t.pathname="/backend/mcp",t.search="",t.hash="",{url:t.toString(),env:{AGENSIS_MCP_TOKEN:e.token}}}function Lo({onStep:e,onSegment:t}={}){let n="",r="",s=!1,o="",i="",c=null,u=!1,a=!1,l=new Set,g=_=>{if(!(typeof e!="function"||!_.name))try{e(_)}catch{}},w=_=>{if(typeof t=="function"){i+=s?r:o,r="",o="";try{t(_)}catch{}}},f=_=>{if(!_||typeof _!="object")return;if(_.type==="agensis_step"){let p=_.step;p&&typeof p=="object"&&(u=!0,g({kind:p.kind||"tool",name:String(p.name||""),detail:String(p.detail||"")}));return}if(_.type==="agensis_segment"){let p=_.segment;p&&typeof p=="object"&&(a=!0,w({text:String(p.text||"")}));return}let S=_.event&&_.event.delta||_.delta;if(S&&S.type==="text_delta"&&typeof S.text=="string"){s=!0,r+=S.text;return}if(_.type==="result"&&typeof _.result=="string"){c=_.result;return}if(_.type==="assistant"&&_.message&&Array.isArray(_.message.content)){let p=_.message.content.filter(v=>v&&v.type==="text"&&typeof v.text=="string").map(v=>v.text).join("");if(p&&(o+=p),p&&!a&&w({text:p}),!u)for(let v of _.message.content){if(!v||v.type!=="tool_use")continue;let k=typeof v.id=="string"?v.id:"";if(k){if(l.has(k))continue;l.add(k)}g({kind:"tool",name:String(v.name||""),detail:De(v.input)})}}},h=_=>{let S=String(_).trim();if(S)try{f(JSON.parse(S))}catch{}};return{feed(_){n+=String(_||"");let S;for(;(S=n.indexOf(`
52
+ `))>=0;)h(n.slice(0,S)),n=n.slice(S+1)},end(){n&&(h(n),n="")},get live(){return s?r:o},get result(){return c??i+(s?r:o)}}}function vn(e,t){return Xe(t?.agent?.model||t?.model||e.model)}function Xe(e){let t=String(e||"").trim();return!t||t==="auto"||t==="claude-fable-5"?So:t}function En(e,t){return Ce(t?.agent?.permissionMode||t?.agent?.permission_mode||t?.permissionMode||t?.permission_mode||e.permissionMode)}function Ce(e){let t=String(e||"").trim().toLowerCase().replace(/[-\s]+/g,"_");return["yolo","no_sandbox","danger","danger_full_access","dangerously_skip_permissions"].includes(t)?"yolo":["accept_edits","acceptedits","auto_approve","auto_approve_edits"].includes(t)?"accept_edits":"default"}function Qe(e){return Ce(e)==="yolo"?["--no-sandbox","--yolo"]:[]}function kn(e){let t=Array.isArray(e)?e:String(e||"").split(/[,\n]/),n=new Set,r=[];for(let s of t){let o=String(s||"").trim();!o||n.has(o)||(n.add(o),r.push(o))}return r}function Uo(e,t){let n=t?.agent?.metadata?.host_folders??t?.agent?.hostFolders??t?.hostFolders??t?.host_folders,r=kn(n);return r.length>0?r:e.hostFolders||[]}function An(e,t){let n=Uo(e,t),r=q({workspace:e.workspace,agent:e.agent});return r&&!n.includes(r)?[...n,r]:n}var te;function Fo(){if(te!==void 0)return te;let e=x.env;if(e.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1"||e.AGENSIS_SANDBOX_HOST==="1"||e.IS_SANDBOX==="1")return te=!0;if(e.AGENSIS_NO_SANDBOX_AUTODETECT==="1")return te=!1;try{if(pe.existsSync("/.dockerenv")||pe.existsSync("/run/.containerenv"))return te=!0}catch{}try{let t=pe.readFileSync("/proc/1/cgroup","utf8");if(/docker|kubepods|containerd|lxc|podman/i.test(t))return te=!0}catch{}return te=!1}function ze(e,t,n,r=null,s=null){let o={busy:t.active()>0,queueSize:t.size(),cwd:e.cwd,model:e.model,permissionMode:e.permissionMode,permissionFlags:Qe(e.permissionMode),daemon:{runtime:"agensis-cli",version:Q,pid:x.pid,node:x.version,platform:x.platform,arch:x.arch,host:ge.hostname(),cwd:e.cwd}};if(s instanceof Map){let i={};for(let c of s.values()){let u=String(c?.model||"");u&&(i[u]=(i[u]||0)+1)}o.activeInferenceByModel=i}return r&&typeof r=="object"&&(o.cursorBuddy=jo(r)),n?.status&&(o.agentStatus=n.status),n?.note&&(o.agentNote=n.note),(n?.status||n?.note)&&(o.agentStatusAt=new Date().toISOString()),o}function jo(e={}){let t=e.client&&typeof e.client=="object"?e.client:{},n=e.page&&typeof e.page=="object"?e.page:{},r=e.runtime&&typeof e.runtime=="object"?e.runtime:{},s=e.manifest&&typeof e.manifest=="object"?e.manifest:{},o=e.project&&typeof e.project=="object"?e.project:{};return{surface:String(e.surface||"").slice(0,80),instanceId:String(e.instanceId||"").slice(0,140),url:String(e.url||"").slice(0,2048),title:String(e.title||"").slice(0,300),origin:String(n.origin||"").slice(0,300),hostname:String(n.hostname||"").slice(0,200),pathname:String(n.pathname||"").slice(0,500),visibilityState:String(n.visibilityState||"").slice(0,40),focused:n.focused===!0,userAgent:String(t.userAgent||"").slice(0,500),platform:String(t.platform||"").slice(0,120),language:String(t.language||"").slice(0,80),viewport:t.viewport&&typeof t.viewport=="object"?{width:Number(t.viewport.width)||0,height:Number(t.viewport.height)||0,devicePixelRatio:Number(t.viewport.devicePixelRatio)||0}:null,runtimeMarker:String(r.marker||"").slice(0,120),extensionMarker:String(r.extensionMarker||"").slice(0,120),manifest:{name:String(s.name||"").slice(0,120),version:String(s.version||"").slice(0,80),source:String(s.source||"").slice(0,500)},project:{name:String(o.name||"").slice(0,120),root:String(o.root||"").slice(0,500),agent:String(o.agent||"").slice(0,80)},updatedAt:String(e.updatedAt||"").slice(0,80)}}function yn(e,t){if(!t||typeof t!="object")return;t.name&&(e.name=String(t.name).trim()||e.name),(t.handle||t.name)&&(e.handle=Mn(t.handle||t.name||e.handle)),t.model&&(e.model=Xe(t.model));let n=t.permissionMode||t.permission_mode;n&&(e.permissionMode=Ce(n)),(t.memory_dir!==void 0||t.memoryDir!==void 0)&&(e.memoryDir=String(t.memory_dir??t.memoryDir??"").trim())}function Go(){let e=["claude","codex","gh","node","npm","python3","git","fly","vercel"],t=(x.env.PATH||"").split(he.delimiter).filter(Boolean);return e.filter(n=>t.some(r=>{try{return pe.existsSync(he.join(r,n))}catch{return!1}}))}function Ho(){try{let e=pe.readFileSync(he.join(ge.homedir(),".claude.json"),"utf8"),n=JSON.parse(e)?.mcpServers;if(n&&typeof n=="object")return Object.keys(n).sort()}catch{}return[]}function Sn(e){return po.createHash("sha1").update(String(e)).digest("hex").slice(0,16)}async function In(e,t=null){let n=zt({cwd:e.cwd}),r=Kt({cwd:e.cwd}),s=Go(),o=Ho(),i=e.syncMemory&&Le({cwd:e.cwd,memoryDir:e.memoryDir})||null,c=Vt(e.sharedModels),u=Sn(JSON.stringify({skills:n,commands:r,clis:s,mcpServers:o,memoryRoot:i,sharedModels:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null})),a=Sn(await Gt(i));return{skills:n,commands:r,clis:s,mcpServers:o,memoryRoot:i,sharedModels:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null,capabilitiesHash:u,memoryHash:a}}async function me(e,t,n=null){try{let r=await In(t,n);L(e,{action:"agent_capabilities_sync",workspaceId:t.workspace,agentId:t.agent,skills:r.skills,commands:r.commands,clis:r.clis,mcpServers:r.mcpServers,sharedModels:r.sharedModels,codingRoute:r.codingRoute,shared:r.shared,memoryRoot:r.memoryRoot,reach:r.reach||void 0,hash:r.capabilitiesHash,memoryHash:r.memoryHash}),D(`Capabilities synced \u2014 skills:${r.skills.length} commands:${r.commands.length} clis:${r.clis.length} mcp:${r.mcpServers.length}`)}catch(r){D(`Capabilities sync skipped: ${r?.message||r}`)}}function Jo(e){let t=ge.networkInterfaces(),n=[];for(let r of Object.values(t))for(let s of r||[])s.family==="IPv4"&&!s.internal&&n.push({host:s.address,port:e,scope:"lan"});return n.slice(0,4)}async function wn(e,t){try{if(!t.syncMemory)return;let n=Le({cwd:t.cwd,memoryDir:t.memoryDir});if(!n)return;let r=await Ht(n);L(e,{action:"agent_memory_sync",workspaceId:t.workspace,agentId:t.agent,root:n,files:r}),D(`Synced ${r.length} memory file${r.length===1?"":"s"} from ${n}`)}catch(n){D(`Memory sync skipped: ${n?.message||n}`)}}function qo(e){let t=new Set(["--model","-m","--permission-mode","--sandbox","--ask-for-approval","--approval-policy"]),n=new Set(["--dangerously-skip-permissions","--no-sandbox","--yolo","--accept-edits"]),r=[];for(let s=0;s<e.length;s+=1){let o=e[s],[i]=String(o).split("=",1);if(!n.has(o)){if(t.has(i)){String(o).includes("=")||(s+=1);continue}r.push(o)}}return r}function xn(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function Cn(e){return/(^|\/)codex(?:$|\.)/.test(String(e||""))}function Ko(e){let t=[],n="",r="",s=!1;for(let o of e){if(s){n+=o,s=!1;continue}if(o==="\\"){s=!0;continue}if(r){o===r?r="":n+=o;continue}if(o==='"'||o==="'"){r=o;continue}if(/\s/.test(o)){n&&(t.push(n),n="");continue}n+=o}if(n&&t.push(n),!t.length)throw new Error("coding command is empty");return{cmd:t[0],args:t.slice(1)}}function We(e){try{return JSON.parse(String(e))}catch{return null}}function L(e,t){return!e||e.readyState!==fe.OPEN?!1:(e.send(JSON.stringify(t)),!0)}function zo(e){return String(e||"").split(/\r?\n/).map(t=>t.trim()).filter(Boolean).slice(-1)[0]||""}function Mn(e){return String(e||"").trim().toLowerCase().replace(/^@+/,"").replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}function Wo(e){return e?.code==="EADDRINUSE"||/\bEADDRINUSE\b/.test(String(e?.message||e))}async function Yo(e){let t=new AbortController,n=setTimeout(()=>t.abort(),700);try{let r=await fetch(`http://127.0.0.1:${Number(e||8787)}/cursorbuddy/health`,{cache:"no-store",signal:t.signal}),s=await r.json().catch(()=>({}));return!r.ok||!s?.ok?null:s}catch{return null}finally{clearTimeout(n)}}function D(e){x.stderr.write(`[agensis] ${e}
53
+ `)}function bn(e){if(e instanceof Map)for(let t of e.values())try{t?.abort?.()}catch{}}import Vo from"node:crypto";import ye from"node:fs/promises";import Xo from"node:os";import Tn from"node:path";var ne="default",On=2,Qo=/^[a-zA-Z0-9_.-]{1,64}$/,Zo=["url","token","workspace","agent","handle","name","cwd","codingCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","fullCliContext","syncMemory","lanListener","primaryDaemon","cursorBuddyBridge","cursorBuddyPort","hostFolders"];function W(e=ne){let t=String(e||ne).trim();if(!Qo.test(t))throw new Error("Daemon profile names may only contain letters, numbers, dot, dash, and underscore.");return t}function Nn(e=ne,t={}){let n=t.homedir||Xo.homedir();return Tn.join(n,".agensis","daemon-profiles",`${W(e)}.json`)}function Ze(e={}){let t={};for(let n of Zo){let r=e[n];r!=null&&r!==""&&(t[n]=r)}return t}function Z(e,t,n=[]){for(let r of t)if(String(e?.[r]||"").trim())return!0;for(let r of n)if(String(process.env[r]||"").trim())return!0;return!1}function $n(e={}){return!!(Z(e,["url","baseUrl"],["AGENSIS_URL"])||Z(e,["token"],["AGENSIS_TOKEN"])||Z(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])||Z(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}function et(e={}){return!!(Z(e,["url","baseUrl"],["AGENSIS_URL"])&&Z(e,["token"],["AGENSIS_TOKEN"])&&Z(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])&&Z(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}async function tt(e=ne,t={}){let n=Nn(e,t),r;try{r=await ye.readFile(n,"utf8")}catch(c){if(c?.code==="ENOENT")return null;throw c}let s;try{s=JSON.parse(r)}catch(c){throw new Error(`Daemon profile "${W(e)}" is unreadable: ${c?.message||c}`)}let o=s?.config;if(!o?.url||!o?.token||!o?.workspace||!o?.agent)return null;let i=Ze(o);return Number(s.version||1)<On&&Number(i.maxConcurrency)===8&&(i.maxConcurrency=2),i}async function Me(e=ne,t={},n={}){let r=Ze(t);if(!r.url||!r.token||!r.workspace||!r.agent)return null;let s=Nn(e,n),o=Tn.dirname(s);await ye.mkdir(o,{recursive:!0,mode:448});let i=`${s}.${process.pid}.${Date.now()}.tmp`,c={version:On,savedAt:new Date().toISOString(),profile:W(e),tokenHash:Vo.createHash("sha256").update(r.token).digest("hex"),config:r};return await ye.writeFile(i,`${JSON.stringify(c,null,2)}
54
+ `,{mode:384}),await ye.rename(i,s),await ye.chmod(s,384).catch(()=>{}),s}function Dn(e,t={}){let n={...e,...Ze(t),command:"connect"};return t.fullCliContext===!0&&(n.leanCli=!1),t.codingCmd!==void 0&&t.noCoding===void 0&&(n.noCoding=!1),t.cursorBuddyBridge===void 0&&!n.primaryDaemon&&(n.cursorBuddyBridge=!1),t.once!==void 0&&(n.once=t.once),t.exitOnOnce!==void 0&&(n.exitOnOnce=t.exitOnOnce),n}function nt(e=ne){let t=W(e);return[`No saved Agensis daemon profile found for "${t}".`,"","To connect the main agent once:","1. Run: agensis setup","2. Sign in or create an account in the browser.","3. Approve this machine as your primary local agent.","","Manual fallback: open Agensis > AI Agents, copy a connection command,","and run that full agensis connect command from the repo folder.","","After the daemon registers successfully, this CLI saves the profile locally.",`Then restart it with: agensis connect${t===ne?"":` --profile ${t}`}`].join(`
55
+ `)}import es from"node:crypto";import Se from"node:fs/promises";import Bn from"node:os";import rt from"node:path";import ot from"node:process";var ts=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/;function ns(e={}){return String(e.url||e.baseUrl||ot.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function Rn(e,t={}){let n=t.homedir||Bn.homedir(),r=es.createHash("sha256").update(String(e)).digest("hex");return rt.join(n,".agensis","cursorbuddy","connection-keys",`${r}.json`)}function rs(){return new Error("Missing or invalid --key. Create a CursorBuddy connection key in Agensis first.")}function st(e){let t=String(e||"").trim();if(!ts.test(t))throw rs();return t}function os(e,t,n,r){let s=t?.token,o=t?.workspaceId||t?.workspace_id||t?.agent?.workspace_id,i=t?.agentId||t?.agent?.id;if(!s||!o||!i)throw new Error("CursorBuddy key claim did not return a complete daemon connection payload");let{key:c,subcommand:u,...a}=e;return{...a,command:"connect",url:t.baseUrl||n,token:s,workspace:o,agent:i,handle:t.handle||e.handle,name:t.agent?.name||e.name||"CursorBuddy runtime",model:t.model||e.model,permissionMode:t.permissionMode||t.permission_mode||e.permissionMode,cwd:e.cwd||r,cursorBuddyRuntime:!0}}async function ss(e,t={}){st(e);let n=Rn(e,t),r;try{r=await Se.readFile(n,"utf8")}catch(i){if(i?.code==="ENOENT")return null;throw i}let s;try{s=JSON.parse(r)}catch(i){throw new Error(`Cached CursorBuddy daemon config is unreadable: ${i?.message||i}`)}let o=s?.daemonArgs;return!o?.token||!o?.workspace||!o?.agent||!o?.url?null:o}async function is(e,t,n={}){if(st(e),!t?.token||!t?.workspace||!t?.agent||!t?.url)return;let r=Rn(e,n),s=rt.dirname(r);await Se.mkdir(s,{recursive:!0,mode:448});let o=`${r}.${ot.pid}.${Date.now()}.tmp`,i={version:1,savedAt:new Date().toISOString(),keyHash:rt.basename(r,".json"),daemonArgs:t};await Se.writeFile(o,`${JSON.stringify(i,null,2)}
56
+ `,{mode:384}),await Se.rename(o,r),await Se.chmod(r,384).catch(()=>{})}function as(e,t,n){let r={...e,command:"connect"};for(let s of["cwd","codingCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","lanListener","once"])t[s]!==void 0&&(r[s]=t[s]);return t.codingCmd!==void 0&&t.noCoding===void 0&&(r.noCoding=!1),r.cwd||(r.cwd=n),r.cursorBuddyRuntime=!0,r}function cs(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function us(e){return e.json().catch(()=>({}))}async function Pn(e,t={}){let n=st(e?.key),r=ns(e),s=t.fetchImpl||globalThis.fetch;if(typeof s!="function")throw new Error("This Node.js runtime does not provide fetch; use a current Node.js release.");let o=t.cwd||ot.cwd(),i=t.hostname||Bn.hostname(),c=t.version||Q,u={homedir:t.homedir},a=await s(`${r}/backend/cursorbuddy/connection-keys/claim`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({key:n,baseUrl:r,host:i,cwd:e.cwd||o,name:e.name,surface:e.surface||"local_cli",scope:e.scope||"machine",runtimeKind:"agensis-cli",version:c,permissionMode:e.permissionMode,model:e.model})}),l=await us(a);if(!a.ok){let w=cs(a,l);if(a.status===409||/already been claimed/i.test(w)){let f=await ss(n,u);if(f)return as(f,e,o);throw new Error(`${w}. No cached daemon config was found on this machine; create a new CursorBuddy key in Agensis or run the full copied agensis connect command.`)}throw new Error(w)}let g=os(e,l?.data||l,r,o);return await is(n,g,u),g}import ls from"node:crypto";import ds from"node:http";import ms from"node:os";import Y from"node:process";import{spawn as fs}from"node:child_process";var ps="https://agensis.io",hs=10*60*1e3;function Te(e,t,n){e.writeHead(t,{"content-type":"application/json","access-control-allow-origin":"*","access-control-allow-methods":"POST, OPTIONS","access-control-allow-headers":"content-type"}),e.end(JSON.stringify(n))}function gs(e){return new Promise((t,n)=>{let r="";e.on("data",s=>{r+=s,r.length>128*1024&&(n(new Error("setup callback body is too large")),e.destroy())}),e.on("error",n),e.on("end",()=>t(r))})}function ys(e){let t=String(e||Y.env.AGENSIS_URL||ps).trim(),n=new URL(t);if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error("Agensis setup URL must be http or https.");return n.search="",n.hash="",n.toString().replace(/\/+$/,"")}function Ss(e){let t=Y.platform==="darwin"?"open":Y.platform==="win32"?"cmd":"xdg-open",n=Y.platform==="win32"?["/c","start","",e]:[e],r=fs(t,n,{detached:!0,stdio:"ignore"});r.on("error",()=>{}),r.unref()}function ws(e){let t=e?.daemonArgs||e?.data?.daemonArgs||e?.data||{},r=["url","token","workspace","agent"].filter(s=>!String(t[s]||"").trim());if(r.length)throw new Error(`Setup callback did not include ${r.join(", ")}`);return{...t,command:"connect"}}function bs(e,t,n){let r=new URL(ys(e.url||e.baseUrl));return r.searchParams.set("source","agensis-cli"),r.searchParams.set("referrer","agensis-cli"),r.searchParams.set("intent","setup"),r.searchParams.set("callback",t),r.searchParams.set("state",n),r.searchParams.set("profile",W(e.profile||"default")),r.searchParams.set("host",ms.hostname()),r.searchParams.set("cwd",String(e.cwd||Y.cwd())),e.handle&&r.searchParams.set("handle",String(e.handle)),e.name&&r.searchParams.set("name",String(e.name)),r.toString()}async function Ln(e={}){let t=W(e.profile||"default"),n=ls.randomBytes(24).toString("base64url"),r=Number(e.setupTimeoutMs||Y.env.AGENSIS_SETUP_TIMEOUT_MS||hs),s,o=new Promise((a,l)=>{let g=setTimeout(()=>l(new Error("Agensis setup timed out waiting for browser login.")),r);g.unref&&g.unref(),s=ds.createServer(async(w,f)=>{if(f.setHeader("access-control-allow-origin","*"),f.setHeader("access-control-allow-methods","POST, OPTIONS"),f.setHeader("access-control-allow-headers","content-type"),w.method==="OPTIONS"){f.writeHead(204),f.end();return}if(w.method!=="POST"||w.url!=="/agensis/setup-callback"){Te(f,404,{ok:!1,error:"Unknown Agensis setup callback route"});return}try{let h=JSON.parse(await gs(w)||"{}");if(h?.state!==n){Te(f,403,{ok:!1,error:"Setup state did not match"});return}let _={...ws(h),primaryDaemon:!0,cursorBuddyBridge:e.cursorBuddyBridge!==!1};await Me(t,_),clearTimeout(g),Te(f,200,{ok:!0,profile:t}),a(_)}catch(h){Te(f,400,{ok:!1,error:String(h?.message||h)})}}),s.once("error",l)});await new Promise((a,l)=>{s.listen(0,"127.0.0.1",g=>g?l(g):a())});let{port:i}=s.address(),c=`http://127.0.0.1:${i}/agensis/setup-callback`,u=bs(e,c,n);Y.stdout.write(`[agensis] Opening Agensis to sign in and connect this machine.
57
+ `),Y.stdout.write(`[agensis] If the browser did not open, visit:
56
58
  ${u}
57
- `),No(u);try{let a=await o;return q.stdout.write(`[agensis] Saved daemon profile "${t}". Starting primary agent daemon.
58
- `),a}finally{await new Promise(a=>s.close(()=>a())).catch(()=>{})}}function Bo(e){let t={command:"connect"},n=[...e],r=n[0];if(r&&!r.startsWith("-")&&(t.command=n.shift(),t.command==="buddy")){let s=n[0];s&&!s.startsWith("-")?t.subcommand=n.shift():t.subcommand="connect"}for(let s=0;s<n.length;s+=1){let o=n[s];if(!o.startsWith("--"))throw new Error(`Unexpected argument: ${o}`);let[i,c]=o.slice(2).split(/=(.*)/s,2),u=i.replace(/-([a-z])/g,(l,h)=>h.toUpperCase());if(u==="help"){t.help=!0;continue}if(u==="version"){t.version=!0;continue}if(u==="once"){t.once=!0;continue}if(u==="lan"){t.lanListener=!0;continue}if(u==="share"){t.share=!0;continue}if(u==="noCoding"){t.noCoding=!0;continue}if(u==="fullCliContext"){t.fullCliContext=!0;continue}if(u==="syncMemory"){t.syncMemory=!0;continue}if(u==="cursorbuddyBridge"){t.cursorBuddyBridge=!0;continue}if(u==="noCursorbuddyBridge"){t.cursorBuddyBridge=!1;continue}if(u==="yolo"||u==="noSandbox"){t.permissionMode="yolo";continue}if(u==="acceptEdits"){t.permissionMode="accept_edits";continue}if(u==="hostFolder"||u==="hostFolders"||u==="addDir"){let l=c!==void 0?c:n[++s];if(l==null||l.startsWith("--"))throw new Error(`Missing value for --${i}`);t.hostFolders=[...t.hostFolders||[],l];continue}let a=c!==void 0?c:n[++s];if(a==null||a.startsWith("--"))throw new Error(`Missing value for --${i}`);t[u]=a}return t}function Do(){return`agensis agent daemon
59
+ `),Ss(u);try{let a=await o;return Y.stdout.write(`[agensis] Saved daemon profile "${t}". Starting primary agent daemon.
60
+ `),a}finally{await new Promise(a=>s.close(()=>a())).catch(()=>{})}}function Ds(e){let t={command:"connect"},n=[...e],r=n[0];if(r&&!r.startsWith("-")&&(t.command=n.shift(),t.command==="buddy")){let s=n[0];s&&!s.startsWith("-")?t.subcommand=n.shift():t.subcommand="connect"}for(let s=0;s<n.length;s+=1){let o=n[s];if(!o.startsWith("--"))throw new Error(`Unexpected argument: ${o}`);let[i,c]=o.slice(2).split(/=(.*)/s,2),u=i.replace(/-([a-z])/g,(l,g)=>g.toUpperCase());if(u==="help"){t.help=!0;continue}if(u==="version"){t.version=!0;continue}if(u==="once"){t.once=!0;continue}if(u==="lan"){t.lanListener=!0;continue}if(u==="share"){t.share=!0;continue}if(u==="noCoding"){t.noCoding=!0;continue}if(u==="fullCliContext"){t.fullCliContext=!0;continue}if(u==="syncMemory"){t.syncMemory=!0;continue}if(u==="cursorbuddyBridge"){t.cursorBuddyBridge=!0;continue}if(u==="noCursorbuddyBridge"){t.cursorBuddyBridge=!1;continue}if(u==="yolo"||u==="noSandbox"){t.permissionMode="yolo";continue}if(u==="acceptEdits"){t.permissionMode="accept_edits";continue}if(u==="hostFolder"||u==="hostFolders"||u==="addDir"){let l=c!==void 0?c:n[++s];if(l==null||l.startsWith("--"))throw new Error(`Missing value for --${i}`);t.hostFolders=[...t.hostFolders||[],l];continue}let a=c!==void 0?c:n[++s];if(a==null||a.startsWith("--"))throw new Error(`Missing value for --${i}`);t[u]=a}return t}function Bs(){return`agensis agent daemon
59
61
 
60
62
  Usage:
61
63
  agensis --url <workspace-url> --token <token> --workspace <id> --agent <id> [options]
62
64
  agensis connect --url <workspace-url> --token <token> --workspace <id> --agent <id> [options]
63
65
  agensis connect [--profile <name>]
64
66
  agensis setup [--url <agensis-url>] [--profile <name>] [--handle <name>]
67
+ agensis supervise [--profile <name>]
65
68
  agensis buddy connect --key <cbk_...> [--url <agensis-url>] [options]
66
69
 
67
70
  Required:
@@ -101,7 +104,16 @@ Options:
101
104
  --profile <name> Save/reuse a local daemon profile, default: default
102
105
  --version Print the CLI version
103
106
  --help Show this help
104
- `}async function Po(e){let t=e.profile!==void 0,n=e.handle||e.name,r=W(e.profile||(Je(e)&&n?n:"default"));if(!an(e)){let s=await cn(r);if(!s)throw new Error(ln(r));return un(s,e)}return Je(e)?{...e,cursorBuddyBridge:e.cursorBuddyBridge===!0,onRegistered:async s=>{await _e(r,s);let o=t||r!=="default"?`agensis connect --profile ${r}`:"agensis connect";Y.stdout.write(`[agensis] Saved daemon profile "${r}". Restart with: ${o}
105
- `)}}:e}async function Ro(){let e=Bo(Y.argv.slice(2));if(e.help){Y.stdout.write(Do());return}if(e.version){Y.stdout.write(`${Z}
106
- `);return}if(e.command==="buddy"){if(e.subcommand!=="connect")throw new Error(`Unknown buddy command "${e.subcommand||""}". Use "agensis buddy connect --key <cbk_...>".`);let n=await fn(e);n.cursorBuddyBridge=e.cursorBuddyBridge!==!1,n.cursorBuddyRuntime=!0,n.exitOnOnce=!0,await we(n),n.once&&Y.exit(0);return}if(e.command==="setup"){let n=await pn(e);n.exitOnOnce=!0,await we({...e,...n}),n.once&&Y.exit(0);return}if(e.command!=="connect")throw new Error(`Unknown command "${e.command}". Use "agensis setup", "agensis connect --url ...", or "agensis buddy connect --key ...".`);let t=await Po(e);t.exitOnOnce=!0,await we(t),t.once&&Y.exit(0)}Ro().catch(e=>{Y.stderr.write(`${e?.message||e}
107
- `),Y.exitCode=1});
107
+
108
+ agensis supervise [--profile <name>] [--poll-ms <ms>]
109
+ Runs the daemon as a supervised child instead of in this process, so an agent
110
+ can request a self-update (writing update-request.json into its own state
111
+ dir) with automatic install + health-check + rollback to the last-known-good
112
+ version on failure. Requires a saved profile (run "agensis setup" or
113
+ "agensis connect" once first). Recommended under a process manager with its
114
+ own restart policy (systemd Restart=always, launchd KeepAlive, pm2) so the
115
+ supervisor itself is recovered if it's ever killed.
116
+ `}async function Rs(e){let t=e.profile!==void 0,n=e.handle||e.name,r=W(e.profile||(et(e)&&n?n:"default"));if(!$n(e)){let s=await tt(r);if(!s)throw new Error(nt(r));return Dn(s,e)}return et(e)?{...e,cursorBuddyBridge:e.cursorBuddyBridge===!0,onRegistered:async s=>{await Me(r,s);let o=t||r!=="default"?`agensis connect --profile ${r}`:"agensis connect";V.stdout.write(`[agensis] Saved daemon profile "${r}". Restart with: ${o}
117
+ `)}}:e}async function Ps(){let e=Ds(V.argv.slice(2));if(e.help){V.stdout.write(Bs());return}if(e.version){V.stdout.write(`${Q}
118
+ `);return}if(e.command==="buddy"){if(e.subcommand!=="connect")throw new Error(`Unknown buddy command "${e.subcommand||""}". Use "agensis buddy connect --key <cbk_...>".`);let n=await Pn(e);n.cursorBuddyBridge=e.cursorBuddyBridge!==!1,n.cursorBuddyRuntime=!0,n.exitOnOnce=!0,await xe(n),n.once&&V.exit(0);return}if(e.command==="supervise"){let n=W(e.profile||"default"),r=await tt(n);if(!r)throw new Error(nt(n));let{runSupervisor:s}=await Promise.resolve().then(()=>(qn(),Jn)),o=e.pollMs?Number(e.pollMs):void 0;await s({config:r,runningVersion:Q,profileName:n,pollIntervalMs:o});return}if(e.command==="setup"){let n=await Ln(e);n.exitOnOnce=!0,await xe({...e,...n}),n.once&&V.exit(0);return}if(e.command!=="connect")throw new Error(`Unknown command "${e.command}". Use "agensis setup", "agensis connect --url ...", "agensis supervise", or "agensis buddy connect --key ...".`);let t=await Rs(e);t.exitOnOnce=!0,await xe(t),t.once&&V.exit(0)}Ps().catch(e=>{V.stderr.write(`${e?.message||e}
119
+ `),V.exitCode=1});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agensis/agensis-agent",
3
- "version": "0.1.30",
3
+ "version": "0.1.31",
4
4
  "description": "Run a local agensis workspace agent daemon. Connects to a workspace, receives @mention jobs, runs a configured coding CLI in the local folder, and posts results back to agensis. Ships as a single minified bundle.",
5
5
  "homepage": "https://agensis.io",
6
6
  "repository": {