broods 0.49.1 → 0.49.3

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/dist/account.d.ts CHANGED
@@ -272,6 +272,12 @@ interface AgentSubagentConfig {
272
272
  * `subagent.task.finished` code hook overrides this for custom shaping.
273
273
  */
274
274
  visibility?: "full" | "result" | "none";
275
+ /**
276
+ * Model for virtual subagents (no `agentId`), laid over the parent's
277
+ * `model` key by key. The child keeps the parent's tools, MCP, sandboxes,
278
+ * hooks and policies. A registered agent always runs on its own model.
279
+ */
280
+ model?: Partial<AgentModelConfig>;
275
281
  [key: string]: unknown;
276
282
  }
277
283
  interface AgentModelConfig extends LanguageModelCallOptions, Partial<Pick<RequestOptions, "maxRetries" | "timeout">> {
@@ -0,0 +1 @@
1
+ import{P,i,F,N,X,Q,ee,b,I,te,ae,ce,Se,be,ve,_e,le,ue,we,Re,$e,j}from"./chunk-kx38nst5.js";var D=Symbol("swallowsErrorsAfterClose"),z=class{_readBuffer;_started=!1;_closed=!1;constructor(t=le.stdin,o=le.stdout,c){this._stdin=t,this._stdout=o,this._readBuffer=new ve({maxBufferSize:c?.maxBufferSize})}onclose;onerror;onmessage;_ondata=(t)=>{try{this._readBuffer.append(t),this.processReadBuffer()}catch(o){this.onerror?.(o),this.close().catch(()=>{})}};_onerror=(t)=>{this.onerror?.(t)};_onstdouterror=(t)=>{if(this._closed)return;this.onerror?.(t),this.close().catch(()=>{})};_onstdinclose=()=>{this.close().catch(()=>{})};async start(){if(this._started)throw Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0;for(let t of this._stdout.listeners("error"))if(t[D])this._stdout.off("error",t);if(this._stdin.readableEnded||this._stdin.destroyed)setImmediate(this._onstdinclose);this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror),this._stdin.on("end",this._onstdinclose),this._stdin.on("close",this._onstdinclose),this._stdout.on("error",this._onstdouterror)}processReadBuffer(){while(!0)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t)}catch(t){this.onerror?.(t)}}async close(){if(this._closed)return;if(this._closed=!0,this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.off("end",this._onstdinclose),this._stdin.off("close",this._onstdinclose),this._onstdouterror[D]=!0,this._stdin.listenerCount("data")===0)this._stdin.pause();this._readBuffer.clear(),this.onclose?.()}send(t){if(this._closed)return Promise.reject(Error("StdioServerTransport is closed"));return new Promise((o,c)=>{let l=_e(t),r=!1,f=(_)=>{if(r)return;r=!0,this._stdout.off("error",f),this._stdout.off("drain",p),c(_)},p=()=>{if(r)return;r=!0,this._stdout.off("error",f),this._stdout.off("drain",p),o()};if(this._stdout.once("error",f),this._stdout.write(l)){if(r)return;r=!0,this._stdout.off("error",f),o()}else if(!r)this._stdout.once("drain",p)})}},M=3000,J=class{onclose;onerror;onmessage;_closed=!1;_pendingRequests=new Set;_drainWaiters=[];constructor(t,o,c){this._wire=t,this._onInstanceClose=o,this._outboundIntercept=c}async start(){}async send(t,o){if(te(t)||ae(t)){let{id:c}=t;if(c!==void 0)this._settle(c)}if(this._closed)return;if(this._outboundIntercept?.(t)==="handled")return;return this._wire.send(t,o)}setProtocolVersion=(t)=>{this._wire.setProtocolVersion?.(t)};deliver(t,o){if(this._closed)return;if(b(t))this._pendingRequests.add(t.id);else if(I(t)&&t.method==="notifications/cancelled"){let c=t.params?.requestId;if(c!==void 0)this._settle(c)}this.onmessage?.(t,o)}async whenRequestsAnswered(t){if(this._closed||this._pendingRequests.size===0)return!0;return await new Promise((o)=>{let c=()=>{clearTimeout(l),o(!0)},l=setTimeout(()=>{this._drainWaiters=this._drainWaiters.filter((r)=>r!==c),o(!1)},t);this._drainWaiters.push(c)})}async close(){if(this._closed)return;this._closed=!0,this._pendingRequests.clear(),this._releaseDrainWaiters();try{this._onInstanceClose()}finally{this.onclose?.()}}_settle(t){if(this._pendingRequests.delete(t),this._pendingRequests.size===0)this._releaseDrainWaiters()}_releaseDrainWaiters(){let t=this._drainWaiters;this._drainWaiters=[];for(let o of t)o()}};function L(t){let o=t.params;if(t.method==="initialize"&&!ce(o)){let f=o!==null&&typeof o==="object"&&typeof o.protocolVersion==="string"?o.protocolVersion:void 0;return{kind:"legacy",reason:"initialize",...f!==void 0&&{requestedVersion:f}}}if(!X(o))return{kind:"legacy",reason:"no-claim"};let c=N(o),l=(c===void 0?[]:ee(c))[0];if(l!==void 0)return{kind:"invalid-envelope",issue:l};let r=Q(o);if(r===void 0||!P.includes(r))return{kind:"unsupported-revision",requested:r??"unknown"};return{kind:"modern",revision:r,classification:{era:"modern",revision:r}}}function H(t,o={}){let c=o.legacy??"serve",l=o.transport??new z,r={phase:"opening"},f,p=!1,_=()=>p||r.phase==="closed",d=(e)=>{try{o.onerror?.(e)}catch{}},y=(e,n,s,a)=>l.send({jsonrpc:"2.0",id:e,error:{code:n,message:s,...a!==void 0&&{data:a}}}).catch((u)=>d(h(u))),w=new we(o.maxSubscriptions??ue),V=(e)=>{if(!I(e))return;let n=w.routeOutbound(e);if(n==="passthrough")return;for(let s of n)l.send({jsonrpc:"2.0",...s}).catch((a)=>d(h(a)));return"handled"},q=async(e)=>{if(b(e)&&e.method==="subscriptions/listen"){let n=N(e.params),s=X(e.params)?(n===void 0?[]:ee(n))[0]:{key:"_meta",problem:"the per-request envelope is required on protocol revision 2026-07-28"},a=Q(e.params),u;if(s!==void 0)u={jsonrpc:"2.0",id:e.id,error:{code:-32602,message:`Invalid _meta envelope: ${s.key}: ${s.problem}`}};else if(a===void 0||!P.includes(a)){let v=new F({supported:[...P],requested:a??"unknown"});u={jsonrpc:"2.0",id:e.id,error:{code:v.code,message:v.message,data:v.data}}}else u=w.serve(e);return await l.send("error"in u?u:{jsonrpc:"2.0",method:u.method,params:u.params}).catch((v)=>d(h(v))),!0}if(I(e)&&e.method==="notifications/cancelled"){let n=e.params?.requestId;if(n!==void 0&&w.cancel(n))return!0}return!1},C=(e,n,s)=>{let a=Se({kind:"legacy",reason:n,...s!==void 0&&{requestedVersion:s}},P);if(a===void 0)return Promise.resolve();return d(Error(`Rejected 2025-era request on a modern-only stdio connection (${a.cell}): ${a.message}`)),y(e.id,a.code,a.message,a.data)},T=(e)=>{if(p||e===f)return;O()},m=async(e,n)=>{let s=await t({era:e}),a=s instanceof j?s.server:s;if(e==="modern")be(a,n),Re(a,P),w.setServerCapabilities(a.getCapabilities(),$e(a));let u=new J(l,()=>T(u),e==="modern"?V:void 0);return await s.connect(u),{product:s,channel:u}},R=(e)=>e.product.close().catch((n)=>d(h(n))),B=async(e)=>{f=e.channel;try{if(!await e.channel.whenRequestsAnswered(M))d(Error(`Discarded the probe instance with requests still unanswered after ${M}ms; continuing with the fallback`));await e.product.close()}catch(n){d(h(n))}finally{f=void 0}},A=async(e)=>{if(r.phase==="closed")return;if(r.phase==="pinned"){if(r.era==="modern"&&b(e)&&e.method==="initialize"&&!ce(e.params)){await C(e,"initialize",e.params!==null&&typeof e.params==="object"&&typeof e.params.protocolVersion==="string"?e.params.protocolVersion:void 0);return}if(r.era==="modern"&&await q(e))return;if(_())return;r.instance.channel.deliver(e);return}if(!b(e)&&!I(e)){d(Error("Discarded a JSON-RPC response received before the connection negotiated an era"));return}let n=L(e);switch(n.kind){case"invalid-envelope":{let s=`Invalid _meta envelope for protocol revision 2026-07-28: ${n.issue.key}: ${n.issue.problem}`;if(b(e))await y(e.id,i.InvalidParams,s,{envelope:n.issue});else d(Error(`Discarded a notification with a malformed envelope: ${s}`));return}case"unsupported-revision":if(b(e)){let s=new F({supported:[...P],requested:n.requested});d(s),await y(e.id,s.code,s.message,s.data)}else d(Error(`Discarded a notification claiming unsupported protocol revision ${n.requested}`));return;case"modern":if(b(e)&&e.method==="server/discover"){if(r.phase==="probe"){r.instance.channel.deliver(e,{classification:n.classification});return}let s=await m("modern",n.revision);if(_()){await R(s);return}r={phase:"probe",instance:s},s.channel.deliver(e,{classification:n.classification});return}if(r.phase==="probe"){if(I(e)){r.instance.channel.deliver(e,{classification:n.classification});return}r={phase:"pinned",era:"modern",instance:r.instance}}else{let s=await m("modern",n.revision);if(_()){await R(s);return}r={phase:"pinned",era:"modern",instance:s}}if(await q(e))return;if(_())return;r.instance.channel.deliver(e,{classification:n.classification});return;case"legacy":{if(c==="reject"){if(b(e))await C(e,n.reason,n.requestedVersion);return}if(r.phase==="probe"){if(await B(r.instance),_())return;r={phase:"opening"}}let s=await m("legacy");if(_()){await R(s);return}r={phase:"pinned",era:"legacy",instance:s},r.instance.channel.deliver(e);return}}},S=[],E=!1,W=async()=>{if(E)return;E=!0;try{while(S.length>0){let e=S.shift();try{await A(e)}catch(n){if(b(e))await y(e.id,i.InternalError,"Internal server error");d(h(n))}}}finally{E=!1}},O=async()=>{if(p||r.phase==="closed")return;p=!0;let e=r;r={phase:"closed"};for(let n of w.teardownAll())await l.send(n).catch((s)=>d(h(s)));if(e.phase==="probe"||e.phase==="pinned")await e.instance.product.close().catch((n)=>d(h(n)));await l.close().catch((n)=>d(h(n)))};l.onmessage=(e)=>{S.push(e),W()},l.onerror=(e)=>{if(d(e),r.phase==="probe"||r.phase==="pinned")r.instance.channel.onerror?.(e)},l.onclose=()=>{if(p||r.phase==="closed")return;p=!0;let e=r;if(r={phase:"closed"},e.phase==="probe"||e.phase==="pinned")e.instance.product.close().catch((n)=>d(h(n)))};let k=l.start().catch((e)=>{throw d(h(e)),e});return k.catch(()=>{}),{close:async()=>{await k.catch(()=>{}),await O()}}}function h(t){return t instanceof Error?t:Error(String(t))}export{H as serveStdio};
@@ -0,0 +1,4 @@
1
+ import{U,E}from"./chunk-6kgtx9kv.js";import{e,o,a,l,n,t,d,C,s,p,r}from"./chunk-n890pdvc.js";import{se,fe,D}from"./cli/index.js";import{spawn as re}from"node:child_process";import{statfsSync as ne}from"node:fs";import{availableParallelism as ie,homedir as ae,hostname as ce,totalmem as le}from"node:os";import{performance as A}from"node:perf_hooks";var N=["cursor_position","double_click","hold_key","key","left_click","left_click_drag","left_mouse_down","left_mouse_up","middle_click","mouse_move","right_click","screenshot","scroll","triple_click","type","wait","zoom"];var _={badFrame:{code:4400,reason:"Malformed frame"},expired:{code:4419,reason:"Credential expired"},occupied:{code:4423,reason:"Already connected from another daemon"},replaced:{code:4409,reason:"Replaced by a newer connection"},unauthorized:{code:4401,reason:"Unauthorized; run broods login"},unknownSandbox:{code:4404,reason:"No machine sandbox with that name in this account"}};var P="/v1/machines/ws",B=t({action:p(N),coordinate:n(o().int()).length(2).optional().describe("[x, y] in screenshot pixels for mouse actions."),start_coordinate:n(o().int()).length(2).optional().describe("[x, y] where a left_click_drag starts."),text:e().optional().describe("Text for type, the key chord for key and hold_key, or modifiers to hold during a click, drag or scroll."),scroll_direction:p(["down","left","right","up"]).optional(),scroll_amount:o().int().min(1).optional().describe("Scroll clicks, default 3."),duration:o().min(0).max(300).optional().describe("Seconds for wait and hold_key."),region:n(o().int()).length(4).optional().describe("[x0, y0, x1, y1] of the screenshot to zoom into."),repeat:o().int().min(1).max(100).optional().describe("How many times to press the key.")}),G=B.extend({type:r("computer"),id:e()}),W=t({type:r("computer-result"),id:e(),text:e().optional(),image:t({data:e(),mediaType:e()}).optional(),app:e().optional(),error:e().optional()}),J=t({type:r("credential"),token:e().min(1)}),K=t({type:r("exec"),id:e(),code:e(),cwd:e().optional(),env:s(e(),e()).optional(),timeoutSeconds:o().positive(),outputLimitBytes:o().positive()}),X=t({type:r("hello"),sandbox:e().min(1),hostname:e().optional(),platform:e().optional(),computer:a().optional(),mcp:n(e()).optional(),instance:e().optional(),force:a().optional(),specs:t({vcpu:o().positive(),memoryMb:o().positive(),storageGb:o().positive().optional()}).optional().catch(void 0)}),Y=t({type:r("mcp-call"),id:e(),server:e(),tool:e(),args:s(e(),l())}),q=t({type:r("mcp-list"),id:e(),server:e()}),Z=t({type:r("mcp-result"),id:e(),result:d({content:n(l())}).optional(),error:e().optional()}),Q=t({type:r("mcp-tools"),id:e(),tools:n(d({name:e(),inputSchema:s(e(),l())})).optional(),error:e().optional()}),V=t({type:r("ready"),sandboxId:e(),expiresInMs:o().optional()}),ee=t({type:r("result"),id:e(),exitCode:o().nullable(),stdout:e(),stderr:e(),durationMs:o(),timedOut:a(),truncated:a()}),te=C("type",[G,K,Y,q,V]),xe=C("type",[W,J,X,Z,Q,ee]);function z(i){let c=new URL(P,i);return c.protocol=c.protocol==="https:"?"wss:":"ws:",c.toString()}function I(i){return oe(te,i)}function oe(i,c){if(typeof c!=="string")return null;try{let y=i.safeParse(JSON.parse(c));return y.success?y.data:null}catch{return null}}var pe=new Set([_.occupied.code,_.replaced.code,_.unauthorized.code,_.unknownSandbox.code]),j=72,O=30000,R=1000;function de(i,c,y){return new Promise((g)=>{let h=A.now(),f=new L(i.outputLimitBytes),x=new L(i.outputLimitBytes),b=!1,v=!1,F=(u,m)=>{if(v)return;if(v=!0,clearTimeout(T),y?.removeEventListener("abort",S),m)x.append(Buffer.from(`${m}
2
+ `));g({type:"result",id:i.id,exitCode:u,stdout:f.text(),stderr:x.text(),durationMs:Math.round(A.now()-h),timedOut:b,truncated:f.truncated||x.truncated})},M=re("bash",["-lc",i.code],{cwd:i.cwd??c,env:{...U(),...i.env},detached:!0,stdio:["ignore","pipe","pipe"]}),k=()=>{if(!M.pid)return;try{process.kill(-M.pid,"SIGKILL")}catch{M.kill("SIGKILL")}},T=setTimeout(()=>{b=!0,k()},i.timeoutSeconds*1000),S=()=>{k(),F(null,"stopped: the daemon closed its socket")};if(y?.addEventListener("abort",S,{once:!0}),M.stdout.on("data",(u)=>f.append(u)),M.stderr.on("data",(u)=>x.append(u)),M.on("error",(u)=>F(null,u.message)),M.on("close",(u)=>F(u)),y?.aborted)S()})}async function Oe(i){let c=fe(),y=crypto.randomUUID(),g=i.mcpFile?await ge(i.mcpFile,i.log):null,h=i.computer?await ye(i.log):null,f=R;try{while(!i.signal.aborted){let x=Date.now(),b;try{b=await i.credential()}catch(F){if(F instanceof D)throw F;i.log(`stage session unavailable (${F instanceof Error?F.message:String(F)}), retrying in ${Math.round(f/1000)}s`),await se(f,i.signal),f=Math.min(f*2,O);continue}let v=await Me(i,b,y,c,h,g);if(i.signal.aborted)return;if(pe.has(v.code))throw Error(v.reason||`core closed the socket (${v.code})`);if(Date.now()-x>O)f=R;i.log(`disconnected (${v.reason||v.code}), reconnecting in ${Math.round(f/1000)}s`),await se(f,i.signal),f=Math.min(f*2,O)}}finally{h?.stop(),await g?.stop()}}class L{#o=[];#e;#t=0;truncated=!1;constructor(i){this.#e=i}append(i){if(this.#t>=this.#e){this.truncated=!0;return}let c=this.#e-this.#t;if(i.byteLength>c){this.#o.push(i.subarray(0,c)),this.#t=this.#e,this.truncated=!0;return}this.#o.push(i),this.#t+=i.byteLength}text(){let i=Buffer.concat(this.#o).toString("utf8");return this.truncated?`${i}
3
+ [output truncated]`:i}}function me(i){let c=[i.action];if(i.coordinate)c.push(`at ${i.coordinate.join(",")}`);if(i.text!==void 0)c.push(JSON.stringify(H(i.text)));if(i.region)c.push(`region ${i.region.join(",")}`);return c.join(" ")}function ue(){let i=he();return{vcpu:ie(),memoryMb:Math.round(le()/1048576),...i?{storageGb:i}:{}}}function he(){try{let i=ne(ae());return Math.round(i.blocks*i.bsize/1073741824)}catch{return}}function H(i){let c=i.trim().split(`
4
+ `)[0]??"";return c.length>j?`${c.slice(0,j)}…`:c}async function ye(i){let{startDesktop:c}=await import("./chunk-5tnnqapc.js"),{display:y,driver:g,permissions:h}=await c(!1);if(i(`computer use on, ${y.width}x${y.height} screenshots`),!h.screenRecording||!h.accessibility)i(" screen recording or accessibility is missing, run `broods machine --doctor --request`");return g}async function ge(i,c){let{McpHost:y,readMcpServersFile:g}=await import("./chunk-ctt7r720.js"),h=new y(g(i),c);return c(`mcp servers from ${i}: ${h.names().join(", ")}`),h}async function be(i,c,y){try{if(i.type==="mcp-list"){let h=await c.listTools(i.server);return y(` mcp ${i.server}: ${h.length} tools`),{type:"mcp-tools",id:i.id,tools:h}}y(` mcp ${i.server}.${i.tool}`);let g=await c.callTool(i.server,i.tool,i.args);return{type:"mcp-result",id:i.id,result:g}}catch(g){let h=g instanceof Error?g.message:String(g);return y(` mcp ${i.server}: ${h}`),{type:i.type==="mcp-call"?"mcp-result":"mcp-tools",id:i.id,error:h}}}function Me(i,c,y,g,h,f){return new Promise((x)=>{let b=new g(z(i.baseUrl),E(c)),v=new AbortController,F=()=>b.close(1000,"daemon stopped"),M=(u)=>{if(b.readyState===b.OPEN)b.send(JSON.stringify(u))},k,T=(u)=>{if(clearTimeout(k),v.signal.aborted)return;k=setTimeout(()=>{i.credential().then((m)=>M({type:"credential",token:m}),(m)=>i.log(`credential refresh failed (${m instanceof Error?m.message:String(m)}), retrying`)).finally(()=>T(u))},Math.max((u-Date.now())/2,R))},S=(u,m)=>{i.signal.removeEventListener("abort",F),clearTimeout(k),v.abort(),x({code:u,reason:m})};i.signal.addEventListener("abort",F,{once:!0}),b.onopen=()=>M({type:"hello",sandbox:i.sandbox,hostname:ce(),platform:process.platform,computer:h!==null,mcp:f?.names(),instance:y,force:i.force,specs:ue()}),b.onmessage=(u)=>{let m=I(u.data);if(m?.type==="ready"){if(k===void 0)i.log(`connected as ${i.sandbox} (${m.sandboxId})`);if(m.expiresInMs!==void 0)T(Date.now()+m.expiresInMs);return}if(m?.type==="computer"&&h){i.log(` ${me(m)}`),h.run(m).then((w)=>{if(w.error)i.log(` error: ${w.error}`);M(w)});return}if((m?.type==="mcp-call"||m?.type==="mcp-list")&&f){be(m,f,i.log).then(M);return}if(m?.type!=="exec")return;i.log(`$ ${H(m.code)}`),de(m,i.cwd,v.signal).then((w)=>{i.log(` exit ${w.exitCode??"none"} in ${w.durationMs}ms${w.timedOut?" (timed out)":""}`),M(w)})},b.onerror=()=>S(1006,"connection failed"),b.onclose=(u)=>S(u.code,u.reason)})}export{Oe as runMachineDaemon};
@@ -1,5 +1,5 @@
1
1
  function V(e){if(e.events&&e.input!==void 0)throw Error("Run input accepts either `input` or `events`, not both");if(e.events&&e.events.length>0)return e.events;if(typeof e.input==="string")return[{role:"user",content:[{type:"text",text:e.input}]}];throw Error("Run input requires `input` (string) or a non-empty `events` array")}async function*ge(e){let n=e.getReader(),t=new TextDecoder,o="";try{while(!0){let{done:r,value:i}=await n.read();if(r)break;o+=t.decode(i,{stream:!0});let s=o.split(`
2
- `);o=s.pop()??"";for(let a of s)if(a.startsWith("data: "))yield a.slice(6)}}finally{n.releaseLock()}}var Me=500,Ce=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,he=/^(?!0{32}$)[0-9a-f]{32}$/;function Pe(e){return e==="DEBUG"||e==="INFO"||e==="WARN"||e==="ERROR"}function Ne(e){if(typeof e!=="object"||e===null)return!1;let n=e;if(n.type==="subscribe")return Re(n);if(n.type==="unsubscribe")return k(n.stream);if(n.type==="fetchTrace")return Ie(n.traceId);return!1}function je(e){return e==="task"||e==="cron"||e==="subtask"}function G(e){return typeof e==="string"&&Ce.test(e)}function Ie(e){return typeof e==="string"&&he.test(e)}function k(e){return e==="logs"||e==="traces"}function Re(e){let n=e.stream;if(!k(n))return!1;let t=e.backfill;if(t!==void 0&&(typeof t!=="number"||!Number.isSafeInteger(t)||t<0||t>500))return!1;if(e.liveOnly!==void 0&&typeof e.liveOnly!=="boolean")return!1;let o=e.minLevel;if(o!==void 0&&!Pe(o))return!1;let r=e.sandboxId;return r===void 0||n==="logs"&&G(r)}import{readFileSync as Se}from"node:fs";import{chmod as B,mkdir as be,writeFile as Ae}from"node:fs/promises";import{homedir as ke}from"node:os";import{dirname as D,join as ve}from"node:path";var y="broods",_="_generated",O=ve(ke(),".broods","config.json"),N="broods.app",P="dashboard",we="gateway";function z(e){let n=process.env.BROODS_TOKEN,t=e??process.env.BROODS_BASE_URL;if(n&&t)return{baseUrl:f(t),token:n,createdAt:new Date().toISOString()};let o=H();if(!o)return null;if(t)return o.logins[f(t)]??null;let r=process.env.BROODS_DASHBOARD_URL;if(r){let i=f(r);return Object.values(o.logins).find((s)=>s.dashboardUrl===i)??null}return o.logins[o.current]??null}async function W(e){let n=H()?.logins??{},t={current:e.baseUrl,logins:{...n,[e.baseUrl]:e}};await be(D(O),{recursive:!0,mode:448}),await B(D(O),448),await K(O,`${JSON.stringify(t,null,2)}
3
- `)}async function K(e,n){await Ae(e,n,{encoding:"utf8",mode:384}),await B(e,384)}function v(){return process.env.BROODS_STAGE}function f(e){let n=e.length;while(n>0&&e.charCodeAt(n-1)===47)n-=1;return e.slice(0,n)}function L(e){try{let n=new URL(e);if(!n.hostname.startsWith(`${P}.`))return;let t=n.hostname.slice(P.length+1);if(t!==N&&!t.endsWith(`.${N}`))return;return n.hostname=`${we}.${t}`,f(n.origin)}catch{return}}function H(){try{let e=JSON.parse(Se(O,"utf8"));if(typeof e.current!=="string"||!e.logins)return null;return{current:e.current,logins:e.logins}}catch{return null}}import{existsSync as q,readFileSync as Z,statSync as Ee}from"node:fs";import{join as X,resolve as Q}from"node:path";var A=new Map,Te=new Set(Object.keys(process.env)),j=new Set;function h(e=process.cwd()){Oe(e);let n=z();return{dashboardUrl:process.env.BROODS_DASHBOARD_URL??n?.dashboardUrl,baseUrl:process.env.BROODS_BASE_URL??n?.baseUrl,token:n?.token,project:process.env.BROODS_PROJECT,stage:v()}}function U(){let e={};for(let[n,t]of Object.entries(process.env))if(typeof t==="string"&&!n.startsWith("BROODS_"))e[n]=t;return e}function M(e,n=process.cwd()){let t=process.env[e];if(t===void 0)return!1;let o=Q(n);for(let r of[".env.local",".env"]){let i=X(o,r);if(!q(i))continue;let s=ee(Z(i,"utf8"));if(s[e]!==void 0)return s[e]!==t}return!0}function Oe(e){let n=Q(e),t=process.env.BROODS_RELOAD_ENV==="1";for(let o of[".env",".env.local"]){let r=X(n,o);if(!q(r)){A.delete(r);continue}let i=Ee(r).mtimeMs,s=A.get(r);if(s&&s.mtimeMs===i)continue;A.set(r,{mtimeMs:i});for(let[a,p]of Object.entries(ee(Z(r,"utf8"))))if(t||!Te.has(a)||j.has(a))process.env[a]=p,j.add(a)}}function ee(e){let n={};for(let t of e.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;let r=o.startsWith("export ")?o.slice(7).trim():o,i=r.indexOf("=");if(i<=0)continue;let s=r.slice(0,i).trim();if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(s))continue;n[s]=_e(r.slice(i+1).trim())}return n}function _e(e){if(e.startsWith('"')&&e.endsWith('"'))return e.slice(1,-1).replace(/\\n/g,`
4
- `).replace(/\\"/g,'"');if(e.startsWith("'")&&e.endsWith("'"))return e.slice(1,-1);let n=e.indexOf(" #");return n>=0?e.slice(0,n).trimEnd():e}var T="https://gateway.broods.app";class ye extends Error{accepted;constructor(e){super(`Ingress ${e.eventId} was accepted asynchronously with status ${e.status??"queued"}`);this.accepted=e;this.name="IngressAcceptedError"}}class F{baseUrl;apiKey;fetchImpl;constructor(e={}){h(),this.baseUrl=J(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||T),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||void 0,this.fetchImpl=e.fetch??fetch}channelWebhookUrl(e){return`${this.baseUrl}${e.webhookPath.startsWith("/")?"":"/"}${e.webhookPath}`}accountWebhookUrl(e,n){let t=[e,n].map(encodeURIComponent);return`${this.baseUrl}/v1/webhooks/${t.join("/")}`}stageWebhookUrl(e,n,t){let o=[e,"dev",n,t].map(encodeURIComponent);return`${this.baseUrl}/v1/webhooks/${o.join("/")}`}agent(e,n){if(typeof e==="string"){let o=e,r=n??"";if(!r)throw Error(`Agent ${o} is missing a generated id. Run broods dev --once or broods deploy to sync it first.`);return{id:r,run:(i)=>this.run({...i,agentName:o,agentId:r}),runAsync:(i)=>this.runAsync({...i,agentName:o,agentId:r}),continue:(i)=>this.continue({...i,agentId:r}),stream:(i)=>this.stream({...i,agentName:o,agentId:r})}}let t=e;if(!t.id)throw Error(`Agent ${t.name} is missing a generated id. Run broods dev --once or broods deploy to sync it first.`);return{id:t.id,run:(o)=>this.run(t,o),runAsync:(o)=>this.runAsync(t,o),continue:(o)=>this.continue(t,o),stream:(o)=>this.stream(t,o)}}async run(e,n){let t=[],o="",r=n?this.stream(e,n):this.stream(e);for await(let i of r)if(t.push(i),i.type==="text-delta")o+=i.text;return{text:o,events:t}}async*stream(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o=ne(t,"cli"),r=n?this.scopedUrl(e):`${this.baseUrl}/v1/runs`,i=await this.openStream(o,r);if(!i.ok)throw Error(`Run failed: ${i.status} ${await i.text()}`);if(i.status===202)throw new ye(te(await i.json(),o));if(!i.body)throw Error("Run response has no body");for await(let s of ge(i.body)){let a;try{a=JSON.parse(s)}catch{continue}if(a.type==="error")throw Error(`Agent run failed: ${$e(a.error)}`);yield a}}async runAsync(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o={...ne(t,"async"),background:!0},r=n?this.scopedUrl(e):`${this.baseUrl}/v1/runs`;return this.postAcceptedRun(r,o,"Async run")}async continue(e,n){let t=n?e:null,o=n??e,r={agentId:t?t.id:e.agentId,eventId:o.eventId??`continue-${crypto.randomUUID()}`,conversationKey:o.conversationKey,continue:!0},i=t?this.scopedUrl(t):`${this.baseUrl}/v1/runs`;return this.postAcceptedRun(i,r,"Continue")}async getAsyncStatus(e){let n=this.resolveStatusUrl(e),t=await this.fetchJson(n,{method:"GET",headers:this.apiKeyHeaders()});if(t.status===404)return{status:"not_found"};if(!t.ok)throw Error(`Status check failed: ${t.status} ${await t.text()}`);return await t.json()}async waitForAsyncStatus(e,n={}){let t=Date.now()+(n.timeoutMs??180000),o=n.intervalMs??2000;while(Date.now()<t){if(n.signal?.aborted)throw Error("Async status polling aborted.");let r=await this.getAsyncStatus(e);if(r.status==="awaiting_approval"||r.status==="awaiting_input"||r.status==="completed"||r.status==="failed"||r.status==="expired"||r.status==="not_found")return r;await en(o,n.signal)}throw Error("Polling timeout")}scopedUrl(e){if(e.projectSlug&&e.stageSlug&&e.endpointId)return`${this.baseUrl}/v1/projects/${encodeURIComponent(e.projectSlug)}/stages/${encodeURIComponent(e.stageSlug)}/agents/${encodeURIComponent(e.endpointId)}`;return`${this.baseUrl}/v1/runs`}asyncAgentRun(e,n){return{...e,conversationKey:n,poll:()=>this.getAsyncStatus(e),wait:(t)=>this.waitForAsyncStatus(e,t)}}async postAcceptedRun(e,n,t){let o=await this.fetchJson(e,{method:"POST",headers:this.apiKeyHeaders(),body:JSON.stringify(n)});if(o.status!==202)throw Error(`${t} failed: ${o.status} ${await ze(o,"202 JSON")}`);return this.asyncAgentRun(te(await o.json(),n),n.conversationKey)}async openStream(e,n){if(this.apiKey)return await this.fetchCore(e,n,{Authorization:`Bearer ${this.apiKey}`});throw Error(`BroodsClient streams directly from the core service at ${this.baseUrl}. Provide apiKey. For a self-hosted core service, set host/baseUrl or BROODS_HOST/BROODS_BASE_URL.`)}async fetchCore(e,n,t){try{return await this.fetchImpl(n,{method:"POST",headers:{"Content-Type":"application/json",Accept:"text/event-stream",...t},body:JSON.stringify(e)})}catch(o){throw Error(`Cannot access the broods core service at ${n}. The SDK uses ${T} by default; set host/baseUrl or BROODS_HOST/BROODS_BASE_URL to your own core service URL if your account uses a custom deployment. Cause: ${o instanceof Error?o.message:String(o)}`)}}apiKeyHeaders(){if(!this.apiKey)throw Error("BroodsClient requires apiKey or BROODS_API_KEY.");return{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}}async fetchJson(e,n){try{return await this.fetchImpl(e,n)}catch(t){throw Error(`Cannot access the broods core service at ${e}. Cause: ${t instanceof Error?t.message:String(t)}`)}}resolveStatusUrl(e){if(typeof e!=="string")return e.statusUrl;if(/^https?:\/\//.test(e))return e;return nn(this.baseUrl,e)}}function J(e){let n=e.trim(),t=/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(n)?n:`https://${n}`;return f(t)}function ne(e,n){let t=e.eventId??`${n}-${crypto.randomUUID()}`;return{agentId:e.agentId,eventId:t,conversationKey:e.conversationKey??t,events:V(e),...e.mode!==void 0?{mode:e.mode}:{},...e.idempotencyKey!==void 0?{idempotencyKey:e.idempotencyKey}:{},...e.system!==void 0?{system:e.system}:{},...e.model!==void 0?{model:e.model}:{}}}function $e(e){if(typeof e==="string")return e;if(!e||typeof e!=="object")return String(e);let n=e,t=n.data?.error?.message??n.message??n.responseBody??JSON.stringify(e),o=n.name?`${n.name}: `:"",r=n.statusCode?` (HTTP ${n.statusCode})`:"";return`${o}${t}${r}`}function te(e,n){if(!e||typeof e!=="object")throw Error("Async response must be an object");let t=e.statusUrl;if(typeof t!=="string"||t.length===0)throw Error("Async response missing statusUrl");let o=e.runId;if(typeof o!=="string"||o.length===0)throw Error("Async response missing runId");let r=typeof e.eventId==="string"?e.eventId:o,{status:i,requestedMode:s}=e;return{statusUrl:t,runId:o,eventId:r,agentId:n.agentId,...i==="accepted"||i==="queued"||i==="applied"||i==="processing"?{status:i}:{},...s==="reject"||s==="followup"||s==="collect"||s==="steer"?{requestedMode:s}:{}}}async function ze(e,n){if((e.headers.get("content-type")??"").toLowerCase().includes("text/event-stream"))return await e.body?.cancel().catch(()=>{}),`expected ${n}, but the server returned an SSE stream. This usually means the core deployment ignored the background flag and ran the request on the direct streaming runner.`;let o=await e.text();if(o.length<=2000)return o;return`${o.slice(0,2000)}... [truncated ${o.length-2000} chars]`}function en(e,n){return new Promise((t,o)=>{if(n?.aborted){o(Error("Async status polling aborted."));return}let r=setTimeout(t,e);n?.addEventListener("abort",()=>{clearTimeout(r),o(Error("Async status polling aborted."))},{once:!0})})}function nn(e,n){return`${J(e)}/v1/runs/${encodeURIComponent(n)}`}var tn=2000,oe=0,R=1;class xe{baseUrl;apiKey;WebSocketImpl;connectTimeoutMs;constructor(e={}){if(h(),this.baseUrl=ue(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||T),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||"",!this.apiKey)throw Error("BroodsWebSocketClient requires apiKey or BROODS_API_KEY.");this.WebSocketImpl=e.WebSocket,this.connectTimeoutMs=e.connectTimeoutMs??tn}subscribe(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=on(e),i=ce(this.baseUrl),s=new t(o,E(this.apiKey)),a=!1,p=!1,d=setTimeout(()=>{if(!a)C(i)},this.connectTimeoutMs),x=(l=1000,b="client closed")=>{if(p)return;if(p=!0,clearTimeout(d),e.signal?.removeEventListener("abort",S),s.readyState===R||s.readyState===oe)s.close(l,b)},C=(l)=>{n.onError?.(l),x(1011,"websocket error")},me=()=>{n.onDone?.(),x(1000,"done")},S=()=>{if(s.readyState===R)s.send(JSON.stringify({type:"cancel"}));C(Error("WebSocket run aborted."))};return e.signal?.addEventListener("abort",S,{once:!0}),s.onopen=()=>{if(a=!0,clearTimeout(d),e.signal?.aborted){S();return}s.send(JSON.stringify({type:"execute",agentId:r,...e.answers?{answers:e.answers}:{events:V(e)},sessionId:e.sessionId,...e.eventId!==void 0?{eventId:e.eventId}:{},...e.mode!==void 0?{mode:e.mode}:{},...e.idempotencyKey!==void 0?{idempotencyKey:e.idempotencyKey}:{},...e.system!==void 0?{system:e.system}:{},...e.model!==void 0?{model:e.model}:{}}))},s.onmessage=(l)=>{if(typeof l.data!=="string")return;let b=se(l.data);if(!b)return;let I=ae(b,n);switch(n.onMessage?.(I),I.type){case"meta":n.onMeta?.(I);break;case"done":me();break;case"error":C(Error(re(I.error)));break}},s.onerror=()=>{C(i)},s.onclose=(l)=>{if(clearTimeout(d),e.signal?.removeEventListener("abort",S),p||l.code===1000)return;C(Error(l.reason||"WebSocket connection closed."))},{url:o,sendControl:function(l){if(s.readyState!==R)throw Error("WebSocket is not open");s.send(JSON.stringify({type:"control",...l}))},close:x}}attach(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=new t(o,E(this.apiKey)),i=!1,s=(a=1000,p="client closed")=>{if(i)return;if(i=!0,r.readyState===R||r.readyState===oe)r.close(a,p)};return r.onopen=()=>r.send(JSON.stringify({type:"attach",...e,signal:void 0,agent:void 0})),r.onmessage=(a)=>{if(typeof a.data!=="string")return;let p=se(a.data);if(!p)return;let d=ae(p,n);if(n.onMessage?.(d),d.type==="done")n.onDone?.();if(d.type==="error")n.onError?.(Error(re(d.error)))},r.onerror=()=>n.onError?.(ce(this.baseUrl)),r.onclose=(a)=>{if(!i&&a.code!==1000)n.onError?.(Error(a.reason||"WebSocket connection closed."))},{url:o,sendControl:function(a){if(r.readyState!==R)throw Error("WebSocket is not open");r.send(JSON.stringify({type:"control",...a}))},close:s}}async*stream(e){let n=[],t=!1,o=null,r=null,i=()=>{r?.(),r=null},s=this.subscribe(e,{onMessage:function(a){n.push(a),i()},onDone:function(){t=!0,i()},onError:function(a){o=a,i()}});try{while(!0){if(n.length>0){yield n.shift();continue}if(o)throw o;if(t)return;await new Promise((a)=>{r=a})}}finally{s.close()}}buildUrl(e){let n=rn(e),t=e.projectSlug??e.agent?.projectSlug,o=e.stageSlug??e.agent?.stageSlug,r=t&&o?`/projects/${encodeURIComponent(t)}/stages/${encodeURIComponent(o)}`:"";return`${Y(this.baseUrl)}/v1${r}/agents/${encodeURIComponent(n)}/ws`}resolveWebSocket(){let e=this.WebSocketImpl??globalThis.WebSocket;if(!e)throw Error("WebSocket is not available. Pass a WebSocket implementation in BroodsWebSocketClient options.");return e}}function Y(e){let n=new URL(ue(e));if(n.protocol==="https:")n.protocol="wss:";if(n.protocol==="http:")n.protocol="ws:";return f(n.toString())}function E(e){return["broods.v1",`broods.token.${e}`]}function re(e){if(typeof e==="string")return e;if(e&&typeof e==="object"&&typeof e.message==="string")return e.message;return e===void 0?"WebSocket stream error.":JSON.stringify(e)}function ue(e){let n=e.trim();if(/^wss?:\/\//.test(n))return f(n);return J(n)}function se(e){try{let n=JSON.parse(e);return typeof n==="object"&&n!==null&&typeof n.type==="string"?n:null}catch{return null}}function on(e){let n=e.agentId??e.agent?.id??e.endpointId;if(!n)throw Error("WebSocket run requires agent, agentId, or endpointId.");return n}function rn(e){let n=e.endpointId??e.agent?.endpointId??e.agent?.id;if(!n)throw Error("WebSocket run requires agent or endpointId.");return n}function ae(e,n){if(e.type!=="output")return e;let t=e;return n.onOutput?.(t),t.data}function ce(e){return Error(`Cannot access the WebSocket service at ${e}.`)}var pe=Symbol.for("broods.resource"),de=Symbol.for("broods.config"),fe=Symbol.for("broods.connection"),le=/^[A-Z][A-Z0-9_]{0,63}$/,qe=new Proxy((e)=>{if(!le.test(e))throw Error("env name must match /^[A-Z][A-Z0-9_]*$/ and be at most 64 characters.");return{__beeblastEnv:!0,name:e}},{get:function(e,n,t){if(typeof n==="string"&&le.test(n))throw Error(`env.${n} is not supported; use env("${n}")`);return Reflect.get(e,n,t)}});function De(e){let{name:n,description:t,...o}=e;return m("agent",n,t,o)}function Le(e){return{[de]:!0,config:e}}function Ue(e){let{name:n,description:t,...o}=e;return m("cron",n,t,o)}function Fe(e){return e}function Be(e){let{name:n,description:t,...o}=e;return m("mcp",n,t,o)}function Ze(e){let{name:n,description:t,...o}=e;return m("policy",n,t,o)}function He(e){let{name:n,description:t,...o}=e;return m("sandbox",n,t,o)}function Ve(e){let{name:n,description:t,...o}=e;return m("skill",n,t,o)}function Ge(e){let{name:n,description:t,...o}=e;return m("workspace",n,t,o)}function We(e){return u("discord",e)}function Ke(e){return u("github",e)}function Je(e){return u("gchat",e)}function Ye(e){return u("instagram",e)}function Xe(e){return u("linear",e)}function Qe(e){return u("matrix",e)}function et(e){return u("messenger",e)}function tt(e){return u("pancake",e)}function nt(e){return u("slack",e)}function rt(e){return u("teams",e)}function ot(e){return u("telegram",e)}function st(e){return u("twilio",e)}function it(e){return u("whatsapp",e)}function at(e){return u("zalo",e)}function ct(e){let{name:n,description:t,channelId:o,guildId:r,...i}=e;return c(n,t,o,r,i)}function lt(e){let{name:n,description:t,repo:o,...r}=e,[i,...s]=o.split("/");if(!i||s.length!==1||!s[0])throw Error(`Channel "${n}" repo must be "owner/name", not "${o}"`);return c(n,t,o,i,r)}function ut(e){let{name:n,description:t,spaceName:o,...r}=e;return c(n,t,o,void 0,r)}function dt(e){let{name:n,description:t,igsid:o,...r}=e;return c(n,t,o,void 0,r)}function pt(e){let{name:n,description:t,team:o,...r}=e;return c(n,t,o,void 0,r)}function mt(e){let{name:n,description:t,channelId:o,...r}=e;return c(n,t,o,void 0,r)}function ht(e){let{name:n,description:t,psid:o,...r}=e;return c(n,t,o,void 0,r)}function ft(e){let{name:n,description:t,conversationId:o,...r}=e;return c(n,t,o,void 0,r)}function gt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return c(n,t,o,r,i)}function yt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return c(n,t,o,r,i)}function St(e){let{name:n,description:t,chatId:o,...r}=e;return c(n,t,o,void 0,r)}function bt(e){let{name:n,description:t,from:o,...r}=e;return c(n,t,o,void 0,r)}function vt(e){let{name:n,description:t,waId:o,...r}=e;return c(n,t,o,void 0,r)}function _t(e){let{name:n,description:t,chatId:o,...r}=e;return c(n,t,o,void 0,r)}function ie(e){return Boolean(e&&typeof e==="object"&&e[de])}function w(e){return Boolean(e&&typeof e==="object"&&e[fe])}function g(e){return Boolean(e&&typeof e==="object"&&e[pe])}function c(e,n,t,o,r){return m("channelRecord",e,n,{...r,externalId:t,...o?{workspaceRef:o}:{}})}function u(e,n){let{partition:t,...o}=n;return{[fe]:!0,kind:"connection",type:e,...t?{partition:t}:{},config:o}}function m(e,n,t,o){return{[pe]:!0,kind:e,name:n,...t?{description:t}:{},config:o}}
5
- export{V,ge,Me,Pe,Ne,je,G,Ie,y,_,O,z,W,K,v,f,L,h,U,M,T,ye,F,J,xe,Y,E,qe,De,Le,Ue,Fe,Be,Ze,He,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ht,ft,gt,yt,St,bt,vt,_t,ie,w,g};
2
+ `);o=s.pop()??"";for(let a of s)if(a.startsWith("data: "))yield a.slice(6)}}finally{await n.cancel().catch(()=>{return}),n.releaseLock()}}var Me=500,Ce=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,he=/^(?!0{32}$)[0-9a-f]{32}$/;function Pe(e){return e==="DEBUG"||e==="INFO"||e==="WARN"||e==="ERROR"}function Ne(e){if(typeof e!=="object"||e===null)return!1;let n=e;if(n.type==="subscribe")return Se(n);if(n.type==="unsubscribe")return k(n.stream);if(n.type==="fetchTrace")return Ie(n.traceId);return!1}function je(e){return e==="task"||e==="cron"||e==="subtask"}function G(e){return typeof e==="string"&&Ce.test(e)}function Ie(e){return typeof e==="string"&&he.test(e)}function k(e){return e==="logs"||e==="traces"}function Se(e){let n=e.stream;if(!k(n))return!1;let t=e.backfill;if(t!==void 0&&(typeof t!=="number"||!Number.isSafeInteger(t)||t<0||t>500))return!1;if(e.liveOnly!==void 0&&typeof e.liveOnly!=="boolean")return!1;let o=e.minLevel;if(o!==void 0&&!Pe(o))return!1;let r=e.sandboxId;return r===void 0||n==="logs"&&G(r)}import{readFileSync as Re}from"node:fs";import{chmod as H,mkdir as be,writeFile as Ae}from"node:fs/promises";import{homedir as ke}from"node:os";import{dirname as D,join as ve}from"node:path";var y="broods",_="_generated",O=ve(ke(),".broods","config.json"),N="broods.app",P="dashboard",we="gateway";function z(e){let n=process.env.BROODS_TOKEN,t=e??process.env.BROODS_BASE_URL;if(n&&t)return{baseUrl:f(t),token:n,createdAt:new Date().toISOString()};let o=j();if(!o)return null;if(t)return o.logins[f(t)]??null;let r=process.env.BROODS_DASHBOARD_URL;if(r){let i=f(r);return Object.values(o.logins).find((s)=>s.dashboardUrl===i)??null}return o.logins[o.current]??null}async function W(e){let n=j()?.logins??{},t={current:e.baseUrl,logins:{...n,[e.baseUrl]:e}};await be(D(O),{recursive:!0,mode:448}),await H(D(O),448),await K(O,`${JSON.stringify(t,null,2)}
3
+ `)}async function K(e,n){await Ae(e,n,{encoding:"utf8",mode:384}),await H(e,384)}function v(){return process.env.BROODS_STAGE}function f(e){let n=e.length;while(n>0&&e.charCodeAt(n-1)===47)n-=1;return e.slice(0,n)}function L(e){try{let n=new URL(e);if(!n.hostname.startsWith(`${P}.`))return;let t=n.hostname.slice(P.length+1);if(t!==N&&!t.endsWith(`.${N}`))return;return n.hostname=`${we}.${t}`,f(n.origin)}catch{return}}function j(){try{let e=JSON.parse(Re(O,"utf8"));if(typeof e.current!=="string"||!e.logins)return null;return{current:e.current,logins:e.logins}}catch{return null}}import{existsSync as F,readFileSync as Z,statSync as Ee}from"node:fs";import{join as X,resolve as Q}from"node:path";var A=new Map,Te=new Set(Object.keys(process.env)),q=new Set;function h(e=process.cwd()){Oe(e);let n=z();return{dashboardUrl:process.env.BROODS_DASHBOARD_URL??n?.dashboardUrl,baseUrl:process.env.BROODS_BASE_URL??n?.baseUrl,token:n?.token,project:process.env.BROODS_PROJECT,stage:v()}}function U(){let e={};for(let[n,t]of Object.entries(process.env))if(typeof t==="string"&&!n.startsWith("BROODS_"))e[n]=t;return e}function M(e,n=process.cwd()){let t=process.env[e];if(t===void 0)return!1;let o=Q(n);for(let r of[".env.local",".env"]){let i=X(o,r);if(!F(i))continue;let s=ee(Z(i,"utf8"));if(s[e]!==void 0)return s[e]!==t}return!0}function Oe(e){let n=Q(e),t=process.env.BROODS_RELOAD_ENV==="1";for(let o of[".env",".env.local"]){let r=X(n,o);if(!F(r)){A.delete(r);continue}let i=Ee(r).mtimeMs,s=A.get(r);if(s&&s.mtimeMs===i)continue;A.set(r,{mtimeMs:i});for(let[a,c]of Object.entries(ee(Z(r,"utf8"))))if(t||!Te.has(a)||q.has(a))process.env[a]=c,q.add(a)}}function ee(e){let n={};for(let t of e.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;let r=o.startsWith("export ")?o.slice(7).trim():o,i=r.indexOf("=");if(i<=0)continue;let s=r.slice(0,i).trim();if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(s))continue;n[s]=_e(r.slice(i+1).trim())}return n}function _e(e){if(e.startsWith('"')&&e.endsWith('"'))return e.slice(1,-1).replace(/\\n/g,`
4
+ `).replace(/\\"/g,'"');if(e.startsWith("'")&&e.endsWith("'"))return e.slice(1,-1);let n=e.indexOf(" #");return n>=0?e.slice(0,n).trimEnd():e}var T="https://gateway.broods.app";class ye extends Error{accepted;constructor(e){super(`Ingress ${e.eventId} was accepted asynchronously with status ${e.status??"queued"}`);this.accepted=e;this.name="IngressAcceptedError"}}class B{baseUrl;apiKey;fetchImpl;constructor(e={}){h(),this.baseUrl=J(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||T),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||void 0,this.fetchImpl=e.fetch??fetch}channelWebhookUrl(e){return`${this.baseUrl}${e.webhookPath.startsWith("/")?"":"/"}${e.webhookPath}`}accountWebhookUrl(e,n){let t=[e,n].map(encodeURIComponent);return`${this.baseUrl}/v1/webhooks/${t.join("/")}`}stageWebhookUrl(e,n,t){let o=[e,"dev",n,t].map(encodeURIComponent);return`${this.baseUrl}/v1/webhooks/${o.join("/")}`}agent(e,n){if(typeof e==="string"){let o=e,r=n??"";if(!r)throw Error(`Agent ${o} is missing a generated id. Run broods dev --once or broods deploy to sync it first.`);return{id:r,run:(i)=>this.run({...i,agentName:o,agentId:r}),runAsync:(i)=>this.runAsync({...i,agentName:o,agentId:r}),continue:(i)=>this.continue({...i,agentId:r}),stream:(i)=>this.stream({...i,agentName:o,agentId:r})}}let t=e;if(!t.id)throw Error(`Agent ${t.name} is missing a generated id. Run broods dev --once or broods deploy to sync it first.`);return{id:t.id,run:(o)=>this.run(t,o),runAsync:(o)=>this.runAsync(t,o),continue:(o)=>this.continue(t,o),stream:(o)=>this.stream(t,o)}}async run(e,n){let t=[],o="",r=n?this.stream(e,n):this.stream(e);for await(let i of r)if(t.push(i),i.type==="text-delta")o+=i.text;return{text:o,events:t}}async*stream(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o=ne(t,"cli"),r=n?this.scopedUrl(e):`${this.baseUrl}/v1/runs`,i=await this.openStream(o,r);if(!i.ok)throw Error(`Run failed: ${i.status} ${await i.text()}`);if(i.status===202)throw new ye(te(await i.json(),o));if(!i.body)throw Error("Run response has no body");for await(let s of ge(i.body)){let a;try{a=JSON.parse(s)}catch{continue}if(a.type==="error")throw Error(`Agent run failed: ${$e(a.error)}`);yield a}}async runAsync(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o={...ne(t,"async"),background:!0},r=n?this.scopedUrl(e):`${this.baseUrl}/v1/runs`;return this.postAcceptedRun(r,o,"Async run")}async continue(e,n){let t=n?e:null,o=n??e,r={agentId:t?t.id:e.agentId,eventId:o.eventId??`continue-${crypto.randomUUID()}`,conversationKey:o.conversationKey,continue:!0},i=t?this.scopedUrl(t):`${this.baseUrl}/v1/runs`;return this.postAcceptedRun(i,r,"Continue")}async getAsyncStatus(e){let n=this.resolveStatusUrl(e),t=await this.fetchJson(n,{method:"GET",headers:this.apiKeyHeaders()});if(t.status===404)return{status:"not_found"};if(!t.ok)throw Error(`Status check failed: ${t.status} ${await t.text()}`);return await t.json()}async waitForAsyncStatus(e,n={}){let t=Date.now()+(n.timeoutMs??180000),o=n.intervalMs??2000;while(Date.now()<t){if(n.signal?.aborted)throw Error("Async status polling aborted.");let r=await this.getAsyncStatus(e);if(r.status==="awaiting_approval"||r.status==="awaiting_input"||r.status==="completed"||r.status==="failed"||r.status==="expired"||r.status==="not_found")return r;await en(o,n.signal)}throw Error("Polling timeout")}scopedUrl(e){if(e.projectSlug&&e.stageSlug&&e.endpointId)return`${this.baseUrl}/v1/projects/${encodeURIComponent(e.projectSlug)}/stages/${encodeURIComponent(e.stageSlug)}/agents/${encodeURIComponent(e.endpointId)}`;return`${this.baseUrl}/v1/runs`}asyncAgentRun(e,n){return{...e,conversationKey:n,poll:()=>this.getAsyncStatus(e),wait:(t)=>this.waitForAsyncStatus(e,t)}}async postAcceptedRun(e,n,t){let o=await this.fetchJson(e,{method:"POST",headers:this.apiKeyHeaders(),body:JSON.stringify(n)});if(o.status!==202)throw Error(`${t} failed: ${o.status} ${await ze(o,"202 JSON")}`);return this.asyncAgentRun(te(await o.json(),n),n.conversationKey)}async openStream(e,n){if(this.apiKey)return await this.fetchCore(e,n,{Authorization:`Bearer ${this.apiKey}`});throw Error(`BroodsClient streams directly from the core service at ${this.baseUrl}. Provide apiKey. For a self-hosted core service, set host/baseUrl or BROODS_HOST/BROODS_BASE_URL.`)}async fetchCore(e,n,t){try{return await this.fetchImpl(n,{method:"POST",headers:{"Content-Type":"application/json",Accept:"text/event-stream",...t},body:JSON.stringify(e)})}catch(o){throw Error(`Cannot access the broods core service at ${n}. The SDK uses ${T} by default; set host/baseUrl or BROODS_HOST/BROODS_BASE_URL to your own core service URL if your account uses a custom deployment. Cause: ${o instanceof Error?o.message:String(o)}`)}}apiKeyHeaders(){if(!this.apiKey)throw Error("BroodsClient requires apiKey or BROODS_API_KEY.");return{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}}async fetchJson(e,n){try{return await this.fetchImpl(e,n)}catch(t){throw Error(`Cannot access the broods core service at ${e}. Cause: ${t instanceof Error?t.message:String(t)}`)}}resolveStatusUrl(e){if(typeof e!=="string")return e.statusUrl;if(/^https?:\/\//.test(e))return e;return nn(this.baseUrl,e)}}function J(e){let n=e.trim(),t=/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(n)?n:`https://${n}`;return f(t)}function ne(e,n){let t=e.eventId??`${n}-${crypto.randomUUID()}`;return{agentId:e.agentId,eventId:t,conversationKey:e.conversationKey??t,events:V(e),...e.mode!==void 0?{mode:e.mode}:{},...e.idempotencyKey!==void 0?{idempotencyKey:e.idempotencyKey}:{},...e.system!==void 0?{system:e.system}:{},...e.model!==void 0?{model:e.model}:{}}}function $e(e){if(typeof e==="string")return e;if(!e||typeof e!=="object")return String(e);let n=e,t=n.data?.error?.message??n.message??n.responseBody??JSON.stringify(e),o=n.name?`${n.name}: `:"",r=n.statusCode?` (HTTP ${n.statusCode})`:"";return`${o}${t}${r}`}function te(e,n){if(!e||typeof e!=="object")throw Error("Async response must be an object");let t=e.statusUrl;if(typeof t!=="string"||t.length===0)throw Error("Async response missing statusUrl");let o=e.runId;if(typeof o!=="string"||o.length===0)throw Error("Async response missing runId");let r=typeof e.eventId==="string"?e.eventId:o,{status:i,requestedMode:s}=e;return{statusUrl:t,runId:o,eventId:r,agentId:n.agentId,...i==="accepted"||i==="queued"||i==="applied"||i==="processing"?{status:i}:{},...s==="reject"||s==="followup"||s==="collect"||s==="steer"?{requestedMode:s}:{}}}async function ze(e,n){if((e.headers.get("content-type")??"").toLowerCase().includes("text/event-stream"))return await e.body?.cancel().catch(()=>{}),`expected ${n}, but the server returned an SSE stream. This usually means the core deployment ignored the background flag and ran the request on the direct streaming runner.`;let o=await e.text();if(o.length<=2000)return o;return`${o.slice(0,2000)}... [truncated ${o.length-2000} chars]`}function en(e,n){return new Promise((t,o)=>{if(n?.aborted){o(Error("Async status polling aborted."));return}let r=setTimeout(t,e);n?.addEventListener("abort",()=>{clearTimeout(r),o(Error("Async status polling aborted."))},{once:!0})})}function nn(e,n){return`${J(e)}/v1/runs/${encodeURIComponent(n)}`}var tn=2000,oe=0,R=1;class xe{baseUrl;apiKey;WebSocketImpl;connectTimeoutMs;constructor(e={}){if(h(),this.baseUrl=ue(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||T),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||"",!this.apiKey)throw Error("BroodsWebSocketClient requires apiKey or BROODS_API_KEY.");this.WebSocketImpl=e.WebSocket,this.connectTimeoutMs=e.connectTimeoutMs??tn}subscribe(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=on(e),i=ce(this.baseUrl),s=new t(o,E(this.apiKey)),a=!1,c=!1,d=setTimeout(()=>{if(!a)S(i)},this.connectTimeoutMs),m=(p=1000,I="client closed")=>{if(c)return;if(c=!0,clearTimeout(d),e.signal?.removeEventListener("abort",b),s.readyState===R||s.readyState===oe)s.close(p,I)},S=(p)=>{n.onError?.(p),m(1011,"websocket error")},me=()=>{n.onDone?.(),m(1000,"done")},b=()=>{if(s.readyState===R)s.send(JSON.stringify({type:"cancel"}));S(Error("WebSocket run aborted."))};return e.signal?.addEventListener("abort",b,{once:!0}),s.onopen=()=>{if(a=!0,clearTimeout(d),e.signal?.aborted){b();return}s.send(JSON.stringify({type:"execute",agentId:r,...e.answers?{answers:e.answers}:{events:V(e)},sessionId:e.sessionId,...e.eventId!==void 0?{eventId:e.eventId}:{},...e.mode!==void 0?{mode:e.mode}:{},...e.idempotencyKey!==void 0?{idempotencyKey:e.idempotencyKey}:{},...e.system!==void 0?{system:e.system}:{},...e.model!==void 0?{model:e.model}:{}}))},s.onmessage=(p)=>{if(typeof p.data!=="string")return;let I=se(p.data);if(!I)return;let x=ae(I,n);switch(n.onMessage?.(x),x.type){case"meta":n.onMeta?.(x);break;case"done":me();break;case"error":S(Error(re(x.error)));break}},s.onerror=()=>{S(i)},s.onclose=(p)=>{if(clearTimeout(d),e.signal?.removeEventListener("abort",b),c||p.code===1000)return;S(Error(p.reason||"WebSocket connection closed."))},{url:o,sendControl:function(p){if(s.readyState!==R)throw Error("WebSocket is not open");s.send(JSON.stringify({type:"control",...p}))},close:m}}attach(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=new t(o,E(this.apiKey)),i=!1,s=(c=1000,d="client closed")=>{if(i)return;if(i=!0,e.signal?.removeEventListener("abort",a),r.readyState===R||r.readyState===oe)r.close(c,d)},a=()=>{s(1000,"aborted"),n.onError?.(Error("WebSocket attach aborted."))};if(e.signal?.aborted)a();else e.signal?.addEventListener("abort",a,{once:!0});return r.onopen=()=>{if(i)return;r.send(JSON.stringify({type:"attach",...e,signal:void 0,agent:void 0}))},r.onmessage=(c)=>{if(i||typeof c.data!=="string")return;let d=se(c.data);if(!d)return;let m=ae(d,n);if(i)return;if(n.onMessage?.(m),i)return;if(m.type==="done")n.onDone?.();if(m.type==="error")n.onError?.(Error(re(m.error)))},r.onerror=()=>{if(i)return;s(1011,"websocket error"),n.onError?.(ce(this.baseUrl))},r.onclose=(c)=>{if(e.signal?.removeEventListener("abort",a),!i&&c.code!==1000)n.onError?.(Error(c.reason||"WebSocket connection closed."))},{url:o,sendControl:function(c){if(r.readyState!==R)throw Error("WebSocket is not open");r.send(JSON.stringify({type:"control",...c}))},close:s}}async*stream(e){let n=[],t=!1,o=null,r=null,i=()=>{r?.(),r=null},s=this.subscribe(e,{onMessage:function(a){n.push(a),i()},onDone:function(){t=!0,i()},onError:function(a){o=a,i()}});try{while(!0){if(n.length>0){yield n.shift();continue}if(o)throw o;if(t)return;await new Promise((a)=>{r=a})}}finally{s.close()}}buildUrl(e){let n=rn(e),t=e.projectSlug??e.agent?.projectSlug,o=e.stageSlug??e.agent?.stageSlug,r=t&&o?`/projects/${encodeURIComponent(t)}/stages/${encodeURIComponent(o)}`:"";return`${Y(this.baseUrl)}/v1${r}/agents/${encodeURIComponent(n)}/ws`}resolveWebSocket(){let e=this.WebSocketImpl??globalThis.WebSocket;if(!e)throw Error("WebSocket is not available. Pass a WebSocket implementation in BroodsWebSocketClient options.");return e}}function Y(e){let n=new URL(ue(e));if(n.protocol==="https:")n.protocol="wss:";if(n.protocol==="http:")n.protocol="ws:";return f(n.toString())}function E(e){return["broods.v1",`broods.token.${e}`]}function re(e){if(typeof e==="string")return e;if(e&&typeof e==="object"&&typeof e.message==="string")return e.message;return e===void 0?"WebSocket stream error.":JSON.stringify(e)}function ue(e){let n=e.trim();if(/^wss?:\/\//.test(n))return f(n);return J(n)}function se(e){try{let n=JSON.parse(e);return typeof n==="object"&&n!==null&&typeof n.type==="string"?n:null}catch{return null}}function on(e){let n=e.agentId??e.agent?.id??e.endpointId;if(!n)throw Error("WebSocket run requires agent, agentId, or endpointId.");return n}function rn(e){let n=e.endpointId??e.agent?.endpointId??e.agent?.id;if(!n)throw Error("WebSocket run requires agent or endpointId.");return n}function ae(e,n){if(e.type!=="output")return e;let t=e;return n.onOutput?.(t),t.data}function ce(e){return Error(`Cannot access the WebSocket service at ${e}.`)}var pe=Symbol.for("broods.resource"),de=Symbol.for("broods.config"),fe=Symbol.for("broods.connection"),le=/^[A-Z][A-Z0-9_]{0,63}$/,qe=new Proxy((e)=>{if(!le.test(e))throw Error("env name must match /^[A-Z][A-Z0-9_]*$/ and be at most 64 characters.");return{__beeblastEnv:!0,name:e}},{get:function(e,n,t){if(typeof n==="string"&&le.test(n))throw Error(`env.${n} is not supported; use env("${n}")`);return Reflect.get(e,n,t)}});function De(e){let{name:n,description:t,...o}=e;return C("agent",n,t,o)}function Le(e){return{[de]:!0,config:e}}function Ue(e){let{name:n,description:t,...o}=e;return C("cron",n,t,o)}function Be(e){return e}function Fe(e){let{name:n,description:t,...o}=e;return C("mcp",n,t,o)}function Ze(e){let{name:n,description:t,...o}=e;return C("policy",n,t,o)}function He(e){let{name:n,description:t,...o}=e;return C("sandbox",n,t,o)}function Ve(e){let{name:n,description:t,...o}=e;return C("skill",n,t,o)}function Ge(e){let{name:n,description:t,...o}=e;return C("workspace",n,t,o)}function We(e){return l("discord",e)}function Ke(e){return l("github",e)}function Je(e){return l("gchat",e)}function Ye(e){return l("instagram",e)}function Xe(e){return l("linear",e)}function Qe(e){return l("matrix",e)}function et(e){return l("messenger",e)}function tt(e){return l("pancake",e)}function nt(e){return l("slack",e)}function rt(e){return l("teams",e)}function ot(e){return l("telegram",e)}function st(e){return l("twilio",e)}function it(e){return l("whatsapp",e)}function at(e){return l("zalo",e)}function ct(e){let{name:n,description:t,channelId:o,guildId:r,...i}=e;return u(n,t,o,r,i)}function lt(e){let{name:n,description:t,repo:o,...r}=e,[i,...s]=o.split("/");if(!i||s.length!==1||!s[0])throw Error(`Channel "${n}" repo must be "owner/name", not "${o}"`);return u(n,t,o,i,r)}function ut(e){let{name:n,description:t,spaceName:o,...r}=e;return u(n,t,o,void 0,r)}function dt(e){let{name:n,description:t,igsid:o,...r}=e;return u(n,t,o,void 0,r)}function pt(e){let{name:n,description:t,team:o,...r}=e;return u(n,t,o,void 0,r)}function mt(e){let{name:n,description:t,channelId:o,...r}=e;return u(n,t,o,void 0,r)}function ht(e){let{name:n,description:t,psid:o,...r}=e;return u(n,t,o,void 0,r)}function ft(e){let{name:n,description:t,conversationId:o,...r}=e;return u(n,t,o,void 0,r)}function gt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function yt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function St(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function bt(e){let{name:n,description:t,from:o,...r}=e;return u(n,t,o,void 0,r)}function vt(e){let{name:n,description:t,waId:o,...r}=e;return u(n,t,o,void 0,r)}function _t(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function ie(e){return Boolean(e&&typeof e==="object"&&e[de])}function w(e){return Boolean(e&&typeof e==="object"&&e[fe])}function g(e){return Boolean(e&&typeof e==="object"&&e[pe])}function u(e,n,t,o,r){return C("channelRecord",e,n,{...r,externalId:t,...o?{workspaceRef:o}:{}})}function l(e,n){let{partition:t,...o}=n;return{[fe]:!0,kind:"connection",type:e,...t?{partition:t}:{},config:o}}function C(e,n,t,o){return{[pe]:!0,kind:e,name:n,...t?{description:t}:{},config:o}}
5
+ export{V,ge,Me,Pe,Ne,je,G,Ie,y,_,O,z,W,K,v,f,L,h,U,M,T,ye,B,J,xe,Y,E,qe,De,Le,Ue,Be,Fe,Ze,He,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ht,ft,gt,yt,St,bt,vt,_t,ie,w,g};
@@ -1 +1 @@
1
- import{U}from"./chunk-vjg21a4e.js";import{Oe,e,n,t,s}from"./chunk-n890pdvc.js";import{readFileSync as m}from"node:fs";import{dirname as d,resolve as p}from"node:path";import{Client as g}from"@modelcontextprotocol/client";import{StdioClientTransport as h}from"@modelcontextprotocol/client/stdio";var f={name:"broods-machine",version:"1.0.0"},u=t({command:e().min(1),args:n(e()).default([]),env:s(e(),e()).optional(),cwd:e().optional()}),w=t({mcpServers:s(e(),u).refine((r)=>Object.keys(r).length>0,"lists no MCP servers")});class y{#t=new Map;#e;#r;constructor(r,o){this.#r=r,this.#e=o}async callTool(r,o,i){return await(await this.#n(r)).callTool({name:o,arguments:i})}async listTools(r){return(await(await this.#n(r)).listTools()).tools}names(){return[...this.#r.keys()]}async stop(){let r=[...this.#t.values()];this.#t.clear(),await Promise.all(r.map((o)=>o.then((i)=>i.close()).catch(()=>{})))}#n(r){let o=this.#r.get(r);if(!o)return Promise.reject(Error(`no MCP server named "${r}" in the --mcp file`));let i=this.#t.get(r);if(i)return i;let c=(async()=>{this.#e(`mcp ${r}: ${[o.command,...o.args].join(" ")}`);let a=new h({...o,env:{...U(),...o.env},stderr:"inherit"});a.onclose=()=>{if(this.#e(`mcp ${r}: exited`),this.#t.get(r)===c)this.#t.delete(r)};let l=new g(f);return await l.connect(a),l})();return c.catch(()=>{if(this.#t.get(r)===c)this.#t.delete(r)}),this.#t.set(r,c),c}}function b(r){let o=p(r),i=w.safeParse(v(o));if(!i.success)throw Error(`${o}: ${Oe(i.error)}`);return new Map(Object.entries(i.data.mcpServers).map(([c,a])=>[c,a.cwd?{...a,cwd:p(d(o),a.cwd)}:a]))}function v(r){try{return JSON.parse(m(r,"utf8"))}catch(o){throw Error(`could not read ${r}: ${o instanceof Error?o.message:String(o)}`)}}export{y as McpHost,b as readMcpServersFile};
1
+ import{U}from"./chunk-6kgtx9kv.js";import{Oe,e,n,t,s}from"./chunk-n890pdvc.js";import{readFileSync as m}from"node:fs";import{dirname as d,resolve as p}from"node:path";import{Client as g}from"@modelcontextprotocol/client";import{StdioClientTransport as h}from"@modelcontextprotocol/client/stdio";var f={name:"broods-machine",version:"1.0.0"},u=t({command:e().min(1),args:n(e()).default([]),env:s(e(),e()).optional(),cwd:e().optional()}),w=t({mcpServers:s(e(),u).refine((r)=>Object.keys(r).length>0,"lists no MCP servers")});class y{#t=new Map;#e;#r;constructor(r,o){this.#r=r,this.#e=o}async callTool(r,o,i){return await(await this.#n(r)).callTool({name:o,arguments:i})}async listTools(r){return(await(await this.#n(r)).listTools()).tools}names(){return[...this.#r.keys()]}async stop(){let r=[...this.#t.values()];this.#t.clear(),await Promise.all(r.map((o)=>o.then((i)=>i.close()).catch(()=>{})))}#n(r){let o=this.#r.get(r);if(!o)return Promise.reject(Error(`no MCP server named "${r}" in the --mcp file`));let i=this.#t.get(r);if(i)return i;let c=(async()=>{this.#e(`mcp ${r}: ${[o.command,...o.args].join(" ")}`);let a=new h({...o,env:{...U(),...o.env},stderr:"inherit"});a.onclose=()=>{if(this.#e(`mcp ${r}: exited`),this.#t.get(r)===c)this.#t.delete(r)};let l=new g(f);return await l.connect(a),l})();return c.catch(()=>{if(this.#t.get(r)===c)this.#t.delete(r)}),this.#t.set(r,c),c}}function b(r){let o=p(r),i=w.safeParse(v(o));if(!i.success)throw Error(`${o}: ${Oe(i.error)}`);return new Map(Object.entries(i.data.mcpServers).map(([c,a])=>[c,a.cwd?{...a,cwd:p(d(o),a.cwd)}:a]))}function v(r){try{return JSON.parse(m(r,"utf8"))}catch(o){throw Error(`could not read ${r}: ${o instanceof Error?o.message:String(o)}`)}}export{y as McpHost,b as readMcpServersFile};