@agensis/agensis-agent 0.1.31 → 0.1.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/agensis.mjs +39 -34
- package/package.json +1 -1
package/bin/agensis.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`),o=String(t.soul??""),i=await
|
|
4
|
-
`}async function
|
|
5
|
-
`)}async function
|
|
2
|
+
var tr=Object.defineProperty;var _e=(e,t)=>()=>(e&&(t=e(e=0)),t);var _t=(e,t)=>{for(var n in t)tr(e,n,{get:t[n],enumerable:!0})};var Tt={};_t(Tt,{createE2bProvider:()=>yr});function Pe(e){return`'${String(e).replace(/'/g,"'\\''")}'`}function yr({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(l){if(l&&(l.code==="ERR_MODULE_NOT_FOUND"||l.code==="MODULE_NOT_FOUND"||/Cannot find package 'e2b'/.test(String(l&&l.message)))){let a=Number(String(process.versions.node).split(".")[0])||0,u=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.${u}`)}throw l}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:gr}},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 ${Pe(i)} ${Pe(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 l=c&&(c.stderr||c.exitCode!=null)?c.stderr||`exit ${c.exitCode}`:String(c?.message||c);throw new Error(`git clone failed: ${l}`)}},async exec(o,{cmd:i,args:c=[],env:l={},onData:a}){let u=`${i} ${c.map(Pe).join(" ")}`,g={cwd:o.dir,envs:{...l,IS_SANDBOX:"1",AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS:"1"},onStdout:w=>{try{a?.(w)}catch{}}};try{let w=await o.sbx.commands.run(u,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 gr,Nt=_e(()=>{gr="/home/user/repo"});import cn from"node:fs";import G from"node:fs/promises";import po from"node:os";import H from"node:path";function ln(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=po.homedir()}={}){return H.join(n,".agensis",ln(e,"workspace"),ln(t,"agent"))}function fn(e){return H.join(q(e),un)}function pn(e){return H.join(q(e),Ye)}async function Ae(e){let t=q(e);try{return await G.mkdir(t,{recursive:!0}),t}catch{return null}}async function me(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 Ve(e,t){if(!t||typeof t!="object")return!1;let n=await Ae(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 me(H.join(n,go),`${JSON.stringify(r,null,2)}
|
|
3
|
+
`),o=String(t.soul??""),i=await me(H.join(n,yo),o);return s&&i}async function hn(e,t={}){let n=await Ae(e);return n?me(H.join(n,dn),yn(e,t)):!1}function gn(e,t={}){let n=q(e);try{return cn.mkdirSync(n,{recursive:!0}),cn.writeFileSync(H.join(n,dn),yn(e,t)),!0}catch{return!1}}function yn(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 Xe(e){let t=H.join(q(e),un),n;try{let c=await G.stat(t);if(!c.isFile()||c.size>ko)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=We(r.status),o=We(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 We(e){return e==null?"":String(e).trim().replace(/\s+/g," ").slice(0,Ao)}function Qe(e){return H.join(q(e),ho)}async function Sn(e){let t=Qe(e),n;try{let i=await G.stat(t);if(!i.isFile()||i.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={};for(let i of xo){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 Co){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 wn(e){return H.join(q(e),So)}function To(e){return H.join(q(e),mn)}async function bn(e){let t=wn(e),n;try{let c=await G.stat(t);if(!c.isFile()||c.size>wo)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(!_o.test(s))return null;let o={targetVersion:s},i=We(r.note);return i&&(o.note=i),typeof r.requestedAt=="string"&&(o.requestedAt=r.requestedAt),o}async function _n(e){try{return await G.rm(wn(e),{force:!0}),!0}catch{return!1}}async function Ie(e){let t=To(e),n;try{let r=await G.stat(t);if(!r.isFile()||r.size>bo)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 ne(e,t={}){let n=await Ae(e);if(!n)return!1;let r={...t,updatedAt:new Date().toISOString()};return me(H.join(n,mn),`${JSON.stringify(r,null,2)}
|
|
5
|
+
`)}async function vn(e){let t=await Ae(e);if(!t)return!1;let n=H.join(t,Ye);try{return await G.access(n),!0}catch{}return me(n,Eo)}async function En(e){let t=H.join(q(e),Ye);try{let n=await G.stat(t);return!n.isFile()||n.size>vo?null:(await G.readFile(t,"utf8")).trim()||null}catch{return null}}var un,ho,dn,Ye,go,yo,So,mn,wo,bo,_o,vo,Eo,ko,Ao,Io,xo,Co,xe=_e(()=>{un="status.json",ho="identity.json",dn="heartbeat.json",Ye="heartbeat.md",go="agent.json",yo="soul.md",So="update-request.json",mn="update.json",wo=4*1024,bo=16*1024,_o=/^[a-zA-Z0-9._+-]{1,64}$/,vo=16*1024,Eo=`# Heartbeat
|
|
6
6
|
|
|
7
7
|
This file tells you what to do on each heartbeat \u2014 the recurring "still here, still
|
|
8
8
|
working" moment. Edit it freely; the daemon reads it but never overwrites your edits.
|
|
@@ -15,49 +15,52 @@ On each heartbeat:
|
|
|
15
15
|
- If you've finished and there's nothing to do, a short idle note is fine.
|
|
16
16
|
|
|
17
17
|
Add your own recurring checks below.
|
|
18
|
-
`,
|
|
19
|
-
`),signal:i,installFn:c=
|
|
20
|
-
`}function
|
|
21
|
-
`}function
|
|
22
|
-
`}function
|
|
23
|
-
`}var
|
|
24
|
-
`):p.result,A=new Error(k||`claude-agent-sdk result error: ${p.subtype}`);
|
|
25
|
-
`))>=0;){let
|
|
18
|
+
`,ko=8*1024,Ao=400;Io=16*1024,xo=["name","avatar","accent_color","description","soul"],Co=["cartesia_voice_id","voice_id","id","speed","emotion","attitude"]});import{spawn as Ls,execFile as Us}from"node:child_process";import mt from"node:fs";import be from"node:fs/promises";import Fs from"node:os";import le from"node:path";import{promisify as js}from"node:util";function pt({homedir:e=Fs.homedir()}={}){return le.join(e,".agensis","versions")}function $e(e,t){return le.join(e,t)}function ht(e){return le.join(e,Hs)}function ce(e){return le.join(e,"node_modules",ft,"bin","agensis.mjs")}async function Wn(e,t){await be.mkdir(le.dirname(e),{recursive:!0}),await be.rm(e,{force:!0}),await be.symlink(t,e)}async function gt({root:e,version:t,log:n=()=>{}}){let r=$e(e,t),s=ce(r);if(mt.existsSync(s))return n(`[self-update] ${t} already installed at ${r}`),r;if(await be.mkdir(r,{recursive:!0}),n(`[self-update] installing ${ft}@${t} into ${r}`),await Gs("npm",["install","--prefix",r,`${ft}@${t}`,"--no-audit","--no-fund","--no-save","--omit=dev"]),!mt.existsSync(s))throw new Error(`npm install reported success but ${s} is missing`);return r}function yt({entry:e,profileName:t,extraArgs:n=[],env:r=process.env}){let s=["connect","--profile",t,...n],o=Ls(process.execPath,[e,...s],{detached:!0,stdio:"inherit",env:r});return o.unref(),o}async function St(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 wt({config:e,pid:t,timeoutMs:n=Yn}){let r=le.join(q(e),"heartbeat.json"),s=Date.now()+n;for(;Date.now()<s;){try{let o=await be.readFile(r,"utf8"),i=JSON.parse(o);if(Number.isFinite(i.ts)&&Date.now()-i.ts<=qs&&i.connected&&(t==null||i.pid===t))return!0}catch{}await new Promise(o=>setTimeout(o,Js))}return!1}async function Vn({config:e,targetVersion:t,currentVersion:n,root:r=pt({}),profileName:s="default",runningChild:o=null,installFn:i=gt,spawnFn:c=yt,stopFn:l=St,healthCheckFn:a=wt,healthTimeoutMs:u=Yn,log:g=()=>{}}={}){let w=await Ie(e)||{},f=n||w.currentVersion||null,h=ht(r),v={version:t,startedAt:new Date().toISOString()};if(t===f){let d={currentVersion:f,previousVersion:w.previousVersion||null,lastAttempt:{...v,result:"noop_already_current"}};return await ne(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:{...v,result:"install_failed",error:String(d?.message||d)}};return await ne(e,b),{...b,child:o}}o&&await l(o),await Wn(h,S);let p=ce(S),E=c({entry:p,profileName:s});if(await a({config:e,pid:E.pid,timeoutMs:u})){let d={currentVersion:t,previousVersion:f,lastAttempt:{...v,result:"ok"}};return await ne(e,d),{...d,child:E}}g(`[self-update] ${t} failed its health check within ${u}ms \u2014 rolling back to ${f||"(no known previous version)"}`),await l(E);let A=!1,T=null;if(f){let d=$e(r,f);mt.existsSync(ce(d))&&(await Wn(h,d),T=c({entry:ce(d),profileName:s}),A=!0)}let B={currentVersion:A?f:w.currentVersion||f,previousVersion:f,lastAttempt:{...v,result:A?"rolled_back":"failed_no_fallback"}};return await ne(e,B),{...B,child:T}}var Gs,ft,Hs,Yn,Js,qs,Xn=_e(()=>{xe();Gs=js(Us),ft="@agensis/agensis-agent",Hs="current",Yn=3e4,Js=1e3,qs=1e4});var Zn={};_t(Zn,{runSupervisor:()=>Vs});import Ks from"node:fs";import bt from"node:fs/promises";import zs from"node:path";async function Ys({root:e,runningVersion:t,installFn:n,log:r}){let s=ht(e);if(Ks.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 bt.mkdir(zs.dirname(s),{recursive:!0}),await bt.rm(s,{force:!0}),await bt.symlink(o,s)}async function Vs({config:e,runningVersion:t,profileName:n="default",pollIntervalMs:r=Ws,root:s=pt({}),log:o=w=>process.stdout.write(`${w}
|
|
19
|
+
`),signal:i,installFn:c=gt,spawnFn:l=yt,stopFn:a=St,healthCheckFn:u=wt,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 Ys({root:s,runningVersion:t,installFn:c,log:o});let w=await Ie(e);w?.currentVersion||(w={currentVersion:t,previousVersion:null,lastAttempt:null},await ne(e,w));let f=null,h=!1,v=0,S=()=>{let k=$e(s,w.currentVersion);return f=l({entry:ce(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=Qn[Math.min(v,Qn.length-1)];v+=1,setTimeout(()=>{h||S()},B).unref?.()}),f.on?.("spawn",()=>{v=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 E=0;for(;!h&&!i?.aborted&&E<g&&(E+=1,await new Promise(T=>setTimeout(T,r)),!(h||i?.aborted));){let k=await bn(e);if(!k||k.targetVersion===w.currentVersion)continue;o(`[supervise] update requested: ${w.currentVersion} -> ${k.targetVersion}${k.note?` (${k.note})`:""}`);let A=await Vn({config:e,targetVersion:k.targetVersion,currentVersion:w.currentVersion,root:s,profileName:n,runningChild:f,installFn:c,spawnFn:l,stopFn:a,healthCheckFn:u,log:o});await _n(e),w=A,f=A.child||f,v=0,o(`[supervise] update attempt "${k.targetVersion}" -> ${A.lastAttempt?.result} (running ${A.currentVersion})`)}return{state:w,child:f}}var Ws,Qn,er=_e(()=>{Xn();xe();Ws=5e3,Qn=[1e3,5e3,15e3,3e4]});import V from"node:process";import he from"node:fs";import ge from"node:path";import ye from"node:os";import No from"node:crypto";import x from"node:process";import pe from"ws";import{spawn as nr}from"node:child_process";function vt(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 rr=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:l="",now:a=Date.now,log:u=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=nr(t,n,{cwd:s,detached:!0,env:R})}catch(y){f({status:null,stdout:"",stderr:"",error:y});return}l?h.stdin?.end(String(l)):h.stdin?.end();let v="",S="";h.stdout?.setEncoding("utf8"),h.stderr?.setEncoding("utf8");let p=(y,I)=>y.length>=rr?y:y+I;h.stdout?.on("data",y=>{if(v=p(v,y),w)try{w(y)}catch{}}),h.stderr?.on("data",y=>S=p(S,y));let E=a(),k=c>0?setInterval(()=>{u.log(` \u2026 still ${i} (${vt(a()-E)}) \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:v,stderr:S,aborted:d,error:I||(d?new Error("cancelled"):T?new Error(`timed out after ${vt(o)}`):null)})};h.on("error",y=>m(null,y)),h.on("close",y=>m(y,null))})}import{spawn as or}from"node:child_process";var kt=10*60*1e3;function At(e={}){let t={...process.env,...e};return delete t.AGENSIS_TOKEN,delete t.ANTHROPIC_API_KEY,delete t.ANTHROPIC_AUTH_TOKEN,t}var Be=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 It(){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 sr=["mcp__agensis"],ir=["Grep","Glob"];function ar(e){return e==="yolo"?{permissionMode:"bypassPermissions",allowDangerouslySkipPermissions:!0}:e==="accept_edits"?{permissionMode:"acceptEdits"}:{permissionMode:"default"}}function cr(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 lr(e){return`${JSON.stringify({type:"stream_event",event:{type:"content_block_delta",delta:{type:"text_delta",text:e}}})}
|
|
20
|
+
`}function ur(e){return`${JSON.stringify({type:"result",result:e})}
|
|
21
|
+
`}function dr(e){return`${JSON.stringify({type:"agensis_step",step:e})}
|
|
22
|
+
`}function mr(e){return`${JSON.stringify({type:"agensis_segment",segment:e})}
|
|
23
|
+
`}var fr=["file_path","path","pattern","command","description","prompt"],Et=120;function Re(e){if(!e||typeof e!="object")return"";for(let t of fr){let n=e[t];if(typeof n!="string")continue;let r=n.replace(/\s+/g," ").trim();if(r)return r.length>Et?`${r.slice(0,Et)}\u2026`:r}return""}function xt(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 Ct({queryFn:e,idleCloseMs:t=kt}={}){let n=new Map,r=It(),s=(l,a,u)=>{let g=n.get(l);if(!(!g||a&&g!==a))if(n.delete(l),clearTimeout(g.idleTimer),g.closed=!0,g.queue.close(),u&&g.activeTurn&&g.activeTurn.finish(u),typeof g.query.close=="function")try{g.query.close()}catch{}else Promise.resolve(g.query.return?.()).catch(()=>{})},o=l=>{let a=n.get(l);a&&(clearTimeout(a.idleTimer),a.idleTimer=setTimeout(()=>s(l),t),a.idleTimer.unref?.())},i=async(l,a)=>{let u=n.get(l),g=xt(a);if(u&&u.fingerprint===g&&!u.closed)return u;u&&s(l,u),e||(e=(await import("@anthropic-ai/claude-agent-sdk")).query);let w=new Be,f=ar(a.permissionMode),h=a.leanCli&&a.mcp?{agensis:{type:"http",url:a.mcp.url,headers:{Authorization:"Bearer ${AGENSIS_MCP_TOKEN}"}}}:void 0,v=e({prompt:w,options:{cwd:a.cwd,model:a.model,...f,allowedTools:[...sr,...ir],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:At(a.mcp?.env)}});return u={query:v,queue:w,sessionId:"",idleTimer:null,activeTurn:null,closed:!1,terminalError:null,fingerprint:g},n.set(l,u),u.pump=(async()=>{let S=null;try{for await(let p of v){p.session_id&&(u.sessionId=p.session_id);let E=u.activeTurn;if(E){if(p.type==="stream_event"){let k=cr(p.event);k&&(E.streamed+=k,E.onData?.(lr(k)))}else if(p.type==="result")if(p.subtype==="success"){let k=p.result==null?E.text:String(p.result);E.onData?.(ur(k)),E.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}`);E.finish({status:1,stdout:E.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&&(E.onData?.(mr({text:A})),E.flushed+=E.streamed,E.streamed="");for(let T of k)!T||T.type!=="tool_use"||!T.name||E.onData?.(dr({kind:"tool",name:String(T.name),detail:Re(T.input)}))}}}}S=new Error("claude-agent-sdk connection closed")}catch(p){S=p}finally{u.closed=!0,u.terminalError=S,clearTimeout(u.idleTimer),u.queue.close(),n.get(l)===u&&n.delete(l),u.activeTurn&&u.activeTurn.finish({status:null,stdout:u.activeTurn.text,stderr:String(S?.message||S||""),error:S})}})(),u};return{run:l=>r(l.sessionKey||"default",async()=>{let{sessionKey:a="default",prompt:u,signal:g,onData:w,timeoutMs:f=0}=l;if(g?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let h;try{h=await i(a,l)}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 v=await new Promise(S=>{let p=!1,E=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),E&&clearTimeout(E),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&&(E=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),E.unref?.()),h.queue.push({type:"user",message:{role:"user",content:u},parent_tool_use_id:null,session_id:h.sessionId})});return n.get(a)===h&&o(a),v}),shutdown:()=>{for(let l of[...n.keys()])s(l)}}}function pr(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 l=n.slice(0,c);if(n=n.slice(c+1),!l.trim())continue;let a;try{a=JSON.parse(l)}catch{continue}if(a.id!==void 0&&r.has(a.id)){let{resolve:u,reject:g}=r.get(a.id);r.delete(a.id),a.error?g(new Error(a.error.message||"codex app-server error")):u(a.result)}else if(a.method)for(let u of s)u(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 l=t++;return new Promise((a,u)=>{r.set(l,{resolve:a,reject:u}),e.stdin.write(`${JSON.stringify({id:l,method:i,params:c})}
|
|
26
26
|
`)})},notify(i,c){e.stdin.write(`${JSON.stringify({method:i,params:c})}
|
|
27
27
|
`)},respond(i,c){e.stdin.write(`${JSON.stringify({id:i,result:c})}
|
|
28
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
|
|
29
|
+
`)},onMessage(i){return s.add(i),()=>s.delete(i)}}}function hr(e){return e==="yolo"?{approvalPolicy:"never",sandbox:"danger-full-access"}:{}}function Mt({spawnFn:e=or,idleCloseMs:t=kt}={}){let n=new Map,r=It(),s=l=>{let a=n.get(l);if(a){n.delete(l),clearTimeout(a.idleTimer);try{a.child.kill("SIGTERM")}catch{}}},o=l=>{let a=n.get(l);a&&(clearTimeout(a.idleTimer),a.idleTimer=setTimeout(()=>s(l),t),a.idleTimer.unref?.())},i=async(l,a)=>{let u=n.get(l),g=xt(a);if(u&&u.fingerprint===g)return u;u&&s(l);let w=e("codex",["app-server"],{cwd:a.cwd,env:At(a.mcp?.env),stdio:["pipe","pipe","pipe"]}),f=pr(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,v=await f.request("thread/start",{cwd:a.cwd,ephemeral:a.leanCli||void 0,model:a.model,config:h,...hr(a.permissionMode)}),S={child:w,rpc:f,threadId:v.thread.id,fingerprint:g,idleTimer:null};return n.set(l,S),S};return{run:l=>r(l.sessionKey||"default",async()=>{let{sessionKey:a="default",prompt:u,signal:g,onData:w,timeoutMs:f=0}=l;if(g?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let h;try{h=await i(a,l)}catch(A){return{status:null,stdout:"",stderr:"",error:A}}let v="",S="",p=null,E=!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=l.permissionMode==="yolo"?"acceptForSession":"decline";h.rpc.respond(R,{decision:C})}else if(y==="item/fileChange/requestApproval"){let C=l.permissionMode==="yolo"||l.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")v+=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||v,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=()=>{E=!0,h.rpc.request("turn/interrupt",{threadId:h.threadId}).catch(()=>{});let y={status:null,stdout:v,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:v,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:u}]}).then(y=>{p=y?.turn?.id||p}).catch(y=>B({status:null,stdout:"",stderr:"",error:y}))});return E||o(a),k}),shutdown:()=>{for(let l of[...n.keys()])s(l)}}}function $t({run:e=ue}={}){return{run:t=>e(t)}}var Sr=null,wr=null,Ot=new Set;function br(e){let t=String(e&&e.message||e||"");return/Cannot find module|ERR_MODULE_NOT_FOUND|ENOENT|command not found/i.test(t)}function _r(e,{local:t,pooled:n,log:r=console}={}){let s=t||$t(),o=n||(e==="claude"?Sr||=Ct():e==="codex"?wr||=Mt():null);return o?{async run(i){if(Ot.has(e))return s.run(i);let c=await o.run(i);return c.error&&br(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 vr(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 l=await e.exec(c,{cmd:t,args:n,env:r,onData:s,signal:o}),a=await e.getResult(c,{job:i}).catch(()=>({})),u=a&&a.patch?String(a.patch).trim():"",g=u?`${l.stdout||""}
|
|
30
30
|
|
|
31
31
|
\`\`\`diff
|
|
32
|
-
${
|
|
33
|
-
\`\`\``:
|
|
32
|
+
${u}
|
|
33
|
+
\`\`\``:l.stdout||"";return{status:l.status,stdout:g,stderr:l.stderr||"",error:l.error||null}}catch(l){return{status:null,stdout:"",stderr:"",error:l}}finally{if(c)try{await e.destroy(c)}catch{}}}}}function Dt(e,{makeProvider:t,family:n}={}){return(e&&e.agent&&e.agent.run_mode)==="sandbox"?vr((t||Er)(e)):n==="claude"||n==="codex"?_r(n):$t()}function Er(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 Ar({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 kr(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 Ar(e){let t=null,n=async()=>{if(!t){if(!kr())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(()=>(Nt(),Tt))).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 Bt(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(E=>E.key===S))return!0;return!1}function l(){for(let[S,p]of r){if(s>=n)break;if(p.active||p.queued.length===0)continue;let E=p.queued.shift(),k=new AbortController;p.active={job:E,controller:k,cancelled:!1},s+=1,Promise.resolve().then(()=>k.signal.aborted?void 0:t(E,{signal:k.signal})).catch(()=>{}).finally(()=>{p.active=null,s-=1,p.queued.length===0&&!p.active&&r.delete(S),l(),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 u(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):"",E=i(p),k=!E.active&&E.queued.length===0&&s<n;E.queued.push(S);let A=E.queued.length+(E.active?1:0);return l(),{accepted:!0,deduped:!1,position:A,startedImmediately:k}}function g(S,p){let E=!1;for(let[k,A]of r)p!=null&&k!==String(p)||A.active&&(A.active.cancelled=!0,A.active.controller.abort(S||"cancelled"),E=!0);return E}function w(S,p){if(S==null)return!1;let E=!1;for(let[k,A]of[...r]){A.active?.job?.key===S&&(A.active.cancelled=!0,A.active.controller.abort(p||"cancelled"),E=!0);let T=A.queued.length;A.queued=A.queued.filter(B=>B.key!==S),A.queued.length!==T&&(E=!0),!A.active&&A.queued.length===0&&r.delete(k)}return a(),E}function f(){let S=0;for(let p of r.values())S+=p.queued.length;return S}function h(){return s}function v(){return s===0&&f()===0?Promise.resolve():new Promise(S=>o.push(S))}return{enqueue:u,cancel:w,cancelActive:g,has:c,size:f,active:h,idle:v}}import jt from"node:crypto";import Ir from"node:http";import Gt from"node:os";import X from"node:process";var Rt=8787,Le="claude-haiku-4-5",xr=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/,Cr=100,Mr=new Set(["say","wave","hush","open","choose"]),ke="x-agensis-bridge-secret";function Tr(){return`cbs_${jt.randomBytes(24).toString("base64url")}`}function Nr(e){let t=e?.headers||{},n=String(t[ke]||t[ke.toLowerCase()]||"").trim();if(n)return n;let s=String(t.authorization||t.Authorization||"").trim().match(/^Bearer\s+(.+)$/i);return s?s[1].trim():""}function Or(e,t){let n=String(t||""),r=Nr(e);if(!n||!r)return!1;let s=Buffer.from(r),o=Buffer.from(n);return s.length!==o.length?!1:jt.timingSafeEqual(s,o)}function $r(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||Tr()}function Dr(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 Pt(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
34
|
|
|
35
|
-
`)}function
|
|
35
|
+
`)}function de(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 Br(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 Rr(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function ve(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()}:
|
|
36
36
|
${o}`)}return n.join(`
|
|
37
37
|
|
|
38
|
-
`).trim()||"Say that the local Agensis runtime is connected."}function
|
|
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
|
-
|
|
41
|
-
|
|
38
|
+
`).trim()||"Say that the local Agensis runtime is connected."}function Ut(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 Pr(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 Lr(e,t=280){let n=Pr(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 Ur(e){let t=Lr(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 Fr(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||Fr(n)?t:n}function Jt(e){let t=String(e||"").trim();return!t||t==="haiku-4.5"||t==="claude-haiku-4.5"?Le:t}function Ue(e={}){return Jt(e.cursorBuddyModel||X.env.AGENSIS_CURSORBUDDY_MODEL||Le)}function Ft(e,t,n,r={}){let{cmd:s,args:o}=Br(e.codingCmd||"claude -p"),i=[...o],c=Jt(Ht(n,Ue(e))),l="",a=!1;return Rr(s)?(c&&!ve(i,"--model")&&i.push("--model",c),r.stream===!0&&!ve(i,"--output-format")?(i.push("--output-format","stream-json","--include-partial-messages"),ve(i,"--verbose")||i.push("--verbose"),a=!0):(ve(i,"--output-format")||i.push("--output-format","json"),a=i.some(g=>String(g).includes("stream-json"))),l=t):i.push(t),{cmd:s,args:i,model:c,stdin:l,streamJson:a}}function jr(e=()=>{}){let t="",n="",r=!1,s="",o=null,i=a=>{a&&e(a)},c=a=>{if(!a||typeof a!="object")return;let u=a.event&&a.event.delta||a.delta;if(u&&u.type==="text_delta"&&typeof u.text=="string"){r=!0,n+=u.text,i(u.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)}},l=a=>{let u=String(a).trim();if(u)try{c(JSON.parse(u))}catch{}};return{feed(a){t+=String(a||"");let u;for(;(u=t.indexOf(`
|
|
39
|
+
`))>=0;)l(t.slice(0,u)),t=t.slice(u+1)},end(){t&&(l(t),t="")},get live(){return r?n:s},get result(){return o??(r?n:s)}}}function se(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 Ee(e){return`http://127.0.0.1:${e}`}function Gr(e={},t={}){return String(t.agensisUrl||t.baseUrl||e.url||X.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function Hr(e){return String(e||"").slice(0,18)}function U(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Jr(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 qr(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function Kr(e,t={},n=globalThis.fetch){let r=String(t.key||"").trim();if(!xr.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=Gr(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:Gt.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(qr(o,i));return{key:r,baseUrl:s,data:i?.data||i}}async function qt(e,t={}){let n=Number(t.port??e.cursorBuddyPort??X.env.AGENSIS_CURSORBUDDY_PORT??Rt),r=$r(e,t),s=new Date().toISOString(),o=[],i=[],c=new Set,l=t.fetchImpl||globalThis.fetch,a=1,u=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()}),v=()=>{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=v();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(!Mr.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 E(d){for(i.push(d);i.length>Cr;)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=Ur(d);if(b){let M=p(b.command);return M&&(E(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=Lt(d?.messages,u),m=Ft(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:Ut(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,se(M,$,m.content)),K(b,se(M,$,"","stop")),K(b,"[DONE]"),f("chat_fast",{chars:m.content.length,model:$}),{content:m.content,model:$,fast:!0}}let y=Lt(d?.messages,u),I=Ft(e,y,d?.model,{stream:!0}),R="",C=$=>{$&&(R+=$,K(b,se(M,I.model||e.model,$)))},O=I.streamJson?jr(C):null,_=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(O)O.feed($);else{let F=String($||"");R+=F,K(b,se(M,I.model||e.model,F))}}});if(O){O.end();let $=O.result||"";!R&&$?C($):R=$||R}if(_.error||_.status!==0){let $=_.error?.message||String(_.stderr||"").trim()||`Command exited with status ${_.status}`;throw new Error($)}let N=O?R:Ut(R||_.stdout||_.stderr);return!O&&N&&N!==R&&(K(b,se(M,I.model||e.model,N)),R=N),K(b,se(M,I.model||e.model,"","stop")),K(b,"[DONE]"),{content:R||N,model:I.model}}let B=Ir.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||"/",Ee(g||Rt));if(!Dr(d.method,M.pathname)&&!Or(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=Ee(g);j(b,200,{ok:!0,runtime:"agensis-cli",backend:e.codingCmd,model:Ue(e),daemonModel:e.model,port:g,host:Gt.hostname(),pid:X.pid,bootedAt:s,authRequired:!0,authHeader:ke,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:u,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:u});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);Pt(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 de(d)||"{}"),y=p(m);if(!y){j(b,400,{ok:!1,error:"unsupported CursorBuddy control command"});return}let I=E(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 de(d)||"{}");u={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:u.url,surface:u.surface,instanceId:u.instanceId}),j(b,200,{ok:!0,context:u})}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 de(d)||"{}"),y=await Kr(e,m,l),I=y.data||{};w={connected:!0,mode:"agensis-claimed",keyId:Hr(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()},u=Jr(m,w,e),f("connect",{mode:w.mode,keyId:w.keyId,agentId:w.agentId,workspaceId:w.workspaceId,url:u.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 de(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 de(d)||"{}");if(f("chat_request",{messages:Array.isArray(m.messages)?m.messages.length:0,model:Ht(m.model,Ue(e))}),m.stream===!0){Pt(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:`${Ee(g)}/cursorbuddy/health`}),{port:g,url:Ee(g),secret:r,authHeader:ke,close(){return new Promise(d=>B.close(()=>d()))},getContext(){return u}}}import ie from"node:fs/promises";import zr from"node:os";import z from"node:path";var Kt=200,zt=256*1024,Wr=2,Yr=new Set([".md",".markdown",".txt"]);function Vr(e){return String(e||"").replace(/[^a-zA-Z0-9]/g,"-")}function Fe({cwd:e,memoryDir:t,homedir:n=zr.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",Vr(s),"memory"):null}async function je(e){if(!e)return null;try{let t=await ie.realpath(e);return(await ie.stat(t)).isDirectory()?t:null}catch{return null}}async function Xr(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 ie.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 Qr(e){let t=z.basename(e).toLowerCase();return t==="memory.md"?"index":t==="claude.md"?"instructions":"memory"}async function Ge(e,t,n,r){if(n>Wr||r.length>=Kt)return;let s;try{s=await ie.readdir(t,{withFileTypes:!0})}catch{return}for(let o of s){if(r.length>=Kt)break;if(o.name.startsWith("."))continue;let i=z.join(t,o.name);if(o.isDirectory())await Ge(e,i,n+1,r);else if(o.isFile()&&Yr.has(z.extname(o.name).toLowerCase())){let c=z.relative(e,i);r.push({path:c,kind:Qr(c)})}}}async function Zr(e){let t=await je(e);if(!t)return[];let n=[];return await Ge(t,t,0,n),n.sort((r,s)=>r.kind==="index"?-1:s.kind==="index"?1:r.path.localeCompare(s.path)),n}async function eo(e,t){let n=await je(e),r=await Xr(n,t),s=await ie.readFile(r),o=s.length>zt;return{content:s.subarray(0,zt).toString("utf8"),byteSize:s.length,truncated:o}}async function Wt(e){let t=await je(e);if(!t)return"";let n=[];await Ge(t,t,0,n),n.sort((s,o)=>s.path.localeCompare(o.path));let r=[];for(let s of n)try{let o=await ie.stat(z.join(t,s.path));r.push(`${s.path}:${o.size}:${Math.floor(o.mtimeMs)}`)}catch{}return r.join("|")}async function Yt(e){let t=await Zr(e),n=[];for(let r of t)try{let{content:s,byteSize:o}=await eo(e,r.path);n.push({path:r.path,kind:r.kind,content:s,byteSize:o})}catch{}return n}import Je from"node:fs";import Q from"node:path";import Vt from"node:os";function to(e){try{return Je.statSync(e).isDirectory()}catch{return!1}}function no(e){try{return Je.statSync(e).isFile()}catch{return!1}}function He(e){try{return Je.readdirSync(e,{withFileTypes:!0})}catch{return[]}}function Xt({home:e=Vt.homedir(),cwd:t=process.cwd()}={}){let n=[e&&Q.join(e,".claude","commands"),t&&Q.join(t,".claude","commands")].filter(Boolean),r=new Set,s=[],o=(i,c)=>{if(!i)return;let l=c?`${c}:${i}`:i;r.has(l)||(r.add(l),s.push({name:i,parent:c||null}))};for(let i of n)for(let c of He(i)){if(c.name.startsWith("."))continue;if(c.name.endsWith(".md")){o(c.name.slice(0,-3),null);continue}let l=Q.join(i,c.name);if(c.isDirectory()||c.isSymbolicLink()&&to(l))for(let a of He(l))a.name.startsWith(".")||a.name.endsWith(".md")&&o(a.name.slice(0,-3),c.name)}return s}function qe({home:e=Vt.homedir(),cwd:t=process.cwd()}={}){let n=[e&&Q.join(e,".claude","skills"),e&&Q.join(e,".codex","skills"),t&&Q.join(t,".claude","skills")].filter(Boolean),r=new Map,s=(o,i)=>{!o||r.has(o)||r.set(o,{name:o,file:i||""})};for(let o of n)for(let i of He(o)){if(i.name.startsWith("."))continue;let c=Q.join(o,i.name);if(i.name.endsWith(".md"))s(i.name.slice(0,-3),c);else if(i.isDirectory()||i.isSymbolicLink()){let l=Q.join(c,"SKILL.md");s(i.name,no(l)?l:"")}}return[...r.values()].sort((o,i)=>o.name<i.name?-1:o.name>i.name?1:0)}function Qt(e={}){return qe(e).map(t=>t.name)}import Ke from"node:fs/promises";var ae=64*1024,ro=200,en=4*1024*1024,oo=2e3,so=512;function Zt(e,t,n=ae){let r=`
|
|
40
|
+
|
|
41
|
+
... [truncated by agensis-agent: ${t}]
|
|
42
|
+
`,s=Math.max(0,n-Buffer.byteLength(r));return`${Buffer.from(String(e||"")).subarray(0,s).toString("utf8").replace(/\uFFFD+$/,"")}${r}`}function io(e){let t=String(e||"").split(/\r?\n/),n="";if(t[0]?.trim()==="---")for(let r=1;r<t.length&&r<200&&t[r].trim()!=="---";r+=1){let s=/^description:\s*(.*)$/i.exec(t[r]);if(!s)continue;let o=s[1].trim();if(o&&!/^[|>][-+]?$/.test(o)){n=o.replace(/^["']|["']$/g,"");break}let i=[];for(let c=r+1;c<t.length&&c<200&&!(t[c].trim()==="---"||t[c].trim()&&!/^\s/.test(t[c]));c+=1)i.push(t[c].trim());n=i.join(" ").trim();break}if(!n){let r=t.findIndex((i,c)=>c>0&&i.trim()==="---"),o=(t[0]?.trim()==="---"&&r>0?t.slice(r+1):t).find(i=>i.trim()&&i.trim()!=="---");n=String(o||"").replace(/^#+\s*/,"").trim()}return n.slice(0,oo)}function tn(e){try{return qe(e).slice(0,ro)}catch{return[]}}async function ao(e){let t;try{t=await Ke.open(e,"r")}catch{return null}try{let n=Buffer.alloc(ae+1),{bytesRead:r}=await t.read(n,0,n.length,0);return n.subarray(0,r)}catch{return null}finally{await t.close().catch(()=>{})}}async function co(e,t){let n=await ao(e.file);if(!n)return null;let r=n.toString("utf8"),s=io(r),o=n.length>ae,i=Math.min(ae,Math.max(0,t)),c=Buffer.byteLength(r)>i;if(!o&&!c)return{skill:e.name,path:e.file,summary:s,content:r,truncated:!1};let l=o?await lo(e.file):0,a=o&&!c?`the file is ${l?`${l} bytes`:`over ${ae} bytes`}; only the first ${ae} were synced`:`this sync reached its ${en}-byte ceiling`,u=i<so?Zt("",a,Number.MAX_SAFE_INTEGER):Zt(r,a,i);return{skill:e.name,path:e.file,summary:s,content:u,truncated:!0}}async function lo(e){try{return(await Ke.stat(e)).size}catch{return 0}}async function ze(e={}){let t=[];for(let n of tn(e)){if(!n.file){t.push(`${n.name}:-`);continue}try{let r=await Ke.stat(n.file);t.push(`${n.name}:${n.file}:${r.size}:${Math.floor(r.mtimeMs)}`)}catch{t.push(`${n.name}:-`)}}return t.join("|")}async function nn(e={}){let t=[],n=0;for(let r of tn(e))if(r.file)try{let s=await co(r,en-n);if(!s)continue;n+=Buffer.byteLength(s.content),t.push(s)}catch{}return t}import{readFile as uo}from"node:fs/promises";var mo=new Set(["127.0.0.1","localhost","::1","[::1]"]);function rn(e,t,n){let r=Number(e);return Number.isFinite(r)?Math.max(1,Math.min(n,Math.trunc(r))):t}function fo(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(!mo.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:rn(e.contextWindow,void 0,1e7)}:{},maxConcurrency:rn(e.maxConcurrency,1,64),shared:!0}}async function on(e){if(!e)return[];let t=JSON.parse(await uo(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(fo).filter(Boolean)}function sn(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 an({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 l={"content-type":"application/json"},a=c.apiKeyEnv?o[c.apiKeyEnv]:"";a&&(l.authorization=`Bearer ${a}`),n({action:"agent_inference_started",requestId:i,model:c.id});let{requestId:u,model:g,type:w,action:f,...h}=t,v=await s(`${c.baseUrl}/chat/completions`,{method:"POST",headers:l,body:JSON.stringify({...h,model:c.upstreamModel,stream:t.stream===!0}),signal:r});if(!v.ok){let p=await v.text().catch(()=>"");throw new Error(p||`Local model returned HTTP ${v.status}.`)}if(t.stream===!0){if(!v.body)throw new Error("Local model returned an empty stream.");let p=v.body.getReader(),E=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+=E.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 v.json();return n({action:"agent_inference_result",requestId:i,model:c.id,response:S}),S}xe();var Oo=30*60*1e3,$o=15*1e3,kn=2,Do=10*1024,Bo="claude-opus-4-8",ee="0.1.32";async function Me(e={}){let t=Ro(e);t.sharedModels=t.share?await on(t.sharedModelsFile):[];let n=!1,r=null,s=null,o=null,i=null,c=0,l=null,a=null,u="",g=null,w=!1,f=null,h=new Map,v=null,S={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"},p=new Map,E=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=()=>{v||!t.lanListener||(v=new pe.Server({port:0}),v.on("listening",()=>{let{port:C}=v.address();S={transport:"ws",listening:!0,addrs:as(C),auth:"hub-pairwise"},D(`Agent-mesh LAN listener on port ${C}`),fe(r,t,A())}),v.on("connection",C=>{let O=!1,_=setTimeout(()=>{if(!O)try{C.close(1008,"peer auth required")}catch{}},5e3);C.once("message",N=>{clearTimeout(_);let $=et(N),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),O=!0,C.on("message",J=>{let L=et(J);L?.type==="agent_job"&&L.job?.id&&a.enqueue({...L.job,key:L.job.id,lane:An(L.job),ws:r}).accepted&&D(`Queued peer-handoff job ${L.job.id} from ${$.fromAgentId}`)})})}),v.on("error",C=>D(`LAN listener error: ${C?.message||C}`)))},d=()=>{if(v){try{v.close()}catch{}v=null}S={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"}},b=C=>new Promise((O,_)=>{if(!P(r,{action:"peer_ticket_request",targetAgentId:C})){_(new Error("hub socket not open"));return}let N=E.get(C)||[];N.push({resolve:O,reject:_}),E.set(C,N),setTimeout(()=>{let $=E.get(C)||[],F=$.findIndex(J=>J.resolve===O);F>=0&&($.splice(F,1),_(new Error("peer ticket request timed out")))},1e4)}),M=()=>new Promise((C,O)=>{if(!P(r,{action:"peer_list_request"})){O(new Error("hub socket not open"));return}k.push(C),setTimeout(()=>{let _=k.indexOf(C);_>=0&&(k.splice(_,1),C([]))},1e4)}),m=async(C,O)=>{let _=null;try{let $=(await M()).find(L=>L.agentId===C&&L.reach?.listening&&L.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:(_=new pe(`ws://${J.host}:${J.port}`),await new Promise((L,De)=>{_.once("open",L),_.once("error",De),setTimeout(()=>De(new Error("peer connect timed out")),5e3)}),P(_,{type:"peer_auth",ticket:F.ticket,fromAgentId:t.agent}),P(_,{type:"agent_job",job:O}),!0)}catch(N){return D(`Peer handoff to ${C} failed, falling back to hub relay: ${N?.message||N}`),!1}finally{try{_?.close()}catch{}}},y=()=>{n=!0,Mn(h),s&&clearTimeout(s),o&&clearInterval(o),i&&clearInterval(i),g&&(g.close().catch(()=>{}),g=null),d(),gn(t,{status:"stopped",connected:!1});try{r?.close()}catch{}l&&l()};if(a=Bt({concurrency:t.once?1:t.maxConcurrency,runJob:async(C,O)=>{await Xo(t,C,O),t.once&&y()}}),t.cursorBuddyBridge)try{g=await qt(t,{port:t.cursorBuddyPort,authSecret:t.cursorBuddyBridgeSecret||void 0,log:D,connectionProvider:T}),g?.secret&&(t.cursorBuddyBridgeSecret=g.secret)}catch(C){if(ds(C)){let O=await ms(t.cursorBuddyPort);if(O?.ok){let _=O.pid?` pid ${O.pid}`:"";D(`CursorBuddy local bridge already running on http://127.0.0.1:${t.cursorBuddyPort}${_}`)}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=Lo(t.url,t.token,t);u="",D(`Connecting to ${C.replace(t.token,"redacted")}`),r=new pe(C),r.on("open",async()=>{w=!1,f=null,D(`Connected. Registering @${t.handle||"agent"} from ${t.cwd}`),P(r,{type:"auth",token:t.token});let O=await Sn(t);P(r,{action:"agent_register",workspaceId:t.workspace,agentId:t.agent,handle:t.handle,name:t.name,host:ye.hostname(),cwd:t.cwd,...O?{identity:O}:{},metadata:{codingCmd:t.codingCmd,model:t.model,permissionMode:t.permissionMode,permissionFlags:ot(t.permissionMode),once:t.once,runtime:"agensis",version:ee}}),o=setInterval(()=>{Promise.all([Bn(t,A()).catch(()=>null),Xe(t).catch(()=>null)]).then(([_,N])=>{P(r,{action:"agent_heartbeat",..._?{capabilitiesHash:_.capabilitiesHash,memoryHash:_.memoryHash}:{},..._?.skillsHash?{skillsHash:_.skillsHash}:{},metadata:Ze(t,a,N,Tn(t)?g?.getContext?.():null,h)})})},t.heartbeatMs),o.unref&&o.unref()}),r.on("message",O=>{let _=et(O);if(_){if(_.type==="agent_registered"){w=!0,f=_.connection||_.agent||null,In(t,_.agent),D(`Registered as ${_.connection?.name||t.name} on ${_.connection?.host||ye.hostname()}`),t.onRegistered&&Promise.resolve(t.onRegistered(t,_)).catch(N=>{D(`Profile save failed: ${N?.message||N}`)}),Ve(t,_.agent).catch(()=>{}),vn(t).catch(()=>{}),xn(r,t),Cn(r,t),B(),fe(r,t,A());return}if(_.type==="agent_config"){In(t,_.agent),D(`Updated config for @${t.handle||"agent"}: model=${t.model}, permission=${t.permissionMode}`),Ve(t,_.agent).catch(()=>{});return}if(_.type==="agent_memory_refresh"){xn(r,t),fe(r,t,A());return}if(_.type==="agent_capabilities_refresh"){fe(r,t,A());return}if(_.type==="agent_skills_refresh"){Cn(r,t);return}if(_.type==="agent_inference_cancel"){h.get(String(_.requestId||""))?.abort();return}if(_.type==="agent_job_cancel"){let N=String(_.jobId||"");N&&a.cancel(N,_.reason||"Cancelled by Agensis")&&D(`Cancelled job ${N}`);return}if(_.type==="agent_inference_request"&&_.requestId){let N=String(_.requestId),$=t.sharedModels.find(L=>L.id===_.model),F=[...h.values()].filter(L=>L.model===_.model).length;if(!$){P(r,{action:"agent_inference_error",requestId:N,error:`Shared model '${_.model||""}' is not available.`});return}if(F>=$.maxConcurrency){P(r,{action:"agent_inference_error",requestId:N,error:"Shared model is at capacity.",code:"capacity_exhausted"});return}let J=new AbortController;h.set(N,{abort:()=>J.abort(),model:$.id}),P(r,{action:"agent_heartbeat",metadata:Ze(t,a,null,null,h)}),an({models:t.sharedModels,request:_,signal:J.signal,send:L=>P(r,L)}).catch(L=>{P(r,{action:"agent_inference_error",requestId:N,error:J.signal.aborted?"Inference cancelled.":L?.message||String(L),code:J.signal.aborted?"cancelled":"inference_failed"})}).finally(()=>{h.delete(N),P(r,{action:"agent_heartbeat",metadata:Ze(t,a,null,null,h)})});return}if(_.type==="peer_ticket"){let N=_.peer?.agentId,$=E.get(N)||[],F=$.shift();$.length?E.set(N,$):E.delete(N),F&&F.resolve(_);return}if(_.type==="peer_ticket_grant"){p.set(_.ticket,{fromAgentId:_.fromAgentId,exp:_.exp});return}if(_.type==="peer_list"){let N=k.shift();N&&N(Array.isArray(_.peers)?_.peers:[]);return}if(_.type==="agent_reach_disable"){d(),fe(r,t,A());return}if(_.type==="error"){D(`Server rejected request: ${_.message||"unknown error"}`);return}if(_.type==="agent_disabled"){w=!1,f=null,D(`Agent disabled by Agensis: ${_.reason||"deactivated"}`),y();return}if(_.type==="agent_job"&&_.job?.id){let N=a.enqueue({..._.job,key:_.job.id,lane:An(_.job),ws:r});N.accepted&&(c+=1,D(`Queued job ${_.job.id} at position ${N.position}`),t.once&&a.idle().then(()=>y()))}}}),r.on("close",(O,_)=>{Mn(h),w=!1,f=null;let N=String(_||"");if(D(`Socket closed (${O||"no-code"}${N?`: ${N}`:""})`),o&&(clearInterval(o),o=null),O===1008&&/agent deactivated|authentication failed/i.test(N)){D("Stopping daemon because Agensis rejected this agent connection."),y();return}if(u==="ECONNREFUSED"&&Fo(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",O=>{u=O?.code||"",D(`Socket error: ${O?.message||O}`)})},R=async()=>{let C=await Xe(t).catch(()=>null);await hn(t,{busy:a.active()>0,active:a.active(),queueSize:a.size(),connected:r?.readyState===pe.OPEN,agentStatus:C?.status,agentNote:C?.note}).catch(()=>{})};R(),i=setInterval(()=>{R()},t.heartbeatMs),i.unref&&i.unref(),I(),await new Promise(C=>{let O=setInterval(async()=>{t.once&&c>0&&a.active()===0&&a.size()===0&&y(),n&&y()},500);l=()=>{clearInterval(O),C()}}),l=null,x.off("SIGINT",y),x.off("SIGTERM",y)}function Ro(e){let t=Po(e.cursorBuddyBridge),n=e.noCoding===!0||x.env.AGENSIS_NO_CODING==="1",s=!Z(e.fullCliContext,Z(x.env.AGENSIS_FULL_CLI_CONTEXT,!1))&&Z(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:Ln(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:rt(e.model||x.env.AGENSIS_MODEL||x.env.CLAUDE_MODEL||""),permissionMode:Te(e.permissionMode||e.permission_mode||e.permission||x.env.AGENSIS_PERMISSION_MODE||"default"),timeoutMs:Number(e.timeoutMs||x.env.AGENSIS_TIMEOUT_MS||Oo),heartbeatMs:Number(e.heartbeatMs||x.env.AGENSIS_HEARTBEAT_MS||$o),maxConcurrency:Math.max(1,Number(e.maxConcurrency||x.env.AGENSIS_MAX_CONCURRENCY||kn)||kn),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:Z(e.fastConnection,Z(x.env.AGENSIS_FAST_CONNECTION,!0)),syncMemory:Z(e.syncMemory,x.env.AGENSIS_SYNC_MEMORY==="1"),syncSkills:Z(e.syncSkills,Z(x.env.AGENSIS_SYNC_SKILLS,!0)),hostFolders:$n(e.hostFolders??e.host_folders??x.env.AGENSIS_HOST_FOLDERS)};o.sharedModelsFile&&!ge.isAbsolute(o.sharedModelsFile)&&(o.sharedModelsFile=ge.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 Z(e,t){return e==null||e===""?t:typeof e=="boolean"?e:!/^(0|false|off|no)$/i.test(String(e).trim())}function Po(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 Lo(e,t,n={}){let r=nt(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 nt(e){let t=new URL(e);return Uo(t)&&(t.protocol="http:",t.hostname="127.0.0.1",t.port="3142"),t}function Uo(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 Fo(e){try{let t=nt(e);return(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="0.0.0.0")&&t.port==="3142"}catch{return!1}}function An(e){let t=String(e?.sessionId||""),n=String(e?.threadParentId||"");return`${t}::${n}`}var jo=/\b(cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\b/i,Go=[/\b(?:make|have|tell)\s+(?:the\s+)?(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\s+(?:say|speak)\s+(.+)$/i];function Ho(e){return String(e||"").trim().replace(/^[`"'“”‘’]+|[`"'“”‘’?.!]+$/g,"").trim().slice(0,1200)}function Jo(e){for(let t of Go){let n=String(e||"").match(t),r=Ho(n?.[1]||"");if(r)return r}return""}function qo(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 Ko(e){let t=String(e||"").replace(/\s+/g," ").trim(),r=qo(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 zo(e){let t=Ko(e);if(!t)return null;let n=/^(open|show|hide|hush|close|dismiss)\b/i.test(t),r=jo.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=Jo(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 Wo(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 Yo(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 Tn(e={}){return e.cursorBuddyBridge===!1?!1:!!(e.cursorBuddyRuntime||e.primaryDaemon)}async function Vo(e,t,n,r){let s="cursorbuddy-control",o="native",i=[],c=(u="")=>{P(t.ws,{action:"agent_job_delta",jobId:t.id,content:u,elapsedMs:Date.now()-r,model:s,permissionMode:o,permissionFlags:i})};c("");let l="",a="";try{await Wo(e,n),l=Yo(n),c(l)}catch(u){a=String(u?.message||u),l=`CursorBuddy control failed: ${a}`,c(l)}P(t.ws,{action:"agent_job_result",jobId:t.id,response:l,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 Xo(e,t,{signal:n}){let r=Date.now();D(`Starting job ${t.id}`);let s=zo(t.prompt);if(s&&Tn(e)){await Vo(e,t,s,r),e.once&&(D("One-shot CursorBuddy control job complete; exiting."),setTimeout(()=>x.exit(0),150));return}let o=es(e,t),i=await Qo(e,t),c="",l="",a=0,u=(d="")=>{P(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=>{P(t.ws,{action:"agent_job_step",jobId:t.id,kind:d.kind,name:d.name,detail:d.detail,elapsedMs:Date.now()-r})},w=d=>{P(t.ws,{action:"agent_job_segment",jobId:t.id,text:d.text,elapsedMs:Date.now()-r})};u("");let f=o.streamJson?ts({onStep:g,onSegment:w}):null,h=setInterval(()=>u(c),1e3);h.unref&&h.unref();let v=!/[\\/]/.test(o.cmd),S=e.fastConnection&&v?Rn(o.cmd)?"claude":Pn(o.cmd)?"codex":null:null,E=await Dt(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:Dn(e,t),leanCli:e.leanCli,mcp:e.leanCli?tt(e):null,sessionKey:`${t.workspaceId||e.workspace||""}:${e.agent||e.handle||""}`,clientVersion:ee,onData:d=>{f?(f.feed(d),c=f.live):(c+=String(d||""),l=us(`${l}
|
|
43
|
+
${d}`));let b=Date.now();b-a>150&&(a=b,u(c))}});clearInterval(h),f&&(f.end(),c=f.live,u(c));let k=String(E.stdout||"").trim(),A=String(E.stderr||"").trim(),T=E.error?E.error.message:E.status===0?"":A||`Command exited with status ${E.status}`,B=f?f.result||(T?"":A):k||(T?"":A)||l||"";P(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 Qo(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=Nn(e,t),i=On(e,t),c=await En(e).catch(()=>null),l=c?`Heartbeat (recurring instructions \u2014 edit at ${pn(e)}):
|
|
44
|
+
${c}`:"",u=["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:
|
|
42
45
|
${n.description}`:"",n.soul?`Soul:
|
|
43
46
|
${n.soul}`:"",n.system_prompt?`System instructions:
|
|
44
47
|
${n.system_prompt}`:"",n.instructions?`Additional instructions:
|
|
45
48
|
${n.instructions}`:"",s?`Enabled tools:
|
|
46
49
|
${s}`:"",r?`Enabled skills:
|
|
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 ${
|
|
50
|
+
${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 ${fn(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 ${Qe(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.`,l,"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(`
|
|
48
51
|
|
|
49
|
-
`);return e.leanCli?
|
|
52
|
+
`);return e.leanCli?Zo(u,Do):u}function Zo(e,t){let n=String(e||"");if(Buffer.byteLength(n,"utf8")<=t)return n;let r=`[... older or optional Agensis context omitted ...]
|
|
50
53
|
|
|
51
|
-
`,s=Math.max(0,t-Buffer.byteLength(r,"utf8")),o=[...n],i=0,c=o.length;for(;i<c;){let
|
|
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
|
|
53
|
-
`)}function
|
|
54
|
-
`,{mode:384}),await
|
|
55
|
-
`)}import
|
|
56
|
-
`,{mode:384}),await
|
|
54
|
+
`,s=Math.max(0,t-Buffer.byteLength(r,"utf8")),o=[...n],i=0,c=o.length;for(;i<c;){let l=Math.ceil((i+c)/2),a=o.slice(o.length-l).join("");Buffer.byteLength(a,"utf8")<=s?i=l:c=l-1}return r+o.slice(o.length-i).join("")}function es(e,t){let{cmd:n,args:r}=ls(e.codingCmd),s=Nn(e,t),o=On(e,t),i=cs(r),c=ot(o),l=Dn(e,t);if(Rn(n)){let a=[...i];s&&a.push("--model",s);let u;if(e.leanCli){let h=tt(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"),u=h.env}if(o==="accept_edits"&&a.push("--permission-mode","acceptEdits"),o==="yolo"){let h=t&&t.agent&&t.agent.run_mode==="sandbox",v=typeof x.getuid=="function"&&x.getuid()===0,S=h||rs(),p=x.env.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1";S||!v||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 l)a.push("--add-dir",h);return{cmd:n,args:a,model:s,permissionMode:o,permissionFlags:c,streamJson:f,env:u}}if(Pn(n)){let a=[...i];s&&a.push("--model",s);let u;if(e.leanCli&&i.includes("exec")){let g=tt(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"'),u=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:u}}return{cmd:n,args:r,model:s,permissionMode:o,permissionFlags:c}}function tt(e){let t=nt(e.url);return t.pathname="/backend/mcp",t.search="",t.hash="",{url:t.toString(),env:{AGENSIS_MCP_TOKEN:e.token}}}function ts({onStep:e,onSegment:t}={}){let n="",r="",s=!1,o="",i="",c=null,l=!1,a=!1,u=new Set,g=v=>{if(!(typeof e!="function"||!v.name))try{e(v)}catch{}},w=v=>{if(typeof t=="function"){i+=s?r:o,r="",o="";try{t(v)}catch{}}},f=v=>{if(!v||typeof v!="object")return;if(v.type==="agensis_step"){let p=v.step;p&&typeof p=="object"&&(l=!0,g({kind:p.kind||"tool",name:String(p.name||""),detail:String(p.detail||"")}));return}if(v.type==="agensis_segment"){let p=v.segment;p&&typeof p=="object"&&(a=!0,w({text:String(p.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 p=v.message.content.filter(E=>E&&E.type==="text"&&typeof E.text=="string").map(E=>E.text).join("");if(p&&(o+=p),p&&!a&&w({text:p}),!l)for(let E of v.message.content){if(!E||E.type!=="tool_use")continue;let k=typeof E.id=="string"?E.id:"";if(k){if(u.has(k))continue;u.add(k)}g({kind:"tool",name:String(E.name||""),detail:Re(E.input)})}}},h=v=>{let S=String(v).trim();if(S)try{f(JSON.parse(S))}catch{}};return{feed(v){n+=String(v||"");let S;for(;(S=n.indexOf(`
|
|
55
|
+
`))>=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 Nn(e,t){return rt(t?.agent?.model||t?.model||e.model)}function rt(e){let t=String(e||"").trim();return!t||t==="auto"||t==="claude-fable-5"?Bo:t}function On(e,t){return Te(t?.agent?.permissionMode||t?.agent?.permission_mode||t?.permissionMode||t?.permission_mode||e.permissionMode)}function Te(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 ot(e){return Te(e)==="yolo"?["--no-sandbox","--yolo"]:[]}function $n(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 ns(e,t){let n=t?.agent?.metadata?.host_folders??t?.agent?.hostFolders??t?.hostFolders??t?.host_folders,r=$n(n);return r.length>0?r:e.hostFolders||[]}function Dn(e,t){let n=ns(e,t),r=q({workspace:e.workspace,agent:e.agent});return r&&!n.includes(r)?[...n,r]:n}var re;function rs(){if(re!==void 0)return re;let e=x.env;if(e.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1"||e.AGENSIS_SANDBOX_HOST==="1"||e.IS_SANDBOX==="1")return re=!0;if(e.AGENSIS_NO_SANDBOX_AUTODETECT==="1")return re=!1;try{if(he.existsSync("/.dockerenv")||he.existsSync("/run/.containerenv"))return re=!0}catch{}try{let t=he.readFileSync("/proc/1/cgroup","utf8");if(/docker|kubepods|containerd|lxc|podman/i.test(t))return re=!0}catch{}return re=!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:ot(e.permissionMode),daemon:{runtime:"agensis-cli",version:ee,pid:x.pid,node:x.version,platform:x.platform,arch:x.arch,host:ye.hostname(),cwd:e.cwd}};if(s instanceof Map){let i={};for(let c of s.values()){let l=String(c?.model||"");l&&(i[l]=(i[l]||0)+1)}o.activeInferenceByModel=i}return r&&typeof r=="object"&&(o.cursorBuddy=os(r)),n?.status&&(o.agentStatus=n.status),n?.note&&(o.agentNote=n.note),(n?.status||n?.note)&&(o.agentStatusAt=new Date().toISOString()),o}function os(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 In(e,t){if(!t||typeof t!="object")return;t.name&&(e.name=String(t.name).trim()||e.name),(t.handle||t.name)&&(e.handle=Ln(t.handle||t.name||e.handle)),t.model&&(e.model=rt(t.model));let n=t.permissionMode||t.permission_mode;n&&(e.permissionMode=Te(n)),(t.memory_dir!==void 0||t.memoryDir!==void 0)&&(e.memoryDir=String(t.memory_dir??t.memoryDir??"").trim())}function ss(){let e=["claude","codex","gh","node","npm","python3","git","fly","vercel"],t=(x.env.PATH||"").split(ge.delimiter).filter(Boolean);return e.filter(n=>t.some(r=>{try{return he.existsSync(ge.join(r,n))}catch{return!1}}))}function is(){try{let e=he.readFileSync(ge.join(ye.homedir(),".claude.json"),"utf8"),n=JSON.parse(e)?.mcpServers;if(n&&typeof n=="object")return Object.keys(n).sort()}catch{}return[]}function Ce(e){return No.createHash("sha1").update(String(e)).digest("hex").slice(0,16)}async function Bn(e,t=null){let n=Qt({cwd:e.cwd}),r=Xt({cwd:e.cwd}),s=ss(),o=is(),i=e.syncMemory&&Fe({cwd:e.cwd,memoryDir:e.memoryDir})||null,c=sn(e.sharedModels),l=Ce(JSON.stringify({skills:n,commands:r,clis:s,mcpServers:o,memoryRoot:i,sharedModels:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null})),a=Ce(await Wt(i)),u=e.syncSkills?Ce(await ze({cwd:e.cwd})):null;return{skills:n,commands:r,clis:s,mcpServers:o,memoryRoot:i,sharedModels:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null,capabilitiesHash:l,memoryHash:a,skillsHash:u}}async function fe(e,t,n=null){try{let r=await Bn(t,n);P(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,skillsHash:r.skillsHash}),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 as(e){let t=ye.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 xn(e,t){try{if(!t.syncMemory)return;let n=Fe({cwd:t.cwd,memoryDir:t.memoryDir});if(!n)return;let r=await Yt(n);P(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}`)}}async function Cn(e,t){try{if(!t.syncSkills)return;let n=Ce(await ze({cwd:t.cwd})),r=await nn({cwd:t.cwd});P(e,{action:"agent_skill_sync",workspaceId:t.workspace,agentId:t.agent,hash:n,skills:r});let s=r.filter(o=>o.truncated).length;D(`Synced ${r.length} skill document${r.length===1?"":"s"}${s?` (${s} truncated)`:""}`)}catch(n){D(`Skill sync skipped: ${n?.message||n}`)}}function cs(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 Rn(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function Pn(e){return/(^|\/)codex(?:$|\.)/.test(String(e||""))}function ls(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 et(e){try{return JSON.parse(String(e))}catch{return null}}function P(e,t){return!e||e.readyState!==pe.OPEN?!1:(e.send(JSON.stringify(t)),!0)}function us(e){return String(e||"").split(/\r?\n/).map(t=>t.trim()).filter(Boolean).slice(-1)[0]||""}function Ln(e){return String(e||"").trim().toLowerCase().replace(/^@+/,"").replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}function ds(e){return e?.code==="EADDRINUSE"||/\bEADDRINUSE\b/.test(String(e?.message||e))}async function ms(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}
|
|
56
|
+
`)}function Mn(e){if(e instanceof Map)for(let t of e.values())try{t?.abort?.()}catch{}}import fs from"node:crypto";import Se from"node:fs/promises";import ps from"node:os";import Un from"node:path";var oe="default",Fn=2,hs=/^[a-zA-Z0-9_.-]{1,64}$/,gs=["url","token","workspace","agent","handle","name","cwd","codingCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","fullCliContext","syncMemory","syncSkills","lanListener","primaryDaemon","cursorBuddyBridge","cursorBuddyPort","hostFolders"];function W(e=oe){let t=String(e||oe).trim();if(!hs.test(t))throw new Error("Daemon profile names may only contain letters, numbers, dot, dash, and underscore.");return t}function jn(e=oe,t={}){let n=t.homedir||ps.homedir();return Un.join(n,".agensis","daemon-profiles",`${W(e)}.json`)}function st(e={}){let t={};for(let n of gs){let r=e[n];r!=null&&r!==""&&(t[n]=r)}return t}function te(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 Gn(e={}){return!!(te(e,["url","baseUrl"],["AGENSIS_URL"])||te(e,["token"],["AGENSIS_TOKEN"])||te(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])||te(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}function it(e={}){return!!(te(e,["url","baseUrl"],["AGENSIS_URL"])&&te(e,["token"],["AGENSIS_TOKEN"])&&te(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])&&te(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}async function at(e=oe,t={}){let n=jn(e,t),r;try{r=await Se.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=st(o);return Number(s.version||1)<Fn&&Number(i.maxConcurrency)===8&&(i.maxConcurrency=2),i}async function Ne(e=oe,t={},n={}){let r=st(t);if(!r.url||!r.token||!r.workspace||!r.agent)return null;let s=jn(e,n),o=Un.dirname(s);await Se.mkdir(o,{recursive:!0,mode:448});let i=`${s}.${process.pid}.${Date.now()}.tmp`,c={version:Fn,savedAt:new Date().toISOString(),profile:W(e),tokenHash:fs.createHash("sha256").update(r.token).digest("hex"),config:r};return await Se.writeFile(i,`${JSON.stringify(c,null,2)}
|
|
57
|
+
`,{mode:384}),await Se.rename(i,s),await Se.chmod(s,384).catch(()=>{}),s}function Hn(e,t={}){let n={...e,...st(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 ct(e=oe){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===oe?"":` --profile ${t}`}`].join(`
|
|
58
|
+
`)}import ys from"node:crypto";import we from"node:fs/promises";import Jn from"node:os";import lt from"node:path";import ut from"node:process";var Ss=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/;function ws(e={}){return String(e.url||e.baseUrl||ut.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function qn(e,t={}){let n=t.homedir||Jn.homedir(),r=ys.createHash("sha256").update(String(e)).digest("hex");return lt.join(n,".agensis","cursorbuddy","connection-keys",`${r}.json`)}function bs(){return new Error("Missing or invalid --key. Create a CursorBuddy connection key in Agensis first.")}function dt(e){let t=String(e||"").trim();if(!Ss.test(t))throw bs();return t}function _s(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:l,...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 vs(e,t={}){dt(e);let n=qn(e,t),r;try{r=await we.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 Es(e,t,n={}){if(dt(e),!t?.token||!t?.workspace||!t?.agent||!t?.url)return;let r=qn(e,n),s=lt.dirname(r);await we.mkdir(s,{recursive:!0,mode:448});let o=`${r}.${ut.pid}.${Date.now()}.tmp`,i={version:1,savedAt:new Date().toISOString(),keyHash:lt.basename(r,".json"),daemonArgs:t};await we.writeFile(o,`${JSON.stringify(i,null,2)}
|
|
59
|
+
`,{mode:384}),await we.rename(o,r),await we.chmod(r,384).catch(()=>{})}function ks(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 As(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function Is(e){return e.json().catch(()=>({}))}async function Kn(e,t={}){let n=dt(e?.key),r=ws(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||ut.cwd(),i=t.hostname||Jn.hostname(),c=t.version||ee,l={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})}),u=await Is(a);if(!a.ok){let w=As(a,u);if(a.status===409||/already been claimed/i.test(w)){let f=await vs(n,l);if(f)return ks(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=_s(e,u?.data||u,r,o);return await Es(n,g,l),g}import xs from"node:crypto";import Cs from"node:http";import Ms from"node:os";import Y from"node:process";import{spawn as Ts}from"node:child_process";var Ns="https://agensis.io",Os=10*60*1e3;function Oe(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 $s(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 Ds(e){let t=String(e||Y.env.AGENSIS_URL||Ns).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 Bs(e){let t=Y.platform==="darwin"?"open":Y.platform==="win32"?"cmd":"xdg-open",n=Y.platform==="win32"?["/c","start","",e]:[e],r=Ts(t,n,{detached:!0,stdio:"ignore"});r.on("error",()=>{}),r.unref()}function Rs(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 Ps(e,t,n){let r=new URL(Ds(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 zn(e={}){let t=W(e.profile||"default"),n=xs.randomBytes(24).toString("base64url"),r=Number(e.setupTimeoutMs||Y.env.AGENSIS_SETUP_TIMEOUT_MS||Os),s,o=new Promise((a,u)=>{let g=setTimeout(()=>u(new Error("Agensis setup timed out waiting for browser login.")),r);g.unref&&g.unref(),s=Cs.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"){Oe(f,404,{ok:!1,error:"Unknown Agensis setup callback route"});return}try{let h=JSON.parse(await $s(w)||"{}");if(h?.state!==n){Oe(f,403,{ok:!1,error:"Setup state did not match"});return}let v={...Rs(h),primaryDaemon:!0,cursorBuddyBridge:e.cursorBuddyBridge!==!1};await Ne(t,v),clearTimeout(g),Oe(f,200,{ok:!0,profile:t}),a(v)}catch(h){Oe(f,400,{ok:!1,error:String(h?.message||h)})}}),s.once("error",u)});await new Promise((a,u)=>{s.listen(0,"127.0.0.1",g=>g?u(g):a())});let{port:i}=s.address(),c=`http://127.0.0.1:${i}/agensis/setup-callback`,l=Ps(e,c,n);Y.stdout.write(`[agensis] Opening Agensis to sign in and connect this machine.
|
|
57
60
|
`),Y.stdout.write(`[agensis] If the browser did not open, visit:
|
|
58
|
-
${
|
|
59
|
-
`),
|
|
60
|
-
`),a}finally{await new Promise(a=>s.close(()=>a())).catch(()=>{})}}function
|
|
61
|
+
${l}
|
|
62
|
+
`),Bs(l);try{let a=await o;return Y.stdout.write(`[agensis] Saved daemon profile "${t}". Starting primary agent daemon.
|
|
63
|
+
`),a}finally{await new Promise(a=>s.close(()=>a())).catch(()=>{})}}function Xs(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),l=i.replace(/-([a-z])/g,(u,g)=>g.toUpperCase());if(l==="help"){t.help=!0;continue}if(l==="version"){t.version=!0;continue}if(l==="once"){t.once=!0;continue}if(l==="lan"){t.lanListener=!0;continue}if(l==="share"){t.share=!0;continue}if(l==="noCoding"){t.noCoding=!0;continue}if(l==="fullCliContext"){t.fullCliContext=!0;continue}if(l==="syncMemory"){t.syncMemory=!0;continue}if(l==="noSyncSkills"){t.syncSkills=!1;continue}if(l==="cursorbuddyBridge"){t.cursorBuddyBridge=!0;continue}if(l==="noCursorbuddyBridge"){t.cursorBuddyBridge=!1;continue}if(l==="yolo"||l==="noSandbox"){t.permissionMode="yolo";continue}if(l==="acceptEdits"){t.permissionMode="accept_edits";continue}if(l==="hostFolder"||l==="hostFolders"||l==="addDir"){let u=c!==void 0?c:n[++s];if(u==null||u.startsWith("--"))throw new Error(`Missing value for --${i}`);t.hostFolders=[...t.hostFolders||[],u];continue}let a=c!==void 0?c:n[++s];if(a==null||a.startsWith("--"))throw new Error(`Missing value for --${i}`);t[l]=a}return t}function Qs(){return`agensis agent daemon
|
|
61
64
|
|
|
62
65
|
Usage:
|
|
63
66
|
agensis --url <workspace-url> --token <token> --workspace <id> --agent <id> [options]
|
|
@@ -85,6 +88,8 @@ Options:
|
|
|
85
88
|
(default isolates Claude/Codex to project + Agensis context)
|
|
86
89
|
--sync-memory Opt in to mirroring this project's Claude memory files
|
|
87
90
|
to the connected Agensis workspace (default: off)
|
|
91
|
+
--no-sync-skills Stop mirroring the text of this machine's skills to the
|
|
92
|
+
workspace; only their names are advertised (default: on)
|
|
88
93
|
--model <id> Default model to pass to supported coding CLIs
|
|
89
94
|
--permission-mode <m> default, accept_edits, or yolo
|
|
90
95
|
--yolo Alias for --permission-mode yolo
|
|
@@ -113,7 +118,7 @@ agensis supervise [--profile <name>] [--poll-ms <ms>]
|
|
|
113
118
|
"agensis connect" once first). Recommended under a process manager with its
|
|
114
119
|
own restart policy (systemd Restart=always, launchd KeepAlive, pm2) so the
|
|
115
120
|
supervisor itself is recovered if it's ever killed.
|
|
116
|
-
`}async function
|
|
117
|
-
`)}}:e}async function
|
|
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
|
|
121
|
+
`}async function Zs(e){let t=e.profile!==void 0,n=e.handle||e.name,r=W(e.profile||(it(e)&&n?n:"default"));if(!Gn(e)){let s=await at(r);if(!s)throw new Error(ct(r));return Hn(s,e)}return it(e)?{...e,cursorBuddyBridge:e.cursorBuddyBridge===!0,onRegistered:async s=>{await Ne(r,s);let o=t||r!=="default"?`agensis connect --profile ${r}`:"agensis connect";V.stdout.write(`[agensis] Saved daemon profile "${r}". Restart with: ${o}
|
|
122
|
+
`)}}:e}async function ei(){let e=Xs(V.argv.slice(2));if(e.help){V.stdout.write(Qs());return}if(e.version){V.stdout.write(`${ee}
|
|
123
|
+
`);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 Kn(e);n.cursorBuddyBridge=e.cursorBuddyBridge!==!1,n.cursorBuddyRuntime=!0,n.exitOnOnce=!0,await Me(n),n.once&&V.exit(0);return}if(e.command==="supervise"){let n=W(e.profile||"default"),r=await at(n);if(!r)throw new Error(ct(n));let{runSupervisor:s}=await Promise.resolve().then(()=>(er(),Zn)),o=e.pollMs?Number(e.pollMs):void 0;await s({config:r,runningVersion:ee,profileName:n,pollIntervalMs:o});return}if(e.command==="setup"){let n=await zn(e);n.exitOnOnce=!0,await Me({...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 Zs(e);t.exitOnOnce=!0,await Me(t),t.once&&V.exit(0)}ei().catch(e=>{V.stderr.write(`${e?.message||e}
|
|
119
124
|
`),V.exitCode=1});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agensis/agensis-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.32",
|
|
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": {
|