@agensis/agensis-agent 0.1.39 → 0.1.40
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 +21 -21
- package/package.json +1 -1
package/bin/agensis.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var Pr=Object.defineProperty;var $e=(e,t)=>()=>(e&&(t=e(e=0)),t);var Gt=(e,t)=>{for(var n in t)Pr(e,n,{get:t[n],enumerable:!0})};var on={};Gt(on,{createE2bProvider:()=>lo});function Xe(e){return`'${String(e).replace(/'/g,"'\\''")}'`}function lo({apiKey:e,anthropicApiKey:t,gitToken:n="",repoUrl:r="",template:o=""}={}){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 s={apiKey:e,envs:t?{ANTHROPIC_API_KEY:t}:{}},i;try{({Sandbox:i}=await import("e2b"))}catch(d){if(d&&(d.code==="ERR_MODULE_NOT_FOUND"||d.code==="MODULE_NOT_FOUND"||/Cannot find package 'e2b'/.test(String(d&&d.message)))){let c=Number(String(process.versions.node).split(".")[0])||0,u=c<20||c===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 d}let a=o?await i.create(o,s):await i.create(s);return await a.commands.run("bash -lc 'command -v claude >/dev/null || npm i -g @anthropic-ai/claude-code'"),{sbx:a,dir:uo}},async putRepo(s){let i=n?r.replace(/^https:\/\//,`https://x-access-token:${n}@`):r;try{let a=await s.sbx.commands.run(`git clone ${Xe(i)} ${Xe(s.dir)}`);if(a&&typeof a.exitCode=="number"&&a.exitCode!==0)throw new Error(`git clone failed: ${a.stderr||`exit ${a.exitCode}`}`)}catch(a){if(a&&String(a.message||"").startsWith("git clone failed:"))throw a;let d=a&&(a.stderr||a.exitCode!=null)?a.stderr||`exit ${a.exitCode}`:String(a?.message||a);throw new Error(`git clone failed: ${d}`)}},async exec(s,{cmd:i,args:a=[],env:d={},onData:c}){let u=`${i} ${a.map(Xe).join(" ")}`,
|
|
2
|
+
var Pr=Object.defineProperty;var $e=(e,t)=>()=>(e&&(t=e(e=0)),t);var Gt=(e,t)=>{for(var n in t)Pr(e,n,{get:t[n],enumerable:!0})};var on={};Gt(on,{createE2bProvider:()=>lo});function Xe(e){return`'${String(e).replace(/'/g,"'\\''")}'`}function lo({apiKey:e,anthropicApiKey:t,gitToken:n="",repoUrl:r="",template:o=""}={}){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 s={apiKey:e,envs:t?{ANTHROPIC_API_KEY:t}:{}},i;try{({Sandbox:i}=await import("e2b"))}catch(d){if(d&&(d.code==="ERR_MODULE_NOT_FOUND"||d.code==="MODULE_NOT_FOUND"||/Cannot find package 'e2b'/.test(String(d&&d.message)))){let c=Number(String(process.versions.node).split(".")[0])||0,u=c<20||c===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 d}let a=o?await i.create(o,s):await i.create(s);return await a.commands.run("bash -lc 'command -v claude >/dev/null || npm i -g @anthropic-ai/claude-code'"),{sbx:a,dir:uo}},async putRepo(s){let i=n?r.replace(/^https:\/\//,`https://x-access-token:${n}@`):r;try{let a=await s.sbx.commands.run(`git clone ${Xe(i)} ${Xe(s.dir)}`);if(a&&typeof a.exitCode=="number"&&a.exitCode!==0)throw new Error(`git clone failed: ${a.stderr||`exit ${a.exitCode}`}`)}catch(a){if(a&&String(a.message||"").startsWith("git clone failed:"))throw a;let d=a&&(a.stderr||a.exitCode!=null)?a.stderr||`exit ${a.exitCode}`:String(a?.message||a);throw new Error(`git clone failed: ${d}`)}},async exec(s,{cmd:i,args:a=[],env:d={},onData:c}){let u=`${i} ${a.map(Xe).join(" ")}`,p={cwd:s.dir,envs:{...d,IS_SANDBOX:"1",AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS:"1"},onStdout:l=>{try{c?.(l)}catch{}}};try{let l=await s.sbx.commands.run(u,p);return{status:l.exitCode,stdout:l.stdout||"",stderr:l.stderr||"",error:null}}catch(l){return l&&typeof l.exitCode=="number"?{status:l.exitCode,stdout:l.stdout||"",stderr:l.stderr||"",error:null}:{status:null,stdout:"",stderr:String(l?.message||l),error:l}}},async getResult(s){try{return{patch:(await s.sbx.commands.run("git add -A && git diff --cached",{cwd:s.dir})).stdout||""}}catch(i){return{patch:i&&i.stdout||""}}},async destroy(s){await s.sbx.kill()}}}var uo,sn=$e(()=>{uo="/home/user/repo"});import Hn from"node:fs";import G from"node:fs/promises";import bs from"node:os";import q from"node:path";function qn(e,t){return String(e||"").trim().replace(/[^a-zA-Z0-9._-]+/g,"-").replace(/\.{2,}/g,".").replace(/^[.-]+/,"").slice(0,96)||t}function K({workspace:e,agent:t,homedir:n=bs.homedir()}={}){return q.join(n,".agensis",qn(e,"workspace"),qn(t,"agent"))}function Wn(e){return q.join(K(e),Jn)}function Yn(e){return q.join(K(e),pt)}async function Le(e){let t=K(e);try{return await G.mkdir(t,{recursive:!0}),t}catch{return null}}async function ke(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 ft(e,t){if(!t||typeof t!="object")return!1;let n=await Le(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()},o=await ke(q.join(n,vs),`${JSON.stringify(r,null,2)}
|
|
3
3
|
`),s=String(t.soul??""),i=await ke(q.join(n,ks),s);return o&&i}async function Vn(e,t={}){let n=await Le(e);return n?ke(q.join(n,zn),Qn(e,t)):!1}function Xn(e,t={}){let n=K(e);try{return Hn.mkdirSync(n,{recursive:!0}),Hn.writeFileSync(q.join(n,zn),Qn(e,t)),!0}catch{return!1}}function Qn(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
4
|
`}async function ht(e){let t=q.join(K(e),Jn),n;try{let a=await G.stat(t);if(!a.isFile()||a.size>Ms)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 o=mt(r.status),s=mt(r.note??r.message);if(!o&&!s)return null;let i={};return o&&(i.status=o),s&&(i.note=s),r.ts!=null&&Number.isFinite(Number(r.ts))&&(i.ts=Number(r.ts)),i}function mt(e){return e==null?"":String(e).trim().replace(/\s+/g," ").slice(0,$s)}function gt(e){return q.join(K(e),_s)}async function Zn(e){let t=gt(e),n;try{let i=await G.stat(t);if(!i.isFile()||i.size>Ns)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 o={};for(let i of Os){let a=i==="description"&&r.description==null?r.profile:r[i];typeof a!="string"||!a.trim()||(o[i]=a.trim())}let s=Ds(r.voice,r.attitude);return s&&(o.voice=s),Object.keys(o).length>0?o:null}function Ds(e,t){let n=e&&typeof e=="object"&&!Array.isArray(e)?e:{},r={};for(let o of Rs){let s=n[o];typeof s=="string"&&s.trim()?r[o]=s.trim():o==="speed"&&typeof s=="number"&&Number.isFinite(s)&&(r.speed=s)}return!r.emotion&&!r.attitude&&typeof t=="string"&&t.trim()&&(r.attitude=t.trim()),Object.keys(r).length>0?r:null}function er(e){return q.join(K(e),Es)}function Bs(e){return q.join(K(e),Kn)}async function tr(e){let t=er(e),n;try{let a=await G.stat(t);if(!a.isFile()||a.size>As)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 o=String(r.targetVersion||"").trim();if(!Is.test(o))return null;let s={targetVersion:o},i=mt(r.note);return i&&(s.note=i),typeof r.requestedAt=="string"&&(s.requestedAt=r.requestedAt),s}async function nr(e){try{return await G.rm(er(e),{force:!0}),!0}catch{return!1}}async function Ue(e){let t=Bs(e),n;try{let r=await G.stat(t);if(!r.isFile()||r.size>xs)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 le(e,t={}){let n=await Le(e);if(!n)return!1;let r={...t,updatedAt:new Date().toISOString()};return ke(q.join(n,Kn),`${JSON.stringify(r,null,2)}
|
|
5
5
|
`)}async function rr(e){let t=await Le(e);if(!t)return!1;let n=q.join(t,pt);try{return await G.access(n),!0}catch{}return ke(n,Ts)}async function or(e){let t=q.join(K(e),pt);try{let n=await G.stat(t);return!n.isFile()||n.size>Cs?null:(await G.readFile(t,"utf8")).trim()||null}catch{return null}}var Jn,_s,zn,pt,vs,ks,Es,Kn,As,xs,Is,Cs,Ts,Ms,$s,Ns,Os,Rs,je=$e(()=>{Jn="status.json",_s="identity.json",zn="heartbeat.json",pt="heartbeat.md",vs="agent.json",ks="soul.md",Es="update-request.json",Kn="update.json",As=4*1024,xs=16*1024,Is=/^[a-zA-Z0-9._+-]{1,64}$/,Cs=16*1024,Ts=`# Heartbeat
|
|
@@ -15,38 +15,38 @@ 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
|
-
`,Ms=8*1024,$s=400;Ns=16*1024,Os=["name","avatar","accent_color","description","soul"],Rs=["cartesia_voice_id","voice_id","id","speed","emotion","attitude"]});import{spawn as zi,execFile as Ki}from"node:child_process";import Ot from"node:fs";import Me from"node:fs/promises";import Wi from"node:os";import _e from"node:path";import{promisify as Yi}from"node:util";function Dt({homedir:e=Wi.homedir()}={}){return _e.join(e,".agensis","versions")}function ze(e,t){return _e.join(e,t)}function Bt(e){return _e.join(e,Xi)}function be(e){return _e.join(e,"node_modules",Rt,"bin","agensis.mjs")}async function Mr(e,t){await Me.mkdir(_e.dirname(e),{recursive:!0}),await Me.rm(e,{force:!0}),await Me.symlink(t,e)}async function Pt({root:e,version:t,log:n=()=>{}}){let r=ze(e,t),o=be(r);if(Ot.existsSync(o))return n(`[self-update] ${t} already installed at ${r}`),r;if(await Me.mkdir(r,{recursive:!0}),n(`[self-update] installing ${Rt}@${t} into ${r}`),await Vi("npm",["install","--prefix",r,`${Rt}@${t}`,"--no-audit","--no-fund","--no-save","--omit=dev"]),!Ot.existsSync(o))throw new Error(`npm install reported success but ${o} is missing`);return r}function Lt({entry:e,profileName:t,extraArgs:n=[],env:r=process.env}){let o=["connect","--profile",t,...n],s=zi(process.execPath,[e,...o],{detached:!0,stdio:"inherit",env:r});return s.unref(),s}async function Ut(e,{graceMs:t=5e3}={}){return!e||e.exitCode!==null||e.killed||await new Promise(n=>{let r=!1,o=()=>{r||(r=!0,clearTimeout(s),n())},s=setTimeout(()=>{try{e.kill("SIGKILL")}catch{}},t);s.unref?.(),e.once("exit",o);try{e.kill("SIGTERM")}catch{o()}}),!0}async function jt({config:e,pid:t,timeoutMs:n=$r}){let r=_e.join(K(e),"heartbeat.json"),o=Date.now()+n;for(;Date.now()<o;){try{let s=await Me.readFile(r,"utf8"),i=JSON.parse(s);if(Number.isFinite(i.ts)&&Date.now()-i.ts<=Zi&&i.connected&&(t==null||i.pid===t))return!0}catch{}await new Promise(s=>setTimeout(s,Qi))}return!1}async function Nr({config:e,targetVersion:t,currentVersion:n,root:r=Dt({}),profileName:o="default",runningChild:s=null,installFn:i=Pt,spawnFn:a=Lt,stopFn:d=Ut,healthCheckFn:c=jt,healthTimeoutMs:u=$r,log:
|
|
19
|
-
`),signal:i,installFn:a=Pt,spawnFn:d=Lt,stopFn:c=Ut,healthCheckFn:u=jt,maxIterations:
|
|
18
|
+
`,Ms=8*1024,$s=400;Ns=16*1024,Os=["name","avatar","accent_color","description","soul"],Rs=["cartesia_voice_id","voice_id","id","speed","emotion","attitude"]});import{spawn as zi,execFile as Ki}from"node:child_process";import Ot from"node:fs";import Me from"node:fs/promises";import Wi from"node:os";import _e from"node:path";import{promisify as Yi}from"node:util";function Dt({homedir:e=Wi.homedir()}={}){return _e.join(e,".agensis","versions")}function ze(e,t){return _e.join(e,t)}function Bt(e){return _e.join(e,Xi)}function be(e){return _e.join(e,"node_modules",Rt,"bin","agensis.mjs")}async function Mr(e,t){await Me.mkdir(_e.dirname(e),{recursive:!0}),await Me.rm(e,{force:!0}),await Me.symlink(t,e)}async function Pt({root:e,version:t,log:n=()=>{}}){let r=ze(e,t),o=be(r);if(Ot.existsSync(o))return n(`[self-update] ${t} already installed at ${r}`),r;if(await Me.mkdir(r,{recursive:!0}),n(`[self-update] installing ${Rt}@${t} into ${r}`),await Vi("npm",["install","--prefix",r,`${Rt}@${t}`,"--no-audit","--no-fund","--no-save","--omit=dev"]),!Ot.existsSync(o))throw new Error(`npm install reported success but ${o} is missing`);return r}function Lt({entry:e,profileName:t,extraArgs:n=[],env:r=process.env}){let o=["connect","--profile",t,...n],s=zi(process.execPath,[e,...o],{detached:!0,stdio:"inherit",env:r});return s.unref(),s}async function Ut(e,{graceMs:t=5e3}={}){return!e||e.exitCode!==null||e.killed||await new Promise(n=>{let r=!1,o=()=>{r||(r=!0,clearTimeout(s),n())},s=setTimeout(()=>{try{e.kill("SIGKILL")}catch{}},t);s.unref?.(),e.once("exit",o);try{e.kill("SIGTERM")}catch{o()}}),!0}async function jt({config:e,pid:t,timeoutMs:n=$r}){let r=_e.join(K(e),"heartbeat.json"),o=Date.now()+n;for(;Date.now()<o;){try{let s=await Me.readFile(r,"utf8"),i=JSON.parse(s);if(Number.isFinite(i.ts)&&Date.now()-i.ts<=Zi&&i.connected&&(t==null||i.pid===t))return!0}catch{}await new Promise(s=>setTimeout(s,Qi))}return!1}async function Nr({config:e,targetVersion:t,currentVersion:n,root:r=Dt({}),profileName:o="default",runningChild:s=null,installFn:i=Pt,spawnFn:a=Lt,stopFn:d=Ut,healthCheckFn:c=jt,healthTimeoutMs:u=$r,log:p=()=>{}}={}){let l=await Ue(e)||{},f=n||l.currentVersion||null,S=Bt(r),g={version:t,startedAt:new Date().toISOString()};if(t===f){let m={currentVersion:f,previousVersion:l.previousVersion||null,lastAttempt:{...g,result:"noop_already_current"}};return await le(e,m),{...m,child:s}}let w;try{w=await i({root:r,version:t,log:p})}catch(m){let y={currentVersion:f,previousVersion:l.previousVersion||null,lastAttempt:{...g,result:"install_failed",error:String(m?.message||m)}};return await le(e,y),{...y,child:s}}s&&await d(s),await Mr(S,w);let b=be(w),k=a({entry:b,profileName:o});if(await c({config:e,pid:k.pid,timeoutMs:u})){let m={currentVersion:t,previousVersion:f,lastAttempt:{...g,result:"ok"}};return await le(e,m),{...m,child:k}}p(`[self-update] ${t} failed its health check within ${u}ms \u2014 rolling back to ${f||"(no known previous version)"}`),await d(k);let v=!1,$=null;if(f){let m=ze(r,f);Ot.existsSync(be(m))&&(await Mr(S,m),$=a({entry:be(m),profileName:o}),v=!0)}let T={currentVersion:v?f:l.currentVersion||f,previousVersion:f,lastAttempt:{...g,result:v?"rolled_back":"failed_no_fallback"}};return await le(e,T),{...T,child:$}}var Vi,Rt,Xi,$r,Qi,Zi,Or=$e(()=>{je();Vi=Yi(Ki),Rt="@agensis/agensis-agent",Xi="current",$r=3e4,Qi=1e3,Zi=1e4});var Dr={};Gt(Dr,{runSupervisor:()=>oa});import ea from"node:fs";import Ft from"node:fs/promises";import ta from"node:path";async function ra({root:e,runningVersion:t,installFn:n,log:r}){let o=Bt(e);if(ea.existsSync(o))return;r(`[supervise] no current version linked yet \u2014 adopting the running version ${t}`);let s=await n({root:e,version:t,log:r});await Ft.mkdir(ta.dirname(o),{recursive:!0}),await Ft.rm(o,{force:!0}),await Ft.symlink(s,o)}async function oa({config:e,runningVersion:t,profileName:n="default",pollIntervalMs:r=na,root:o=Dt({}),log:s=l=>process.stdout.write(`${l}
|
|
19
|
+
`),signal:i,installFn:a=Pt,spawnFn:d=Lt,stopFn:c=Ut,healthCheckFn:u=jt,maxIterations:p=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 ra({root:o,runningVersion:t,installFn:a,log:s});let l=await Ue(e);l?.currentVersion||(l={currentVersion:t,previousVersion:null,lastAttempt:null},await le(e,l));let f=null,S=!1,g=0,w=()=>{let E=ze(o,l.currentVersion);return f=d({entry:be(E),profileName:n}),f.on?.("exit",(v,$)=>{if(S)return;s(`[supervise] daemon (version ${l.currentVersion}) exited (code=${v} signal=${$}); respawning`);let T=Rr[Math.min(g,Rr.length-1)];g+=1,setTimeout(()=>{S||w()},T).unref?.()}),f.on?.("spawn",()=>{g=0}),f};w();let b=async()=>{S=!0,f&&await c(f)};i?.addEventListener("abort",()=>{b()}),process.once("SIGTERM",()=>{b().then(()=>process.exit(0))}),process.once("SIGINT",()=>{b().then(()=>process.exit(0))});let k=0;for(;!S&&!i?.aborted&&k<p&&(k+=1,await new Promise($=>setTimeout($,r)),!(S||i?.aborted));){let E=await tr(e);if(!E||E.targetVersion===l.currentVersion)continue;s(`[supervise] update requested: ${l.currentVersion} -> ${E.targetVersion}${E.note?` (${E.note})`:""}`);let v=await Nr({config:e,targetVersion:E.targetVersion,currentVersion:l.currentVersion,root:o,profileName:n,runningChild:f,installFn:a,spawnFn:d,stopFn:c,healthCheckFn:u,log:s});await nr(e),l=v,f=v.child||f,g=0,s(`[supervise] update attempt "${E.targetVersion}" -> ${v.lastAttempt?.result} (running ${v.currentVersion})`)}return{state:l,child:f}}var na,Rr,Br=$e(()=>{Or();je();na=5e3,Rr=[1e3,5e3,15e3,3e4]});import ne from"node:process";import xe from"node:fs";import me from"node:path";import Ie from"node:os";import Ps from"node:crypto";import M from"node:process";import Ae from"ws";import{spawn as Lr}from"node:child_process";function Ht(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 Ur=50*1024*1024;function Z(e){let{cmd:t,args:n=[],env:r={},cwd:o,timeoutMs:s=0,label:i="working",heartbeatMs:a=15e3,input:d="",now:c=Date.now,log:u=console,signal:p,onData:l}=e||{};return new Promise(f=>{if(p?.aborted){f({status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")});return}let S;try{let A=n.some(V=>V==="--dangerously-skip-permissions"),C=typeof process.getuid=="function"&&process.getuid()===0,O={...process.env,...r};delete O.AGENSIS_TOKEN,delete O.ANTHROPIC_API_KEY,delete O.ANTHROPIC_AUTH_TOKEN,A&&C&&(O.IS_SANDBOX="1"),S=Lr(t,n,{cwd:o,detached:!0,env:O})}catch(A){f({status:null,stdout:"",stderr:"",error:A});return}d?S.stdin?.end(String(d)):S.stdin?.end();let g="",w="";S.stdout?.setEncoding("utf8"),S.stderr?.setEncoding("utf8");let b=(A,C)=>A.length>=Ur?A:A+C;S.stdout?.on("data",A=>{if(g=b(g,A),l)try{l(A)}catch{}}),S.stderr?.on("data",A=>w=b(w,A));let k=c(),E=a>0?setInterval(()=>{u.log(` \u2026 still ${i} (${Ht(c()-k)}) \u2014 Ctrl+C to cancel`)},a):null;E?.unref&&E.unref();let v=A=>{if(S.pid!=null)try{process.kill(-S.pid,A)}catch{try{S.kill(A)}catch{}}},$=!1,T=s>0?setTimeout(()=>{$=!0,v("SIGKILL")},s):null;T?.unref&&T.unref();let m=!1,y=null,I=()=>{m=!0,v("SIGTERM"),y=setTimeout(()=>v("SIGKILL"),3e3),y?.unref&&y.unref()};p&&p.addEventListener("abort",I,{once:!0});let h=(A,C)=>{E&&clearInterval(E),T&&clearTimeout(T),y&&clearTimeout(y),p&&p.removeEventListener("abort",I),f({status:A,stdout:g,stderr:w,aborted:m,error:C||(m?new Error("cancelled"):$?new Error(`timed out after ${Ht(s)}`):null)})};S.on("error",A=>h(null,A)),S.on("close",A=>h(A,null))})}import{spawn as Kr}from"node:child_process";import jr from"node:crypto";var Fr=Number(process.env.AGENSIS_PERMISSION_TIMEOUT_MS||10*60*1e3),qt=["once","session","always"];function Jt(e){let t=String(e?.toolName??"").trim();if(!t)return"";let n=String(e?.ruleContent??"").trim();return n?`${t}(${n})`:t}function Gr(e){let t=[];for(let n of Array.isArray(e)?e:[])if(!(!n||n.type!=="addRules"||n.behavior!=="allow"))for(let r of Array.isArray(n.rules)?n.rules:[]){let o=Jt(r);o&&!t.includes(o)&&t.push(o)}return t}var Hr=/\d*>&\d*|&>/g,qr=/[;&|`]|\$\(/;function Jr(e,t){if(String(e||"")!=="Bash")return[];let n=String(t?.command??"").trim();if(!n||qr.test(n.replace(Hr," ")))return[];let r=n.split(/\s+/),o=r[0];if(!o||o.startsWith("-"))return[];let s=r[1];return[`Bash(${s&&/^[a-z][a-z0-9:_-]*$/i.test(s)?`${o} ${s}`:o}:*)`]}function zt({toolName:e,input:t,suggestions:n}={}){let r=Gr(n);return r.length>0?r:Jr(e,t)}function zr(e){let t=Array.isArray(e)?e:Array.isArray(e?.allow)?e.allow:[],n=[];for(let r of t){let o=typeof r=="string"?r.trim():Jt(r);o&&!n.includes(o)&&n.push(o)}return n}function Kt(e){return zr(e?.agent?.metadata?.permission_rules??e?.agent?.permissionRules??e?.permissionRules??e?.permission_rules)}function Wt(e,{toolName:t,input:n,suggestions:r}={}){let o=Array.isArray(e)?e:[];if(o.length===0)return!1;let s=String(t||"").trim();return s&&o.includes(s)?!0:zt({toolName:t,input:n,suggestions:r}).some(i=>o.includes(i))}function fe(e){return{behavior:"deny",message:e}}function Yt({send:e,timeoutMs:t=Fr,log:n=()=>{},idFactory:r=()=>jr.randomUUID()}={}){if(typeof e!="function")throw new Error("createPermissionBroker requires send()");let o=new Map,s=(i,a)=>{let d=o.get(i);return d?(o.delete(i),clearTimeout(d.timer),d.resolve(a),!0):!1};return{request({jobId:i,toolName:a,title:d,description:c,detail:u,input:p,suggestions:l,signal:f}={}){let S=r(),g=zt({toolName:a,input:p,suggestions:l});return e({action:"agent_permission_request",jobId:i||"",requestId:S,toolName:String(a||"").trim(),title:String(d||"").trim(),description:String(c||"").trim(),detail:String(u||"").trim(),input:p||null,rules:g,scopes:g.length>0?qt:["once","session"],expiresInMs:t})?(n(`permission requested for ${a||"a tool"} (${S})`),new Promise(b=>{let k=setTimeout(()=>{s(S,fe(`Nobody approved this within ${Math.round(t/6e4)} minutes. Ask again in the chat, or have the workspace grant it on the agent.`))},t);k.unref?.();let E={jobId:i||"",timer:k,resolve:b};o.set(S,E),f?.addEventListener?.("abort",()=>{s(S,fe("The job was cancelled before this was approved."))},{once:!0})})):Promise.resolve(fe("Agensis was unreachable, so this tool call could not be approved."))},decide(i){let a=String(i?.requestId||"");if(!a||!o.has(a))return!1;let d=i.behavior==="allow",c=qt.includes(i.scope)?i.scope:"once",u=String(i.decidedBy||"").trim();return n(`permission ${d?`allowed (${c})`:"denied"} for ${a}${u?` by ${u}`:""}`),s(a,d?{behavior:"allow",scope:c,decidedBy:u}:fe(String(i.message||"").trim()||`${u||"The workspace"} denied this tool call.`))},cancelJob(i,a="The job ended before this was approved."){let d=String(i||""),c=0;for(let[u,p]of[...o.entries()])p.jobId===d&&s(u,fe(a))&&(c+=1);return c},shutdown(i="The agent daemon disconnected before this was approved."){let a=0;for(let d of[...o.keys()])s(d,fe(i))&&(a+=1);return a},pendingCount(){return o.size}}}var Qt=10*60*1e3;function Zt(e={}){let t={...process.env,...e};return delete t.AGENSIS_TOKEN,delete t.ANTHROPIC_API_KEY,delete t.ANTHROPIC_AUTH_TOKEN,t}var Ve=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 en(){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 Wr=["mcp__agensis"],Yr=["Grep","Glob"];function Vr(e){return e==="yolo"?{permissionMode:"bypassPermissions",allowDangerouslySkipPermissions:!0}:e==="accept_edits"?{permissionMode:"acceptEdits"}:{permissionMode:"default"}}function Xr(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 Qr(e){return`${JSON.stringify({type:"stream_event",event:{type:"content_block_delta",delta:{type:"text_delta",text:e}}})}
|
|
20
20
|
`}function Zr(e){return`${JSON.stringify({type:"result",result:e})}
|
|
21
21
|
`}function eo(e){return`${JSON.stringify({type:"agensis_step",step:e})}
|
|
22
22
|
`}function to(e){return`${JSON.stringify({type:"agensis_segment",segment:e})}
|
|
23
|
-
`}var no=["file_path","path","pattern","command","description","prompt"],Vt=120;function Ne(e){if(!e||typeof e!="object")return"";for(let t of no){let n=e[t];if(typeof n!="string")continue;let r=n.replace(/\s+/g," ").trim();if(r)return r.length>Vt?`${r.slice(0,Vt)}\u2026`:r}return""}function tn(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||"",canAsk:!!e.requestPermission})}function ro(e,t){return async(n,r,o={})=>{let s=e.activeTurn;if(!s)return{behavior:"deny",message:"This tool call arrived with no active job to ask about."};let i=s.requestPermission||t;if(!i)return{behavior:"deny",message:"This agent has no way to ask for approval right now."};if(Wt(s.permissionRules,{toolName:n,input:r,suggestions:o.suggestions}))return{behavior:"allow"};let a=await i({jobId:s.jobId,toolName:n,title:o.title,description:o.description,detail:Ne(r),input:r,suggestions:o.suggestions,signal:o.signal});if(a?.behavior!=="allow")return{behavior:"deny",message:a?.message||"This tool call was not approved."};let d=a.scope==="once"?void 0:o.suggestions;return d?.length?{behavior:"allow",updatedPermissions:d}:{behavior:"allow"}}}function nn({queryFn:e,idleCloseMs:t=Qt,requestPermission:n}={}){let r=new Map,o=en(),s=(c,u,
|
|
24
|
-
`):v.result,
|
|
25
|
-
`))>=0;){let d=n.slice(0,a);if(n=n.slice(a+1),!d.trim())continue;let c;try{c=JSON.parse(d)}catch{continue}if(c.id!==void 0&&r.has(c.id)){let{resolve:u,reject:
|
|
23
|
+
`}var no=["file_path","path","pattern","command","description","prompt"],Vt=120;function Ne(e){if(!e||typeof e!="object")return"";for(let t of no){let n=e[t];if(typeof n!="string")continue;let r=n.replace(/\s+/g," ").trim();if(r)return r.length>Vt?`${r.slice(0,Vt)}\u2026`:r}return""}function tn(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||"",canAsk:!!e.requestPermission})}function ro(e,t){return async(n,r,o={})=>{let s=e.activeTurn;if(!s)return{behavior:"deny",message:"This tool call arrived with no active job to ask about."};let i=s.requestPermission||t;if(!i)return{behavior:"deny",message:"This agent has no way to ask for approval right now."};if(Wt(s.permissionRules,{toolName:n,input:r,suggestions:o.suggestions}))return{behavior:"allow"};let a=await i({jobId:s.jobId,toolName:n,title:o.title,description:o.description,detail:Ne(r),input:r,suggestions:o.suggestions,signal:o.signal});if(a?.behavior!=="allow")return{behavior:"deny",message:a?.message||"This tool call was not approved."};let d=a.scope==="once"?void 0:o.suggestions;return d?.length?{behavior:"allow",updatedPermissions:d}:{behavior:"allow"}}}function nn({queryFn:e,idleCloseMs:t=Qt,requestPermission:n}={}){let r=new Map,o=en(),s=(c,u,p)=>{let l=r.get(c);if(!(!l||u&&l!==u))if(r.delete(c),clearTimeout(l.idleTimer),l.closed=!0,l.queue.close(),p&&l.activeTurn&&l.activeTurn.finish(p),typeof l.query.close=="function")try{l.query.close()}catch{}else Promise.resolve(l.query.return?.()).catch(()=>{})},i=c=>{let u=r.get(c);u&&(clearTimeout(u.idleTimer),u.idleTimer=setTimeout(()=>s(c),t),u.idleTimer.unref?.())},a=async(c,u)=>{let p=r.get(c),l=tn(u);if(p&&p.fingerprint===l&&!p.closed)return p;p&&s(c,p),e||(e=(await import("@anthropic-ai/claude-agent-sdk")).query);let f=new Ve,S=Vr(u.permissionMode),g=S.permissionMode!=="bypassPermissions"&&!!(n||u.requestPermission),w={query:null,queue:f,sessionId:"",idleTimer:null,activeTurn:null,closed:!1,terminalError:null,fingerprint:l},b=u.leanCli&&u.mcp?{agensis:{type:"http",url:u.mcp.url,headers:{Authorization:"Bearer ${AGENSIS_MCP_TOKEN}"}}}:void 0,k=e({prompt:f,options:{cwd:u.cwd,model:u.model,...S,allowedTools:[...Wr,...Yr],canUseTool:g?ro(w,n):void 0,additionalDirectories:u.hostFolders&&u.hostFolders.length?u.hostFolders:void 0,mcpServers:b,strictMcpConfig:u.leanCli?!0:void 0,settingSources:u.leanCli?[]:void 0,persistSession:u.leanCli?!1:void 0,includePartialMessages:!0,env:Zt(u.mcp?.env)}});return w.query=k,r.set(c,w),w.pump=(async()=>{let E=null;try{for await(let v of k){v.session_id&&(w.sessionId=v.session_id);let $=w.activeTurn;if($){if(v.type==="stream_event"){let T=Xr(v.event);T&&($.streamed+=T,$.onData?.(Qr(T)))}else if(v.type==="result")if(v.subtype==="success"){let T=v.result==null?$.text:String(v.result);$.onData?.(Zr(T)),$.finish({status:0,stdout:T,stderr:"",error:null})}else{let T=Array.isArray(v.errors)?v.errors.filter(Boolean).join(`
|
|
24
|
+
`):v.result,m=new Error(T||`claude-agent-sdk result error: ${v.subtype}`);$.finish({status:1,stdout:$.text,stderr:m.message,error:m})}else if(v.type==="assistant"){let T=v.message?.content;if(Array.isArray(T)){let m=T.filter(y=>y&&y.type==="text"&&typeof y.text=="string").map(y=>y.text).join("");m&&($.onData?.(to({text:m})),$.flushed+=$.streamed,$.streamed="");for(let y of T)!y||y.type!=="tool_use"||!y.name||$.onData?.(eo({kind:"tool",name:String(y.name),detail:Ne(y.input)}))}}}}E=new Error("claude-agent-sdk connection closed")}catch(v){E=v}finally{w.closed=!0,w.terminalError=E,clearTimeout(w.idleTimer),w.queue.close(),r.get(c)===w&&r.delete(c),w.activeTurn&&w.activeTurn.finish({status:null,stdout:w.activeTurn.text,stderr:String(E?.message||E||""),error:E})}})(),w};return{run:c=>o(c.sessionKey||"default",async()=>{let{sessionKey:u="default",prompt:p,signal:l,onData:f,timeoutMs:S=0}=c;if(l?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let g;try{g=await a(u,c)}catch(b){return{status:null,stdout:"",stderr:"",error:b}}if(g.closed){let b=g.terminalError||new Error("claude-agent-sdk connection closed");return{status:null,stdout:"",stderr:String(b.message||b),error:b}}clearTimeout(g.idleTimer);let w=await new Promise(b=>{let k=!1,E=null,v={streamed:"",flushed:"",get text(){return this.flushed+this.streamed},onData:f,jobId:c.job?.id||"",permissionRules:Kt(c.job),requestPermission:c.requestPermission||null,finish(T){k||(k=!0,g.activeTurn===v&&(g.activeTurn=null),l&&l.removeEventListener("abort",$),E&&clearTimeout(E),b(T))}},$=()=>{let T={status:null,stdout:v.text,stderr:"",aborted:!0,error:new Error("cancelled")};Promise.resolve(g.query.interrupt?.()).catch(()=>{}),s(u,g,T)};g.activeTurn=v,l&&l.addEventListener("abort",$,{once:!0}),S>0&&(E=setTimeout(()=>{let T=new Error(`timed out after ${S}ms`);Promise.resolve(g.query.interrupt?.()).catch(()=>{}),s(u,g,{status:null,stdout:v.text,stderr:T.message,error:T})},S),E.unref?.()),g.queue.push({type:"user",message:{role:"user",content:p},parent_tool_use_id:null,session_id:g.sessionId})});return r.get(u)===g&&i(u),w}),shutdown:()=>{for(let c of[...r.keys()])s(c)}}}function oo(e){let t=1,n="",r=new Map,o=new Set;e.stdout.setEncoding("utf8"),e.stdout.on("data",i=>{n+=i;let a;for(;(a=n.indexOf(`
|
|
25
|
+
`))>=0;){let d=n.slice(0,a);if(n=n.slice(a+1),!d.trim())continue;let c;try{c=JSON.parse(d)}catch{continue}if(c.id!==void 0&&r.has(c.id)){let{resolve:u,reject:p}=r.get(c.id);r.delete(c.id),c.error?p(new Error(c.error.message||"codex app-server error")):u(c.result)}else if(c.method)for(let u of o)u(c.method,c.params,c.id)}});let s=i=>{for(let{reject:a}of r.values())a(i);r.clear()};return e.on("exit",()=>s(new Error("codex app-server exited"))),e.on("error",i=>s(i)),{request(i,a){let d=t++;return new Promise((c,u)=>{r.set(d,{resolve:c,reject:u}),e.stdin.write(`${JSON.stringify({id:d,method:i,params:a})}
|
|
26
26
|
`)})},notify(i,a){e.stdin.write(`${JSON.stringify({method:i,params:a})}
|
|
27
27
|
`)},respond(i,a){e.stdin.write(`${JSON.stringify({id:i,result:a})}
|
|
28
28
|
`)},respondError(i,a){e.stdin.write(`${JSON.stringify({id:i,error:{code:-32601,message:a}})}
|
|
29
|
-
`)},onMessage(i){return o.add(i),()=>o.delete(i)}}}function so(e){return e==="yolo"?{approvalPolicy:"never",sandbox:"danger-full-access"}:{}}function io(e,t,n){let r=Array.isArray(e)?e.map(String):[];if(r.length){let o=t.find(s=>r.includes(s));if(o)return o}return n}var We={preferences:["decline"],fallback:"decline"},ao={preferences:["accept","acceptForSession"],fallback:"acceptForSession"},Xt={preferences:["acceptForSession","accept"],fallback:"acceptForSession"};function Ye(e,t){return io(e,t.preferences,t.fallback)}function co(e,t){let n=t?.command,r=Array.isArray(n)?n.join(" "):String(n||"");if(r.trim())return r.replace(/\s+/g," ").trim().slice(0,200);let o=t?.fileChanges||t?.changes,s=o&&typeof o=="object"?Object.keys(o):[];return s.length?s.slice(0,4).join(", "):e==="item/fileChange/requestApproval"?"apply a file change":"run a command"}function rn({spawnFn:e=Kr,idleCloseMs:t=Qt,requestPermission:n}={}){let r=new Map,o=en(),s=c=>{let u=r.get(c);if(u){r.delete(c),clearTimeout(u.idleTimer);try{u.child.kill("SIGTERM")}catch{}}},i=c=>{let u=r.get(c);u&&(clearTimeout(u.idleTimer),u.idleTimer=setTimeout(()=>s(c),t),u.idleTimer.unref?.())},a=async(c,u)=>{let
|
|
29
|
+
`)},onMessage(i){return o.add(i),()=>o.delete(i)}}}function so(e){return e==="yolo"?{approvalPolicy:"never",sandbox:"danger-full-access"}:{}}function io(e,t,n){let r=Array.isArray(e)?e.map(String):[];if(r.length){let o=t.find(s=>r.includes(s));if(o)return o}return n}var We={preferences:["decline"],fallback:"decline"},ao={preferences:["accept","acceptForSession"],fallback:"acceptForSession"},Xt={preferences:["acceptForSession","accept"],fallback:"acceptForSession"};function Ye(e,t){return io(e,t.preferences,t.fallback)}function co(e,t){let n=t?.command,r=Array.isArray(n)?n.join(" "):String(n||"");if(r.trim())return r.replace(/\s+/g," ").trim().slice(0,200);let o=t?.fileChanges||t?.changes,s=o&&typeof o=="object"?Object.keys(o):[];return s.length?s.slice(0,4).join(", "):e==="item/fileChange/requestApproval"?"apply a file change":"run a command"}function rn({spawnFn:e=Kr,idleCloseMs:t=Qt,requestPermission:n}={}){let r=new Map,o=en(),s=c=>{let u=r.get(c);if(u){r.delete(c),clearTimeout(u.idleTimer);try{u.child.kill("SIGTERM")}catch{}}},i=c=>{let u=r.get(c);u&&(clearTimeout(u.idleTimer),u.idleTimer=setTimeout(()=>s(c),t),u.idleTimer.unref?.())},a=async(c,u)=>{let p=r.get(c),l=tn(u);if(p&&p.fingerprint===l)return p;p&&s(c);let f=e("codex",["app-server"],{cwd:u.cwd,env:Zt(u.mcp?.env),stdio:["pipe","pipe","pipe"]}),S=oo(f);await S.request("initialize",{clientInfo:{name:"agensis-agent",version:u.clientVersion||"unknown"}}),S.notify("initialized");let g=u.leanCli&&u.mcp?{mcp_servers:{agensis:{url:u.mcp.url,bearer_token_env_var:"AGENSIS_MCP_TOKEN"}}}:void 0,w=await S.request("thread/start",{cwd:u.cwd,ephemeral:u.leanCli||void 0,model:u.model,config:g,...so(u.permissionMode)}),b={child:f,rpc:S,threadId:w.thread.id,fingerprint:l,idleTimer:null};return r.set(c,b),b};return{run:c=>o(c.sessionKey||"default",async()=>{let{sessionKey:u="default",prompt:p,signal:l,onData:f,timeoutMs:S=0}=c;if(l?.aborted)return{status:null,stdout:"",stderr:"",aborted:!0,error:new Error("cancelled")};let g;try{g=await a(u,c)}catch($){return{status:null,stdout:"",stderr:"",error:$}}let w="",b="",k=null,E=!1,v=await new Promise($=>{let T=!1,m=C=>{T||(T=!0,A(),$(C))},y=g.rpc.onMessage((C,O,V)=>{if(V!==void 0){let P=C==="item/commandExecution/requestApproval",J=C==="item/fileChange/requestApproval";if(!P&&!J){g.rpc.respondError(V,`Agensis daemon cannot handle Codex request ${C}`);return}let X=c.permissionMode==="yolo"||J&&c.permissionMode==="accept_edits",x=c.requestPermission||n;if(X||!x){let D=Ye(O?.availableDecisions,X?Xt:We);g.rpc.respond(V,{decision:D});return}Promise.resolve(x({jobId:c.job?.id||"",toolName:P?"Codex command":"Codex file change",detail:co(C,O),description:String(O?.reason||"").trim(),input:O||null})).then(D=>{let _=D?.behavior!=="allow"?We:D.scope==="once"?ao:Xt;g.rpc.respond(V,{decision:Ye(O?.availableDecisions,_)})}).catch(()=>{g.rpc.respond(V,{decision:Ye(O?.availableDecisions,We)})});return}if(!(!O||O.threadId!==g.threadId)){if(C==="turn/started"){k=O.turn?.id??k;return}if(!(k&&O.turnId&&O.turnId!==k)){if(C==="item/agentMessage/delta")w+=O.delta||"",f?.(O.delta||"");else if(C==="item/completed"&&O.item?.type==="agentMessage")b=O.item.text||b;else if(C==="turn/completed"){let P=O.turn?.status==="failed"||O.turn?.error;m({status:P?1:0,stdout:b||w,stderr:P?String(O.turn?.error?.message||O.turn?.error||""):"",error:P?new Error(String(O.turn?.error?.message||O.turn?.error||"codex turn failed")):null})}}}}),I=()=>{E=!0,g.rpc.request("turn/interrupt",{threadId:g.threadId}).catch(()=>{});let C={status:null,stdout:w,stderr:"",aborted:!0,error:new Error("cancelled")};m(C),s(u)};l&&l.addEventListener("abort",I,{once:!0});let h=S>0?setTimeout(()=>{let C=new Error(`timed out after ${S}ms`);g.rpc.request("turn/interrupt",{threadId:g.threadId}).catch(()=>{}),m({status:null,stdout:w,stderr:C.message,error:C}),s(u)},S):null;h?.unref?.();function A(){y(),l&&l.removeEventListener("abort",I),h&&clearTimeout(h)}g.rpc.request("turn/start",{threadId:g.threadId,input:[{type:"text",text:p}]}).then(C=>{k=C?.turn?.id||k}).catch(C=>m({status:null,stdout:"",stderr:"",error:C}))});return E||i(u),v}),shutdown:()=>{for(let c of[...r.keys()])s(c)}}}function cn({run:e=Z}={}){return{run:t=>e(t)}}var mo=null,po=null,an=new Set;function fo(e){let t=String(e&&e.message||e||"");return/Cannot find module|ERR_MODULE_NOT_FOUND|ENOENT|command not found/i.test(t)}function ho(e,{local:t,pooled:n,log:r=console}={}){let o=t||cn(),s=n||(e==="claude"?mo||=nn():e==="codex"?po||=rn():null);return s?{async run(i){if(an.has(e))return o.run(i);let a=await s.run(i);return a.error&&fo(a.error)?(an.add(e),r.log?.(`[executor] ${e} fast connection unavailable (${a.error.message}); falling back to subprocess mode for this and future jobs.`),o.run(i)):a}}:o}function go(e){return{async run({cmd:t,args:n=[],env:r={},onData:o,signal:s,job:i}){let a=null;try{a=await e.ensureEnv({job:i,signal:s}),await e.putRepo(a,{job:i,signal:s});let d=await e.exec(a,{cmd:t,args:n,env:r,onData:o,signal:s}),c=await e.getResult(a,{job:i}).catch(()=>({})),u=c&&c.patch?String(c.patch).trim():"",p=u?`${d.stdout||""}
|
|
30
30
|
|
|
31
31
|
\`\`\`diff
|
|
32
32
|
${u}
|
|
33
|
-
\`\`\``:d.stdout||"";return{status:d.status,stdout:
|
|
33
|
+
\`\`\``:d.stdout||"";return{status:d.status,stdout:p,stderr:d.stderr||"",error:d.error||null}}catch(d){return{status:null,stdout:"",stderr:"",error:d}}finally{if(a)try{await e.destroy(a)}catch{}}}}}function un(e,{makeProvider:t,family:n}={}){return(e&&e.agent&&e.agent.run_mode)==="sandbox"?go((t||yo)(e)):n==="claude"||n==="codex"?ho(n):cn()}function yo(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 wo({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 So(e=process.versions.node){let[t,n,r]=String(e).split(".").map(o=>Number(o)||0);return t===21?!1:t>=22?!0:t!==20?!1:n>18?!0:n<18?!1:r>=1}function wo(e){let t=null,n=async()=>{if(!t){if(!So())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(()=>(sn(),on))).createE2bProvider(e)}return t};return{ensureEnv:async r=>(await n()).ensureEnv(r),putRepo:async(r,o)=>(await n()).putRepo(r,o),exec:async(r,o)=>(await n()).exec(r,o),getResult:async(r,o)=>(await n()).getResult(r,o),destroy:async r=>(await n()).destroy(r)}}import ln from"node:fs/promises";import Oe from"node:path";var Ze="amp",bo=/^T-[A-Za-z0-9-]{20,100}$/,Qe={amp_not_installed:"Amp CLI is not installed on the connected machine. Install Amp, then reconnect this agent.",amp_version_unsupported:"The installed Amp CLI does not support orb execute streaming. Update Amp, then reconnect this agent.",amp_not_authenticated:"Amp is not signed in on the connected machine. Run `amp login` there, then try again.",amp_auth_expired:"The Amp sign-in on the connected machine has expired. Run `amp login` there, then try again.",amp_project_not_found:"This repository is not an Amp project. Run `amp projects create <repository-url> --workspace` in it (or `--personal`), then try again.",amp_project_unmatched:"This repository is not linked to an Amp project. Run `amp projects create <repository-url> --workspace` in it (or `--personal`), then try again.",amp_project_forbidden:"The connected Amp account cannot access this repository project.",amp_repo_access_denied:"Amp cannot reach this GitHub repository. Grant the Amp GitHub connection access to it at https://ampcode.com/settings, then try again.",amp_repo_not_allowed:"This repository is not allowed by the connected Agensis daemon profile.",amp_insufficient_credit:"The connected Amp account does not have enough credit to start or continue this orb.",amp_orb_provision_failed:"Amp could not provision the orb for this turn.",amp_setup_failed:"The repository `.agents/setup` script exists but is not executable.",amp_thread_not_found:"The Amp thread linked to this conversation no longer exists. Start a new Agensis conversation to create a new thread.",amp_stream_invalid:"Amp completed without returning a valid thread stream.",amp_cli_crashed:"The Amp CLI stopped unexpectedly on the connected machine.",amp_turn_cancelled:"The Amp turn was cancelled.",amp_turn_timed_out:"The Amp turn timed out on the connected machine."};function ee(e,t=""){let n=new Error(Qe[e]||Qe.amp_cli_crashed);return n.code=e,t&&(n.detail=String(t).slice(0,1e3)),n}function et(e){return String(e?.agent?.metadata?.runtime||"").trim().toLowerCase()===Ze}function he(e){let t=String(e||"").trim();return bo.test(t)?t:""}function _o(e){let t=he(e);return t?`https://ampcode.com/threads/${t}`:""}function dn({prompt:e,threadId:t="",executable:n="amp"}={}){let r=he(t);return r?{cmd:n,args:["threads","continue",r,"-x",String(e||""),"--stream-json"]}:{cmd:n,args:["-ox",String(e||""),"--stream-json","--no-archive-after-execute"]}}function mn(){let e="",t="",n=r=>{try{let o=JSON.parse(String(r).trim()),s=he(o?.session_id||o?.sessionId||o?.thread_id||o?.threadId);s&&(t=s)}catch{}};return{feed(r){e+=String(r||"");let o;for(;(o=e.indexOf(`
|
|
34
34
|
`))>=0;)n(e.slice(0,o)),e=e.slice(o+1)},end(){e&&n(e),e=""},get threadId(){return t},get threadUrl(){return _o(t)}}}function Re(e={}){let t=`${e?.error?.message||""}
|
|
35
35
|
${e?.stderr||""}
|
|
36
|
-
${e?.stdout||""}`.trim(),n="amp_cli_crashed";return e?.error?.code==="ENOENT"||/spawn\s+amp\s+ENOENT|command not found/i.test(t)?n="amp_not_installed":/unknown option|unknown command|unrecognized option/i.test(t)?n="amp_version_unsupported":/could not access this github repository|github connection has access/i.test(t)?n="amp_repo_access_denied":e?.aborted===!0||/^cancelled$/i.test(String(e?.error?.message||"").trim())?n="amp_turn_cancelled":/timed out|timeout/i.test(t)?n="amp_turn_timed_out":/(?:auth(?:entication)?|session|token|credential)[^\n]*(?:expired|invalid|revoked)/i.test(t)?n="amp_auth_expired":/not (?:logged|signed) in|not authenticated|please (?:log|sign) ?in|(?:log|sign) ?in (?:to|required)|authentication required|unauthenticated|unauthorized/i.test(t)?n="amp_not_authenticated":/insufficient[^\n]*(?:credit|balance)|(?:credit|balance)[^\n]*(?:exhausted|too low|not enough|run out|out of)|(?:run )?out of[^\n]*(?:credit|balance)|(?:usage|spend)[^\n]*limit[^\n]*(?:exceeded|reached)/i.test(t)?n="amp_insufficient_credit":/thread[^\n]*(?:not found|does not exist|unknown)/i.test(t)?n="amp_thread_not_found":/project[^\n]*(?:forbidden|permission|access denied|not allowed)/i.test(t)?n="amp_project_forbidden":/project[^\n]*(?:not found|does not exist|unmatched)/i.test(t)?n="amp_project_not_found":/\.agents\/setup|setup script/i.test(t)?n="amp_setup_failed":/provision|creating orb|start(?:ing)? orb/i.test(t)&&(n="amp_orb_provision_failed"),{code:n,message:Qe[n],detail:t.slice(0,1e3)}}async function pn({cwd:e,allowedRoots:t=[]}={}){let n=Oe.resolve(String(e||""));if(!t.map(s=>String(s||"").trim()).filter(Boolean).map(s=>Oe.resolve(s)).includes(n))throw ee("amp_repo_not_allowed");try{await ln.access(Oe.join(n,".git"))}catch{throw ee("amp_repo_not_allowed","cwd is not a Git repository root")}let o=Oe.join(n,".agents","setup");try{let s=await ln.stat(o);if(s.isFile()&&!(s.mode&73))throw ee("amp_setup_failed")}catch(s){if(s?.code!=="ENOENT")throw s}return n}function re(e,t){return{id:Ze,available:!1,version:e,reason:t,project:null}}function vo(e){return!e||typeof e!="object"?null:{id:String(e.id||"").slice(0,160),name:String(e.name||e.slug||"").slice(0,200),repository:String(e.repositoryURL||e.repository||e.repo||e.repositoryUrl||"").slice(0,500)}}async function tt({cwd:e,executable:t="amp",run:n=Z,signal:r}={}){let o=(l,
|
|
37
|
-
${a?.stderr||""}`;if(a?.status!==0||!/--stream-json/.test(d)||!/threads[\s\S]*continue/i.test(d)||!/\borb\b/i.test(d))return re(i,"amp_version_unsupported");let c=await o(["usage"]);if(c?.status!==0){let l=Re(c);return re(i,l.code)}let u=await o(["projects","status","--json"]);if(u?.status!==0){let l=Re(u);return re(i,l.code)}let
|
|
36
|
+
${e?.stdout||""}`.trim(),n="amp_cli_crashed";return e?.error?.code==="ENOENT"||/spawn\s+amp\s+ENOENT|command not found/i.test(t)?n="amp_not_installed":/unknown option|unknown command|unrecognized option/i.test(t)?n="amp_version_unsupported":/could not access this github repository|github connection has access/i.test(t)?n="amp_repo_access_denied":e?.aborted===!0||/^cancelled$/i.test(String(e?.error?.message||"").trim())?n="amp_turn_cancelled":/timed out|timeout/i.test(t)?n="amp_turn_timed_out":/(?:auth(?:entication)?|session|token|credential)[^\n]*(?:expired|invalid|revoked)/i.test(t)?n="amp_auth_expired":/not (?:logged|signed) in|not authenticated|please (?:log|sign) ?in|(?:log|sign) ?in (?:to|required)|authentication required|unauthenticated|unauthorized/i.test(t)?n="amp_not_authenticated":/insufficient[^\n]*(?:credit|balance)|(?:credit|balance)[^\n]*(?:exhausted|too low|not enough|run out|out of)|(?:run )?out of[^\n]*(?:credit|balance)|(?:usage|spend)[^\n]*limit[^\n]*(?:exceeded|reached)/i.test(t)?n="amp_insufficient_credit":/thread[^\n]*(?:not found|does not exist|unknown)/i.test(t)?n="amp_thread_not_found":/project[^\n]*(?:forbidden|permission|access denied|not allowed)/i.test(t)?n="amp_project_forbidden":/project[^\n]*(?:not found|does not exist|unmatched)/i.test(t)?n="amp_project_not_found":/\.agents\/setup|setup script/i.test(t)?n="amp_setup_failed":/provision|creating orb|start(?:ing)? orb/i.test(t)&&(n="amp_orb_provision_failed"),{code:n,message:Qe[n],detail:t.slice(0,1e3)}}async function pn({cwd:e,allowedRoots:t=[]}={}){let n=Oe.resolve(String(e||""));if(!t.map(s=>String(s||"").trim()).filter(Boolean).map(s=>Oe.resolve(s)).includes(n))throw ee("amp_repo_not_allowed");try{await ln.access(Oe.join(n,".git"))}catch{throw ee("amp_repo_not_allowed","cwd is not a Git repository root")}let o=Oe.join(n,".agents","setup");try{let s=await ln.stat(o);if(s.isFile()&&!(s.mode&73))throw ee("amp_setup_failed")}catch(s){if(s?.code!=="ENOENT")throw s}return n}function re(e,t){return{id:Ze,available:!1,version:e,reason:t,project:null}}function vo(e){return!e||typeof e!="object"?null:{id:String(e.id||"").slice(0,160),name:String(e.name||e.slug||"").slice(0,200),repository:String(e.repositoryURL||e.repository||e.repo||e.repositoryUrl||"").slice(0,500)}}async function tt({cwd:e,executable:t="amp",run:n=Z,signal:r}={}){let o=(l,f=1e4)=>n({cmd:t,args:l,cwd:e,timeoutMs:f,heartbeatMs:0,label:"checking Amp",signal:r}),s=await o(["version"],5e3);if(s?.status!==0){let l=Re(s);return re("",l.code)}let i=String(s.stdout||s.stderr||"").trim().split(/\r?\n/).at(-1)?.slice(0,120)||"",a=await o(["--help"],5e3),d=`${a?.stdout||""}
|
|
37
|
+
${a?.stderr||""}`;if(a?.status!==0||!/--stream-json/.test(d)||!/threads[\s\S]*continue/i.test(d)||!/\borb\b/i.test(d))return re(i,"amp_version_unsupported");let c=await o(["usage"]);if(c?.status!==0){let l=Re(c);return re(i,l.code)}let u=await o(["projects","status","--json"]);if(u?.status!==0){let l=Re(u);return re(i,l.code)}let p;try{p=JSON.parse(String(u.stdout||""))}catch{return re(i,"amp_version_unsupported")}return["forbidden","permission_denied","access_denied"].includes(String(p?.status||"").toLowerCase())?re(i,"amp_project_forbidden"):p?.status==="unmatched"?re(i,"amp_project_unmatched"):p?.status!=="matched"||!p?.project?re(i,"amp_project_not_found"):{id:Ze,available:!0,version:i,reason:null,project:vo(p.project)}}function fn(e){let t=Re(e);return ee(t.code,t.detail)}function hn(e={}){let{runJob:t}=e,n=Math.max(1,Number(e.concurrency)||1),r=new Map,o=0,s=[];function i(w){let b=r.get(w);return b||(b={queued:[],active:null},r.set(w,b)),b}function a(w){if(w==null)return!1;for(let b of r.values())if(b.active&&!b.active.cancelled&&b.active.job.key===w||b.queued.some(k=>k.key===w))return!0;return!1}function d(){for(let[w,b]of r){if(o>=n)break;if(b.active||b.queued.length===0)continue;let k=b.queued.shift(),E=new AbortController;b.active={job:k,controller:E,cancelled:!1},o+=1,Promise.resolve().then(()=>E.signal.aborted?void 0:t(k,{signal:E.signal})).catch(()=>{}).finally(()=>{b.active=null,o-=1,b.queued.length===0&&!b.active&&r.delete(w),d(),c()})}}function c(){if(o>0)return;for(let b of r.values())if(b.queued.length)return;let w=s;s=[];for(let b of w)b()}function u(w){if(w&&w.key!=null&&a(w.key))return{accepted:!1,deduped:!0,position:0,startedImmediately:!1};let b=w&&w.lane!=null?String(w.lane):"",k=i(b),E=!k.active&&k.queued.length===0&&o<n;k.queued.push(w);let v=k.queued.length+(k.active?1:0);return d(),{accepted:!0,deduped:!1,position:v,startedImmediately:E}}function p(w,b){let k=!1;for(let[E,v]of r)b!=null&&E!==String(b)||v.active&&(v.active.cancelled=!0,v.active.controller.abort(w||"cancelled"),k=!0);return k}function l(w,b){if(w==null)return!1;let k=!1;for(let[E,v]of[...r]){v.active?.job?.key===w&&(v.active.cancelled=!0,v.active.controller.abort(b||"cancelled"),k=!0);let $=v.queued.length;v.queued=v.queued.filter(T=>T.key!==w),v.queued.length!==$&&(k=!0),!v.active&&v.queued.length===0&&r.delete(E)}return c(),k}function f(){let w=0;for(let b of r.values())w+=b.queued.length;return w}function S(){return o}function g(){return o===0&&f()===0?Promise.resolve():new Promise(w=>s.push(w))}return{enqueue:u,cancel:l,cancelActive:p,has:a,size:f,active:S,idle:g}}import _n from"node:crypto";import ko from"node:http";import vn from"node:os";import oe from"node:process";var gn=8787,nt="claude-haiku-4-5",Eo=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/,Ao=100,xo=new Set(["say","wave","hush","open","choose"]),Pe="x-agensis-bridge-secret";function Io(){return`cbs_${_n.randomBytes(24).toString("base64url")}`}function Co(e){let t=e?.headers||{},n=String(t[Pe]||t[Pe.toLowerCase()]||"").trim();if(n)return n;let o=String(t.authorization||t.Authorization||"").trim().match(/^Bearer\s+(.+)$/i);return o?o[1].trim():""}function To(e,t){let n=String(t||""),r=Co(e);if(!n||!r)return!1;let o=Buffer.from(r),s=Buffer.from(n);return o.length!==s.length?!1:_n.timingSafeEqual(o,s)}function Mo(e={},t={}){let n=String(t.authSecret||"").trim();if(n)return n;let r=String(e.cursorBuddyBridgeSecret||"").trim();if(r)return r;let o=String(oe.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim();return o||Io()}function $o(e,t){return e==="OPTIONS"||e==="GET"&&t==="/cursorbuddy/health"}function F(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 yn(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 W(e,t){e.write(`data: ${typeof t=="string"?t:JSON.stringify(t)}
|
|
38
38
|
|
|
39
39
|
`)}function ve(e){return new Promise((t,n)=>{let r="";e.on("data",o=>{r+=o,r.length>256*1024&&(n(new Error("request body is too large")),e.destroy())}),e.on("error",n),e.on("end",()=>t(r))})}function No(e){let t=[],n="",r="",o=!1;for(let s of String(e||"")){if(o){n+=s,o=!1;continue}if(s==="\\"){o=!0;continue}if(r){s===r?r="":n+=s;continue}if(s==='"'||s==="'"){r=s;continue}if(/\s/.test(s)){n&&(t.push(n),n="");continue}n+=s}if(n&&t.push(n),!t.length)throw new Error("coding command is empty");return{cmd:t[0],args:t.slice(1)}}function Oo(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function De(e,t){return e.some(n=>n===t||String(n).startsWith(`${t}=`))}function Sn(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 o=String(r?.role||"user"),s=String(r?.content||"");s.trim()&&n.push(`${o.toUpperCase()}:
|
|
40
40
|
${s}`)}return n.join(`
|
|
41
41
|
|
|
42
|
-
`).trim()||"Say that the local Agensis runtime is connected."}function wn(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 Ro(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 o=String(r?.content||"").trim();if(o)return o}return""}function Do(e,t=280){let n=Ro(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 o of r){let s=n.match(o);if(s?.[0])return s[0].trim()}return n.slice(-t).trim()}function Bo(e){let t=Do(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 Po(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 kn(e,t){let n=String(e||"").trim();return!n||Po(n)?t:n}function En(e){let t=String(e||"").trim();return!t||t==="haiku-4.5"||t==="claude-haiku-4.5"?nt:t}function rt(e={}){return En(e.cursorBuddyModel||oe.env.AGENSIS_CURSORBUDDY_MODEL||nt)}function bn(e,t,n,r={}){let{cmd:o,args:s}=No(e.codingCmd||"claude -p"),i=[...s],a=En(kn(n,rt(e))),d="",c=!1;return Oo(o)?(a&&!De(i,"--model")&&i.push("--model",a),r.stream===!0&&!De(i,"--output-format")?(i.push("--output-format","stream-json","--include-partial-messages"),De(i,"--verbose")||i.push("--verbose"),c=!0):(De(i,"--output-format")||i.push("--output-format","json"),c=i.some(
|
|
43
|
-
`))>=0;)d(t.slice(0,u)),t=t.slice(u+1)},end(){t&&(d(t),t="")},get live(){return r?n:o},get result(){return s??(r?n:o)}}}function ge(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 Be(e){return`http://127.0.0.1:${e}`}function Uo(e={},t={}){return String(t.agensisUrl||t.baseUrl||e.url||oe.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function jo(e){return String(e||"").slice(0,18)}function j(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Fo(e={},t={},n={}){let r=j(e.metadata)||{},o=j(e.page)||j(r.page)||{},s=j(e.client)||j(r.client)||{},i=j(r.runtime)||{},a=j(e.manifest)||j(r.manifest)||null;return{url:String(e.url||o.url||r.websiteSource||e.websiteSource||"").slice(0,2048),title:String(e.title||o.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:o,client:s,project:j(e.project)||j(r.project)||null,manifest:a,selection:j(e.selection)||null,updatedAt:new Date().toISOString()}}function Go(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function Ho(e,t={},n=globalThis.fetch){let r=String(t.key||"").trim();if(!Eo.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 o=Uo(e,t),s=await n(`${o}/backend/cursorbuddy/connection-keys/claim`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({key:r,baseUrl:o,host:vn.hostname(),cwd:t.cwd||e.cwd||oe.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||oe.env.npm_package_version||"",permissionMode:t.permissionMode||e.permissionMode,model:t.model||e.model,metadata:j(t.metadata)||null,websiteSource:t.websiteSource||t.metadata?.websiteSource||"",page:j(t.page)||j(t.metadata?.page)||null,client:j(t.client)||j(t.metadata?.client)||null,manifest:j(t.manifest)||j(t.metadata?.manifest)||null})}),i=await s.json().catch(()=>({}));if(!s.ok)throw new Error(Go(s,i));return{key:r,baseUrl:o,data:i?.data||i}}async function An(e,t={}){let n=Number(t.port??e.cursorBuddyPort??oe.env.AGENSIS_CURSORBUDDY_PORT??gn),r=Mo(e,t),o=new Date().toISOString(),s=[],i=[],a=new Set,d=t.fetchImpl||globalThis.fetch,c=1,u=null,f=n,l=null,h=(m,S={})=>{let I={ts:new Date().toISOString(),event:m,detail:S};return s.push(I),s.length>200&&s.shift(),t.log?.(`CursorBuddy local bridge: ${m}${Object.keys(S).length?` ${JSON.stringify(S)}`:""}`),I},y=()=>({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()}),p=()=>{if(typeof t.connectionProvider!="function")return null;try{let m=t.connectionProvider();return!m||typeof m!="object"||Array.isArray(m)?null:{...y(),...m,connected:m.connected===!0}}catch{return null}},b=()=>{let m=p();return m?.connected===!1?m:l?{...y(),...m||{},...l,connected:!0,updatedAt:m?.updatedAt||l.updatedAt}:m||y()};function w(m={}){if(!m||typeof m!="object"||Array.isArray(m))return null;let S=String(m.action||m.type||"").trim().toLowerCase();if(!xo.has(S))return null;let I={id:c++,ts:new Date().toISOString(),action:S,text:String(m.text||m.say||m.message||"").slice(0,1200),label:String(m.label||"").slice(0,80),value:String(m.value||m.prompt||"").slice(0,1200),holdMs:Number.isFinite(m.holdMs)?Math.max(0,Math.min(6e4,m.holdMs)):void 0,source:String(m.source||"agensis-daemon").slice(0,80)};return m.options&&Array.isArray(m.options)&&(I.options=m.options.map(g=>({label:String(g?.label||"").slice(0,80),value:String(g?.value||g?.task||"").slice(0,1200)})).filter(g=>g.label).slice(0,6)),I}function k(m){for(i.push(m);i.length>Ao;)i.shift();h("control",{id:m.id,action:m.action,chars:m.text.length});for(let S of[...a])try{W(S,{type:"command",command:m})}catch{a.delete(S)}return m}function v(m){let S=Bo(m);if(S){let I=w(S.command);return I&&(k(I),h("chat_control",{id:I.id,action:I.action})),{content:S.content,model:"cursorbuddy-local-control",fast:!0}}return null}async function E(m){let S=v(m);if(S)return S;let I=Sn(m?.messages,u),g=bn(e,I,m?.model),A=await Z({cmd:g.cmd,args:g.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:g.stdin});if(A.error||A.status!==0)throw new Error(A.error?.message||String(A.stderr||"").trim()||`Command exited with status ${A.status}`);return{content:wn(A.stdout||A.stderr),model:g.model}}async function $(m,S){let I=`agensis-cursorbuddy-${Date.now()}`,g=v(m);if(g){let x=g.model||"cursorbuddy-local-control";return W(S,ge(I,x,g.content)),W(S,ge(I,x,"","stop")),W(S,"[DONE]"),h("chat_fast",{chars:g.content.length,model:x}),{content:g.content,model:x,fast:!0}}let A=Sn(m?.messages,u),C=bn(e,A,m?.model,{stream:!0}),O="",V=x=>{x&&(O+=x,W(S,ge(I,C.model||e.model,x)))},P=C.streamJson?Lo(V):null,J=await Z({cmd:C.cmd,args:C.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:C.stdin,onData:x=>{if(P)P.feed(x);else{let D=String(x||"");O+=D,W(S,ge(I,C.model||e.model,D))}}});if(P){P.end();let x=P.result||"";!O&&x?V(x):O=x||O}if(J.error||J.status!==0){let x=J.error?.message||String(J.stderr||"").trim()||`Command exited with status ${J.status}`;throw new Error(x)}let X=P?O:wn(O||J.stdout||J.stderr);return!P&&X&&X!==O&&(W(S,ge(I,C.model||e.model,X)),O=X),W(S,ge(I,C.model||e.model,"","stop")),W(S,"[DONE]"),{content:O||X,model:C.model}}let M=ko.createServer(async(m,S)=>{if(S.setHeader("access-control-allow-origin","*"),S.setHeader("access-control-allow-methods","GET, POST, OPTIONS"),S.setHeader("access-control-allow-headers","content-type, authorization, x-agensis-bridge-secret"),m.method==="OPTIONS"){S.writeHead(204),S.end();return}let I=new URL(m.url||"/",Be(f||gn));if(!$o(m.method,I.pathname)&&!To(m,r)){F(S,401,{ok:!1,error:"Authentication required",code:"bridge_auth_required"});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/health"){let g=Be(f);F(S,200,{ok:!0,runtime:"agensis-cli",backend:e.codingCmd,model:rt(e),daemonModel:e.model,port:f,host:vn.hostname(),pid:oe.pid,bootedAt:o,authRequired:!0,authHeader:Pe,stream:!0,streaming:!0,supportsStreaming:!0,chatStream:!0,capabilities:{chatStream:!0,controlStream:!0,fastAvatarReplies:!1,nativeCursorBuddyControl:!0},latestControlId:i.at(-1)?.id||0,connection:b(),context:u,endpoints:{chat:`${g}/v1/chat/completions`,chatStream:`${g}/v1/chat/completions`,edit:`${g}/cursorbuddy/edit`,context:`${g}/cursorbuddy/context`,control:`${g}/cursorbuddy/control`,controlStream:`${g}/cursorbuddy/control/stream`,logs:`${g}/cursorbuddy/logs`}});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/logs"){F(S,200,{ok:!0,events:s.slice(-100)});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/context"){F(S,200,{ok:!0,context:u});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/control"){let g=Number(I.searchParams.get("after")||0),A=i.filter(C=>C.id>g);F(S,200,{ok:!0,commands:A,latestId:i.at(-1)?.id||0});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/control/stream"){let g=Number(I.searchParams.get("after")||0);yn(S),a.add(S),W(S,{type:"ready",latestId:i.at(-1)?.id||0});for(let C of i.filter(O=>O.id>g))W(S,{type:"command",command:C});let A=setInterval(()=>{try{W(S,{type:"ping",ts:new Date().toISOString()})}catch{a.delete(S),clearInterval(A)}},15e3);A.unref&&A.unref(),m.on("close",()=>{a.delete(S),clearInterval(A)});return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/control"){try{let g=JSON.parse(await ve(m)||"{}"),A=w(g);if(!A){F(S,400,{ok:!1,error:"unsupported CursorBuddy control command"});return}let C=k(A);F(S,200,{ok:!0,command:C})}catch(g){h("control_error",{error:String(g?.message||g)}),F(S,400,{ok:!1,error:String(g?.message||g)})}return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/context"){try{let g=JSON.parse(await ve(m)||"{}");u={url:String(g.url||"").slice(0,2048),title:String(g.title||"").slice(0,300),surface:String(g.surface||"").slice(0,80),instanceId:String(g.instanceId||"").slice(0,140),workspaceId:String(g.workspaceId||e.workspace||"").slice(0,120),agentId:String(g.agentId||e.agent||"").slice(0,120),runtime:g.runtime&&typeof g.runtime=="object"?g.runtime:null,page:g.page&&typeof g.page=="object"?g.page:null,client:g.client&&typeof g.client=="object"?g.client:null,project:g.project&&typeof g.project=="object"?g.project:null,manifest:g.manifest&&typeof g.manifest=="object"?g.manifest:null,selection:g.selection&&typeof g.selection=="object"?g.selection:null,updatedAt:new Date().toISOString()},h("context",{url:u.url,surface:u.surface,instanceId:u.instanceId}),F(S,200,{ok:!0,context:u})}catch(g){h("context_error",{error:String(g?.message||g)}),F(S,400,{ok:!1,error:String(g?.message||g)})}return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/connect"){try{let g=JSON.parse(await ve(m)||"{}"),A=await Ho(e,g,d),C=A.data||{};l={connected:!0,mode:"agensis-claimed",keyId:jo(A.key),agentId:String(C.agentId||C.agent?.id||e.agent||""),workspaceId:String(C.workspaceId||C.workspace_id||C.agent?.workspace_id||e.workspace||""),agensisUrl:A.baseUrl,handle:String(C.handle||C.agent?.handle||e.handle||""),name:String(C.agent?.name||g.name||e.name||"CursorBuddy runtime"),cwd:String(g.cwd||e.cwd||oe.cwd()),surface:String(g.surface||"browser_extension"),command:String(C.command||C.localCommand||""),updatedAt:new Date().toISOString()},u=Fo(g,l,e),h("connect",{mode:l.mode,keyId:l.keyId,agentId:l.agentId,workspaceId:l.workspaceId,url:u.url}),F(S,200,{ok:!0,connection:l,claim:C})}catch(g){h("connect_error",{error:String(g?.message||g)}),F(S,400,{ok:!1,error:String(g?.message||g)})}return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/edit"){try{let g=JSON.parse(await ve(m)||"{}"),A=[{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(g,null,2)}];h("edit_request",{selector:g?.target?.selector||""});let C=await E({messages:A,model:g?.model});h("edit_done",{chars:C.content.length}),F(S,200,{ok:!0,backend:e.codingCmd,cwd:e.cwd,content:C.content})}catch(g){h("edit_error",{error:String(g?.message||g)}),F(S,500,{ok:!1,error:String(g?.message||g)})}return}if(m.method==="POST"&&I.pathname.endsWith("/chat/completions")){try{let g=JSON.parse(await ve(m)||"{}");if(h("chat_request",{messages:Array.isArray(g.messages)?g.messages.length:0,model:kn(g.model,rt(e))}),g.stream===!0){yn(S);let C=await $(g,S);h("chat_done",{chars:C.content.length,stream:!0,fast:C.fast===!0}),S.end();return}let A=await E(g);h("chat_done",{chars:A.content.length,fast:A.fast===!0}),F(S,200,{id:`agensis-cursorbuddy-${Date.now()}`,object:"chat.completion",model:A.model||g.model||e.model,choices:[{index:0,message:{role:"assistant",content:A.content},finish_reason:"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}catch(g){h("chat_error",{error:String(g?.message||g)}),F(S,500,{error:{message:String(g?.message||g)}})}return}S.writeHead(404),S.end("CursorBuddy local bridge")});return await new Promise((m,S)=>{M.once("error",S),M.listen(n,"127.0.0.1",()=>{f=M.address().port,M.off("error",S),m()})}),h("listening",{url:`${Be(f)}/cursorbuddy/health`}),{port:f,url:Be(f),secret:r,authHeader:Pe,close(){return new Promise(m=>M.close(()=>m()))},getContext(){return u}}}import ye from"node:fs/promises";import qo from"node:os";import Y from"node:path";var xn=200,In=256*1024,Jo=2,zo=new Set([".md",".markdown",".txt"]);function Ko(e){return String(e||"").replace(/[^a-zA-Z0-9]/g,"-")}function ot({cwd:e,memoryDir:t,homedir:n=qo.homedir()}={}){let r=String(t||"").trim();if(r)return r.startsWith("~")?Y.join(n,r.slice(1)):Y.resolve(r);let o=String(e||"").trim();return o?Y.join(n,".claude","projects",Ko(o),"memory"):null}async function st(e){if(!e)return null;try{let t=await ye.realpath(e);return(await ye.stat(t)).isDirectory()?t:null}catch{return null}}async function Wo(e,t){if(!e)throw new Error("memory root unavailable");let n=Y.isAbsolute(String(t))?String(t):Y.join(e,String(t)),r=await ye.realpath(n),o=e.endsWith(Y.sep)?e:e+Y.sep;if(r!==e&&!r.startsWith(o))throw new Error(`path escapes memory root: ${t}`);return r}function Yo(e){let t=Y.basename(e).toLowerCase();return t==="memory.md"?"index":t==="claude.md"?"instructions":"memory"}async function it(e,t,n,r){if(n>Jo||r.length>=xn)return;let o;try{o=await ye.readdir(t,{withFileTypes:!0})}catch{return}for(let s of o){if(r.length>=xn)break;if(s.name.startsWith("."))continue;let i=Y.join(t,s.name);if(s.isDirectory())await it(e,i,n+1,r);else if(s.isFile()&&zo.has(Y.extname(s.name).toLowerCase())){let a=Y.relative(e,i);r.push({path:a,kind:Yo(a)})}}}async function Vo(e){let t=await st(e);if(!t)return[];let n=[];return await it(t,t,0,n),n.sort((r,o)=>r.kind==="index"?-1:o.kind==="index"?1:r.path.localeCompare(o.path)),n}async function Xo(e,t){let n=await st(e),r=await Wo(n,t),o=await ye.readFile(r),s=o.length>In;return{content:o.subarray(0,In).toString("utf8"),byteSize:o.length,truncated:s}}async function Cn(e){let t=await st(e);if(!t)return"";let n=[];await it(t,t,0,n),n.sort((o,s)=>o.path.localeCompare(s.path));let r=[];for(let o of n)try{let s=await ye.stat(Y.join(t,o.path));r.push(`${o.path}:${s.size}:${Math.floor(s.mtimeMs)}`)}catch{}return r.join("|")}async function Tn(e){let t=await Vo(e),n=[];for(let r of t)try{let{content:o,byteSize:s}=await Xo(e,r.path);n.push({path:r.path,kind:r.kind,content:o,byteSize:s})}catch{}return n}import ct from"node:fs";import se from"node:path";import Mn from"node:os";function Qo(e){try{return ct.statSync(e).isDirectory()}catch{return!1}}function Zo(e){try{return ct.statSync(e).isFile()}catch{return!1}}function at(e){try{return ct.readdirSync(e,{withFileTypes:!0})}catch{return[]}}function $n({home:e=Mn.homedir(),cwd:t=process.cwd()}={}){let n=[e&&se.join(e,".claude","commands"),t&&se.join(t,".claude","commands")].filter(Boolean),r=new Set,o=[],s=(i,a)=>{if(!i)return;let d=a?`${a}:${i}`:i;r.has(d)||(r.add(d),o.push({name:i,parent:a||null}))};for(let i of n)for(let a of at(i)){if(a.name.startsWith("."))continue;if(a.name.endsWith(".md")){s(a.name.slice(0,-3),null);continue}let d=se.join(i,a.name);if(a.isDirectory()||a.isSymbolicLink()&&Qo(d))for(let c of at(d))c.name.startsWith(".")||c.name.endsWith(".md")&&s(c.name.slice(0,-3),a.name)}return o}function ut({home:e=Mn.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 Map,o=(s,i)=>{!s||r.has(s)||r.set(s,{name:s,file:i||""})};for(let s of n)for(let i of at(s)){if(i.name.startsWith("."))continue;let a=se.join(s,i.name);if(i.name.endsWith(".md"))o(i.name.slice(0,-3),a);else if(i.isDirectory()||i.isSymbolicLink()){let d=se.join(a,"SKILL.md");o(i.name,Zo(d)?d:"")}}return[...r.values()].sort((s,i)=>s.name<i.name?-1:s.name>i.name?1:0)}function Nn(e={}){return ut(e).map(t=>t.name)}import lt from"node:fs/promises";var Se=64*1024,es=200,Rn=4*1024*1024,ts=2e3,ns=512;function On(e,t,n=Se){let r=`
|
|
42
|
+
`).trim()||"Say that the local Agensis runtime is connected."}function wn(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 Ro(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 o=String(r?.content||"").trim();if(o)return o}return""}function Do(e,t=280){let n=Ro(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 o of r){let s=n.match(o);if(s?.[0])return s[0].trim()}return n.slice(-t).trim()}function Bo(e){let t=Do(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 Po(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 kn(e,t){let n=String(e||"").trim();return!n||Po(n)?t:n}function En(e){let t=String(e||"").trim();return!t||t==="haiku-4.5"||t==="claude-haiku-4.5"?nt:t}function rt(e={}){return En(e.cursorBuddyModel||oe.env.AGENSIS_CURSORBUDDY_MODEL||nt)}function bn(e,t,n,r={}){let{cmd:o,args:s}=No(e.codingCmd||"claude -p"),i=[...s],a=En(kn(n,rt(e))),d="",c=!1;return Oo(o)?(a&&!De(i,"--model")&&i.push("--model",a),r.stream===!0&&!De(i,"--output-format")?(i.push("--output-format","stream-json","--include-partial-messages"),De(i,"--verbose")||i.push("--verbose"),c=!0):(De(i,"--output-format")||i.push("--output-format","json"),c=i.some(p=>String(p).includes("stream-json"))),d=t):i.push(t),{cmd:o,args:i,model:a,stdin:d,streamJson:c}}function Lo(e=()=>{}){let t="",n="",r=!1,o="",s=null,i=c=>{c&&e(c)},a=c=>{if(!c||typeof c!="object")return;let u=c.event&&c.event.delta||c.delta;if(u&&u.type==="text_delta"&&typeof u.text=="string"){r=!0,n+=u.text,i(u.text);return}if(c.type==="result"&&typeof c.result=="string"){s=c.result;return}if(c.type==="assistant"&&c.message&&Array.isArray(c.message.content)){let p=c.message.content.filter(l=>l&&l.type==="text"&&typeof l.text=="string").map(l=>l.text).join("");p&&(o+=p)}},d=c=>{let u=String(c).trim();if(u)try{a(JSON.parse(u))}catch{}};return{feed(c){t+=String(c||"");let u;for(;(u=t.indexOf(`
|
|
43
|
+
`))>=0;)d(t.slice(0,u)),t=t.slice(u+1)},end(){t&&(d(t),t="")},get live(){return r?n:o},get result(){return s??(r?n:o)}}}function ge(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 Be(e){return`http://127.0.0.1:${e}`}function Uo(e={},t={}){return String(t.agensisUrl||t.baseUrl||e.url||oe.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function jo(e){return String(e||"").slice(0,18)}function j(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:null}function Fo(e={},t={},n={}){let r=j(e.metadata)||{},o=j(e.page)||j(r.page)||{},s=j(e.client)||j(r.client)||{},i=j(r.runtime)||{},a=j(e.manifest)||j(r.manifest)||null;return{url:String(e.url||o.url||r.websiteSource||e.websiteSource||"").slice(0,2048),title:String(e.title||o.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:o,client:s,project:j(e.project)||j(r.project)||null,manifest:a,selection:j(e.selection)||null,updatedAt:new Date().toISOString()}}function Go(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function Ho(e,t={},n=globalThis.fetch){let r=String(t.key||"").trim();if(!Eo.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 o=Uo(e,t),s=await n(`${o}/backend/cursorbuddy/connection-keys/claim`,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({key:r,baseUrl:o,host:vn.hostname(),cwd:t.cwd||e.cwd||oe.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||oe.env.npm_package_version||"",permissionMode:t.permissionMode||e.permissionMode,model:t.model||e.model,metadata:j(t.metadata)||null,websiteSource:t.websiteSource||t.metadata?.websiteSource||"",page:j(t.page)||j(t.metadata?.page)||null,client:j(t.client)||j(t.metadata?.client)||null,manifest:j(t.manifest)||j(t.metadata?.manifest)||null})}),i=await s.json().catch(()=>({}));if(!s.ok)throw new Error(Go(s,i));return{key:r,baseUrl:o,data:i?.data||i}}async function An(e,t={}){let n=Number(t.port??e.cursorBuddyPort??oe.env.AGENSIS_CURSORBUDDY_PORT??gn),r=Mo(e,t),o=new Date().toISOString(),s=[],i=[],a=new Set,d=t.fetchImpl||globalThis.fetch,c=1,u=null,p=n,l=null,f=(m,y={})=>{let I={ts:new Date().toISOString(),event:m,detail:y};return s.push(I),s.length>200&&s.shift(),t.log?.(`CursorBuddy local bridge: ${m}${Object.keys(y).length?` ${JSON.stringify(y)}`:""}`),I},S=()=>({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()}),g=()=>{if(typeof t.connectionProvider!="function")return null;try{let m=t.connectionProvider();return!m||typeof m!="object"||Array.isArray(m)?null:{...S(),...m,connected:m.connected===!0}}catch{return null}},w=()=>{let m=g();return m?.connected===!1?m:l?{...S(),...m||{},...l,connected:!0,updatedAt:m?.updatedAt||l.updatedAt}:m||S()};function b(m={}){if(!m||typeof m!="object"||Array.isArray(m))return null;let y=String(m.action||m.type||"").trim().toLowerCase();if(!xo.has(y))return null;let I={id:c++,ts:new Date().toISOString(),action:y,text:String(m.text||m.say||m.message||"").slice(0,1200),label:String(m.label||"").slice(0,80),value:String(m.value||m.prompt||"").slice(0,1200),holdMs:Number.isFinite(m.holdMs)?Math.max(0,Math.min(6e4,m.holdMs)):void 0,source:String(m.source||"agensis-daemon").slice(0,80)};return m.options&&Array.isArray(m.options)&&(I.options=m.options.map(h=>({label:String(h?.label||"").slice(0,80),value:String(h?.value||h?.task||"").slice(0,1200)})).filter(h=>h.label).slice(0,6)),I}function k(m){for(i.push(m);i.length>Ao;)i.shift();f("control",{id:m.id,action:m.action,chars:m.text.length});for(let y of[...a])try{W(y,{type:"command",command:m})}catch{a.delete(y)}return m}function E(m){let y=Bo(m);if(y){let I=b(y.command);return I&&(k(I),f("chat_control",{id:I.id,action:I.action})),{content:y.content,model:"cursorbuddy-local-control",fast:!0}}return null}async function v(m){let y=E(m);if(y)return y;let I=Sn(m?.messages,u),h=bn(e,I,m?.model),A=await Z({cmd:h.cmd,args:h.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:h.stdin});if(A.error||A.status!==0)throw new Error(A.error?.message||String(A.stderr||"").trim()||`Command exited with status ${A.status}`);return{content:wn(A.stdout||A.stderr),model:h.model}}async function $(m,y){let I=`agensis-cursorbuddy-${Date.now()}`,h=E(m);if(h){let x=h.model||"cursorbuddy-local-control";return W(y,ge(I,x,h.content)),W(y,ge(I,x,"","stop")),W(y,"[DONE]"),f("chat_fast",{chars:h.content.length,model:x}),{content:h.content,model:x,fast:!0}}let A=Sn(m?.messages,u),C=bn(e,A,m?.model,{stream:!0}),O="",V=x=>{x&&(O+=x,W(y,ge(I,C.model||e.model,x)))},P=C.streamJson?Lo(V):null,J=await Z({cmd:C.cmd,args:C.args,cwd:e.cwd,timeoutMs:Math.min(Number(e.timeoutMs||18e5),5*60*1e3),heartbeatMs:e.heartbeatMs,label:"cursorbuddy local chat",input:C.stdin,onData:x=>{if(P)P.feed(x);else{let D=String(x||"");O+=D,W(y,ge(I,C.model||e.model,D))}}});if(P){P.end();let x=P.result||"";!O&&x?V(x):O=x||O}if(J.error||J.status!==0){let x=J.error?.message||String(J.stderr||"").trim()||`Command exited with status ${J.status}`;throw new Error(x)}let X=P?O:wn(O||J.stdout||J.stderr);return!P&&X&&X!==O&&(W(y,ge(I,C.model||e.model,X)),O=X),W(y,ge(I,C.model||e.model,"","stop")),W(y,"[DONE]"),{content:O||X,model:C.model}}let T=ko.createServer(async(m,y)=>{if(y.setHeader("access-control-allow-origin","*"),y.setHeader("access-control-allow-methods","GET, POST, OPTIONS"),y.setHeader("access-control-allow-headers","content-type, authorization, x-agensis-bridge-secret"),m.method==="OPTIONS"){y.writeHead(204),y.end();return}let I=new URL(m.url||"/",Be(p||gn));if(!$o(m.method,I.pathname)&&!To(m,r)){F(y,401,{ok:!1,error:"Authentication required",code:"bridge_auth_required"});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/health"){let h=Be(p);F(y,200,{ok:!0,runtime:"agensis-cli",backend:e.codingCmd,model:rt(e),daemonModel:e.model,port:p,host:vn.hostname(),pid:oe.pid,bootedAt:o,authRequired:!0,authHeader:Pe,stream:!0,streaming:!0,supportsStreaming:!0,chatStream:!0,capabilities:{chatStream:!0,controlStream:!0,fastAvatarReplies:!1,nativeCursorBuddyControl:!0},latestControlId:i.at(-1)?.id||0,connection:w(),context:u,endpoints:{chat:`${h}/v1/chat/completions`,chatStream:`${h}/v1/chat/completions`,edit:`${h}/cursorbuddy/edit`,context:`${h}/cursorbuddy/context`,control:`${h}/cursorbuddy/control`,controlStream:`${h}/cursorbuddy/control/stream`,logs:`${h}/cursorbuddy/logs`}});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/logs"){F(y,200,{ok:!0,events:s.slice(-100)});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/context"){F(y,200,{ok:!0,context:u});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/control"){let h=Number(I.searchParams.get("after")||0),A=i.filter(C=>C.id>h);F(y,200,{ok:!0,commands:A,latestId:i.at(-1)?.id||0});return}if(m.method==="GET"&&I.pathname==="/cursorbuddy/control/stream"){let h=Number(I.searchParams.get("after")||0);yn(y),a.add(y),W(y,{type:"ready",latestId:i.at(-1)?.id||0});for(let C of i.filter(O=>O.id>h))W(y,{type:"command",command:C});let A=setInterval(()=>{try{W(y,{type:"ping",ts:new Date().toISOString()})}catch{a.delete(y),clearInterval(A)}},15e3);A.unref&&A.unref(),m.on("close",()=>{a.delete(y),clearInterval(A)});return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/control"){try{let h=JSON.parse(await ve(m)||"{}"),A=b(h);if(!A){F(y,400,{ok:!1,error:"unsupported CursorBuddy control command"});return}let C=k(A);F(y,200,{ok:!0,command:C})}catch(h){f("control_error",{error:String(h?.message||h)}),F(y,400,{ok:!1,error:String(h?.message||h)})}return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/context"){try{let h=JSON.parse(await ve(m)||"{}");u={url:String(h.url||"").slice(0,2048),title:String(h.title||"").slice(0,300),surface:String(h.surface||"").slice(0,80),instanceId:String(h.instanceId||"").slice(0,140),workspaceId:String(h.workspaceId||e.workspace||"").slice(0,120),agentId:String(h.agentId||e.agent||"").slice(0,120),runtime:h.runtime&&typeof h.runtime=="object"?h.runtime:null,page:h.page&&typeof h.page=="object"?h.page:null,client:h.client&&typeof h.client=="object"?h.client:null,project:h.project&&typeof h.project=="object"?h.project:null,manifest:h.manifest&&typeof h.manifest=="object"?h.manifest:null,selection:h.selection&&typeof h.selection=="object"?h.selection:null,updatedAt:new Date().toISOString()},f("context",{url:u.url,surface:u.surface,instanceId:u.instanceId}),F(y,200,{ok:!0,context:u})}catch(h){f("context_error",{error:String(h?.message||h)}),F(y,400,{ok:!1,error:String(h?.message||h)})}return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/connect"){try{let h=JSON.parse(await ve(m)||"{}"),A=await Ho(e,h,d),C=A.data||{};l={connected:!0,mode:"agensis-claimed",keyId:jo(A.key),agentId:String(C.agentId||C.agent?.id||e.agent||""),workspaceId:String(C.workspaceId||C.workspace_id||C.agent?.workspace_id||e.workspace||""),agensisUrl:A.baseUrl,handle:String(C.handle||C.agent?.handle||e.handle||""),name:String(C.agent?.name||h.name||e.name||"CursorBuddy runtime"),cwd:String(h.cwd||e.cwd||oe.cwd()),surface:String(h.surface||"browser_extension"),command:String(C.command||C.localCommand||""),updatedAt:new Date().toISOString()},u=Fo(h,l,e),f("connect",{mode:l.mode,keyId:l.keyId,agentId:l.agentId,workspaceId:l.workspaceId,url:u.url}),F(y,200,{ok:!0,connection:l,claim:C})}catch(h){f("connect_error",{error:String(h?.message||h)}),F(y,400,{ok:!1,error:String(h?.message||h)})}return}if(m.method==="POST"&&I.pathname==="/cursorbuddy/edit"){try{let h=JSON.parse(await ve(m)||"{}"),A=[{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(h,null,2)}];f("edit_request",{selector:h?.target?.selector||""});let C=await v({messages:A,model:h?.model});f("edit_done",{chars:C.content.length}),F(y,200,{ok:!0,backend:e.codingCmd,cwd:e.cwd,content:C.content})}catch(h){f("edit_error",{error:String(h?.message||h)}),F(y,500,{ok:!1,error:String(h?.message||h)})}return}if(m.method==="POST"&&I.pathname.endsWith("/chat/completions")){try{let h=JSON.parse(await ve(m)||"{}");if(f("chat_request",{messages:Array.isArray(h.messages)?h.messages.length:0,model:kn(h.model,rt(e))}),h.stream===!0){yn(y);let C=await $(h,y);f("chat_done",{chars:C.content.length,stream:!0,fast:C.fast===!0}),y.end();return}let A=await v(h);f("chat_done",{chars:A.content.length,fast:A.fast===!0}),F(y,200,{id:`agensis-cursorbuddy-${Date.now()}`,object:"chat.completion",model:A.model||h.model||e.model,choices:[{index:0,message:{role:"assistant",content:A.content},finish_reason:"stop"}],usage:{prompt_tokens:0,completion_tokens:0,total_tokens:0}})}catch(h){f("chat_error",{error:String(h?.message||h)}),F(y,500,{error:{message:String(h?.message||h)}})}return}y.writeHead(404),y.end("CursorBuddy local bridge")});return await new Promise((m,y)=>{T.once("error",y),T.listen(n,"127.0.0.1",()=>{p=T.address().port,T.off("error",y),m()})}),f("listening",{url:`${Be(p)}/cursorbuddy/health`}),{port:p,url:Be(p),secret:r,authHeader:Pe,close(){return new Promise(m=>T.close(()=>m()))},getContext(){return u}}}import ye from"node:fs/promises";import qo from"node:os";import Y from"node:path";var xn=200,In=256*1024,Jo=2,zo=new Set([".md",".markdown",".txt"]);function Ko(e){return String(e||"").replace(/[^a-zA-Z0-9]/g,"-")}function ot({cwd:e,memoryDir:t,homedir:n=qo.homedir()}={}){let r=String(t||"").trim();if(r)return r.startsWith("~")?Y.join(n,r.slice(1)):Y.resolve(r);let o=String(e||"").trim();return o?Y.join(n,".claude","projects",Ko(o),"memory"):null}async function st(e){if(!e)return null;try{let t=await ye.realpath(e);return(await ye.stat(t)).isDirectory()?t:null}catch{return null}}async function Wo(e,t){if(!e)throw new Error("memory root unavailable");let n=Y.isAbsolute(String(t))?String(t):Y.join(e,String(t)),r=await ye.realpath(n),o=e.endsWith(Y.sep)?e:e+Y.sep;if(r!==e&&!r.startsWith(o))throw new Error(`path escapes memory root: ${t}`);return r}function Yo(e){let t=Y.basename(e).toLowerCase();return t==="memory.md"?"index":t==="claude.md"?"instructions":"memory"}async function it(e,t,n,r){if(n>Jo||r.length>=xn)return;let o;try{o=await ye.readdir(t,{withFileTypes:!0})}catch{return}for(let s of o){if(r.length>=xn)break;if(s.name.startsWith("."))continue;let i=Y.join(t,s.name);if(s.isDirectory())await it(e,i,n+1,r);else if(s.isFile()&&zo.has(Y.extname(s.name).toLowerCase())){let a=Y.relative(e,i);r.push({path:a,kind:Yo(a)})}}}async function Vo(e){let t=await st(e);if(!t)return[];let n=[];return await it(t,t,0,n),n.sort((r,o)=>r.kind==="index"?-1:o.kind==="index"?1:r.path.localeCompare(o.path)),n}async function Xo(e,t){let n=await st(e),r=await Wo(n,t),o=await ye.readFile(r),s=o.length>In;return{content:o.subarray(0,In).toString("utf8"),byteSize:o.length,truncated:s}}async function Cn(e){let t=await st(e);if(!t)return"";let n=[];await it(t,t,0,n),n.sort((o,s)=>o.path.localeCompare(s.path));let r=[];for(let o of n)try{let s=await ye.stat(Y.join(t,o.path));r.push(`${o.path}:${s.size}:${Math.floor(s.mtimeMs)}`)}catch{}return r.join("|")}async function Tn(e){let t=await Vo(e),n=[];for(let r of t)try{let{content:o,byteSize:s}=await Xo(e,r.path);n.push({path:r.path,kind:r.kind,content:o,byteSize:s})}catch{}return n}import ct from"node:fs";import se from"node:path";import Mn from"node:os";function Qo(e){try{return ct.statSync(e).isDirectory()}catch{return!1}}function Zo(e){try{return ct.statSync(e).isFile()}catch{return!1}}function at(e){try{return ct.readdirSync(e,{withFileTypes:!0})}catch{return[]}}function $n({home:e=Mn.homedir(),cwd:t=process.cwd()}={}){let n=[e&&se.join(e,".claude","commands"),t&&se.join(t,".claude","commands")].filter(Boolean),r=new Set,o=[],s=(i,a)=>{if(!i)return;let d=a?`${a}:${i}`:i;r.has(d)||(r.add(d),o.push({name:i,parent:a||null}))};for(let i of n)for(let a of at(i)){if(a.name.startsWith("."))continue;if(a.name.endsWith(".md")){s(a.name.slice(0,-3),null);continue}let d=se.join(i,a.name);if(a.isDirectory()||a.isSymbolicLink()&&Qo(d))for(let c of at(d))c.name.startsWith(".")||c.name.endsWith(".md")&&s(c.name.slice(0,-3),a.name)}return o}function ut({home:e=Mn.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 Map,o=(s,i)=>{!s||r.has(s)||r.set(s,{name:s,file:i||""})};for(let s of n)for(let i of at(s)){if(i.name.startsWith("."))continue;let a=se.join(s,i.name);if(i.name.endsWith(".md"))o(i.name.slice(0,-3),a);else if(i.isDirectory()||i.isSymbolicLink()){let d=se.join(a,"SKILL.md");o(i.name,Zo(d)?d:"")}}return[...r.values()].sort((s,i)=>s.name<i.name?-1:s.name>i.name?1:0)}function Nn(e={}){return ut(e).map(t=>t.name)}import lt from"node:fs/promises";var Se=64*1024,es=200,Rn=4*1024*1024,ts=2e3,ns=512;function On(e,t,n=Se){let r=`
|
|
44
44
|
|
|
45
45
|
... [truncated by agensis-agent: ${t}]
|
|
46
|
-
`,o=Math.max(0,n-Buffer.byteLength(r));return`${Buffer.from(String(e||"")).subarray(0,o).toString("utf8").replace(/\uFFFD+$/,"")}${r}`}function rs(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 o=/^description:\s*(.*)$/i.exec(t[r]);if(!o)continue;let s=o[1].trim();if(s&&!/^[|>][-+]?$/.test(s)){n=s.replace(/^["']|["']$/g,"");break}let i=[];for(let a=r+1;a<t.length&&a<200&&!(t[a].trim()==="---"||t[a].trim()&&!/^\s/.test(t[a]));a+=1)i.push(t[a].trim());n=i.join(" ").trim();break}if(!n){let r=t.findIndex((i,a)=>a>0&&i.trim()==="---"),s=(t[0]?.trim()==="---"&&r>0?t.slice(r+1):t).find(i=>i.trim()&&i.trim()!=="---");n=String(s||"").replace(/^#+\s*/,"").trim()}return n.slice(0,ts)}function Dn(e){try{return ut(e).slice(0,es)}catch{return[]}}async function os(e){let t;try{t=await lt.open(e,"r")}catch{return null}try{let n=Buffer.alloc(Se+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 ss(e,t){let n=await os(e.file);if(!n)return null;let r=n.toString("utf8"),o=rs(r),s=n.length>Se,i=Math.min(Se,Math.max(0,t)),a=Buffer.byteLength(r)>i;if(!s&&!a)return{skill:e.name,path:e.file,summary:o,content:r,truncated:!1};let d=s?await is(e.file):0,c=s&&!a?`the file is ${d?`${d} bytes`:`over ${Se} bytes`}; only the first ${Se} were synced`:`this sync reached its ${Rn}-byte ceiling`,u=i<ns?On("",c,Number.MAX_SAFE_INTEGER):On(r,c,i);return{skill:e.name,path:e.file,summary:o,content:u,truncated:!0}}async function is(e){try{return(await lt.stat(e)).size}catch{return 0}}async function dt(e={}){let t=[];for(let n of Dn(e)){if(!n.file){t.push(`${n.name}:-`);continue}try{let r=await lt.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 Bn(e={}){let t=[],n=0;for(let r of Dn(e))if(r.file)try{let o=await ss(r,Rn-n);if(!o)continue;n+=Buffer.byteLength(o.content),t.push(o)}catch{}return t}import{readFile as as}from"node:fs/promises";var cs=new Set(["127.0.0.1","localhost","::1","[::1]"]);function Pn(e,t,n){let r=Number(e);return Number.isFinite(r)?Math.max(1,Math.min(n,Math.trunc(r))):t}function us(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(!cs.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(o=>String(o||"").trim().toLowerCase()).filter(Boolean))].slice(0,16),...e.contextWindow?{contextWindow:Pn(e.contextWindow,void 0,1e7)}:{},maxConcurrency:Pn(e.maxConcurrency,1,64),shared:!0}}async function Ln(e){if(!e)return[];let t=JSON.parse(await as(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(us).filter(Boolean)}function Un(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 jn({models:e,request:t,send:n,signal:r,fetchImpl:o=fetch,env:s=process.env}){let i=String(t?.requestId||"").trim();if(!i)throw new Error("Inference requestId is required.");let a=(Array.isArray(e)?e:[]).find(
|
|
47
|
-
`);s=d.pop()??"";for(let c of d){if(!c.trim())continue;let u;try{u=JSON.parse(c)}catch{continue}let
|
|
48
|
-
`),null},stop(){try{o.kill()}catch{}}}}async function Ss({bridgeId:e,externalId:t,emit:n,config:r}){let o=(await import("ws")).default,s=String(r?.gatewayUrl||"ws://127.0.0.1:18789"),i=String(r?.authToken||""),a=new o(s),d=1,c=new Map,u=(f,l)=>new Promise((h,y)=>{let p=String(d++);c.set(p,{resolve:h,reject:y}),a.send(JSON.stringify({type:"req",id:p,method:f,params:l})),setTimeout(()=>{c.has(p)&&(c.delete(p),y(new Error(`OpenClaw ${f} timed out`)))},3e4)});return a.on("open",()=>n({action:"bridge_status",bridgeId:e,status:"connecting"})),a.on("error",f=>n({action:"bridge_status",bridgeId:e,status:"error",error:`OpenClaw gateway: ${f?.message||f}`})),a.on("message",async f=>{let l;try{l=JSON.parse(String(f))}catch{return}if(l.type==="event"&&l.event==="connect.challenge"){try{await u("connect",{minProtocol:4,maxProtocol:4,client:{id:"agensis",version:"1",platform:process.platform,mode:"operator"},role:"operator",scopes:["operator.read","operator.write"],auth:{token:i},device:{id:`agensis-${e}`,nonce:l.payload?.nonce}}),await u("watch.subscribe",{}),n({action:"bridge_status",bridgeId:e,status:"connected"})}catch(h){n({action:"bridge_status",bridgeId:e,status:"error",error:String(h.message||h)})}return}if(l.type==="res"&&c.has(l.id)){let{resolve:h,reject:y}=c.get(l.id);c.delete(l.id),l.ok?h(l.payload):y(new Error(l.error?.message||"OpenClaw request failed"));return}if(l.method==="message"||l.event==="message"){let h=l.params||l.payload||{},y=String(h.chat_id??h.chatId??"");if(t&&y!==t||h.fromMe||h.outbound)return;let p=String(h.text??h.message??"");if(!p.trim())return;n({action:"bridge_inbound",bridgeId:e,externalMessageId:String(h.id??h.message_id??""),author:String(h.sender_name??h.author??"OpenClaw"),text:p,externalId:y})}}),{provider:"openclaw",async send(f,l){let h=l?`${l}: ${f}`:f,y=await u("send",{chat_id:t,text:h,idempotency_key:`agensis-${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`});return y?.id?String(y.id):null},stop(){try{a.close()}catch{}}}}var ws={whatsapp:Fn,signal:ys,openclaw:Ss};async function Gn(e,t){let n=String(e?.bridgeId||"");if(n){if(e.action==="bridge_stop"){we.get(n)?.stop?.(),we.delete(n);return}if(e.action==="bridge_start"){if(we.has(n))return;let r=ws[String(e.provider)];if(!r)return;try{let o=await r({bridgeId:n,externalId:String(e.externalId||""),config:e.config||{},account:e.account,emit:t});o&&we.set(n,o)}catch(o){t({action:"bridge_status",bridgeId:n,status:"error",error:String(o?.message||o)})}return}if(e.action==="bridge_send"){let r=we.get(n);if(!r){t({action:"bridge_status",bridgeId:n,status:"error",error:"This bridge is not running on this machine."});return}try{let o=await r.send(String(e.text||""),String(e.author||""));o&&t({action:"bridge_status",bridgeId:n,status:"connected",sentMessageId:o})}catch(o){t({action:"bridge_status",bridgeId:n,status:"error",error:String(o?.message||o)})}}}}je();var Ls=30*60*1e3,Us=15*1e3,sr=2,js=10*1024,Fs="claude-opus-4-8",ce="0.1.39";async function Ge(e={}){let t=Gs(e);t.sharedModels=t.share?await Ln(t.sharedModelsFile):[];let n=!1,r=null,o=null,s=null,i=null,a=0,d=null,c=null,u="",f=null,l=!1,h=null,y=new Map,p=Yt({send:x=>B(r,x),log:N}),b=[],w=x=>{b.length>=32&&b.shift(),b.push(x),N(`Socket was gone \u2014 parked the result for job ${x.jobId} to re-send on reconnect`)},k=()=>{if(b.length!==0)for(let x of b.splice(0,b.length))B(r,x)?N(`Re-sent the result for job ${x.jobId} after reconnecting`):b.push(x)},v=null,E={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"},$=new Map,M=new Map,m=[],S=()=>E,I=()=>({connected:l&&!!t.cursorBuddyRuntime,mode:t.cursorBuddyRuntime?"agensis-cli":"agensis-cli-unclaimed",agentId:h?.agentId||h?.agent_id||t.agent,workspaceId:h?.workspaceId||h?.workspace_id||t.workspace,agensisUrl:t.url,handle:h?.handle||t.handle,name:h?.name||t.name,cwd:t.cwd,updatedAt:new Date().toISOString()}),g=()=>{v||!t.lanListener||(v=new Ae.Server({port:0}),v.on("listening",()=>{let{port:x}=v.address();E={transport:"ws",listening:!0,addrs:gi(x),auth:"hub-pairwise"},N(`Agent-mesh LAN listener on port ${x}`),Ee(r,t,S())}),v.on("connection",x=>{let D=!1,_=setTimeout(()=>{if(!D)try{x.close(1008,"peer auth required")}catch{}},5e3);x.once("message",R=>{clearTimeout(_);let U=St(R),H=U?.type==="peer_auth"?$.get(U.ticket):null;if(!H||H.fromAgentId!==U.fromAgentId||Date.now()>H.exp){try{x.close(1008,"invalid ticket")}catch{}return}$.delete(U.ticket),D=!0,x.on("message",z=>{let L=St(z);L?.type==="agent_job"&&L.job?.id&&c.enqueue({...L.job,key:L.job.id,lane:ir(L.job),ws:r}).accepted&&N(`Queued peer-handoff job ${L.job.id} from ${U.fromAgentId}`)})})}),v.on("error",x=>N(`LAN listener error: ${x?.message||x}`)))},A=()=>{if(v){try{v.close()}catch{}v=null}E={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"}},C=x=>new Promise((D,_)=>{if(!B(r,{action:"peer_ticket_request",targetAgentId:x})){_(new Error("hub socket not open"));return}let R=M.get(x)||[];R.push({resolve:D,reject:_}),M.set(x,R),setTimeout(()=>{let U=M.get(x)||[],H=U.findIndex(z=>z.resolve===D);H>=0&&(U.splice(H,1),_(new Error("peer ticket request timed out")))},1e4)}),O=()=>new Promise((x,D)=>{if(!B(r,{action:"peer_list_request"})){D(new Error("hub socket not open"));return}m.push(x),setTimeout(()=>{let _=m.indexOf(x);_>=0&&(m.splice(_,1),x([]))},1e4)}),V=async(x,D)=>{let _=null;try{let U=(await O()).find(L=>L.agentId===x&&L.reach?.listening&&L.reach.addrs?.length);if(!U)return!1;let H=await C(x),z=H.peer?.addrs?.[0]||U.reach.addrs[0];return!z?.host||!z?.port?!1:(_=new Ae(`ws://${z.host}:${z.port}`),await new Promise((L,Ke)=>{_.once("open",L),_.once("error",Ke),setTimeout(()=>Ke(new Error("peer connect timed out")),5e3)}),B(_,{type:"peer_auth",ticket:H.ticket,fromAgentId:t.agent}),B(_,{type:"agent_job",job:D}),!0)}catch(R){return N(`Peer handoff to ${x} failed, falling back to hub relay: ${R?.message||R}`),!1}finally{try{_?.close()}catch{}}},P=()=>{n=!0,lr(y),p.shutdown("The agent daemon shut down before this was approved."),o&&clearTimeout(o),s&&clearInterval(s),i&&clearInterval(i),f&&(f.close().catch(()=>{}),f=null),A(),Xn(t,{status:"stopped",connected:!1});try{r?.close()}catch{}d&&d()};if(c=hn({concurrency:t.once?1:t.maxConcurrency,runJob:async(x,D)=>{await ri(t,x,{...D,requestPermission:p.request}),t.once&&P()}}),t.cursorBuddyBridge)try{f=await An(t,{port:t.cursorBuddyPort,authSecret:t.cursorBuddyBridgeSecret||void 0,log:N,connectionProvider:I}),f?.secret&&(t.cursorBuddyBridgeSecret=f.secret)}catch(x){if(wi(x)){let D=await bi(t.cursorBuddyPort);if(D?.ok){let _=D.pid?` pid ${D.pid}`:"";N(`CursorBuddy local bridge already running on http://127.0.0.1:${t.cursorBuddyPort}${_}`)}else N(`CursorBuddy local bridge port ${t.cursorBuddyPort} is in use but did not answer health`)}else N(`CursorBuddy local bridge unavailable: ${x?.message||x}`);f=null}T.once("SIGINT",P),T.once("SIGTERM",P);let J=()=>{if(n)return;let x=qs(t.url,t.token,t);u="",N(`Connecting to ${x.replace(t.token,"redacted")}`),r=new Ae(x),r.on("open",async()=>{l=!1,h=null,N(`Connected. Registering @${t.handle||"agent"} from ${t.cwd}`),B(r,{type:"auth",token:t.token});let D=await Zn(t);B(r,{action:"agent_register",workspaceId:t.workspace,agentId:t.agent,handle:t.handle,name:t.name,host:Ie.hostname(),cwd:t.cwd,...D?{identity:D}:{},metadata:{codingCmd:t.codingCmd,model:t.model,permissionMode:t.permissionMode,permissionFlags:vt(t.permissionMode),once:t.once,runtime:"agensis",executionRuntime:t.runtime,version:ce}}),s=setInterval(()=>{Promise.all([Sr(t,S()).catch(()=>null),ht(t).catch(()=>null)]).then(([_,R])=>{B(r,{action:"agent_heartbeat",..._?{capabilitiesHash:_.capabilitiesHash,memoryHash:_.memoryHash}:{},..._?.skillsHash?{skillsHash:_.skillsHash}:{},metadata:yt(t,c,R,dr(t)?f?.getContext?.():null,y)})})},t.heartbeatMs),s.unref&&s.unref()}),r.on("message",D=>{let _=St(D);if(_){if(_.type==="agent_registered"){l=!0,h=_.connection||_.agent||null,ar(t,_.agent),k(),N(`Registered as ${_.connection?.name||t.name} on ${_.connection?.host||Ie.hostname()}`),t.onRegistered&&Promise.resolve(t.onRegistered(t,_)).catch(R=>{N(`Profile save failed: ${R?.message||R}`)}),ft(t,_.agent).catch(()=>{}),rr(t).catch(()=>{}),cr(r,t),ur(r,t),g(),Ee(r,t,S());return}if(_.type==="agent_config"){ar(t,_.agent),N(`Updated config for @${t.handle||"agent"}: model=${t.model}, permission=${t.permissionMode}`),ft(t,_.agent).catch(()=>{});return}if(_.type==="agent_memory_refresh"){cr(r,t),Ee(r,t,S());return}if(_.type==="agent_capabilities_refresh"){Ee(r,t,S());return}if(_.type==="agent_skills_refresh"){ur(r,t);return}if(_.type==="agent_inference_cancel"){y.get(String(_.requestId||""))?.abort();return}if(_.type==="agent_job_cancel"){let R=String(_.jobId||"");R&&(p.cancelJob(R,_.reason||"Cancelled by Agensis"),c.cancel(R,_.reason||"Cancelled by Agensis")&&N(`Cancelled job ${R}`));return}if(_.type==="agent_permission_decision"){p.decide(_);return}if(_.type==="agent_inference_request"&&_.requestId){let R=String(_.requestId),U=t.sharedModels.find(L=>L.id===_.model),H=[...y.values()].filter(L=>L.model===_.model).length;if(!U){B(r,{action:"agent_inference_error",requestId:R,error:`Shared model '${_.model||""}' is not available.`});return}if(H>=U.maxConcurrency){B(r,{action:"agent_inference_error",requestId:R,error:"Shared model is at capacity.",code:"capacity_exhausted"});return}let z=new AbortController;y.set(R,{abort:()=>z.abort(),model:U.id}),B(r,{action:"agent_heartbeat",metadata:yt(t,c,null,null,y)}),jn({models:t.sharedModels,request:_,signal:z.signal,send:L=>B(r,L)}).catch(L=>{B(r,{action:"agent_inference_error",requestId:R,error:z.signal.aborted?"Inference cancelled.":L?.message||String(L),code:z.signal.aborted?"cancelled":"inference_failed"})}).finally(()=>{y.delete(R),B(r,{action:"agent_heartbeat",metadata:yt(t,c,null,null,y)})});return}if(_.type==="bridge_start"||_.type==="bridge_send"||_.type==="bridge_stop"){Gn({..._,action:_.type},R=>B(r,R));return}if(_.type==="peer_ticket"){let R=_.peer?.agentId,U=M.get(R)||[],H=U.shift();U.length?M.set(R,U):M.delete(R),H&&H.resolve(_);return}if(_.type==="peer_ticket_grant"){$.set(_.ticket,{fromAgentId:_.fromAgentId,exp:_.exp});return}if(_.type==="peer_list"){let R=m.shift();R&&R(Array.isArray(_.peers)?_.peers:[]);return}if(_.type==="agent_reach_disable"){A(),Ee(r,t,S());return}if(_.type==="error"){N(`Server rejected request: ${_.message||"unknown error"}`);return}if(_.type==="agent_disabled"){l=!1,h=null,N(`Agent disabled by Agensis: ${_.reason||"deactivated"}`),P();return}if(_.type==="agent_job"&&_.job?.id){let R=c.enqueue({..._.job,key:_.job.id,lane:ir(_.job),get ws(){return r},parkResult:w});R.accepted&&(a+=1,N(`Queued job ${_.job.id} at position ${R.position}`),t.once&&c.idle().then(()=>P()))}}}),r.on("close",(D,_)=>{lr(y),p.shutdown(),l=!1,h=null;let R=String(_||"");if(N(`Socket closed (${D||"no-code"}${R?`: ${R}`:""})`),s&&(clearInterval(s),s=null),D===1008&&/agent deactivated|authentication failed/i.test(R)){N("Stopping daemon because Agensis rejected this agent connection."),P();return}if(u==="ECONNREFUSED"&&zs(t.url)){N("Local agent backend is not running on 127.0.0.1:3142."),N("Start it in another terminal with: npm run backend"),N("Then rerun this connect command."),P();return}t.once&&a>0&&c.active()===0&&c.size()===0&&P(),!(n||t.once)&&(o=setTimeout(J,2e3),o.unref&&o.unref())}),r.on("error",D=>{u=D?.code||"",N(`Socket error: ${D?.message||D}`)})},X=async()=>{let x=await ht(t).catch(()=>null);await Vn(t,{busy:c.active()>0,active:c.active(),queueSize:c.size(),connected:r?.readyState===Ae.OPEN,agentStatus:x?.status,agentNote:x?.note}).catch(()=>{})};X(),i=setInterval(()=>{X()},t.heartbeatMs),i.unref&&i.unref(),J(),await new Promise(x=>{let D=setInterval(async()=>{t.once&&a>0&&c.active()===0&&c.size()===0&&P(),n&&P()},500);d=()=>{clearInterval(D),x()}}),d=null,T.off("SIGINT",P),T.off("SIGTERM",P)}function Gs(e){let t=Hs(e.cursorBuddyBridge),n=e.noCoding===!0||T.env.AGENSIS_NO_CODING==="1",o=!ie(e.fullCliContext,ie(T.env.AGENSIS_FULL_CLI_CONTEXT,!1))&&ie(e.leanCli,!0),s=String(e.runtime||T.env.AGENSIS_RUNTIME||"").trim().toLowerCase();if(s&&!["claude","codex","amp"].includes(s))throw new Error("--runtime must be one of: claude, codex, amp");let i=s==="codex"?"codex exec":"claude -p",a=n||s==="amp"?"":String(e.codingCmd||T.env.AGENSIS_CODING_CMD||T.env.CODING_CMD||i).trim(),d=s||ci(a),c={url:String(e.url||e.baseUrl||T.env.AGENSIS_URL||"").trim(),token:String(e.token||T.env.AGENSIS_TOKEN||"").trim(),workspace:String(e.workspace||e.workspaceId||T.env.AGENSIS_WORKSPACE||T.env.AGENSIS_WORKSPACE_ID||"").trim(),agent:String(e.agent||e.agentId||T.env.AGENSIS_AGENT||T.env.AGENSIS_AGENT_ID||"").trim(),handle:br(e.handle||T.env.AGENSIS_HANDLE||e.name||T.env.AGENSIS_NAME||"agent"),name:String(e.name||T.env.AGENSIS_NAME||e.handle||T.env.AGENSIS_HANDLE||"agensis Agent").trim(),cwd:String(e.cwd||T.env.AGENSIS_CWD||T.cwd()).trim(),codingCmd:a,runtime:d,runtimeLocked:!!s,ampCmd:String(e.ampCmd||T.env.AGENSIS_AMP_CMD||"amp").trim()||"amp",model:_t(e.model||T.env.AGENSIS_MODEL||T.env.CLAUDE_MODEL||"",d),permissionMode:He(e.permissionMode||e.permission_mode||e.permission||T.env.AGENSIS_PERMISSION_MODE||"default"),timeoutMs:Number(e.timeoutMs||T.env.AGENSIS_TIMEOUT_MS||Ls),heartbeatMs:Number(e.heartbeatMs||T.env.AGENSIS_HEARTBEAT_MS||Us),maxConcurrency:Math.max(1,Number(e.maxConcurrency||T.env.AGENSIS_MAX_CONCURRENCY||sr)||sr),once:!!(e.once||T.env.AGENSIS_ONCE==="1"),exitOnOnce:!!e.exitOnOnce,onRegistered:typeof e.onRegistered=="function"?e.onRegistered:null,primaryDaemon:!!(e.primaryDaemon||T.env.AGENSIS_PRIMARY_DAEMON==="1"),cursorBuddyRuntime:!!(e.cursorBuddyRuntime||T.env.AGENSIS_CURSORBUDDY_RUNTIME==="1"),cursorBuddyBridge:t,cursorBuddyPort:Number(e.cursorBuddyPort||T.env.AGENSIS_CURSORBUDDY_PORT||8787),cursorBuddyBridgeSecret:String(e.cursorBuddyBridgeSecret||T.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),cursorBuddyModel:String(e.cursorBuddyModel||T.env.AGENSIS_CURSORBUDDY_MODEL||"haiku-4.5").trim(),lanListener:!!(e.lanListener||e.lan||T.env.AGENSIS_LAN==="1"),share:!!(e.share||T.env.AGENSIS_SHARE==="1"),sharedModelsFile:String(e.sharedModelsFile||T.env.AGENSIS_SHARED_MODELS_FILE||"").trim(),noCoding:n,leanCli:o,fastConnection:ie(e.fastConnection,ie(T.env.AGENSIS_FAST_CONNECTION,!0)),syncMemory:ie(e.syncMemory,T.env.AGENSIS_SYNC_MEMORY==="1"),syncSkills:ie(e.syncSkills,ie(T.env.AGENSIS_SYNC_SKILLS,!0)),hostFolders:gr(e.hostFolders??e.host_folders??T.env.AGENSIS_HOST_FOLDERS)};c.sharedModelsFile&&!me.isAbsolute(c.sharedModelsFile)&&(c.sharedModelsFile=me.resolve(c.cwd,c.sharedModelsFile));let u=[];if(c.url||u.push("--url"),c.token||u.push("--token"),c.workspace||u.push("--workspace"),c.agent||u.push("--agent"),c.share&&!c.sharedModelsFile&&u.push("--shared-models-file"),u.length)throw new Error(`Missing required option(s): ${u.join(", ")}`);return c}function ie(e,t){return e==null||e===""?t:typeof e=="boolean"?e:!/^(0|false|off|no)$/i.test(String(e).trim())}function Hs(e){let t=T.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 qs(e,t,n={}){let r=bt(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 bt(e){let t=new URL(e);return Js(t)&&(t.protocol="http:",t.hostname="127.0.0.1",t.port="3142"),t}function Js(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 zs(e){try{let t=bt(e);return(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="0.0.0.0")&&t.port==="3142"}catch{return!1}}function ir(e){let t=String(e?.sessionId||""),n=String(e?.threadParentId||"");return`${t}::${n}`}var Ks=/\b(cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\b/i,Ws=[/\b(?:make|have|tell)\s+(?:the\s+)?(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\s+(?:say|speak)\s+(.+)$/i];function Ys(e){return String(e||"").trim().replace(/^[`"'“”‘’]+|[`"'“”‘’?.!]+$/g,"").trim().slice(0,1200)}function Vs(e){for(let t of Ws){let n=String(e||"").match(t),r=Ys(n?.[1]||"");if(r)return r}return""}function Xs(e){let t=String(e||"").replace(/\s+/g," ").trim();if(!t)return"";let n=/latest user message\s*:\s*/gi,r=null,o=null;for(;r=n.exec(t);)o=r;if(!o)return"";let s=t.slice(o.index+o[0].length).trim(),i=s.search(/\b(Return a useful response|Conversation context follows|Previous user|Previous assistant|Diagnostic notes|System prompt|Developer message)\b/i);return(i>=0?s.slice(0,i):s).trim().replace(/^["'“”‘’]+|["'“”‘’]+$/g,"").trim()}function Qs(e){let t=String(e||"").replace(/\s+/g," ").trim(),r=Xs(t)||t;if(!r)return"";if(r.length<=500)return r;let o=[/\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 s of o){let i=r.match(s);if(i?.[0])return i[0].trim()}return""}function Zs(e){let t=Qs(e);if(!t)return null;let n=/^(open|show|hide|hush|close|dismiss)\b/i.test(t),r=Ks.test(t);if(!n&&!r)return null;let o="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:o};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:o};let s=Vs(t);return s&&r?{action:"say",text:s,source:o}:r&&/\b(wave|waves|waving)\b/i.test(t)?{action:"wave",text:s,source:o}:null}async function ei(e,t){let r=`http://127.0.0.1:${Number(e.cursorBuddyPort||8787)}/cursorbuddy/control`,o=String(e.cursorBuddyBridgeSecret||T.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),s={"content-type":"application/json"};o&&(s.authorization=`Bearer ${o}`,s["x-agensis-bridge-secret"]=o);let i=await fetch(r,{method:"POST",headers:s,body:JSON.stringify(t)}),a=null;try{a=await i.json()}catch{a=null}if(!i.ok||a?.ok===!1)throw new Error(a?.error||`CursorBuddy control failed with HTTP ${i.status}`);return a}function ti(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 dr(e={}){return e.cursorBuddyBridge===!1?!1:!!(e.cursorBuddyRuntime||e.primaryDaemon)}async function ni(e,t,n,r){let o="cursorbuddy-control",s="native",i=[],a=(u="")=>{B(t.ws,{action:"agent_job_delta",jobId:t.id,content:u,elapsedMs:Date.now()-r,model:o,permissionMode:s,permissionFlags:i})};a("");let d="",c="";try{await ei(e,n),d=ti(n),a(d)}catch(u){c=String(u?.message||u),d=`CursorBuddy control failed: ${c}`,a(d)}At(t,{action:"agent_job_result",jobId:t.id,response:d,error:c,elapsedMs:Date.now()-r,model:o,permissionMode:s,permissionFlags:i}),N(`Finished native CursorBuddy ${n.action} job ${t.id} in ${Math.round((Date.now()-r)/1e3)}s`)}async function ri(e,t,{signal:n,requestPermission:r=null}){let o=Date.now();N(`Starting job ${t.id}`);let s=mr(e,t);if(e.runtimeLocked&&s!==e.runtime){let I=`Executor runtime ${e.runtime} cannot accept job runtime ${s}.`;B(t.ws,{action:"agent_job_result",jobId:t.id,response:"",error:I,errorCode:"runtime_mismatch",elapsedMs:Date.now()-o,metadata:{executionRuntime:e.runtime}}),N(`Job ${t.id} refused: runtime mismatch (${e.runtime} != ${s})`);return}if(et(t)){await oi(e,t,{signal:n,started:o}),e.once&&(N("One-shot Amp job complete; exiting."),setTimeout(()=>T.exit(0),150));return}let i=Zs(t.prompt);if(i&&dr(e)){await ni(e,t,i,o),e.once&&(N("One-shot CursorBuddy control job complete; exiting."),setTimeout(()=>T.exit(0),150));return}let a=ai(e,t),d=await si(e,t),c="",u="",f=0,l=(I="")=>{B(t.ws,{action:"agent_job_delta",jobId:t.id,content:I,elapsedMs:Date.now()-o,model:a.model,permissionMode:a.permissionMode,permissionFlags:a.permissionFlags})},h=I=>{B(t.ws,{action:"agent_job_step",jobId:t.id,kind:I.kind,name:I.name,detail:I.detail,elapsedMs:Date.now()-o})},y=I=>{B(t.ws,{action:"agent_job_segment",jobId:t.id,text:I.text,elapsedMs:Date.now()-o})};l("");let p=a.streamJson?pr({onStep:h,onSegment:y}):null,b=setInterval(()=>l(c),1e3);b.unref&&b.unref();let w=!/[\\/]/.test(a.cmd),k=e.fastConnection&&w?kt(a.cmd)?"claude":Et(a.cmd)?"codex":null:null,E=await un(t,{family:k}).run({cmd:a.cmd,args:[...a.args,d],env:a.env,cwd:t.cwd||e.cwd,timeoutMs:e.timeoutMs,heartbeatMs:e.heartbeatMs,label:"agent job",signal:n,job:t,prompt:d,model:a.model,permissionMode:a.permissionMode,hostFolders:yr(e,t),leanCli:e.leanCli,mcp:e.leanCli?wt(e):null,sessionKey:`${t.workspaceId||e.workspace||""}:${e.agent||e.handle||""}`,clientVersion:ce,requestPermission:r,onData:I=>{p?(p.feed(I),c=p.live):(c+=String(I||""),u=Si(`${u}
|
|
49
|
-
${I}`));let
|
|
46
|
+
`,o=Math.max(0,n-Buffer.byteLength(r));return`${Buffer.from(String(e||"")).subarray(0,o).toString("utf8").replace(/\uFFFD+$/,"")}${r}`}function rs(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 o=/^description:\s*(.*)$/i.exec(t[r]);if(!o)continue;let s=o[1].trim();if(s&&!/^[|>][-+]?$/.test(s)){n=s.replace(/^["']|["']$/g,"");break}let i=[];for(let a=r+1;a<t.length&&a<200&&!(t[a].trim()==="---"||t[a].trim()&&!/^\s/.test(t[a]));a+=1)i.push(t[a].trim());n=i.join(" ").trim();break}if(!n){let r=t.findIndex((i,a)=>a>0&&i.trim()==="---"),s=(t[0]?.trim()==="---"&&r>0?t.slice(r+1):t).find(i=>i.trim()&&i.trim()!=="---");n=String(s||"").replace(/^#+\s*/,"").trim()}return n.slice(0,ts)}function Dn(e){try{return ut(e).slice(0,es)}catch{return[]}}async function os(e){let t;try{t=await lt.open(e,"r")}catch{return null}try{let n=Buffer.alloc(Se+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 ss(e,t){let n=await os(e.file);if(!n)return null;let r=n.toString("utf8"),o=rs(r),s=n.length>Se,i=Math.min(Se,Math.max(0,t)),a=Buffer.byteLength(r)>i;if(!s&&!a)return{skill:e.name,path:e.file,summary:o,content:r,truncated:!1};let d=s?await is(e.file):0,c=s&&!a?`the file is ${d?`${d} bytes`:`over ${Se} bytes`}; only the first ${Se} were synced`:`this sync reached its ${Rn}-byte ceiling`,u=i<ns?On("",c,Number.MAX_SAFE_INTEGER):On(r,c,i);return{skill:e.name,path:e.file,summary:o,content:u,truncated:!0}}async function is(e){try{return(await lt.stat(e)).size}catch{return 0}}async function dt(e={}){let t=[];for(let n of Dn(e)){if(!n.file){t.push(`${n.name}:-`);continue}try{let r=await lt.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 Bn(e={}){let t=[],n=0;for(let r of Dn(e))if(r.file)try{let o=await ss(r,Rn-n);if(!o)continue;n+=Buffer.byteLength(o.content),t.push(o)}catch{}return t}import{readFile as as}from"node:fs/promises";var cs=new Set(["127.0.0.1","localhost","::1","[::1]"]);function Pn(e,t,n){let r=Number(e);return Number.isFinite(r)?Math.max(1,Math.min(n,Math.trunc(r))):t}function us(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(!cs.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(o=>String(o||"").trim().toLowerCase()).filter(Boolean))].slice(0,16),...e.contextWindow?{contextWindow:Pn(e.contextWindow,void 0,1e7)}:{},maxConcurrency:Pn(e.maxConcurrency,1,64),shared:!0}}async function Ln(e){if(!e)return[];let t=JSON.parse(await as(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(us).filter(Boolean)}function Un(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 jn({models:e,request:t,send:n,signal:r,fetchImpl:o=fetch,env:s=process.env}){let i=String(t?.requestId||"").trim();if(!i)throw new Error("Inference requestId is required.");let a=(Array.isArray(e)?e:[]).find(b=>b.id===t?.model);if(!a)throw new Error(`Shared model '${t?.model||""}' is not available.`);let d={"content-type":"application/json"},c=a.apiKeyEnv?s[a.apiKeyEnv]:"";c&&(d.authorization=`Bearer ${c}`),n({action:"agent_inference_started",requestId:i,model:a.id});let{requestId:u,model:p,type:l,action:f,...S}=t,g=await o(`${a.baseUrl}/chat/completions`,{method:"POST",headers:d,body:JSON.stringify({...S,model:a.upstreamModel,stream:t.stream===!0}),signal:r});if(!g.ok){let b=await g.text().catch(()=>"");throw new Error(b||`Local model returned HTTP ${g.status}.`)}if(t.stream===!0){if(!g.body)throw new Error("Local model returned an empty stream.");let b=g.body.getReader(),k=new TextDecoder,E="",v,$=y=>{let I=y.trim();if(!I.startsWith("data:"))return!1;let h=I.slice(5).trim();if(!h)return!1;if(h==="[DONE]")return!0;try{let A=JSON.parse(h);A?.usage&&(v=A.usage),n({action:"agent_inference_delta",requestId:i,model:a.id,chunk:A})}catch{}return!1},T=!1;for(;!T;){let{done:y,value:I}=await b.read();E+=k.decode(I||new Uint8Array,{stream:!y});let h=E.split(/\r?\n/);E=y?"":h.pop()||"";for(let A of h)if($(A)){T=!0;break}if(y)break}E&&$(E);let m={action:"agent_inference_result",requestId:i,model:a.id,...v?{usage:v}:{}};return n(m),m}let w=await g.json();return n({action:"agent_inference_result",requestId:i,model:a.id,response:w}),w}import{createRequire as ls}from"node:module";import{spawn as ds}from"node:child_process";import{mkdirSync as ms}from"node:fs";import ps from"node:path";import fs from"node:os";var hs=ls(import.meta.url),we=new Map;function gs(e,t){let n=ps.join(fs.homedir(),".agensis","bridges",t,String(e));return ms(n,{recursive:!0}),n}async function Fn({bridgeId:e,externalId:t,emit:n}){let r;try{r=hs("@whiskeysockets/baileys")}catch{return n({action:"bridge_status",bridgeId:e,status:"error",error:"WhatsApp support needs @whiskeysockets/baileys installed on this machine: npm i -g @whiskeysockets/baileys"}),null}let{default:o,useMultiFileAuthState:s,DisconnectReason:i}=r,{state:a,saveCreds:d}=await s(gs(e,"whatsapp")),c=o({auth:a,printQRInTerminal:!1});return c.ev.on("creds.update",d),c.ev.on("connection.update",u=>{if(u.qr&&n({action:"bridge_status",bridgeId:e,status:"pairing",qr:u.qr}),u.connection==="open"&&n({action:"bridge_status",bridgeId:e,status:"connected"}),u.connection==="close"){let l=u.lastDisconnect?.error?.output?.statusCode===i?.loggedOut;n({action:"bridge_status",bridgeId:e,status:l?"error":"reconnecting",error:l?"WhatsApp was unlinked on the phone. Scan again to reconnect.":null}),!l&&we.has(e)&&setTimeout(()=>{Fn({bridgeId:e,externalId:t,emit:n})},5e3)}}),c.ev.on("messages.upsert",({messages:u,type:p})=>{if(p==="notify")for(let l of u){if(l.key?.fromMe)continue;let f=l.key?.remoteJid;if(!f||t&&f!==t)continue;let S=l.message?.conversation||l.message?.extendedTextMessage?.text||"";S.trim()&&n({action:"bridge_inbound",bridgeId:e,externalMessageId:l.key.id?`${f}:${l.key.id}`:"",author:l.pushName||f.split("@")[0],text:S,externalId:f})}}),{provider:"whatsapp",async send(u,p){let l=t;if(!l)throw new Error("No WhatsApp conversation selected yet");let f=p?`*${p}*: ${u}`:u,S=await c.sendMessage(l,{text:f});return S?.key?.id?`${l}:${S.key.id}`:null},stop(){try{c.end()}catch{}}}}async function ys({bridgeId:e,externalId:t,emit:n,account:r}){let o=ds("signal-cli",["-a",r||"","jsonRpc"],{stdio:["pipe","pipe","pipe"]}),s="",i=1;return o.on("error",()=>{n({action:"bridge_status",bridgeId:e,status:"error",error:"signal-cli is not installed on this machine. Install it (brew install signal-cli) and link a device."})}),o.stderr.on("data",a=>{let d=String(a);if(/link|tsdevice/i.test(d)){let c=d.match(/(sgnl:\/\/linkdevice\S+|tsdevice:\S+)/);c&&n({action:"bridge_status",bridgeId:e,status:"pairing",qr:c[1]})}}),o.stdout.on("data",a=>{s+=String(a);let d=s.split(`
|
|
47
|
+
`);s=d.pop()??"";for(let c of d){if(!c.trim())continue;let u;try{u=JSON.parse(c)}catch{continue}let p=u?.params?.envelope,l=p?.dataMessage;if(!p||!l?.message)continue;let f=l.groupInfo?.groupId||p.sourceNumber;t&&f!==t||n({action:"bridge_inbound",bridgeId:e,externalMessageId:`${f}:${p.timestamp}`,author:p.sourceName||p.sourceNumber||"Signal user",text:l.message,externalId:f})}}),n({action:"bridge_status",bridgeId:e,status:"connected"}),{provider:"signal",async send(a,d){let c=d?`${d}: ${a}`:a,u=String(t||"").length>20,p={jsonrpc:"2.0",id:String(i++),method:"send",params:u?{groupId:t,message:c}:{recipient:[t],message:c}};return o.stdin.write(`${JSON.stringify(p)}
|
|
48
|
+
`),null},stop(){try{o.kill()}catch{}}}}async function Ss({bridgeId:e,externalId:t,emit:n,config:r}){let o=(await import("ws")).default,s=String(r?.gatewayUrl||"ws://127.0.0.1:18789"),i=String(r?.authToken||""),a=new o(s),d=1,c=new Map,u=(p,l)=>new Promise((f,S)=>{let g=String(d++);c.set(g,{resolve:f,reject:S}),a.send(JSON.stringify({type:"req",id:g,method:p,params:l})),setTimeout(()=>{c.has(g)&&(c.delete(g),S(new Error(`OpenClaw ${p} timed out`)))},3e4)});return a.on("open",()=>n({action:"bridge_status",bridgeId:e,status:"connecting"})),a.on("error",p=>n({action:"bridge_status",bridgeId:e,status:"error",error:`OpenClaw gateway: ${p?.message||p}`})),a.on("message",async p=>{let l;try{l=JSON.parse(String(p))}catch{return}if(l.type==="event"&&l.event==="connect.challenge"){try{await u("connect",{minProtocol:4,maxProtocol:4,client:{id:"agensis",version:"1",platform:process.platform,mode:"operator"},role:"operator",scopes:["operator.read","operator.write"],auth:{token:i},device:{id:`agensis-${e}`,nonce:l.payload?.nonce}}),await u("watch.subscribe",{}),n({action:"bridge_status",bridgeId:e,status:"connected"})}catch(f){n({action:"bridge_status",bridgeId:e,status:"error",error:String(f.message||f)})}return}if(l.type==="res"&&c.has(l.id)){let{resolve:f,reject:S}=c.get(l.id);c.delete(l.id),l.ok?f(l.payload):S(new Error(l.error?.message||"OpenClaw request failed"));return}if(l.method==="message"||l.event==="message"){let f=l.params||l.payload||{},S=String(f.chat_id??f.chatId??"");if(t&&S!==t||f.fromMe||f.outbound)return;let g=String(f.text??f.message??"");if(!g.trim())return;n({action:"bridge_inbound",bridgeId:e,externalMessageId:String(f.id??f.message_id??""),author:String(f.sender_name??f.author??"OpenClaw"),text:g,externalId:S})}}),{provider:"openclaw",async send(p,l){let f=l?`${l}: ${p}`:p,S=await u("send",{chat_id:t,text:f,idempotency_key:`agensis-${e}-${Date.now()}-${Math.random().toString(16).slice(2)}`});return S?.id?String(S.id):null},stop(){try{a.close()}catch{}}}}var ws={whatsapp:Fn,signal:ys,openclaw:Ss};async function Gn(e,t){let n=String(e?.bridgeId||"");if(n){if(e.action==="bridge_stop"){we.get(n)?.stop?.(),we.delete(n);return}if(e.action==="bridge_start"){if(we.has(n))return;let r=ws[String(e.provider)];if(!r)return;try{let o=await r({bridgeId:n,externalId:String(e.externalId||""),config:e.config||{},account:e.account,emit:t});o&&we.set(n,o)}catch(o){t({action:"bridge_status",bridgeId:n,status:"error",error:String(o?.message||o)})}return}if(e.action==="bridge_send"){let r=we.get(n);if(!r){t({action:"bridge_status",bridgeId:n,status:"error",error:"This bridge is not running on this machine."});return}try{let o=await r.send(String(e.text||""),String(e.author||""));o&&t({action:"bridge_status",bridgeId:n,status:"connected",sentMessageId:o})}catch(o){t({action:"bridge_status",bridgeId:n,status:"error",error:String(o?.message||o)})}}}}je();var Ls=30*60*1e3,Us=15*1e3,sr=2,js=10*1024,Fs="claude-opus-4-8",ce="0.1.40";async function Ge(e={}){let t=Gs(e);t.sharedModels=t.share?await Ln(t.sharedModelsFile):[];let n=!1,r=null,o=null,s=null,i=null,a=0,d=null,c=null,u="",p=null,l=!1,f=null,S=new Map,g=Yt({send:x=>B(r,x),log:N}),w=[],b=x=>{w.length>=32&&w.shift(),w.push(x),N(`Socket was gone \u2014 parked the result for job ${x.jobId} to re-send on reconnect`)},k=()=>{if(w.length!==0)for(let x of w.splice(0,w.length))B(r,x)?N(`Re-sent the result for job ${x.jobId} after reconnecting`):w.push(x)},E=null,v={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"},$=new Map,T=new Map,m=[],y=()=>v,I=()=>({connected:l&&!!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()}),h=()=>{E||!t.lanListener||(E=new Ae.Server({port:0}),E.on("listening",()=>{let{port:x}=E.address();v={transport:"ws",listening:!0,addrs:gi(x),auth:"hub-pairwise"},N(`Agent-mesh LAN listener on port ${x}`),Ee(r,t,y())}),E.on("connection",x=>{let D=!1,_=setTimeout(()=>{if(!D)try{x.close(1008,"peer auth required")}catch{}},5e3);x.once("message",R=>{clearTimeout(_);let U=St(R),H=U?.type==="peer_auth"?$.get(U.ticket):null;if(!H||H.fromAgentId!==U.fromAgentId||Date.now()>H.exp){try{x.close(1008,"invalid ticket")}catch{}return}$.delete(U.ticket),D=!0,x.on("message",z=>{let L=St(z);L?.type==="agent_job"&&L.job?.id&&c.enqueue({...L.job,key:L.job.id,lane:ir(L.job),ws:r}).accepted&&N(`Queued peer-handoff job ${L.job.id} from ${U.fromAgentId}`)})})}),E.on("error",x=>N(`LAN listener error: ${x?.message||x}`)))},A=()=>{if(E){try{E.close()}catch{}E=null}v={transport:"ws",listening:!1,addrs:[],auth:"hub-pairwise"}},C=x=>new Promise((D,_)=>{if(!B(r,{action:"peer_ticket_request",targetAgentId:x})){_(new Error("hub socket not open"));return}let R=T.get(x)||[];R.push({resolve:D,reject:_}),T.set(x,R),setTimeout(()=>{let U=T.get(x)||[],H=U.findIndex(z=>z.resolve===D);H>=0&&(U.splice(H,1),_(new Error("peer ticket request timed out")))},1e4)}),O=()=>new Promise((x,D)=>{if(!B(r,{action:"peer_list_request"})){D(new Error("hub socket not open"));return}m.push(x),setTimeout(()=>{let _=m.indexOf(x);_>=0&&(m.splice(_,1),x([]))},1e4)}),V=async(x,D)=>{let _=null;try{let U=(await O()).find(L=>L.agentId===x&&L.reach?.listening&&L.reach.addrs?.length);if(!U)return!1;let H=await C(x),z=H.peer?.addrs?.[0]||U.reach.addrs[0];return!z?.host||!z?.port?!1:(_=new Ae(`ws://${z.host}:${z.port}`),await new Promise((L,Ke)=>{_.once("open",L),_.once("error",Ke),setTimeout(()=>Ke(new Error("peer connect timed out")),5e3)}),B(_,{type:"peer_auth",ticket:H.ticket,fromAgentId:t.agent}),B(_,{type:"agent_job",job:D}),!0)}catch(R){return N(`Peer handoff to ${x} failed, falling back to hub relay: ${R?.message||R}`),!1}finally{try{_?.close()}catch{}}},P=()=>{n=!0,lr(S),g.shutdown("The agent daemon shut down before this was approved."),o&&clearTimeout(o),s&&clearInterval(s),i&&clearInterval(i),p&&(p.close().catch(()=>{}),p=null),A(),Xn(t,{status:"stopped",connected:!1});try{r?.close()}catch{}d&&d()};if(c=hn({concurrency:t.once?1:t.maxConcurrency,runJob:async(x,D)=>{await ri(t,x,{...D,requestPermission:g.request}),t.once&&P()}}),t.cursorBuddyBridge)try{p=await An(t,{port:t.cursorBuddyPort,authSecret:t.cursorBuddyBridgeSecret||void 0,log:N,connectionProvider:I}),p?.secret&&(t.cursorBuddyBridgeSecret=p.secret)}catch(x){if(wi(x)){let D=await bi(t.cursorBuddyPort);if(D?.ok){let _=D.pid?` pid ${D.pid}`:"";N(`CursorBuddy local bridge already running on http://127.0.0.1:${t.cursorBuddyPort}${_}`)}else N(`CursorBuddy local bridge port ${t.cursorBuddyPort} is in use but did not answer health`)}else N(`CursorBuddy local bridge unavailable: ${x?.message||x}`);p=null}M.once("SIGINT",P),M.once("SIGTERM",P);let J=()=>{if(n)return;let x=qs(t.url,t.token,t);u="",N(`Connecting to ${x.replace(t.token,"redacted")}`),r=new Ae(x),r.on("open",async()=>{l=!1,f=null,N(`Connected. Registering @${t.handle||"agent"} from ${t.cwd}`),B(r,{type:"auth",token:t.token});let D=await Zn(t);B(r,{action:"agent_register",workspaceId:t.workspace,agentId:t.agent,handle:t.handle,name:t.name,host:Ie.hostname(),cwd:t.cwd,...D?{identity:D}:{},metadata:{codingCmd:t.codingCmd,model:t.model,permissionMode:t.permissionMode,permissionFlags:vt(t.permissionMode),once:t.once,runtime:"agensis",executionRuntime:t.runtime,version:ce}}),s=setInterval(()=>{Promise.all([Sr(t,y()).catch(()=>null),ht(t).catch(()=>null)]).then(([_,R])=>{B(r,{action:"agent_heartbeat",..._?{capabilitiesHash:_.capabilitiesHash,memoryHash:_.memoryHash}:{},..._?.skillsHash?{skillsHash:_.skillsHash}:{},metadata:yt(t,c,R,dr(t)?p?.getContext?.():null,S)})})},t.heartbeatMs),s.unref&&s.unref()}),r.on("message",D=>{let _=St(D);if(_){if(_.type==="agent_registered"){l=!0,f=_.connection||_.agent||null,ar(t,_.agent),k(),N(`Registered as ${_.connection?.name||t.name} on ${_.connection?.host||Ie.hostname()}`),t.onRegistered&&Promise.resolve(t.onRegistered(t,_)).catch(R=>{N(`Profile save failed: ${R?.message||R}`)}),ft(t,_.agent).catch(()=>{}),rr(t).catch(()=>{}),cr(r,t),ur(r,t),h(),Ee(r,t,y());return}if(_.type==="agent_config"){ar(t,_.agent),N(`Updated config for @${t.handle||"agent"}: model=${t.model}, permission=${t.permissionMode}`),ft(t,_.agent).catch(()=>{});return}if(_.type==="agent_memory_refresh"){cr(r,t),Ee(r,t,y());return}if(_.type==="agent_capabilities_refresh"){Ee(r,t,y());return}if(_.type==="agent_skills_refresh"){ur(r,t);return}if(_.type==="agent_inference_cancel"){S.get(String(_.requestId||""))?.abort();return}if(_.type==="agent_job_cancel"){let R=String(_.jobId||"");R&&(g.cancelJob(R,_.reason||"Cancelled by Agensis"),c.cancel(R,_.reason||"Cancelled by Agensis")&&N(`Cancelled job ${R}`));return}if(_.type==="agent_permission_decision"){g.decide(_);return}if(_.type==="agent_inference_request"&&_.requestId){let R=String(_.requestId),U=t.sharedModels.find(L=>L.id===_.model),H=[...S.values()].filter(L=>L.model===_.model).length;if(!U){B(r,{action:"agent_inference_error",requestId:R,error:`Shared model '${_.model||""}' is not available.`});return}if(H>=U.maxConcurrency){B(r,{action:"agent_inference_error",requestId:R,error:"Shared model is at capacity.",code:"capacity_exhausted"});return}let z=new AbortController;S.set(R,{abort:()=>z.abort(),model:U.id}),B(r,{action:"agent_heartbeat",metadata:yt(t,c,null,null,S)}),jn({models:t.sharedModels,request:_,signal:z.signal,send:L=>B(r,L)}).catch(L=>{B(r,{action:"agent_inference_error",requestId:R,error:z.signal.aborted?"Inference cancelled.":L?.message||String(L),code:z.signal.aborted?"cancelled":"inference_failed"})}).finally(()=>{S.delete(R),B(r,{action:"agent_heartbeat",metadata:yt(t,c,null,null,S)})});return}if(_.type==="bridge_start"||_.type==="bridge_send"||_.type==="bridge_stop"){Gn({..._,action:_.type},R=>B(r,R));return}if(_.type==="peer_ticket"){let R=_.peer?.agentId,U=T.get(R)||[],H=U.shift();U.length?T.set(R,U):T.delete(R),H&&H.resolve(_);return}if(_.type==="peer_ticket_grant"){$.set(_.ticket,{fromAgentId:_.fromAgentId,exp:_.exp});return}if(_.type==="peer_list"){let R=m.shift();R&&R(Array.isArray(_.peers)?_.peers:[]);return}if(_.type==="agent_reach_disable"){A(),Ee(r,t,y());return}if(_.type==="error"){N(`Server rejected request: ${_.message||"unknown error"}`);return}if(_.type==="agent_disabled"){l=!1,f=null,N(`Agent disabled by Agensis: ${_.reason||"deactivated"}`),P();return}if(_.type==="agent_job"&&_.job?.id){let R=c.enqueue({..._.job,key:_.job.id,lane:ir(_.job),get ws(){return r},parkResult:b});R.accepted&&(a+=1,N(`Queued job ${_.job.id} at position ${R.position}`),t.once&&c.idle().then(()=>P()))}}}),r.on("close",(D,_)=>{lr(S),g.shutdown(),l=!1,f=null;let R=String(_||"");if(N(`Socket closed (${D||"no-code"}${R?`: ${R}`:""})`),s&&(clearInterval(s),s=null),D===1008&&/agent deactivated|authentication failed/i.test(R)){N("Stopping daemon because Agensis rejected this agent connection."),P();return}if(u==="ECONNREFUSED"&&zs(t.url)){N("Local agent backend is not running on 127.0.0.1:3142."),N("Start it in another terminal with: npm run backend"),N("Then rerun this connect command."),P();return}t.once&&a>0&&c.active()===0&&c.size()===0&&P(),!(n||t.once)&&(o=setTimeout(J,2e3),o.unref&&o.unref())}),r.on("error",D=>{u=D?.code||"",N(`Socket error: ${D?.message||D}`)})},X=async()=>{let x=await ht(t).catch(()=>null);await Vn(t,{busy:c.active()>0,active:c.active(),queueSize:c.size(),connected:r?.readyState===Ae.OPEN,agentStatus:x?.status,agentNote:x?.note}).catch(()=>{})};X(),i=setInterval(()=>{X()},t.heartbeatMs),i.unref&&i.unref(),J(),await new Promise(x=>{let D=setInterval(async()=>{t.once&&a>0&&c.active()===0&&c.size()===0&&P(),n&&P()},500);d=()=>{clearInterval(D),x()}}),d=null,M.off("SIGINT",P),M.off("SIGTERM",P)}function Gs(e){let t=Hs(e.cursorBuddyBridge),n=e.noCoding===!0||M.env.AGENSIS_NO_CODING==="1",o=!ie(e.fullCliContext,ie(M.env.AGENSIS_FULL_CLI_CONTEXT,!1))&&ie(e.leanCli,!0),s=String(e.runtime||M.env.AGENSIS_RUNTIME||"").trim().toLowerCase();if(s&&!["claude","codex","amp"].includes(s))throw new Error("--runtime must be one of: claude, codex, amp");let i=s==="codex"?"codex exec":"claude -p",a=n||s==="amp"?"":String(e.codingCmd||M.env.AGENSIS_CODING_CMD||M.env.CODING_CMD||i).trim(),d=s||ci(a),c={url:String(e.url||e.baseUrl||M.env.AGENSIS_URL||"").trim(),token:String(e.token||M.env.AGENSIS_TOKEN||"").trim(),workspace:String(e.workspace||e.workspaceId||M.env.AGENSIS_WORKSPACE||M.env.AGENSIS_WORKSPACE_ID||"").trim(),agent:String(e.agent||e.agentId||M.env.AGENSIS_AGENT||M.env.AGENSIS_AGENT_ID||"").trim(),handle:br(e.handle||M.env.AGENSIS_HANDLE||e.name||M.env.AGENSIS_NAME||"agent"),name:String(e.name||M.env.AGENSIS_NAME||e.handle||M.env.AGENSIS_HANDLE||"agensis Agent").trim(),cwd:String(e.cwd||M.env.AGENSIS_CWD||M.cwd()).trim(),codingCmd:a,runtime:d,runtimeLocked:!!s,ampCmd:String(e.ampCmd||M.env.AGENSIS_AMP_CMD||"amp").trim()||"amp",model:_t(e.model||M.env.AGENSIS_MODEL||M.env.CLAUDE_MODEL||"",d),permissionMode:He(e.permissionMode||e.permission_mode||e.permission||M.env.AGENSIS_PERMISSION_MODE||"default"),timeoutMs:Number(e.timeoutMs||M.env.AGENSIS_TIMEOUT_MS||Ls),heartbeatMs:Number(e.heartbeatMs||M.env.AGENSIS_HEARTBEAT_MS||Us),maxConcurrency:Math.max(1,Number(e.maxConcurrency||M.env.AGENSIS_MAX_CONCURRENCY||sr)||sr),once:!!(e.once||M.env.AGENSIS_ONCE==="1"),exitOnOnce:!!e.exitOnOnce,onRegistered:typeof e.onRegistered=="function"?e.onRegistered:null,primaryDaemon:!!(e.primaryDaemon||M.env.AGENSIS_PRIMARY_DAEMON==="1"),cursorBuddyRuntime:!!(e.cursorBuddyRuntime||M.env.AGENSIS_CURSORBUDDY_RUNTIME==="1"),cursorBuddyBridge:t,cursorBuddyPort:Number(e.cursorBuddyPort||M.env.AGENSIS_CURSORBUDDY_PORT||8787),cursorBuddyBridgeSecret:String(e.cursorBuddyBridgeSecret||M.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),cursorBuddyModel:String(e.cursorBuddyModel||M.env.AGENSIS_CURSORBUDDY_MODEL||"haiku-4.5").trim(),lanListener:!!(e.lanListener||e.lan||M.env.AGENSIS_LAN==="1"),share:!!(e.share||M.env.AGENSIS_SHARE==="1"),sharedModelsFile:String(e.sharedModelsFile||M.env.AGENSIS_SHARED_MODELS_FILE||"").trim(),noCoding:n,leanCli:o,fastConnection:ie(e.fastConnection,ie(M.env.AGENSIS_FAST_CONNECTION,!0)),syncMemory:ie(e.syncMemory,M.env.AGENSIS_SYNC_MEMORY==="1"),syncSkills:ie(e.syncSkills,ie(M.env.AGENSIS_SYNC_SKILLS,!0)),hostFolders:gr(e.hostFolders??e.host_folders??M.env.AGENSIS_HOST_FOLDERS)};c.sharedModelsFile&&!me.isAbsolute(c.sharedModelsFile)&&(c.sharedModelsFile=me.resolve(c.cwd,c.sharedModelsFile));let u=[];if(c.url||u.push("--url"),c.token||u.push("--token"),c.workspace||u.push("--workspace"),c.agent||u.push("--agent"),c.share&&!c.sharedModelsFile&&u.push("--shared-models-file"),u.length)throw new Error(`Missing required option(s): ${u.join(", ")}`);return c}function ie(e,t){return e==null||e===""?t:typeof e=="boolean"?e:!/^(0|false|off|no)$/i.test(String(e).trim())}function Hs(e){let t=M.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 qs(e,t,n={}){let r=bt(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 bt(e){let t=new URL(e);return Js(t)&&(t.protocol="http:",t.hostname="127.0.0.1",t.port="3142"),t}function Js(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 zs(e){try{let t=bt(e);return(t.hostname==="localhost"||t.hostname==="127.0.0.1"||t.hostname==="0.0.0.0")&&t.port==="3142"}catch{return!1}}function ir(e){let t=String(e?.sessionId||""),n=String(e?.threadParentId||"");return`${t}::${n}`}var Ks=/\b(cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\b/i,Ws=[/\b(?:make|have|tell)\s+(?:the\s+)?(?:cursorbuddy|cursor buddy|avatar|buddy|pet|character|him|guy)\s+(?:say|speak)\s+(.+)$/i];function Ys(e){return String(e||"").trim().replace(/^[`"'“”‘’]+|[`"'“”‘’?.!]+$/g,"").trim().slice(0,1200)}function Vs(e){for(let t of Ws){let n=String(e||"").match(t),r=Ys(n?.[1]||"");if(r)return r}return""}function Xs(e){let t=String(e||"").replace(/\s+/g," ").trim();if(!t)return"";let n=/latest user message\s*:\s*/gi,r=null,o=null;for(;r=n.exec(t);)o=r;if(!o)return"";let s=t.slice(o.index+o[0].length).trim(),i=s.search(/\b(Return a useful response|Conversation context follows|Previous user|Previous assistant|Diagnostic notes|System prompt|Developer message)\b/i);return(i>=0?s.slice(0,i):s).trim().replace(/^["'“”‘’]+|["'“”‘’]+$/g,"").trim()}function Qs(e){let t=String(e||"").replace(/\s+/g," ").trim(),r=Xs(t)||t;if(!r)return"";if(r.length<=500)return r;let o=[/\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 s of o){let i=r.match(s);if(i?.[0])return i[0].trim()}return""}function Zs(e){let t=Qs(e);if(!t)return null;let n=/^(open|show|hide|hush|close|dismiss)\b/i.test(t),r=Ks.test(t);if(!n&&!r)return null;let o="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:o};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:o};let s=Vs(t);return s&&r?{action:"say",text:s,source:o}:r&&/\b(wave|waves|waving)\b/i.test(t)?{action:"wave",text:s,source:o}:null}async function ei(e,t){let r=`http://127.0.0.1:${Number(e.cursorBuddyPort||8787)}/cursorbuddy/control`,o=String(e.cursorBuddyBridgeSecret||M.env.AGENSIS_CURSORBUDDY_BRIDGE_SECRET||"").trim(),s={"content-type":"application/json"};o&&(s.authorization=`Bearer ${o}`,s["x-agensis-bridge-secret"]=o);let i=await fetch(r,{method:"POST",headers:s,body:JSON.stringify(t)}),a=null;try{a=await i.json()}catch{a=null}if(!i.ok||a?.ok===!1)throw new Error(a?.error||`CursorBuddy control failed with HTTP ${i.status}`);return a}function ti(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 dr(e={}){return e.cursorBuddyBridge===!1?!1:!!(e.cursorBuddyRuntime||e.primaryDaemon)}async function ni(e,t,n,r){let o="cursorbuddy-control",s="native",i=[],a=(u="")=>{B(t.ws,{action:"agent_job_delta",jobId:t.id,content:u,elapsedMs:Date.now()-r,model:o,permissionMode:s,permissionFlags:i})};a("");let d="",c="";try{await ei(e,n),d=ti(n),a(d)}catch(u){c=String(u?.message||u),d=`CursorBuddy control failed: ${c}`,a(d)}At(t,{action:"agent_job_result",jobId:t.id,response:d,error:c,elapsedMs:Date.now()-r,model:o,permissionMode:s,permissionFlags:i}),N(`Finished native CursorBuddy ${n.action} job ${t.id} in ${Math.round((Date.now()-r)/1e3)}s`)}async function ri(e,t,{signal:n,requestPermission:r=null}){let o=Date.now();N(`Starting job ${t.id}`);let s=mr(e,t);if(e.runtimeLocked&&s!==e.runtime){let I=`Executor runtime ${e.runtime} cannot accept job runtime ${s}.`;B(t.ws,{action:"agent_job_result",jobId:t.id,response:"",error:I,errorCode:"runtime_mismatch",elapsedMs:Date.now()-o,metadata:{executionRuntime:e.runtime}}),N(`Job ${t.id} refused: runtime mismatch (${e.runtime} != ${s})`);return}if(et(t)){await oi(e,t,{signal:n,started:o}),e.once&&(N("One-shot Amp job complete; exiting."),setTimeout(()=>M.exit(0),150));return}let i=Zs(t.prompt);if(i&&dr(e)){await ni(e,t,i,o),e.once&&(N("One-shot CursorBuddy control job complete; exiting."),setTimeout(()=>M.exit(0),150));return}let a=ai(e,t),d=await si(e,t),c="",u="",p=0,l=(I="")=>{B(t.ws,{action:"agent_job_delta",jobId:t.id,content:I,elapsedMs:Date.now()-o,model:a.model,permissionMode:a.permissionMode,permissionFlags:a.permissionFlags})},f=I=>{B(t.ws,{action:"agent_job_step",jobId:t.id,kind:I.kind,name:I.name,detail:I.detail,elapsedMs:Date.now()-o})},S=I=>{B(t.ws,{action:"agent_job_segment",jobId:t.id,text:I.text,elapsedMs:Date.now()-o})};l("");let g=a.streamJson?pr({onStep:f,onSegment:S}):null,w=setInterval(()=>l(c),1e3);w.unref&&w.unref();let b=!/[\\/]/.test(a.cmd),k=e.fastConnection&&b?kt(a.cmd)?"claude":Et(a.cmd)?"codex":null:null,v=await un(t,{family:k}).run({cmd:a.cmd,args:[...a.args,d],env:a.env,cwd:t.cwd||e.cwd,timeoutMs:e.timeoutMs,heartbeatMs:e.heartbeatMs,label:"agent job",signal:n,job:t,prompt:d,model:a.model,permissionMode:a.permissionMode,hostFolders:yr(e,t),leanCli:e.leanCli,mcp:e.leanCli?wt(e):null,sessionKey:`${t.workspaceId||e.workspace||""}:${e.agent||e.handle||""}`,clientVersion:ce,requestPermission:r,onData:I=>{g?(g.feed(I),c=g.live):(c+=String(I||""),u=Si(`${u}
|
|
49
|
+
${I}`));let h=Date.now();h-p>150&&(p=h,l(c))}});clearInterval(w),g&&(g.end(),c=g.live,l(c));let $=String(v.stdout||"").trim(),T=String(v.stderr||"").trim(),m=v.error?v.error.message:v.status===0?"":T||`Command exited with status ${v.status}`,y=g?g.result||(m?"":T):$||(m?"":T)||u||"";At(t,{action:"agent_job_result",jobId:t.id,response:y,error:m,elapsedMs:Date.now()-o,model:a.model,permissionMode:a.permissionMode,permissionFlags:a.permissionFlags}),N(`Finished job ${t.id} in ${Math.round((Date.now()-o)/1e3)}s`),e.once&&(N("One-shot job complete; exiting."),setTimeout(()=>M.exit(0),150))}async function oi(e,t,{signal:n,started:r=Date.now()}={}){let o="amp-orb",s="amp-managed",i=[],a=(m="")=>B(t.ws,{action:"agent_job_delta",jobId:t.id,content:m,elapsedMs:Date.now()-r,model:o,permissionMode:s,permissionFlags:i}),d=m=>B(t.ws,{action:"agent_job_step",jobId:t.id,kind:m.kind,name:m.name,detail:m.detail,elapsedMs:Date.now()-r}),c=m=>B(t.ws,{action:"agent_job_segment",jobId:t.id,text:m.text,elapsedMs:Date.now()-r}),u=({response:m="",error:y="",errorCode:I="",threadId:h=""}={})=>{let A=he(h);At(t,{action:"agent_job_result",jobId:t.id,response:m,error:y,errorCode:I||void 0,elapsedMs:Date.now()-r,model:o,permissionMode:s,permissionFlags:i,metadata:{runtime:"amp",...A?{ampThreadId:A,ampThreadUrl:`https://ampcode.com/threads/${A}`}:{},...I?{ampErrorCode:I}:{}}})};a("");let p=me.resolve(String(t.cwd||e.cwd)),l=[e.cwd,...e.hostFolders||[]];try{await pn({cwd:p,allowedRoots:l});let m=await tt({cwd:p,executable:e.ampCmd,signal:n});if(!m.available)throw ee(m.reason||"amp_cli_crashed")}catch(m){let y=n?.aborted?"amp_turn_cancelled":String(m?.code||"amp_cli_crashed");u({error:m?.message||ee(y).message,errorCode:y}),N(`Amp job ${t.id} refused: ${y}`);return}let f=String(t?.runtime?.threadId||t?.ampThreadId||t?.metadata?.ampThreadId||"").trim(),S=he(f);if(t?.runtime?.continuationRequired===!0&&!S||f&&!S){let m=ee("amp_thread_not_found");u({error:m.message,errorCode:m.code}),N(`Amp job ${t.id} refused: ${m.code}`);return}let g=dn({executable:e.ampCmd,prompt:String(t.prompt||""),threadId:S}),w=pr({onStep:d,onSegment:c}),b=mn(),k="",E=0,v=setInterval(()=>a(k),1e3);v.unref&&v.unref();let $=await Z({cmd:g.cmd,args:g.args,cwd:p,timeoutMs:e.timeoutMs,heartbeatMs:e.heartbeatMs,label:"Amp orb turn",signal:n,onData:m=>{w.feed(m),b.feed(m),k=w.live;let y=Date.now();y-E>150&&(E=y,a(k))}});clearInterval(v),w.end(),b.end(),k=w.live,a(k);let T=b.threadId||S;if($.status!==0||$.error){let m=fn($);u({error:m.message,errorCode:m.code,threadId:T}),N(`Amp job ${t.id} failed: ${m.code}`);return}if(!T){let m=ee("amp_stream_invalid");u({error:m.message,errorCode:m.code}),N(`Amp job ${t.id} failed: ${m.code}`);return}u({response:w.result||"",threadId:T}),N(`Finished Amp job ${t.id} in ${Math.round((Date.now()-r)/1e3)}s (${T})`)}async function si(e,t){let n=t.agent||{},r=Array.isArray(n.skills)?n.skills.join(", "):String(n.skills||""),o=Array.isArray(n.tools)?n.tools.join(", "):String(n.tools||""),s=fr(e,t),i=hr(e,t),a=await or(e).catch(()=>null),d=a?`Heartbeat (recurring instructions \u2014 edit at ${Yn(e)}):
|
|
50
50
|
${a}`:"",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: ${s}`,`Permission mode: ${i}`,n.description?`Description:
|
|
51
51
|
${n.description}`:"",n.soul?`Soul:
|
|
52
52
|
${n.soul}`:"",n.system_prompt?`System instructions:
|
|
@@ -57,17 +57,17 @@ ${r}`:"",'Thread widgets: this chat has a right-side widget rail the human watch
|
|
|
57
57
|
|
|
58
58
|
`);return e.leanCli?ii(u,js):u}function ii(e,t){let n=String(e||"");if(Buffer.byteLength(n,"utf8")<=t)return n;let r=`[... older or optional Agensis context omitted ...]
|
|
59
59
|
|
|
60
|
-
`,o=Math.max(0,t-Buffer.byteLength(r,"utf8")),s=[...n],i=0,a=s.length;for(;i<a;){let d=Math.ceil((i+a)/2),c=s.slice(s.length-d).join("");Buffer.byteLength(c,"utf8")<=o?i=d:a=d-1}return r+s.slice(s.length-i).join("")}function ai(e,t){let{cmd:n,args:r}=wr(e.codingCmd),o=fr(e,t),s=hr(e,t),i=yi(r),a=vt(s),d=yr(e,t);if(kt(n)){let c=[...i];o&&c.push("--model",o);let u;if(e.leanCli){let
|
|
61
|
-
`))>=0;)
|
|
62
|
-
${me.resolve(e.cwd)}`;if(ae?.key===t&&Date.now()-ae.at<6e4)return ae.value??ae.pending;let n=tt({cwd:e.cwd,executable:e.ampCmd});ae={key:t,at:Date.now(),pending:n};try{let r=await n;return ae={key:t,at:Date.now(),value:r},r}catch(r){throw ae?.pending===n&&(ae=null),r}}async function Ee(e,t,n=null){try{let r=await Sr(t,n);B(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,runtimes:r.runtimes,codingRoute:r.codingRoute,shared:r.shared,memoryRoot:r.memoryRoot,reach:r.reach||void 0,hash:r.capabilitiesHash,memoryHash:r.memoryHash,skillsHash:r.skillsHash}),N(`Capabilities synced \u2014 skills:${r.skills.length} commands:${r.commands.length} clis:${r.clis.length} mcp:${r.mcpServers.length}`)}catch(r){N(`Capabilities sync skipped: ${r?.message||r}`)}}function gi(e){let t=Ie.networkInterfaces(),n=[];for(let r of Object.values(t))for(let o of r||[])o.family==="IPv4"&&!o.internal&&n.push({host:o.address,port:e,scope:"lan"});return n.slice(0,4)}async function cr(e,t){try{if(!t.syncMemory)return;let n=ot({cwd:t.cwd,memoryDir:t.memoryDir});if(!n)return;let r=await Tn(n);B(e,{action:"agent_memory_sync",workspaceId:t.workspace,agentId:t.agent,root:n,files:r}),N(`Synced ${r.length} memory file${r.length===1?"":"s"} from ${n}`)}catch(n){N(`Memory sync skipped: ${n?.message||n}`)}}async function ur(e,t){try{if(!t.syncSkills)return;let n=Fe(await dt({cwd:t.cwd})),r=await Bn({cwd:t.cwd});B(e,{action:"agent_skill_sync",workspaceId:t.workspace,agentId:t.agent,hash:n,skills:r});let o=r.filter(s=>s.truncated).length;N(`Synced ${r.length} skill document${r.length===1?"":"s"}${o?` (${o} truncated)`:""}`)}catch(n){N(`Skill sync skipped: ${n?.message||n}`)}}function yi(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 o=0;o<e.length;o+=1){let s=e[o],[i]=String(s).split("=",1);if(!n.has(s)){if(t.has(i)){String(s).includes("=")||(o+=1);continue}r.push(s)}}return r}function kt(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function Et(e){return/(^|\/)codex(?:$|\.)/.test(String(e||""))}function wr(e){let t=[],n="",r="",o=!1;for(let s of e){if(o){n+=s,o=!1;continue}if(s==="\\"){o=!0;continue}if(r){s===r?r="":n+=s;continue}if(s==='"'||s==="'"){r=s;continue}if(/\s/.test(s)){n&&(t.push(n),n="");continue}n+=s}if(n&&t.push(n),!t.length)throw new Error("coding command is empty");return{cmd:t[0],args:t.slice(1)}}function St(e){try{return JSON.parse(String(e))}catch{return null}}function B(e,t){return!e||e.readyState!==Ae.OPEN?!1:(e.send(JSON.stringify(t)),!0)}function At(e,t){return B(e.ws,t)?!0:(e.parkResult?.(t),!1)}function Si(e){return String(e||"").split(/\r?\n/).map(t=>t.trim()).filter(Boolean).slice(-1)[0]||""}function br(e){return String(e||"").trim().toLowerCase().replace(/^@+/,"").replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}function wi(e){return e?.code==="EADDRINUSE"||/\bEADDRINUSE\b/.test(String(e?.message||e))}async function bi(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}),o=await r.json().catch(()=>({}));return!r.ok||!o?.ok?null:o}catch{return null}finally{clearTimeout(n)}}function N(e){
|
|
60
|
+
`,o=Math.max(0,t-Buffer.byteLength(r,"utf8")),s=[...n],i=0,a=s.length;for(;i<a;){let d=Math.ceil((i+a)/2),c=s.slice(s.length-d).join("");Buffer.byteLength(c,"utf8")<=o?i=d:a=d-1}return r+s.slice(s.length-i).join("")}function ai(e,t){let{cmd:n,args:r}=wr(e.codingCmd),o=fr(e,t),s=hr(e,t),i=yi(r),a=vt(s),d=yr(e,t);if(kt(n)){let c=[...i];o&&c.push("--model",o);let u;if(e.leanCli){let S=wt(e);c.push("--no-session-persistence","--safe-mode","--mcp-config",JSON.stringify({mcpServers:{agensis:{type:"http",url:S.url,headers:{Authorization:"Bearer ${AGENSIS_MCP_TOKEN}"}}}}),"--strict-mcp-config"),u=S.env}if(s==="accept_edits"&&c.push("--permission-mode","acceptEdits"),s==="yolo"){let S=t&&t.agent&&t.agent.run_mode==="sandbox",g=typeof M.getuid=="function"&&M.getuid()===0,w=S||di(),b=M.env.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1";w||!g||b?c.push("--dangerously-skip-permissions"):(a=[],N("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 p=i.some(S=>S==="--output-format"||String(S).startsWith("--output-format=")),l=i.includes("-p")||i.includes("--print"),f=!1;!p&&l?(c.push("--output-format","stream-json","--include-partial-messages"),i.includes("--verbose")||c.push("--verbose"),f=!0):p&&(f=i.some(S=>/stream-json/.test(String(S))));for(let S of d)c.push("--add-dir",S);return{cmd:n,args:c,model:o,permissionMode:s,permissionFlags:a,streamJson:f,env:u}}if(Et(n)){let c=[...i];o&&c.push("--model",o);let u;if(e.leanCli&&i.includes("exec")){let p=wt(e);c.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(p.url)}`,"-c",'mcp_servers.agensis.bearer_token_env_var="AGENSIS_MCP_TOKEN"'),u=p.env}return s==="yolo"&&c.push("--sandbox","danger-full-access","--ask-for-approval","never"),{cmd:n,args:c,model:o,permissionMode:s,permissionFlags:a,env:u}}return{cmd:n,args:r,model:o,permissionMode:s,permissionFlags:a}}function ci(e){if(!String(e||"").trim())return"custom";let t;try{({cmd:t}=wr(e))}catch{return"custom"}return kt(t)?"claude":Et(t)?"codex":"custom"}function mr(e,t){if(et(t))return"amp";let n=String(t?.agent?.metadata?.executionRuntime||t?.agent?.metadata?.runtime||"").trim().toLowerCase();return["claude","codex","amp","custom"].includes(n)?n:e.runtime==="amp"?"custom":e.runtime}function wt(e){let t=bt(e.url);return t.pathname="/backend/mcp",t.search="",t.hash="",{url:t.toString(),env:{AGENSIS_MCP_TOKEN:e.token}}}function pr({onStep:e,onSegment:t}={}){let n="",r="",o=!1,s="",i="",a=null,d=!1,c=!1,u=new Set,p=g=>{if(!(typeof e!="function"||!g.name))try{e(g)}catch{}},l=g=>{if(typeof t=="function"){i+=o?r:s,r="",s="";try{t(g)}catch{}}},f=g=>{if(!g||typeof g!="object")return;if(g.type==="agensis_step"){let b=g.step;b&&typeof b=="object"&&(d=!0,p({kind:b.kind||"tool",name:String(b.name||""),detail:String(b.detail||"")}));return}if(g.type==="agensis_segment"){let b=g.segment;b&&typeof b=="object"&&(c=!0,l({text:String(b.text||"")}));return}let w=g.event&&g.event.delta||g.delta;if(w&&w.type==="text_delta"&&typeof w.text=="string"){o=!0,r+=w.text;return}if(g.type==="result"&&typeof g.result=="string"){a=g.result;return}if(g.type==="assistant"&&g.message&&Array.isArray(g.message.content)){let b=g.message.content.filter(k=>k&&k.type==="text"&&typeof k.text=="string").map(k=>k.text).join("");if(b&&(s+=b),b&&!c&&l({text:b}),!d)for(let k of g.message.content){if(!k||k.type!=="tool_use")continue;let E=typeof k.id=="string"?k.id:"";if(E){if(u.has(E))continue;u.add(E)}p({kind:"tool",name:String(k.name||""),detail:Ne(k.input)})}}},S=g=>{let w=String(g).trim();if(w)try{f(JSON.parse(w))}catch{}};return{feed(g){n+=String(g||"");let w;for(;(w=n.indexOf(`
|
|
61
|
+
`))>=0;)S(n.slice(0,w)),n=n.slice(w+1)},end(){n&&(S(n),n="")},get live(){return o?r:s},get result(){return a??i+(o?r:s)}}}function fr(e,t){return _t(t?.agent?.model||t?.model||e.model,mr(e,t))}function ui(e){let t=String(e||"").trim();return!t||t==="auto"||t==="claude-fable-5"?Fs:t}function _t(e,t){let n=String(e||"").trim();return t==="codex"||t==="amp"?!n||n==="auto"?"":n:ui(n)}function hr(e,t){return He(t?.agent?.permissionMode||t?.agent?.permission_mode||t?.permissionMode||t?.permission_mode||e.permissionMode)}function He(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 vt(e){return He(e)==="yolo"?["--no-sandbox","--yolo"]:[]}function gr(e){let t=Array.isArray(e)?e:String(e||"").split(/[,\n]/),n=new Set,r=[];for(let o of t){let s=String(o||"").trim();!s||n.has(s)||(n.add(s),r.push(s))}return r}function li(e,t){let n=t?.agent?.metadata?.host_folders??t?.agent?.hostFolders??t?.hostFolders??t?.host_folders,r=gr(n);return r.length>0?r:e.hostFolders||[]}function yr(e,t){let n=li(e,t),r=K({workspace:e.workspace,agent:e.agent});return r&&!n.includes(r)?[...n,r]:n}var de;function di(){if(de!==void 0)return de;let e=M.env;if(e.AGENSIS_ALLOW_ROOT_SKIP_PERMISSIONS==="1"||e.AGENSIS_SANDBOX_HOST==="1"||e.IS_SANDBOX==="1")return de=!0;if(e.AGENSIS_NO_SANDBOX_AUTODETECT==="1")return de=!1;try{if(xe.existsSync("/.dockerenv")||xe.existsSync("/run/.containerenv"))return de=!0}catch{}try{let t=xe.readFileSync("/proc/1/cgroup","utf8");if(/docker|kubepods|containerd|lxc|podman/i.test(t))return de=!0}catch{}return de=!1}function yt(e,t,n,r=null,o=null){let s={busy:t.active()>0,queueSize:t.size(),cwd:e.cwd,model:e.model,permissionMode:e.permissionMode,permissionFlags:vt(e.permissionMode),daemon:{runtime:"agensis-cli",version:ce,pid:M.pid,node:M.version,platform:M.platform,arch:M.arch,host:Ie.hostname(),cwd:e.cwd}};if(o instanceof Map){let i={};for(let a of o.values()){let d=String(a?.model||"");d&&(i[d]=(i[d]||0)+1)}s.activeInferenceByModel=i}return r&&typeof r=="object"&&(s.cursorBuddy=mi(r)),n?.status&&(s.agentStatus=n.status),n?.note&&(s.agentNote=n.note),(n?.status||n?.note)&&(s.agentStatusAt=new Date().toISOString()),s}function mi(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:{},o=e.manifest&&typeof e.manifest=="object"?e.manifest:{},s=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(o.name||"").slice(0,120),version:String(o.version||"").slice(0,80),source:String(o.source||"").slice(0,500)},project:{name:String(s.name||"").slice(0,120),root:String(s.root||"").slice(0,500),agent:String(s.agent||"").slice(0,80)},updatedAt:String(e.updatedAt||"").slice(0,80)}}function ar(e,t){if(!t||typeof t!="object")return;t.name&&(e.name=String(t.name).trim()||e.name),(t.handle||t.name)&&(e.handle=br(t.handle||t.name||e.handle)),t.model&&(e.model=_t(t.model,e.runtime));let n=t.permissionMode||t.permission_mode;n&&(e.permissionMode=He(n)),(t.memory_dir!==void 0||t.memoryDir!==void 0)&&(e.memoryDir=String(t.memory_dir??t.memoryDir??"").trim())}function pi(){let e=["amp","claude","codex","gh","node","npm","python3","git","fly","vercel"],t=(M.env.PATH||"").split(me.delimiter).filter(Boolean);return e.filter(n=>t.some(r=>{try{return xe.existsSync(me.join(r,n))}catch{return!1}}))}function fi(){try{let e=xe.readFileSync(me.join(Ie.homedir(),".claude.json"),"utf8"),n=JSON.parse(e)?.mcpServers;if(n&&typeof n=="object")return Object.keys(n).sort()}catch{}return[]}function Fe(e){return Ps.createHash("sha1").update(String(e)).digest("hex").slice(0,16)}async function Sr(e,t=null){let n=Nn({cwd:e.cwd}),r=$n({cwd:e.cwd}),o=pi(),s=fi(),i=e.syncMemory&&ot({cwd:e.cwd,memoryDir:e.memoryDir})||null,a=Un(e.sharedModels),d=await hi(e),c={claude:{id:"claude",label:"Claude",available:o.includes("claude")},codex:{id:"codex",label:"Codex",available:o.includes("codex")},amp:{...d,label:"Amp"}},u=Fe(JSON.stringify({skills:n,commands:r,clis:o,mcpServers:s,memoryRoot:i,sharedModels:a,runtimes:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null})),p=Fe(await Cn(i)),l=e.syncSkills?Fe(await dt({cwd:e.cwd})):null;return{skills:n,commands:r,clis:o,mcpServers:s,memoryRoot:i,sharedModels:a,runtimes:c,codingRoute:!!e.codingCmd,shared:e.share,reach:t||null,capabilitiesHash:u,memoryHash:p,skillsHash:l}}var ae=null;async function hi(e){let t=`${e.ampCmd}
|
|
62
|
+
${me.resolve(e.cwd)}`;if(ae?.key===t&&Date.now()-ae.at<6e4)return ae.value??ae.pending;let n=tt({cwd:e.cwd,executable:e.ampCmd});ae={key:t,at:Date.now(),pending:n};try{let r=await n;return ae={key:t,at:Date.now(),value:r},r}catch(r){throw ae?.pending===n&&(ae=null),r}}async function Ee(e,t,n=null){try{let r=await Sr(t,n);B(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,runtimes:r.runtimes,codingRoute:r.codingRoute,shared:r.shared,memoryRoot:r.memoryRoot,reach:r.reach||void 0,hash:r.capabilitiesHash,memoryHash:r.memoryHash,skillsHash:r.skillsHash}),N(`Capabilities synced \u2014 skills:${r.skills.length} commands:${r.commands.length} clis:${r.clis.length} mcp:${r.mcpServers.length}`)}catch(r){N(`Capabilities sync skipped: ${r?.message||r}`)}}function gi(e){let t=Ie.networkInterfaces(),n=[];for(let r of Object.values(t))for(let o of r||[])o.family==="IPv4"&&!o.internal&&n.push({host:o.address,port:e,scope:"lan"});return n.slice(0,4)}async function cr(e,t){try{if(!t.syncMemory)return;let n=ot({cwd:t.cwd,memoryDir:t.memoryDir});if(!n)return;let r=await Tn(n);B(e,{action:"agent_memory_sync",workspaceId:t.workspace,agentId:t.agent,root:n,files:r}),N(`Synced ${r.length} memory file${r.length===1?"":"s"} from ${n}`)}catch(n){N(`Memory sync skipped: ${n?.message||n}`)}}async function ur(e,t){try{if(!t.syncSkills)return;let n=Fe(await dt({cwd:t.cwd})),r=await Bn({cwd:t.cwd});B(e,{action:"agent_skill_sync",workspaceId:t.workspace,agentId:t.agent,hash:n,skills:r});let o=r.filter(s=>s.truncated).length;N(`Synced ${r.length} skill document${r.length===1?"":"s"}${o?` (${o} truncated)`:""}`)}catch(n){N(`Skill sync skipped: ${n?.message||n}`)}}function yi(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 o=0;o<e.length;o+=1){let s=e[o],[i]=String(s).split("=",1);if(!n.has(s)){if(t.has(i)){String(s).includes("=")||(o+=1);continue}r.push(s)}}return r}function kt(e){return/(^|\/)claude(?:$|\.)/.test(String(e||""))}function Et(e){return/(^|\/)codex(?:$|\.)/.test(String(e||""))}function wr(e){let t=[],n="",r="",o=!1;for(let s of e){if(o){n+=s,o=!1;continue}if(s==="\\"){o=!0;continue}if(r){s===r?r="":n+=s;continue}if(s==='"'||s==="'"){r=s;continue}if(/\s/.test(s)){n&&(t.push(n),n="");continue}n+=s}if(n&&t.push(n),!t.length)throw new Error("coding command is empty");return{cmd:t[0],args:t.slice(1)}}function St(e){try{return JSON.parse(String(e))}catch{return null}}function B(e,t){return!e||e.readyState!==Ae.OPEN?!1:(e.send(JSON.stringify(t)),!0)}function At(e,t){return B(e.ws,t)?!0:(e.parkResult?.(t),!1)}function Si(e){return String(e||"").split(/\r?\n/).map(t=>t.trim()).filter(Boolean).slice(-1)[0]||""}function br(e){return String(e||"").trim().toLowerCase().replace(/^@+/,"").replace(/[^a-z0-9_.-]+/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}function wi(e){return e?.code==="EADDRINUSE"||/\bEADDRINUSE\b/.test(String(e?.message||e))}async function bi(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}),o=await r.json().catch(()=>({}));return!r.ok||!o?.ok?null:o}catch{return null}finally{clearTimeout(n)}}function N(e){M.stderr.write(`[agensis] ${e}
|
|
63
63
|
`)}function lr(e){if(e instanceof Map)for(let t of e.values())try{t?.abort?.()}catch{}}import _i from"node:crypto";import Ce from"node:fs/promises";import vi from"node:os";import _r from"node:path";var pe="default",vr=2,ki=/^[a-zA-Z0-9_.-]{1,64}$/,Ei=["url","token","workspace","agent","handle","name","cwd","runtime","codingCmd","ampCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","fullCliContext","syncMemory","syncSkills","lanListener","primaryDaemon","cursorBuddyBridge","cursorBuddyPort","hostFolders"];function Q(e=pe){let t=String(e||pe).trim();if(!ki.test(t))throw new Error("Daemon profile names may only contain letters, numbers, dot, dash, and underscore.");return t}function kr(e=pe,t={}){let n=t.homedir||vi.homedir();return _r.join(n,".agensis","daemon-profiles",`${Q(e)}.json`)}function xt(e={}){let t={};for(let n of Ei){let r=e[n];r!=null&&r!==""&&(t[n]=r)}return t}function ue(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 Er(e={}){return!!(ue(e,["url","baseUrl"],["AGENSIS_URL"])||ue(e,["token"],["AGENSIS_TOKEN"])||ue(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])||ue(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}function It(e={}){return!!(ue(e,["url","baseUrl"],["AGENSIS_URL"])&&ue(e,["token"],["AGENSIS_TOKEN"])&&ue(e,["workspace","workspaceId"],["AGENSIS_WORKSPACE","AGENSIS_WORKSPACE_ID"])&&ue(e,["agent","agentId"],["AGENSIS_AGENT","AGENSIS_AGENT_ID"]))}async function Ct(e=pe,t={}){let n=kr(e,t),r;try{r=await Ce.readFile(n,"utf8")}catch(a){if(a?.code==="ENOENT")return null;throw a}let o;try{o=JSON.parse(r)}catch(a){throw new Error(`Daemon profile "${Q(e)}" is unreadable: ${a?.message||a}`)}let s=o?.config;if(!s?.url||!s?.token||!s?.workspace||!s?.agent)return null;let i=xt(s);return Number(o.version||1)<vr&&Number(i.maxConcurrency)===8&&(i.maxConcurrency=2),i}async function qe(e=pe,t={},n={}){let r=xt(t);if(!r.url||!r.token||!r.workspace||!r.agent)return null;let o=kr(e,n),s=_r.dirname(o);await Ce.mkdir(s,{recursive:!0,mode:448});let i=`${o}.${process.pid}.${Date.now()}.tmp`,a={version:vr,savedAt:new Date().toISOString(),profile:Q(e),tokenHash:_i.createHash("sha256").update(r.token).digest("hex"),config:r};return await Ce.writeFile(i,`${JSON.stringify(a,null,2)}
|
|
64
64
|
`,{mode:384}),await Ce.rename(i,o),await Ce.chmod(o,384).catch(()=>{}),o}function Ar(e,t={}){let n={...e,...xt(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 Tt(e=pe){let t=Q(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===pe?"":` --profile ${t}`}`].join(`
|
|
65
65
|
`)}import Ai from"node:crypto";import Te from"node:fs/promises";import xr from"node:os";import Mt from"node:path";import $t from"node:process";var xi=/^cbk_[a-z0-9_]+_[A-Z2-9]{18}$/;function Ii(e={}){return String(e.url||e.baseUrl||$t.env.AGENSIS_URL||"https://agensis.io").trim().replace(/\/+$/,"")}function Ir(e,t={}){let n=t.homedir||xr.homedir(),r=Ai.createHash("sha256").update(String(e)).digest("hex");return Mt.join(n,".agensis","cursorbuddy","connection-keys",`${r}.json`)}function Ci(){return new Error("Missing or invalid --key. Create a CursorBuddy connection key in Agensis first.")}function Nt(e){let t=String(e||"").trim();if(!xi.test(t))throw Ci();return t}function Ti(e,t,n,r){let o=t?.token,s=t?.workspaceId||t?.workspace_id||t?.agent?.workspace_id,i=t?.agentId||t?.agent?.id;if(!o||!s||!i)throw new Error("CursorBuddy key claim did not return a complete daemon connection payload");let{key:a,subcommand:d,...c}=e;return{...c,command:"connect",url:t.baseUrl||n,token:o,workspace:s,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 Mi(e,t={}){Nt(e);let n=Ir(e,t),r;try{r=await Te.readFile(n,"utf8")}catch(i){if(i?.code==="ENOENT")return null;throw i}let o;try{o=JSON.parse(r)}catch(i){throw new Error(`Cached CursorBuddy daemon config is unreadable: ${i?.message||i}`)}let s=o?.daemonArgs;return!s?.token||!s?.workspace||!s?.agent||!s?.url?null:s}async function $i(e,t,n={}){if(Nt(e),!t?.token||!t?.workspace||!t?.agent||!t?.url)return;let r=Ir(e,n),o=Mt.dirname(r);await Te.mkdir(o,{recursive:!0,mode:448});let s=`${r}.${$t.pid}.${Date.now()}.tmp`,i={version:1,savedAt:new Date().toISOString(),keyHash:Mt.basename(r,".json"),daemonArgs:t};await Te.writeFile(s,`${JSON.stringify(i,null,2)}
|
|
66
|
-
`,{mode:384}),await Te.rename(s,r),await Te.chmod(r,384).catch(()=>{})}function Ni(e,t,n){let r={...e,command:"connect"};for(let o of["cwd","codingCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","lanListener","once"])t[o]!==void 0&&(r[o]=t[o]);return t.codingCmd!==void 0&&t.noCoding===void 0&&(r.noCoding=!1),r.cwd||(r.cwd=n),r.cursorBuddyRuntime=!0,r}function Oi(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function Ri(e){return e.json().catch(()=>({}))}async function Cr(e,t={}){let n=Nt(e?.key),r=Ii(e),o=t.fetchImpl||globalThis.fetch;if(typeof o!="function")throw new Error("This Node.js runtime does not provide fetch; use a current Node.js release.");let s=t.cwd||$t.cwd(),i=t.hostname||xr.hostname(),a=t.version||ce,d={homedir:t.homedir},c=await o(`${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||s,name:e.name,surface:e.surface||"local_cli",scope:e.scope||"machine",runtimeKind:"agensis-cli",version:a,permissionMode:e.permissionMode,model:e.model})}),u=await Ri(c);if(!c.ok){let l=Oi(c,u);if(c.status===409||/already been claimed/i.test(l)){let
|
|
66
|
+
`,{mode:384}),await Te.rename(s,r),await Te.chmod(r,384).catch(()=>{})}function Ni(e,t,n){let r={...e,command:"connect"};for(let o of["cwd","codingCmd","model","permissionMode","timeoutMs","heartbeatMs","maxConcurrency","share","sharedModelsFile","noCoding","leanCli","lanListener","once"])t[o]!==void 0&&(r[o]=t[o]);return t.codingCmd!==void 0&&t.noCoding===void 0&&(r.noCoding=!1),r.cwd||(r.cwd=n),r.cursorBuddyRuntime=!0,r}function Oi(e,t){return t?.error?.message||t?.message||`CursorBuddy key claim failed with HTTP ${e.status}`}async function Ri(e){return e.json().catch(()=>({}))}async function Cr(e,t={}){let n=Nt(e?.key),r=Ii(e),o=t.fetchImpl||globalThis.fetch;if(typeof o!="function")throw new Error("This Node.js runtime does not provide fetch; use a current Node.js release.");let s=t.cwd||$t.cwd(),i=t.hostname||xr.hostname(),a=t.version||ce,d={homedir:t.homedir},c=await o(`${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||s,name:e.name,surface:e.surface||"local_cli",scope:e.scope||"machine",runtimeKind:"agensis-cli",version:a,permissionMode:e.permissionMode,model:e.model})}),u=await Ri(c);if(!c.ok){let l=Oi(c,u);if(c.status===409||/already been claimed/i.test(l)){let f=await Mi(n,d);if(f)return Ni(f,e,s);throw new Error(`${l}. 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(l)}let p=Ti(e,u?.data||u,r,s);return await $i(n,p,d),p}import Di from"node:crypto";import Bi from"node:http";import Pi from"node:os";import te from"node:process";import{spawn as Li}from"node:child_process";var Ui="https://agensis.io",ji=10*60*1e3;function Je(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 Fi(e){return new Promise((t,n)=>{let r="";e.on("data",o=>{r+=o,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 Gi(e){let t=String(e||te.env.AGENSIS_URL||Ui).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 Hi(e){let t=te.platform==="darwin"?"open":te.platform==="win32"?"cmd":"xdg-open",n=te.platform==="win32"?["/c","start","",e]:[e],r=Li(t,n,{detached:!0,stdio:"ignore"});r.on("error",()=>{}),r.unref()}function qi(e){let t=e?.daemonArgs||e?.data?.daemonArgs||e?.data||{},r=["url","token","workspace","agent"].filter(o=>!String(t[o]||"").trim());if(r.length)throw new Error(`Setup callback did not include ${r.join(", ")}`);return{...t,command:"connect"}}function Ji(e,t,n){let r=new URL(Gi(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",Q(e.profile||"default")),r.searchParams.set("host",Pi.hostname()),r.searchParams.set("cwd",String(e.cwd||te.cwd())),e.handle&&r.searchParams.set("handle",String(e.handle)),e.name&&r.searchParams.set("name",String(e.name)),r.toString()}async function Tr(e={}){let t=Q(e.profile||"default"),n=Di.randomBytes(24).toString("base64url"),r=Number(e.setupTimeoutMs||te.env.AGENSIS_SETUP_TIMEOUT_MS||ji),o,s=new Promise((c,u)=>{let p=setTimeout(()=>u(new Error("Agensis setup timed out waiting for browser login.")),r);p.unref&&p.unref(),o=Bi.createServer(async(l,f)=>{if(f.setHeader("access-control-allow-origin","*"),f.setHeader("access-control-allow-methods","POST, OPTIONS"),f.setHeader("access-control-allow-headers","content-type"),l.method==="OPTIONS"){f.writeHead(204),f.end();return}if(l.method!=="POST"||l.url!=="/agensis/setup-callback"){Je(f,404,{ok:!1,error:"Unknown Agensis setup callback route"});return}try{let S=JSON.parse(await Fi(l)||"{}");if(S?.state!==n){Je(f,403,{ok:!1,error:"Setup state did not match"});return}let g={...qi(S),primaryDaemon:!0,cursorBuddyBridge:e.cursorBuddyBridge!==!1};await qe(t,g),clearTimeout(p),Je(f,200,{ok:!0,profile:t}),c(g)}catch(S){Je(f,400,{ok:!1,error:String(S?.message||S)})}}),o.once("error",u)});await new Promise((c,u)=>{o.listen(0,"127.0.0.1",p=>p?u(p):c())});let{port:i}=o.address(),a=`http://127.0.0.1:${i}/agensis/setup-callback`,d=Ji(e,a,n);te.stdout.write(`[agensis] Opening Agensis to sign in and connect this machine.
|
|
67
67
|
`),te.stdout.write(`[agensis] If the browser did not open, visit:
|
|
68
68
|
${d}
|
|
69
69
|
`),Hi(d);try{let c=await s;return te.stdout.write(`[agensis] Saved daemon profile "${t}". Starting primary agent daemon.
|
|
70
|
-
`),c}finally{await new Promise(c=>o.close(()=>c())).catch(()=>{})}}function sa(e){let t={command:"connect"},n=[...e],r=n[0];if(r&&!r.startsWith("-")&&(t.command=n.shift(),t.command==="buddy")){let o=n[0];o&&!o.startsWith("-")?t.subcommand=n.shift():t.subcommand="connect"}for(let o=0;o<n.length;o+=1){let s=n[o];if(!s.startsWith("--"))throw new Error(`Unexpected argument: ${s}`);let[i,a]=s.slice(2).split(/=(.*)/s,2),d=i.replace(/-([a-z])/g,(u,
|
|
70
|
+
`),c}finally{await new Promise(c=>o.close(()=>c())).catch(()=>{})}}function sa(e){let t={command:"connect"},n=[...e],r=n[0];if(r&&!r.startsWith("-")&&(t.command=n.shift(),t.command==="buddy")){let o=n[0];o&&!o.startsWith("-")?t.subcommand=n.shift():t.subcommand="connect"}for(let o=0;o<n.length;o+=1){let s=n[o];if(!s.startsWith("--"))throw new Error(`Unexpected argument: ${s}`);let[i,a]=s.slice(2).split(/=(.*)/s,2),d=i.replace(/-([a-z])/g,(u,p)=>p.toUpperCase());if(d==="help"){t.help=!0;continue}if(d==="version"){t.version=!0;continue}if(d==="once"){t.once=!0;continue}if(d==="lan"){t.lanListener=!0;continue}if(d==="share"){t.share=!0;continue}if(d==="noCoding"){t.noCoding=!0;continue}if(d==="fullCliContext"){t.fullCliContext=!0;continue}if(d==="syncMemory"){t.syncMemory=!0;continue}if(d==="noSyncSkills"){t.syncSkills=!1;continue}if(d==="cursorbuddyBridge"){t.cursorBuddyBridge=!0;continue}if(d==="noCursorbuddyBridge"){t.cursorBuddyBridge=!1;continue}if(d==="yolo"||d==="noSandbox"){t.permissionMode="yolo";continue}if(d==="acceptEdits"){t.permissionMode="accept_edits";continue}if(d==="hostFolder"||d==="hostFolders"||d==="addDir"){let u=a!==void 0?a:n[++o];if(u==null||u.startsWith("--"))throw new Error(`Missing value for --${i}`);t.hostFolders=[...t.hostFolders||[],u];continue}let c=a!==void 0?a:n[++o];if(c==null||c.startsWith("--"))throw new Error(`Missing value for --${i}`);t[d]=c}return t}function ia(){return`agensis agent daemon
|
|
71
71
|
|
|
72
72
|
Usage:
|
|
73
73
|
agensis --url <workspace-url> --token <token> --workspace <id> --agent <id> [options]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agensis/agensis-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.40",
|
|
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": {
|