broods 0.51.0 → 0.51.1
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 +1 -1
- package/dist/{chunk-hd88jbj7.js → chunk-8c952qsc.js} +2 -2
- package/dist/{chunk-vx04brkn.js → chunk-e2z6q3rv.js} +1 -1
- package/dist/{chunk-f19xvx4b.js → chunk-gqyk7vva.js} +1 -1
- package/dist/cli/index.js +3 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/dist/account.d.ts
CHANGED
|
@@ -737,7 +737,7 @@ type UpdateCronInput = {
|
|
|
737
737
|
* rules, core's executor registry and the SDK derive from. A leaf on purpose,
|
|
738
738
|
* so `schema.ts` can read it without pulling the rules' import graph.
|
|
739
739
|
*/
|
|
740
|
-
declare const SANDBOX_PROVIDERS: readonly ["sandbox", "lambda", "e2b", "daytona", "vercel", "cloudflare", "machine", "custom"];
|
|
740
|
+
declare const SANDBOX_PROVIDERS: readonly ["sandbox", "lambda", "e2b", "daytona", "vercel", "cloudflare", "worker", "machine", "custom"];
|
|
741
741
|
type SandboxProvider = (typeof SANDBOX_PROVIDERS)[number];
|
|
742
742
|
|
|
743
743
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{F,z}from"./chunk-
|
|
1
|
+
import{F,z}from"./chunk-gqyk7vva.js";import{e,o,a,l,n,t,d,E,s,p,r}from"./chunk-qxxrmem2.js";import{ue,_e,L}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 se,hostname as ae,totalmem as ce}from"node:os";import{performance as j}from"node:perf_hooks";var P=["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 C={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 U="/v1/machines/ws",B=t({action:p(P),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=E("type",[G,K,Y,q,V]),Fe=E("type",[W,J,X,Z,Q,ee]);function I(i){let c=new URL(U,i);return c.protocol=c.protocol==="https:"?"wss:":"ws:",c.toString()}function A(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 le=new Set([C.occupied.code,C.replaced.code,C.unauthorized.code,C.unknownSandbox.code]),H=72,D=30000,O=1000;function pe(i,c,y){return new Promise((g)=>{let h=j.now(),f=new R(i.outputLimitBytes),w=new R(i.outputLimitBytes),b=!1,v=!1,x=(u,m)=>{if(v)return;if(v=!0,clearTimeout(T),y?.removeEventListener("abort",_),m)w.append(Buffer.from(`${m}
|
|
2
2
|
`));g({type:"result",id:i.id,exitCode:u,stdout:f.text(),stderr:w.text(),durationMs:Math.round(j.now()-h),timedOut:b,truncated:f.truncated||w.truncated})},M=re("bash",["-lc",i.code],{cwd:i.cwd??c,env:{...F(),...i.env},detached:!0,stdio:["ignore","pipe","pipe"]}),S=()=>{if(!M.pid)return;try{process.kill(-M.pid,"SIGKILL")}catch{M.kill("SIGKILL")}},T=setTimeout(()=>{b=!0,S()},i.timeoutSeconds*1000),_=()=>{S(),x(null,"stopped: the daemon closed its socket")};if(y?.addEventListener("abort",_,{once:!0}),M.stdout.on("data",(u)=>f.append(u)),M.stderr.on("data",(u)=>w.append(u)),M.on("error",(u)=>x(null,u.message)),M.on("close",(u)=>x(u)),y?.aborted)_()})}async function Oe(i){let c=_e(),y=crypto.randomUUID(),g=i.mcpFile?await fe(i.mcpFile,i.log):null,h=i.computer?await ye(i.log):null,f=O;try{while(!i.signal.aborted){let w=Date.now(),b;try{b=await i.credential()}catch(x){if(x instanceof L)throw x;i.log(`stage session unavailable (${x instanceof Error?x.message:String(x)}), retrying in ${Math.round(f/1000)}s`),await ue(f,i.signal),f=Math.min(f*2,D);continue}let v=await be(i,b,y,c,h,g);if(i.signal.aborted)return;if(le.has(v.code))throw Error(v.reason||`core closed the socket (${v.code})`);if(Date.now()-w>D)f=O;i.log(`disconnected (${v.reason||v.code}), reconnecting in ${Math.round(f/1000)}s`),await ue(f,i.signal),f=Math.min(f*2,D)}}finally{h?.stop(),await g?.stop()}}class R{#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
3
|
[output truncated]`:i}}function de(i){let c=[i.action];if(i.coordinate)c.push(`at ${i.coordinate.join(",")}`);if(i.text!==void 0)c.push(JSON.stringify(N(i.text)));if(i.region)c.push(`region ${i.region.join(",")}`);return c.join(" ")}function me(){let i=he();return{vcpu:ie(),memoryMb:Math.round(ce()/1048576),...i?{storageGb:i}:{}}}function he(){try{let i=ne(se());return Math.round(i.blocks*i.bsize/1073741824)}catch{return}}function N(i){let c=i.trim().split(`
|
|
4
|
-
`)[0]??"";return c.length>H?`${c.slice(0,H)}…`: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 fe(i,c){let{McpHost:y,readMcpServersFile:g}=await import("./chunk-
|
|
4
|
+
`)[0]??"";return c.length>H?`${c.slice(0,H)}…`: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 fe(i,c){let{McpHost:y,readMcpServersFile:g}=await import("./chunk-e2z6q3rv.js"),h=new y(g(i),c);return c(`mcp servers from ${i}: ${h.names().join(", ")}`),h}async function ge(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 be(i,c,y,g,h,f){return new Promise((w)=>{let b=new g(I(i.baseUrl),z(c)),v=new AbortController,x=()=>b.close(1000,"daemon stopped"),M=(u)=>{if(b.readyState===b.OPEN)b.send(JSON.stringify(u))},S,T=(u)=>{if(clearTimeout(S),v.signal.aborted)return;S=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,O))},_=(u,m)=>{i.signal.removeEventListener("abort",x),clearTimeout(S),v.abort(),w({code:u,reason:m})};i.signal.addEventListener("abort",x,{once:!0}),b.onopen=()=>M({type:"hello",sandbox:i.sandbox,hostname:ae(),platform:process.platform,computer:h!==null,mcp:f?.names(),instance:y,force:i.force,specs:me()}),b.onmessage=(u)=>{let m=A(u.data);if(m?.type==="ready"){if(S===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(` ${de(m)}`),h.run(m).then((k)=>{if(k.error)i.log(` error: ${k.error}`);M(k)});return}if((m?.type==="mcp-call"||m?.type==="mcp-list")&&f){ge(m,f,i.log).then(M);return}if(m?.type!=="exec")return;i.log(`$ ${N(m.code)}`),pe(m,i.cwd,v.signal).then((k)=>{i.log(` exit ${k.exitCode??"none"} in ${k.durationMs}ms${k.timedOut?" (timed out)":""}`),M(k)})},b.onerror=()=>_(1006,"connection failed"),b.onclose=(u)=>_(u.code,u.reason)})}export{Oe as runMachineDaemon};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{F}from"./chunk-
|
|
1
|
+
import{F}from"./chunk-gqyk7vva.js";import{De,e,n,t,s}from"./chunk-qxxrmem2.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:{...F(),...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}: ${De(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,5 +1,5 @@
|
|
|
1
1
|
function G(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*we(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
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 Le=500,Oe=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,Me=/^(?!0{32}$)[0-9a-f]{32}$/;function Ne(e){return e==="DEBUG"||e==="INFO"||e==="WARN"||e==="ERROR"}function Ue(e){if(typeof e!=="object"||e===null)return!1;let n=e;if(n.type==="subscribe")return _e(n);if(n.type==="unsubscribe")return O(n.stream);if(n.type==="fetchTrace")return K(n.traceId);return!1}function Fe(e){return e==="task"||e==="cron"||e==="subtask"}function W(e){return typeof e==="string"&&Oe.test(e)}function K(e){return typeof e==="string"&&Me.test(e)}function O(e){return e==="logs"||e==="traces"}function _e(e){let n=e.stream;if(!O(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&&!Ne(o))return!1;let r=e.sandboxId;return r===void 0||n==="logs"&&W(r)}import{readFileSync as Pe}from"node:fs";import{chmod as j,mkdir as $e,writeFile as qe}from"node:fs/promises";import{homedir as ze}from"node:os";import{dirname as M,join as en}from"node:path";var S="broods",w="_generated",N=en(ze(),".broods","config.json"),L="broods.app",H="dashboard",nn="gateway";function P(e){let n=process.env.BROODS_TOKEN,t=e??process.env.BROODS_BASE_URL;if(n&&t)return{baseUrl:h(t),token:n,createdAt:new Date().toISOString()};let o=q();if(!o)return null;if(t)return o.logins[h(t)]??null;let r=process.env.BROODS_DASHBOARD_URL;if(r){let i=h(r);return Object.values(o.logins).find((s)=>s.dashboardUrl===i)??null}return o.logins[o.current]??null}async function J(e){let n=q()?.logins??{},t={current:e.baseUrl,logins:{...n,[e.baseUrl]:e}};await $e(M(N),{recursive:!0,mode:448}),await j(M(N),448),await Y(N,`${JSON.stringify(t,null,2)}
|
|
3
3
|
`)}async function Y(e,n){await qe(e,n,{encoding:"utf8",mode:384}),await j(e,384)}function _(){return process.env.BROODS_STAGE}function h(e){let n=e.length;while(n>0&&e.charCodeAt(n-1)===47)n-=1;return e.slice(0,n)}function U(e){try{let n=new URL(e);if(!n.hostname.startsWith(`${H}.`))return;let t=n.hostname.slice(H.length+1);if(t!==L&&!t.endsWith(`.${L}`))return;return n.hostname=`${nn}.${t}`,h(n.origin)}catch{return}}function q(){try{let e=JSON.parse(Pe(N,"utf8"));if(typeof e.current!=="string"||!e.logins)return null;return{current:e.current,logins:e.logins}}catch{return null}}import{existsSync as V,readFileSync as oe,statSync as tn}from"node:fs";import{join as re,resolve as ie}from"node:path";var E=new Map,on=new Set(Object.keys(process.env)),Z=new Set;function f(e=process.cwd()){rn(e);let n=P();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:_()}}function F(){let e={};for(let[n,t]of Object.entries(process.env))if(typeof t==="string"&&!n.startsWith("BROODS_"))e[n]=t;return e}function T(e,n=process.cwd()){let t=process.env[e];if(t===void 0)return!1;let o=ie(n);for(let r of[".env.local",".env"]){let i=re(o,r);if(!V(i))continue;let s=X(oe(i,"utf8"));if(s[e]!==void 0)return s[e]!==t}return!0}function rn(e){let n=ie(e),t=process.env.BROODS_RELOAD_ENV==="1";for(let o of[".env",".env.local"]){let r=re(n,o);if(!V(r)){E.delete(r);continue}let i=tn(r).mtimeMs,s=E.get(r);if(s&&s.mtimeMs===i)continue;E.set(r,{mtimeMs:i});for(let[a,c]of Object.entries(X(oe(r,"utf8"))))if(t||!on.has(a)||Z.has(a))process.env[a]=c,Z.add(a)}}function X(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]=sn(r.slice(i+1).trim())}return n}function sn(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 D=new TextEncoder,ae={name:"HMAC",hash:"SHA-256"};async function ce(e,n,t,o){let r=se(D.encode(JSON.stringify(t))),i=await crypto.subtle.sign(ae,await an(n,o),D.encode(r));return`${e}${r}.${se(new Uint8Array(i))}`}function se(e){let n="";for(let t of e)n+=String.fromCharCode(t);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function an(e,n){let t=await crypto.subtle.digest("SHA-256",D.encode(`${e}${n}`));return crypto.subtle.importKey("raw",t,ae,!1,["sign","verify"])}var cn="buat_",Q="bsig_",de="x-broods-user-token",ue="broods.user.";var ge=600000,ee=3600000,un="broods-user-token:",le=/^[A-Za-z0-9._@+=-]{1,128}$/,fe=100,gn=256,ln=60000;async function ye(e,n,t=Date.now()){if(!n.startsWith(Q))throw Error(`The user token signing secret must start with ${Q}. It is not the bsk_ runtime key.`);let o=pn(e,t);if(!o||e.expiresAt>t+ee)throw Error(`Invalid user token: userId must match ${le.source}, conversations must be at most ${fe} non-empty keys, and expiresAt must be in the next ${ee/60000} minutes.`);return await ce(cn,un,o,n)}function pn(e,n){if(!e||typeof e!=="object")return null;let{userId:t,conversations:o,expiresAt:r}=e;if(typeof t!=="string"||!le.test(t)||typeof r!=="number"||!Number.isFinite(r)||r<=n||r>n+ee+ln)return null;if(o===void 0)return{userId:t,expiresAt:r};if(!Array.isArray(o)||o.length>fe||!o.every((i)=>typeof i==="string"&&i.trim()===i&&i.length>0&&i.length<=gn))return null;return{userId:t,conversations:o,expiresAt:r}}var y="BROODS_USER_TOKEN_SECRET";async function Be(e){let n=e.secret??process.env[y];if(!n)throw Error(`signUserToken needs the stage's signing secret: pass secret or set ${y}. \`broods dev\` and \`broods deploy\` write it to .env.local; the dashboard's Runtime key tab rotates it.`);return await ye({userId:e.userId,...e.conversations?{conversations:e.conversations}:{},expiresAt:Date.now()+(e.ttlMs??ge)},n)}var I="https://gateway.broods.app";class Re 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;userToken;fetchImpl;constructor(e={}){f(),this.baseUrl=te(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||I),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||void 0,this.userToken=e.userToken,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=me(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 Re(Ce(await i.json(),o));if(!i.body)throw Error("Run response has no body");for await(let s of we(i.body)){let a;try{a=JSON.parse(s)}catch{continue}if(a.type==="error")throw Error(`Agent run failed: ${dn(a.error)}`);yield a}}async runAsync(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o={...me(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:await 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 yn(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:await this.apiKeyHeaders(),body:JSON.stringify(n)});if(o.status!==202)throw Error(`${t} failed: ${o.status} ${await fn(o,"202 JSON")}`);return this.asyncAgentRun(Ce(await o.json(),n),n.conversationKey)}async openStream(e,n){if(this.apiKey)return await this.fetchCore(e,n,{Authorization:`Bearer ${this.apiKey}`,...await this.userTokenHeaders()});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 ${I} 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)}`)}}async apiKeyHeaders(){if(!this.apiKey)throw Error("BroodsClient requires apiKey or BROODS_API_KEY.");return{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...await this.userTokenHeaders()}}async userTokenHeaders(){let e=typeof this.userToken==="function"?await this.userToken():this.userToken;return e?{[de]:e}:{}}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 mn(this.baseUrl,e)}}function te(e){let n=e.trim(),t=/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(n)?n:`https://${n}`;return h(t)}function me(e,n){let t=e.eventId??`${n}-${crypto.randomUUID()}`;return{agentId:e.agentId,eventId:t,conversationKey:e.conversationKey??t,events:G(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 dn(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 Ce(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 fn(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 yn(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 mn(e,n){return`${te(e)}/v1/runs/${encodeURIComponent(n)}`}var Cn=2000,he=0,x=1;class je{baseUrl;apiKey;userToken;WebSocketImpl;connectTimeoutMs;constructor(e={}){if(f(),this.baseUrl=ke(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||I),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||"",!this.apiKey)throw Error("BroodsWebSocketClient requires apiKey or BROODS_API_KEY.");this.userToken=e.userToken,this.WebSocketImpl=e.WebSocket,this.connectTimeoutMs=e.connectTimeoutMs??Cn}subscribe(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=hn(e),i=xe(this.baseUrl),s=new t(o,z(this.apiKey,e.userToken??this.userToken)),a=!1,c=!1,d=setTimeout(()=>{if(!a)b(i)},this.connectTimeoutMs),m=(p=1000,A="client closed")=>{if(c)return;if(c=!0,clearTimeout(d),e.signal?.removeEventListener("abort",k),s.readyState===x||s.readyState===he)s.close(p,A)},b=(p)=>{n.onError?.(p),m(1011,"websocket error")},De=()=>{n.onDone?.(),m(1000,"done")},k=()=>{if(s.readyState===x)s.send(JSON.stringify({type:"cancel"}));b(Error("WebSocket run aborted."))};return e.signal?.addEventListener("abort",k,{once:!0}),s.onopen=()=>{if(a=!0,clearTimeout(d),e.signal?.aborted){k();return}s.send(JSON.stringify({type:"execute",agentId:r,...e.answers?{answers:e.answers}:{events:G(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 A=be(p.data);if(!A)return;let v=Ie(A,n);switch(n.onMessage?.(v),v.type){case"meta":n.onMeta?.(v);break;case"done":De();break;case"error":b(Error(Se(v.error)));break}},s.onerror=()=>{b(i)},s.onclose=(p)=>{if(clearTimeout(d),e.signal?.removeEventListener("abort",k),c||p.code===1000)return;b(Error(p.reason||"WebSocket connection closed."))},{url:o,sendControl:function(p){if(s.readyState!==x)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,z(this.apiKey,e.userToken??this.userToken)),i=!1,s=(c=1000,d="client closed")=>{if(i)return;if(i=!0,e.signal?.removeEventListener("abort",a),r.readyState===x||r.readyState===he)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,userToken:void 0}))},r.onmessage=(c)=>{if(i||typeof c.data!=="string")return;let d=be(c.data);if(!d)return;let m=Ie(d,n);if(i)return;if(n.onMessage?.(m),i)return;if(m.type==="done")n.onDone?.();if(m.type==="error")n.onError?.(Error(Se(m.error)))},r.onerror=()=>{if(i)return;s(1011,"websocket error"),n.onError?.(xe(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!==x)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=Sn(e),t=e.projectSlug??e.agent?.projectSlug,o=e.stageSlug??e.agent?.stageSlug,r=t&&o?`/projects/${encodeURIComponent(t)}/stages/${encodeURIComponent(o)}`:"";return`${ne(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 ne(e){let n=new URL(ke(e));if(n.protocol==="https:")n.protocol="wss:";if(n.protocol==="http:")n.protocol="ws:";return h(n.toString())}function z(e,n){return["broods.v1",`broods.token.${e}`,...n?[`${ue}${n}`]:[]]}function Se(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 ke(e){let n=e.trim();if(/^wss?:\/\//.test(n))return h(n);return te(n)}function be(e){try{let n=JSON.parse(e);return typeof n==="object"&&n!==null&&typeof n.type==="string"?n:null}catch{return null}}function hn(e){let n=e.agentId??e.agent?.id??e.endpointId;if(!n)throw Error("WebSocket run requires agent, agentId, or endpointId.");return n}function Sn(e){let n=e.endpointId??e.agent?.endpointId??e.agent?.id;if(!n)throw Error("WebSocket run requires agent or endpointId.");return n}function Ie(e,n){if(e.type!=="output")return e;let t=e;return n.onOutput?.(t),t.data}function xe(e){return Error(`Cannot access the WebSocket service at ${e}.`)}var ve=Symbol.for("broods.resource"),Te=Symbol.for("broods.config"),Ee=Symbol.for("broods.connection"),Ae=/^[A-Z][A-Z0-9_]{0,63}$/,He=new Proxy((e)=>{if(!Ae.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"&&Ae.test(n))throw Error(`env.${n} is not supported; use env("${n}")`);return Reflect.get(e,n,t)}});function Ze(e){let{name:n,description:t,...o}=e;return C("agent",n,t,o)}function Ve(e){return{[Te]:!0,config:e}}function Ge(e){let{name:n,description:t,...o}=e;return C("cron",n,t,o)}function We(e){return e}function Ke(e){let{name:n,description:t,...o}=e;return C("mcp",n,t,o)}function Je(e){let{name:n,description:t,...o}=e;return C("policy",n,t,o)}function Ye(e){let{name:n,description:t,...o}=e;return C("sandbox",n,t,o)}function Xe(e){let{name:n,description:t,...o}=e;return C("skill",n,t,o)}function Qe(e){let{name:n,description:t,...o}=e;return C("workspace",n,t,o)}function et(e){return l("discord",e)}function tt(e){return l("github",e)}function nt(e){return l("gchat",e)}function rt(e){return l("instagram",e)}function ot(e){return l("linear",e)}function st(e){return l("matrix",e)}function it(e){return l("messenger",e)}function at(e){return l("pancake",e)}function ct(e){return l("slack",e)}function lt(e){return l("teams",e)}function ut(e){return l("telegram",e)}function dt(e){return l("twilio",e)}function pt(e){return l("whatsapp",e)}function mt(e){return l("zalo",e)}function ft(e){let{name:n,description:t,channelId:o,guildId:r,...i}=e;return u(n,t,o,r,i)}function ht(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 gt(e){let{name:n,description:t,spaceName:o,...r}=e;return u(n,t,o,void 0,r)}function yt(e){let{name:n,description:t,igsid:o,...r}=e;return u(n,t,o,void 0,r)}function St(e){let{name:n,description:t,team:o,...r}=e;return u(n,t,o,void 0,r)}function bt(e){let{name:n,description:t,channelId:o,...r}=e;return u(n,t,o,void 0,r)}function vt(e){let{name:n,description:t,psid:o,...r}=e;return u(n,t,o,void 0,r)}function _t(e){let{name:n,description:t,conversationId:o,...r}=e;return u(n,t,o,void 0,r)}function wt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function Rt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function $t(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function Ct(e){let{name:n,description:t,from:o,...r}=e;return u(n,t,o,void 0,r)}function Et(e){let{name:n,description:t,waId:o,...r}=e;return u(n,t,o,void 0,r)}function kt(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function pe(e){return Boolean(e&&typeof e==="object"&&e[Te])}function R(e){return Boolean(e&&typeof e==="object"&&e[Ee])}function g(e){return Boolean(e&&typeof e==="object"&&e[ve])}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{[Ee]:!0,kind:"connection",type:e,...t?{partition:t}:{},config:o}}function C(e,n,t,o){return{[ve]:!0,kind:e,name:n,...t?{description:t}:{},config:o}}
|
|
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 D=new TextEncoder,ae={name:"HMAC",hash:"SHA-256"};async function ce(e,n,t,o){let r=se(D.encode(JSON.stringify(t))),i=await crypto.subtle.sign(ae,await an(n,o),D.encode(r));return`${e}${r}.${se(new Uint8Array(i))}`}function se(e){let n="";for(let t of e)n+=String.fromCharCode(t);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}async function an(e,n){let t=await crypto.subtle.digest("SHA-256",D.encode(`${e}${n}`));return crypto.subtle.importKey("raw",t,ae,!1,["sign","verify"])}var cn="buat_",Q="bsig_",de="x-broods-user-token",ue="broods.user.";var ge=600000,ee=3600000,un="broods-user-token:",le=/^[A-Za-z0-9._@+=-]{1,128}$/,fe=100,gn=256,ln=60000;async function ye(e,n,t=Date.now()){if(!n.startsWith(Q))throw Error(`The user token signing secret must start with ${Q}. It is not the bsk_ runtime key.`);let o=pn(e,t);if(!o||e.expiresAt>t+ee)throw Error(`Invalid user token: userId must match ${le.source}, conversations must be at most ${fe} non-empty keys, and expiresAt must be in the next ${ee/60000} minutes.`);return await ce(cn,un,o,n)}function pn(e,n){if(!e||typeof e!=="object")return null;let{userId:t,conversations:o,expiresAt:r}=e;if(typeof t!=="string"||!le.test(t)||typeof r!=="number"||!Number.isFinite(r)||r<=n||r>n+ee+ln)return null;if(o===void 0)return{userId:t,expiresAt:r};if(!Array.isArray(o)||o.length>fe||!o.every((i)=>typeof i==="string"&&i.trim()===i&&i.length>0&&i.length<=gn))return null;return{userId:t,conversations:o,expiresAt:r}}var y="BROODS_USER_TOKEN_SECRET";async function Be(e){let n=e.secret??process.env[y];if(!n)throw Error(`signUserToken needs the stage's signing secret: pass secret or set ${y}. \`broods dev\` and \`broods deploy\` write it to .env.local; the dashboard's Runtime key tab rotates it.`);return await ye({userId:e.userId,...e.conversations?{conversations:e.conversations}:{},expiresAt:Date.now()+(e.ttlMs??ge)},n)}var I="https://gateway.broods.app";class Re 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;userToken;fetchImpl;constructor(e={}){f(),this.baseUrl=te(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||I),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||void 0,this.userToken=e.userToken,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=me(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 Re(Ce(await i.json(),o));if(!i.body)throw Error("Run response has no body");for await(let s of we(i.body)){let a;try{a=JSON.parse(s)}catch{continue}if(a.type==="error")throw Error(`Agent run failed: ${dn(a.error)}`);yield a}}async runAsync(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o={...me(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:await 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 yn(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:await this.apiKeyHeaders(),body:JSON.stringify(n)});if(o.status!==202)throw Error(`${t} failed: ${o.status} ${await fn(o,"202 JSON")}`);return this.asyncAgentRun(Ce(await o.json(),n),n.conversationKey)}async openStream(e,n){if(this.apiKey)return await this.fetchCore(e,n,{Authorization:`Bearer ${this.apiKey}`,...await this.userTokenHeaders()});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 ${I} 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)}`)}}async apiKeyHeaders(){if(!this.apiKey)throw Error("BroodsClient requires apiKey or BROODS_API_KEY.");return{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`,...await this.userTokenHeaders()}}async userTokenHeaders(){let e=typeof this.userToken==="function"?await this.userToken():this.userToken;return e?{[de]:e}:{}}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 mn(this.baseUrl,e)}}function te(e){let n=e.trim(),t=/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(n)?n:`https://${n}`;return h(t)}function me(e,n){let t=e.eventId??`${n}-${crypto.randomUUID()}`;return{agentId:e.agentId,eventId:t,conversationKey:e.conversationKey??t,events:G(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 dn(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 Ce(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 fn(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 yn(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 mn(e,n){return`${te(e)}/v1/runs/${encodeURIComponent(n)}`}var Cn=2000,he=0,x=1;class je{baseUrl;apiKey;userToken;WebSocketImpl;connectTimeoutMs;constructor(e={}){if(f(),this.baseUrl=ke(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||I),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||"",!this.apiKey)throw Error("BroodsWebSocketClient requires apiKey or BROODS_API_KEY.");this.userToken=e.userToken,this.WebSocketImpl=e.WebSocket,this.connectTimeoutMs=e.connectTimeoutMs??Cn}subscribe(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=hn(e),i=xe(this.baseUrl),s=new t(o,z(this.apiKey,e.userToken??this.userToken)),a=!1,c=!1,d=setTimeout(()=>{if(!a)b(i)},this.connectTimeoutMs),m=(p=1000,A="client closed")=>{if(c)return;if(c=!0,clearTimeout(d),e.signal?.removeEventListener("abort",k),s.readyState===x||s.readyState===he)s.close(p,A)},b=(p)=>{n.onError?.(p),m(1000,"websocket error")},De=()=>{n.onDone?.(),m(1000,"done")},k=()=>{if(s.readyState===x)s.send(JSON.stringify({type:"cancel"}));b(Error("WebSocket run aborted."))};return e.signal?.addEventListener("abort",k,{once:!0}),s.onopen=()=>{if(a=!0,clearTimeout(d),e.signal?.aborted){k();return}s.send(JSON.stringify({type:"execute",agentId:r,...e.answers?{answers:e.answers}:{events:G(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 A=be(p.data);if(!A)return;let v=Ie(A,n);switch(n.onMessage?.(v),v.type){case"meta":n.onMeta?.(v);break;case"done":De();break;case"error":b(Error(Se(v.error)));break}},s.onerror=()=>{b(i)},s.onclose=(p)=>{if(clearTimeout(d),e.signal?.removeEventListener("abort",k),c||p.code===1000)return;b(Error(p.reason||"WebSocket connection closed."))},{url:o,sendControl:function(p){if(s.readyState!==x)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,z(this.apiKey,e.userToken??this.userToken)),i=!1,s=(c=1000,d="client closed")=>{if(i)return;if(i=!0,e.signal?.removeEventListener("abort",a),r.readyState===x||r.readyState===he)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,userToken:void 0}))},r.onmessage=(c)=>{if(i||typeof c.data!=="string")return;let d=be(c.data);if(!d)return;let m=Ie(d,n);if(i)return;if(n.onMessage?.(m),i)return;if(m.type==="done")n.onDone?.();if(m.type==="error")n.onError?.(Error(Se(m.error)))},r.onerror=()=>{if(i)return;s(1000,"websocket error"),n.onError?.(xe(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!==x)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=Sn(e),t=e.projectSlug??e.agent?.projectSlug,o=e.stageSlug??e.agent?.stageSlug,r=t&&o?`/projects/${encodeURIComponent(t)}/stages/${encodeURIComponent(o)}`:"";return`${ne(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 ne(e){let n=new URL(ke(e));if(n.protocol==="https:")n.protocol="wss:";if(n.protocol==="http:")n.protocol="ws:";return h(n.toString())}function z(e,n){return["broods.v1",`broods.token.${e}`,...n?[`${ue}${n}`]:[]]}function Se(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 ke(e){let n=e.trim();if(/^wss?:\/\//.test(n))return h(n);return te(n)}function be(e){try{let n=JSON.parse(e);return typeof n==="object"&&n!==null&&typeof n.type==="string"?n:null}catch{return null}}function hn(e){let n=e.agentId??e.agent?.id??e.endpointId;if(!n)throw Error("WebSocket run requires agent, agentId, or endpointId.");return n}function Sn(e){let n=e.endpointId??e.agent?.endpointId??e.agent?.id;if(!n)throw Error("WebSocket run requires agent or endpointId.");return n}function Ie(e,n){if(e.type!=="output")return e;let t=e;return n.onOutput?.(t),t.data}function xe(e){return Error(`Cannot access the WebSocket service at ${e}.`)}var ve=Symbol.for("broods.resource"),Te=Symbol.for("broods.config"),Ee=Symbol.for("broods.connection"),Ae=/^[A-Z][A-Z0-9_]{0,63}$/,He=new Proxy((e)=>{if(!Ae.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"&&Ae.test(n))throw Error(`env.${n} is not supported; use env("${n}")`);return Reflect.get(e,n,t)}});function Ze(e){let{name:n,description:t,...o}=e;return C("agent",n,t,o)}function Ve(e){return{[Te]:!0,config:e}}function Ge(e){let{name:n,description:t,...o}=e;return C("cron",n,t,o)}function We(e){return e}function Ke(e){let{name:n,description:t,...o}=e;return C("mcp",n,t,o)}function Je(e){let{name:n,description:t,...o}=e;return C("policy",n,t,o)}function Ye(e){let{name:n,description:t,...o}=e;return C("sandbox",n,t,o)}function Xe(e){let{name:n,description:t,...o}=e;return C("skill",n,t,o)}function Qe(e){let{name:n,description:t,...o}=e;return C("workspace",n,t,o)}function et(e){return l("discord",e)}function tt(e){return l("github",e)}function nt(e){return l("gchat",e)}function rt(e){return l("instagram",e)}function ot(e){return l("linear",e)}function st(e){return l("matrix",e)}function it(e){return l("messenger",e)}function at(e){return l("pancake",e)}function ct(e){return l("slack",e)}function lt(e){return l("teams",e)}function ut(e){return l("telegram",e)}function dt(e){return l("twilio",e)}function pt(e){return l("whatsapp",e)}function mt(e){return l("zalo",e)}function ft(e){let{name:n,description:t,channelId:o,guildId:r,...i}=e;return u(n,t,o,r,i)}function ht(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 gt(e){let{name:n,description:t,spaceName:o,...r}=e;return u(n,t,o,void 0,r)}function yt(e){let{name:n,description:t,igsid:o,...r}=e;return u(n,t,o,void 0,r)}function St(e){let{name:n,description:t,team:o,...r}=e;return u(n,t,o,void 0,r)}function bt(e){let{name:n,description:t,channelId:o,...r}=e;return u(n,t,o,void 0,r)}function vt(e){let{name:n,description:t,psid:o,...r}=e;return u(n,t,o,void 0,r)}function _t(e){let{name:n,description:t,conversationId:o,...r}=e;return u(n,t,o,void 0,r)}function wt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function Rt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function $t(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function Ct(e){let{name:n,description:t,from:o,...r}=e;return u(n,t,o,void 0,r)}function Et(e){let{name:n,description:t,waId:o,...r}=e;return u(n,t,o,void 0,r)}function kt(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function pe(e){return Boolean(e&&typeof e==="object"&&e[Te])}function R(e){return Boolean(e&&typeof e==="object"&&e[Ee])}function g(e){return Boolean(e&&typeof e==="object"&&e[ve])}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{[Ee]:!0,kind:"connection",type:e,...t?{partition:t}:{},config:o}}function C(e,n,t,o){return{[ve]:!0,kind:e,name:n,...t?{description:t}:{},config:o}}
|
|
5
5
|
export{G,we,Le,Ne,Ue,Fe,W,K,S,w,N,P,J,Y,_,h,U,f,F,T,X,Q,de,ee,y,Be,I,Re,B,te,je,ne,z,He,Ze,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ft,ht,gt,yt,St,bt,vt,_t,wt,Rt,$t,Ct,Et,kt,pe,R,g};
|
package/dist/cli/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{W,K,S,w,N,P,J,Y,_,h,U,f,T,X,Q,y,I,B,ne,z,pe,R,g}from"../chunk-
|
|
2
|
+
import{W,K,S,w,N,P,J,Y,_,h,U,f,T,X,Q,y,I,B,ne,z,pe,R,g}from"../chunk-gqyk7vva.js";import{m,C}from"../chunk-njxsdp91.js";import{chmod as Ws,lstat as Fs,mkdir as Wn,readFile as ro,readdir as Ks,stat as Hs,writeFile as ye}from"node:fs/promises";import{createHash as so}from"node:crypto";import Ys from"node:module";import{basename as Vs,join as Me,relative as zs,resolve as x,sep as Js}from"node:path";import{watch as qs}from"node:fs";import{spawn as io}from"node:child_process";import{tmpdir as Zs}from"node:os";import{performance as Qt}from"node:perf_hooks";import{stripVTControlCharacters as Un}from"node:util";import{fileURLToPath as To,pathToFileURL as ut}from"node:url";import{createHash as Io}from"node:crypto";import{existsSync as _o,readFileSync as jo}from"node:fs";import{mkdtemp as Do,readdir as gt,readFile as Uo,rm as No,writeFile as Lo}from"node:fs/promises";import nt from"node:module";import{tmpdir as Mo}from"node:os";import{basename as Bo,isAbsolute as Go,join as Ke,relative as Se,resolve as He}from"node:path";import{build as Wo,transformSync as pt}from"esbuild";var Jn=/\$\{([A-Z][A-Z0-9_]*)\}/;var qn={alibaba:{label:"Alibaba Qwen",modelPlaceholder:"qwen3-max"},anthropic:{label:"Anthropic",modelPlaceholder:"claude-sonnet-4-5-20250929"},azure:{label:"Azure OpenAI",modelPlaceholder:"gpt-4.1-mini"},baseten:{label:"Baseten",modelPlaceholder:"deepseek-ai/DeepSeek-V3"},bedrock:{label:"Amazon Bedrock",modelPlaceholder:"anthropic.claude-sonnet-4-5-20250929-v1:0"},cerebras:{label:"Cerebras",modelPlaceholder:"llama3.1-8b"},chatgpt:{label:"ChatGPT plan",modelPlaceholder:"gpt-5.5"},cloudflare:{label:"Cloudflare",modelPlaceholder:"@cf/meta/llama-3.3-70b-instruct-fp8-fast"},cohere:{label:"Cohere",modelPlaceholder:"command-a-03-2025"},custom:{label:"Custom OpenAI-compatible",modelPlaceholder:"gpt-oss-120b"},deepinfra:{label:"DeepInfra",modelPlaceholder:"deepseek-ai/DeepSeek-V3"},deepseek:{label:"DeepSeek",modelPlaceholder:"deepseek-chat"},fireworks:{label:"Fireworks",modelPlaceholder:"accounts/fireworks/models/deepseek-v3"},google:{label:"Google",modelPlaceholder:"gemini-2.5-flash"},groq:{label:"Groq",modelPlaceholder:"llama-3.3-70b-versatile"},huggingface:{label:"Hugging Face",modelPlaceholder:"meta-llama/Llama-3.3-70B-Instruct"},llmgateway:{label:"LLM Gateway",modelPlaceholder:"openai/gpt-4.1-mini"},minimax:{label:"MiniMax",modelPlaceholder:"MiniMax-M2.7"},mistral:{label:"Mistral",modelPlaceholder:"mistral-large-latest"},moonshotai:{label:"Moonshot AI Kimi",modelPlaceholder:"kimi-k2.6"},ollama:{label:"Ollama",modelPlaceholder:"gpt-oss:120b"},openai:{label:"OpenAI",modelPlaceholder:"gpt-4.1-mini"},openrouter:{label:"OpenRouter",modelPlaceholder:"anthropic/claude-sonnet-4.5"},perplexity:{label:"Perplexity",modelPlaceholder:"low"},togetherai:{label:"Together.ai",modelPlaceholder:"deepseek-ai/DeepSeek-V3"},v0:{label:"Vercel v0",modelPlaceholder:"v0-1.0-md"},vercel:{label:"Vercel AI Gateway",modelPlaceholder:"openai/gpt-4.1-mini"},vertex:{label:"Google Vertex AI",modelPlaceholder:"gemini-2.5-flash"},xai:{label:"xAI Grok",modelPlaceholder:"grok-4"},zai:{label:"Z.ai GLM",modelPlaceholder:"glm-4.7"}},Zn=Object.keys(qn);function Xn(e){return Object.hasOwn(qn,e)}var Co=/(?:^|[\n;])\s*import\s+(?:[^;"'`]*?\s+from\s*)?["'](?!\.{1,2}\/|\/|node:)[^"']+["']|import\s*\(\s*["'](?!\.{1,2}\/|\/|node:)[^"']+["']\s*\)/,Oo=/(?:import\s+(?:[^;"'`]*?\s+from\s*)?["']node:|import\s*\(\s*["']node:)/,Ao=/(?<![.\w$])(?:process|Buffer)\s*(?:\?\.|\.|\[)/,xo=[/\b(?:__)?require\s*\(/,/(?<![.\w$])setImmediate\s*\(/,Oo,Ao,/\b__dirname\b/,Co],Po=/(?<![.\w$])eval\s*\(|\bnew\s+Function\s*\(/;function Qn(e){return![...xo,Po].some((n)=>n.test(e))}var dn=32;var un=["conversation","agent"];function et(e){return un.some((n)=>n===e)}var Ae="*",Fo=new RegExp(Jn.source,"g"),Ko=`const passthrough = (input) => input;
|
|
3
3
|
export const defineAgent = passthrough;
|
|
4
4
|
export const defineBroods = passthrough;
|
|
5
5
|
export const defineCron = passthrough;
|
|
@@ -87,7 +87,7 @@ Check the browser tab and the dashboard logs for an error. If the browser shows
|
|
|
87
87
|
404 on /cli-auth/start, deploy the dashboard build that includes CLI auth or pass
|
|
88
88
|
--dashboard-url for the environment you deployed. Other common causes are missing
|
|
89
89
|
cliAuth Convex functions or no active API account (Organization settings -> API access).`,Wt=new Set(["--base-url","--cwd","--dashboard-url","--stage","--from","--level","--limit","--mcp","--project","--region","--sandbox","-n"]);function ws(e,n=process.platform){if(n==="darwin")return{command:"open",args:[e]};if(n==="win32")return{command:"rundll32",args:["url.dll,FileProtocolHandler",e]};return{command:"xdg-open",args:[e]}}function D(e,n){let t=Wt.has(n)?`${n}=`:null;return e.some((o)=>o===n||t!==null&&o.startsWith(t))}function we(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function b(e,n){for(let t=0;t<e.length;t+=1){let o=e[t];if(o===n)return e[t+1];if(o?.startsWith(`${n}=`))return o.slice(n.length+1)||void 0}return}function ee(e){let n=[];for(let t=0;t<e.length;t+=1){let o=e[t];if(o===void 0)continue;if(Wt.has(o)){t+=1;continue}if(o.startsWith("-"))continue;n.push(o)}return n}async function On(e){let n=gs(),t=us(32).toString("base64url"),o=ds("sha256").update(t).digest("base64url"),{code:r,close:s}=await xn(n,{port:ys(),fixedPort:Boolean(process.env.BROODS_LOGIN_PORT),path:"/callback",read:vs,done:"broods CLI login complete. You can close this tab."});try{let i=r.callbackUrl,a=`${h(e)}/cli-auth/start?`+new URLSearchParams({callback:i,state:n,code_challenge:o});await bs(a),console.log(`Opening ${a}`),An(a);let c=await Pn(r.promise),d=await en(`${c.baseUrl}/v1/account/auth/exchange`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({code:c.code,code_verifier:t})});if(!d.ok)throw Error(`Login exchange failed: ${d.status} ${await d.text()}`);let l=await d.json(),u={baseUrl:c.baseUrl,dashboardUrl:h(e),token:l.token,createdAt:new Date().toISOString(),...l.user?{user:l.user}:{},...l.org?{org:l.org}:{},...l.account?{account:l.account}:{}};return await J(u),u}finally{s()}}async function te(e){f();let n=P(e);if(!n){let t=process.env.BROODS_DASHBOARD_URL,o=e??process.env.BROODS_BASE_URL??(t?U(t):void 0);throw Error(o?`Not logged in to ${h(o)}. Run \`broods login\`.`:"Run `broods login` first, or set BROODS_TOKEN and BROODS_BASE_URL.")}return n}async function on(e){if(!se.isTTY)return!1;let n=De({input:se,output:re});try{let t=(await n.question(`${e} [y/N] `)).trim().toLowerCase();return t==="y"||t==="yes"}finally{n.close()}}async function Ft(e){re.write(`${e}: `);let n=new fs({write:(o,r,s)=>s()}),t=De({input:se,output:n,terminal:se.isTTY===!0});try{let o=await t.question("");if(!o)throw Error(`${e} is required`);return o}finally{t.close(),re.write(`
|
|
90
|
-
`)}}async function Ue(e,n,t,o){if(n.length===0)throw Error(`${e}: no options available`);if(n.length===1)return n[0];let r=o!==void 0&&o>=0&&o<n.length?o:void 0;console.log(e),n.forEach((a,c)=>{console.log(Re(`${c+1}. ${t(a)}`,c===r))});let s=r===void 0?`Choose 1-${n.length}: `:`Choose 1-${n.length} [${r+1}]: `,i=De({input:se,output:re});try{for(;;){let a=(await i.question(s)).trim();if(a===""&&r!==void 0)return n[r];let c=Number(a);if(Number.isInteger(c)&&c>=1&&c<=n.length)return n[c-1];console.log(`Enter a number from 1 to ${n.length}.`)}}finally{i.close()}}async function Kt(e,n,t,o){console.log(e),n.forEach((i,a)=>{console.log(` ${a+1}. ${t(i)}`)});let r=n.length>0?`Choose 1-${n.length}, or `:"",s=De({input:se,output:re});try{let i=(await s.question(`${r}${o.hint} [${o.defaultValue}]: `)).trim();if(i==="")return o.defaultValue;let a=Number(i);if(Number.isInteger(a)&&a>=1&&a<=n.length)return n[a-1];return i}finally{s.close()}}async function be(e,n){if(!se.isTTY)return n??"";let t=De({input:se,output:re});try{let o=t.question(`${e}: `);if(n){if(se.isTTY&&re.isTTY)re.write("\x1B[90m");if(t.write(n),se.isTTY&&re.isTTY)re.write("\x1B[0m")}return(await o).trim()||n||""}finally{t.close()}}function An(e){let{command:n,args:t}=ws(e),o=ps(n,t,{stdio:"ignore",detached:!0});o.on("error",(r)=>{console.error(je(`Could not open a browser (${r.message}). Open the URL above to continue.`,{stream:"stderr"}))}),o.unref()}function xn(e,n){return new Promise((t,o)=>{let r=ls((c,d)=>{let l=new URL(c.url??"/","http://127.0.0.1");if(l.pathname!==n.path||l.searchParams.get("state")!==e){d.writeHead(400).end("Invalid callback.");return}try{let u=n.read(l.searchParams);d.writeHead(200,{"Content-Type":"text/plain"}).end(n.done),s(u)}catch(u){d.writeHead(400,{"Content-Type":"text/plain"}).end(u instanceof Error?u.message:String(u)),i(u)}}),s,i,a=new Promise((c,d)=>{s=c,i=d});r.on("error",(c)=>{if(!n.fixedPort&&n.port!==0&&c.code==="EADDRINUSE"){r.listen(0,"127.0.0.1");return}o(c)}),r.listen(n.port,"127.0.0.1",()=>{let c=r.address();if(!c||typeof c==="string"){o(Error("Failed to allocate callback port"));return}t({code:{callbackUrl:`http://127.0.0.1:${c.port}${n.path}`,promise:a},close:()=>r.close()})})})}async function Pn(e,n=hs){let t,o=new Promise((r,s)=>{t=setTimeout(()=>s(Error(n)),ms)});try{return await Promise.race([e,o])}finally{if(t)clearTimeout(t)}}async function bs(e){let n=await en(e,{method:"GET",redirect:"manual"});if(n.status===404){let t=new URL(e);throw Error(`${t.origin} has no broods login page. Check that --dashboard-url points at your broods dashboard.`)}if(n.status>=500)throw Error(`The broods login page failed: ${n.status} ${await n.text()}`)}function ys(){let e=process.env.BROODS_LOGIN_PORT;if(e){let n=Number(e);if(Number.isInteger(n)&&n>0&&n<65536)return n;throw Error("BROODS_LOGIN_PORT must be a TCP port number")}return 18987}function vs(e){let n=e.get("error");if(n)throw Error(`Login failed: ${n}`);let t=e.get("code");if(!t)throw Error("Login callback carried no code.");let o=e.get("base_url");if(!o)throw Error("Login callback did not advertise the API base URL (base_url). Deploy a dashboard build that includes the Convex-direct CLI auth flow.");return{code:t,baseUrl:h(o)}}var Ss=1455,$s="/auth/callback";async function Yt(e,n,t=An){let o=he[n].label,r=Ht(),s=Ht(),i=ks(32).toString("base64url"),{code:a,close:c}=await xn(r,{port:Ss,fixedPort:!1,path:$s,read:Rs,done:`${o} is connected to broods. You can close this tab.`});try{let d=a.callbackUrl,l=await e.startConnection(n,{redirectUri:d,codeChallenge:Es("sha256").update(i).digest("base64url"),state:r,nonce:s});t(l.authorizeUrl),console.log(`Opening ${l.authorizeUrl}`);let u=await Pn(a.promise,`Timed out waiting for the ${o} sign-in to finish in the browser.`);return await e.connect(n,{code:u.code,codeVerifier:i,redirectUri:d,nonce:s,clientId:u.clientId??l.clientId,hostId:l.hostId})}finally{c()}}function Rs(e){let n=e.get("error");if(n)throw Error(`Sign-in failed: ${e.get("error_description")??n}`);let t=e.get("code");if(!t)throw Error("Sign-in callback carried no code.");return{code:t,clientId:e.get("client_id")??void 0}}import{existsSync as zt}from"node:fs";import{mkdir as Os,readFile as As,writeFile as xs}from"node:fs/promises";import{dirname as Jt,join as _n,resolve as Ps,sep as ge}from"node:path";import{fileURLToPath as Ts}from"node:url";var Ne={name:"broods",version:"0.51.
|
|
90
|
+
`)}}async function Ue(e,n,t,o){if(n.length===0)throw Error(`${e}: no options available`);if(n.length===1)return n[0];let r=o!==void 0&&o>=0&&o<n.length?o:void 0;console.log(e),n.forEach((a,c)=>{console.log(Re(`${c+1}. ${t(a)}`,c===r))});let s=r===void 0?`Choose 1-${n.length}: `:`Choose 1-${n.length} [${r+1}]: `,i=De({input:se,output:re});try{for(;;){let a=(await i.question(s)).trim();if(a===""&&r!==void 0)return n[r];let c=Number(a);if(Number.isInteger(c)&&c>=1&&c<=n.length)return n[c-1];console.log(`Enter a number from 1 to ${n.length}.`)}}finally{i.close()}}async function Kt(e,n,t,o){console.log(e),n.forEach((i,a)=>{console.log(` ${a+1}. ${t(i)}`)});let r=n.length>0?`Choose 1-${n.length}, or `:"",s=De({input:se,output:re});try{let i=(await s.question(`${r}${o.hint} [${o.defaultValue}]: `)).trim();if(i==="")return o.defaultValue;let a=Number(i);if(Number.isInteger(a)&&a>=1&&a<=n.length)return n[a-1];return i}finally{s.close()}}async function be(e,n){if(!se.isTTY)return n??"";let t=De({input:se,output:re});try{let o=t.question(`${e}: `);if(n){if(se.isTTY&&re.isTTY)re.write("\x1B[90m");if(t.write(n),se.isTTY&&re.isTTY)re.write("\x1B[0m")}return(await o).trim()||n||""}finally{t.close()}}function An(e){let{command:n,args:t}=ws(e),o=ps(n,t,{stdio:"ignore",detached:!0});o.on("error",(r)=>{console.error(je(`Could not open a browser (${r.message}). Open the URL above to continue.`,{stream:"stderr"}))}),o.unref()}function xn(e,n){return new Promise((t,o)=>{let r=ls((c,d)=>{let l=new URL(c.url??"/","http://127.0.0.1");if(l.pathname!==n.path||l.searchParams.get("state")!==e){d.writeHead(400).end("Invalid callback.");return}try{let u=n.read(l.searchParams);d.writeHead(200,{"Content-Type":"text/plain"}).end(n.done),s(u)}catch(u){d.writeHead(400,{"Content-Type":"text/plain"}).end(u instanceof Error?u.message:String(u)),i(u)}}),s,i,a=new Promise((c,d)=>{s=c,i=d});r.on("error",(c)=>{if(!n.fixedPort&&n.port!==0&&c.code==="EADDRINUSE"){r.listen(0,"127.0.0.1");return}o(c)}),r.listen(n.port,"127.0.0.1",()=>{let c=r.address();if(!c||typeof c==="string"){o(Error("Failed to allocate callback port"));return}t({code:{callbackUrl:`http://127.0.0.1:${c.port}${n.path}`,promise:a},close:()=>r.close()})})})}async function Pn(e,n=hs){let t,o=new Promise((r,s)=>{t=setTimeout(()=>s(Error(n)),ms)});try{return await Promise.race([e,o])}finally{if(t)clearTimeout(t)}}async function bs(e){let n=await en(e,{method:"GET",redirect:"manual"});if(n.status===404){let t=new URL(e);throw Error(`${t.origin} has no broods login page. Check that --dashboard-url points at your broods dashboard.`)}if(n.status>=500)throw Error(`The broods login page failed: ${n.status} ${await n.text()}`)}function ys(){let e=process.env.BROODS_LOGIN_PORT;if(e){let n=Number(e);if(Number.isInteger(n)&&n>0&&n<65536)return n;throw Error("BROODS_LOGIN_PORT must be a TCP port number")}return 18987}function vs(e){let n=e.get("error");if(n)throw Error(`Login failed: ${n}`);let t=e.get("code");if(!t)throw Error("Login callback carried no code.");let o=e.get("base_url");if(!o)throw Error("Login callback did not advertise the API base URL (base_url). Deploy a dashboard build that includes the Convex-direct CLI auth flow.");return{code:t,baseUrl:h(o)}}var Ss=1455,$s="/auth/callback";async function Yt(e,n,t=An){let o=he[n].label,r=Ht(),s=Ht(),i=ks(32).toString("base64url"),{code:a,close:c}=await xn(r,{port:Ss,fixedPort:!1,path:$s,read:Rs,done:`${o} is connected to broods. You can close this tab.`});try{let d=a.callbackUrl,l=await e.startConnection(n,{redirectUri:d,codeChallenge:Es("sha256").update(i).digest("base64url"),state:r,nonce:s});t(l.authorizeUrl),console.log(`Opening ${l.authorizeUrl}`);let u=await Pn(a.promise,`Timed out waiting for the ${o} sign-in to finish in the browser.`);return await e.connect(n,{code:u.code,codeVerifier:i,redirectUri:d,nonce:s,clientId:u.clientId??l.clientId,hostId:l.hostId})}finally{c()}}function Rs(e){let n=e.get("error");if(n)throw Error(`Sign-in failed: ${e.get("error_description")??n}`);let t=e.get("code");if(!t)throw Error("Sign-in callback carried no code.");return{code:t,clientId:e.get("client_id")??void 0}}import{existsSync as zt}from"node:fs";import{mkdir as Os,readFile as As,writeFile as xs}from"node:fs/promises";import{dirname as Jt,join as _n,resolve as Ps,sep as ge}from"node:path";import{fileURLToPath as Ts}from"node:url";var Ne={name:"broods",version:"0.51.1",description:"CLI + TypeScript SDK for the broods agent platform.",keywords:["agents","ai","broods","cli","sdk"],homepage:"https://github.com/beeblastco/broods#readme",bugs:{url:"https://github.com/beeblastco/broods/issues"},license:"MIT",repository:{type:"git",url:"git+https://github.com/beeblastco/broods.git",directory:"packages/broods"},bin:{broods:"dist/cli/index.js"},files:["dist","README.md","LICENSE.md"],type:"module",main:"./dist/index.js",types:"./dist/index.d.ts",typesVersions:{"*":{account:["./dist/account.d.ts"]}},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.js"},"./account":{types:"./dist/account.d.ts",import:"./dist/account.js"}},scripts:{build:"bun scripts/build.ts && rollup -c rollup.dts.config.mjs && rm -rf .dts-temp",check:"tsc --noEmit && tsc --noEmit -p tsconfig.scripts.json","pack:check":"bun run build && publint && attw --pack .",prepublishOnly:"bun run build",test:"bun test"},dependencies:{"@modelcontextprotocol/client":"^2.2.0",esbuild:"^0.28.2"},devDependencies:{"@ai-sdk/tui":"1.0.138","@arethetypeswrong/cli":"^0.18.5","@chat-adapter/discord":"^4.38.1","@chat-adapter/github":"^4.38.1","@chat-adapter/slack":"^4.38.1","@chat-adapter/telegram":"^4.38.1","@modelcontextprotocol/server":"2.2.0","@types/bun":"^1.3.14","@typescript/typescript6":"6.0.2",ai:"^7.0.137",publint:"^0.3.23",rollup:"^4.62.4","rollup-plugin-dts":"^6.5.1",typescript:"^7.0.2",zod:"^4.4.3"},peerDependencies:{ai:"^7.0.137"},engines:{node:">=22.15"}};var Tn=_n(Jt(N),"update-check.json"),Is=86400000,_s="https://registry.npmjs.org/broods/latest",js=2000,Ds=[["bun.lock","bun"],["bun.lockb","bun"],["pnpm-lock.yaml","pnpm"],["yarn.lock","yarn"]];function jn(e,n){let t=In(e),o=In(n);for(let r=0;r<3;r+=1){let s=t[r]??0,i=o[r]??0;if(s!==i)return s>i}return!Vt(e)&&Vt(n)}async function Dn(e={}){let n=await Ns(),t=e.maxAgeMs??Is;if(n&&Date.now()-n.checkedAt<t)return n.latest;let o=await Us();if(o===null)return n?.latest??null;return await Ms({checkedAt:Date.now(),latest:o}),o}function Le(e){return In(e)[0]??0}function qt(e=Ps(process.cwd()),n=Ts(import.meta.url),t=Ne.version){let o=`${ge}node_modules${ge}`,r=n.indexOf(o),s=r===-1?null:n.slice(0,r),i=s===null?n.startsWith(`${e}${ge}`):e===s||e.startsWith(`${s}${ge}`),a=n.includes(`${ge}.bun${ge}install${ge}global${ge}`),c=s??e,d=i?Ls(c):a?"bun":"npm",l=d==="npm"?"install":"add",u=d==="pnpm"&&zt(_n(c,"pnpm-workspace.yaml"))?["-w"]:[],p=`broods@${Le(t)}`;return{manager:d,global:!i,command:d,cwd:i?c:e,args:i?[l,...u,p]:[l,"-g",p]}}async function Us(){try{let e=await fetch(_s,{signal:AbortSignal.timeout(js),headers:{accept:"application/json"}});if(!e.ok)return null;let n=await e.json();return typeof n.version==="string"?n.version:null}catch{return null}}function Vt(e){return e.includes("-")}async function Ns(){try{let e=JSON.parse(await As(Tn,"utf8"));if(typeof e.latest!=="string")return null;if(typeof e.checkedAt!=="number")return null;return{checkedAt:e.checkedAt,latest:e.latest}}catch{return null}}function Ls(e){return Ds.find(([t])=>zt(_n(e,t)))?.[1]??"npm"}function In(e){let[n]=e.trim().replace(/^v/,"").split("-");return(n??"").split(".").slice(0,3).map((t)=>Number.parseInt(t,10)||0)}async function Ms(e){try{await Os(Jt(Tn),{recursive:!0}),await xs(Tn,`${JSON.stringify(e)}
|
|
91
91
|
`,"utf8")}catch{}}var Zt=`---
|
|
92
92
|
name: broods
|
|
93
93
|
description: Work on a broods account alongside a developer from Claude Code or a development agent. Covers onboarding and sign-in, creating a broods project, defining and deploying agents and their resources with the CLI, and integrating a deployed agent into existing code with the SDK. Use when asked to set up broods, create or work on a broods project, create or manage agents or any account resource, or call a deployed agent from application code.
|
|
@@ -419,7 +419,7 @@ ${q("stage")}`);let i=f(),a=b(e,"--dashboard-url")??i.dashboardUrl??ie,c=ln(e),d
|
|
|
419
419
|
|
|
420
420
|
${q("env")}`);if(a&&!t)throw Error(`broods env ${n} needs a variable name.
|
|
421
421
|
|
|
422
|
-
${q("env")}`);let{manifest:c,config:d}=await ce({project:b(e,"--project"),stage:b(e,"--stage"),command:"dev"}),l=await te(b(e,"--base-url")??d.baseUrl),u=new F({baseUrl:l.baseUrl,token:l.token}),p=`${c.project}/${c.stage}`;if(i){await Fi(u,c,p);return}if(o){let k=await u.listEnv(c.project,c.stage);if(k.length===0){console.log(`No environment variables set for ${p}.`);return}console.log(`Environment variables for ${p} (values hidden):`);for(let E of k)console.log(` ${E.name}`);return}if(s){let k=await u.getEnv(c.project,c.stage,t);if(k===null){console.error(`${t} is not set for ${p}`),process.exitCode=1;return}console.log(k);return}if(r){await u.removeEnv(c.project,c.stage,t),H(`Removed ${t} from ${p}`);return}let v=await Ft(t);await u.setEnv(c.project,c.stage,t,v),H(`Stored ${t} for ${p}`)}async function Fi(e,n,t){let o=await Fn(e,n);if(o.length===0){console.log('No env("NAME") references in this project.');return}let r=await wo(e,n,o);if(r.length>0)Rn(r);let s=sn(o,"synced").length;console.log(r.length>0?`${s} other referenced variable(s) already in step with ${t}.`:`${s} referenced variable(s) already in step with ${t}.`);let i=sn(o,"stage-only");if(i.length>0)console.log(`${i.length} referenced variable(s) live only on ${t}: ${i.join(", ")}`);let a=sn(o,"unresolved");if(a.length>0)A(`${a.length} referenced variable(s) with no value here or on ${t}: ${a.join(", ")}. Put them in .env.local, or run \`broods env set <NAME> --stage ${n.stage}\`.`)}function Kn(e){if(D(e,"--all"))return"DEBUG";let n=b(e,"--level");if(n===void 0&&D(e,"--level"))throw Error("Missing value for --level. Use DEBUG, INFO, WARN, or ERROR.");if(!n)return"WARN";let t=n.toUpperCase();if(t==="DEBUG")return"DEBUG";if(t==="INFO")return"INFO";if(t==="WARN"||t==="WARNING")return"WARN";if(t==="ERROR")return"ERROR";throw Error(`Unknown log level: ${n}. Use DEBUG, INFO, WARN, or ERROR.`)}async function Ki(e){f();let n=b(e,"--project")??process.env.BROODS_PROJECT,t=b(e,"--stage")??_();if(!n)throw Error("Project name is required. Pass --project <name> or set BROODS_PROJECT in .env.local.");if(!t)throw Error("Stage name is required. Pass --stage <name> or set BROODS_STAGE in .env.local.");return{project:n,stage:t}}async function Fe(e){let n=await Ki(e),t=f(),o=await We(b(e,"--dashboard-url")??t.dashboardUrl??ie,b(e,"--base-url")),r=new F({baseUrl:o.baseUrl,token:o.token}),s=await r.mintStageSession(n.project,n.stage),i=s,a=async()=>{let c=i??await r.mintStageSession(n.project,n.stage);return i=void 0,c.token};return{baseUrl:o.baseUrl,credential:a,project:s.projectSlug,stage:s.stageSlug}}function bo(e){return e==="WARN"?" (--all for INFO too)":""}function Hn(e,n){console.error(je(`Reconnecting to live logs (attempt ${e}): ${n}`,{stream:"stderr"}))}function Yn(e){let n=new Date(e.ts).toISOString().slice(11,23),t=e.level.padEnd(5),o=Un(e.message);return`${n} ${t} ${e.eventType} ${o}`}async function Hi(e){let n=await Fe(e),{project:t,stage:o}=n,r=Kn(e),s=new AbortController,i=()=>s.abort();process.on("SIGINT",i),console.log(`Streaming live logs for ${t}/${o} [${r}+]`+bo(r)+", Ctrl+C to stop");try{for await(let a of qe(n,{backfill:0,minLevel:r,signal:s.signal,onReconnect:Hn}))console.log(Yn(a))}catch(a){if(!s.signal.aborted)console.error(a instanceof Error?a.message:String(a)),process.exitCode=1}finally{process.off("SIGINT",i)}}async function Yi(e){if(D(e,"--doctor")){await Vi(D(e,"--request"));return}let n=ee(e)[0];if(!n){console.log(Ee("machine",e));return}let{runMachineDaemon:t}=await import("../chunk-
|
|
422
|
+
${q("env")}`);let{manifest:c,config:d}=await ce({project:b(e,"--project"),stage:b(e,"--stage"),command:"dev"}),l=await te(b(e,"--base-url")??d.baseUrl),u=new F({baseUrl:l.baseUrl,token:l.token}),p=`${c.project}/${c.stage}`;if(i){await Fi(u,c,p);return}if(o){let k=await u.listEnv(c.project,c.stage);if(k.length===0){console.log(`No environment variables set for ${p}.`);return}console.log(`Environment variables for ${p} (values hidden):`);for(let E of k)console.log(` ${E.name}`);return}if(s){let k=await u.getEnv(c.project,c.stage,t);if(k===null){console.error(`${t} is not set for ${p}`),process.exitCode=1;return}console.log(k);return}if(r){await u.removeEnv(c.project,c.stage,t),H(`Removed ${t} from ${p}`);return}let v=await Ft(t);await u.setEnv(c.project,c.stage,t,v),H(`Stored ${t} for ${p}`)}async function Fi(e,n,t){let o=await Fn(e,n);if(o.length===0){console.log('No env("NAME") references in this project.');return}let r=await wo(e,n,o);if(r.length>0)Rn(r);let s=sn(o,"synced").length;console.log(r.length>0?`${s} other referenced variable(s) already in step with ${t}.`:`${s} referenced variable(s) already in step with ${t}.`);let i=sn(o,"stage-only");if(i.length>0)console.log(`${i.length} referenced variable(s) live only on ${t}: ${i.join(", ")}`);let a=sn(o,"unresolved");if(a.length>0)A(`${a.length} referenced variable(s) with no value here or on ${t}: ${a.join(", ")}. Put them in .env.local, or run \`broods env set <NAME> --stage ${n.stage}\`.`)}function Kn(e){if(D(e,"--all"))return"DEBUG";let n=b(e,"--level");if(n===void 0&&D(e,"--level"))throw Error("Missing value for --level. Use DEBUG, INFO, WARN, or ERROR.");if(!n)return"WARN";let t=n.toUpperCase();if(t==="DEBUG")return"DEBUG";if(t==="INFO")return"INFO";if(t==="WARN"||t==="WARNING")return"WARN";if(t==="ERROR")return"ERROR";throw Error(`Unknown log level: ${n}. Use DEBUG, INFO, WARN, or ERROR.`)}async function Ki(e){f();let n=b(e,"--project")??process.env.BROODS_PROJECT,t=b(e,"--stage")??_();if(!n)throw Error("Project name is required. Pass --project <name> or set BROODS_PROJECT in .env.local.");if(!t)throw Error("Stage name is required. Pass --stage <name> or set BROODS_STAGE in .env.local.");return{project:n,stage:t}}async function Fe(e){let n=await Ki(e),t=f(),o=await We(b(e,"--dashboard-url")??t.dashboardUrl??ie,b(e,"--base-url")),r=new F({baseUrl:o.baseUrl,token:o.token}),s=await r.mintStageSession(n.project,n.stage),i=s,a=async()=>{let c=i??await r.mintStageSession(n.project,n.stage);return i=void 0,c.token};return{baseUrl:o.baseUrl,credential:a,project:s.projectSlug,stage:s.stageSlug}}function bo(e){return e==="WARN"?" (--all for INFO too)":""}function Hn(e,n){console.error(je(`Reconnecting to live logs (attempt ${e}): ${n}`,{stream:"stderr"}))}function Yn(e){let n=new Date(e.ts).toISOString().slice(11,23),t=e.level.padEnd(5),o=Un(e.message);return`${n} ${t} ${e.eventType} ${o}`}async function Hi(e){let n=await Fe(e),{project:t,stage:o}=n,r=Kn(e),s=new AbortController,i=()=>s.abort();process.on("SIGINT",i),console.log(`Streaming live logs for ${t}/${o} [${r}+]`+bo(r)+", Ctrl+C to stop");try{for await(let a of qe(n,{backfill:0,minLevel:r,signal:s.signal,onReconnect:Hn}))console.log(Yn(a))}catch(a){if(!s.signal.aborted)console.error(a instanceof Error?a.message:String(a)),process.exitCode=1}finally{process.off("SIGINT",i)}}async function Yi(e){if(D(e,"--doctor")){await Vi(D(e,"--request"));return}let n=ee(e)[0];if(!n){console.log(Ee("machine",e));return}let{runMachineDaemon:t}=await import("../chunk-8c952qsc.js"),{baseUrl:o,credential:r}=await Fe(e),s=x(b(e,"--cwd")??process.cwd()),i=D(e,"--computer"),a=b(e,"--mcp"),c=D(e,"--force"),d=new AbortController,l=()=>d.abort();process.on("SIGINT",l),console.log(`Connecting ${n} to ${o} (cwd ${s}${i?", computer use on":""}), Ctrl+C to stop`);try{await t({baseUrl:o,computer:i,credential:r,cwd:s,force:c,log:(u)=>console.log(u),mcpFile:a?x(a):void 0,sandbox:n,signal:d.signal})}catch(u){console.error(u instanceof Error?u.message:String(u)),process.exitCode=1}finally{process.off("SIGINT",l)}}async function Vi(e){try{let{startDesktop:n}=await import("../chunk-5tnnqapc.js"),{display:t,driver:o,permissions:r}=await n(e);o.stop();let s=(i)=>i?"granted":"missing";if(console.log(`screenshot frame ${t.width}x${t.height} (scale ${t.scale.toFixed(2)})`),console.log(`screen recording ${s(r.screenRecording)}`),console.log(`accessibility ${s(r.accessibility)}`),!r.screenRecording||!r.accessibility)console.log(e?"Approve the prompts, or add this terminal under System Settings > Privacy & Security, then run again.":"Run `broods machine --doctor --request` to show the macOS prompts."),process.exitCode=1}catch(n){console.error(n instanceof Error?n.message:String(n)),process.exitCode=1}}async function zi(e){let n=await Fe(e),{project:t,stage:o}=n,r=b(e,"--sandbox");if(D(e,"--sandbox")&&!W(r))throw Error("--sandbox needs the instance log id, the UUID shown in the dashboard Instances sheet.");let s=r?"DEBUG":Kn(e),i=Number(b(e,"--limit")??b(e,"-n")??100),a=D(e,"--json"),c=new AbortController,d=()=>c.abort();process.on("SIGINT",d),console.log(`Logs for ${t}/${o}`+(r?` sandbox ${r}`:"")+` [${s}+]`+bo(s)+` (backfill ${i}), Ctrl+C to stop`);try{for await(let l of qe(n,{backfill:i,minLevel:s,...r?{sandboxId:r}:{},signal:c.signal,onReconnect:Hn}))if(a)console.log(JSON.stringify(l));else console.log(Yn(l))}catch(l){if(!c.signal.aborted)console.error(l instanceof Error?l.message:String(l)),process.exitCode=1}finally{process.off("SIGINT",d)}}async function Ji(e){let[n]=ee(e);if(!K(n))throw Error(`Missing or malformed trace id: 32 lowercase hex characters, as the dashboard copies it.
|
|
423
423
|
|
|
424
424
|
${q("trace")}`);let t=await Fe(e),o=(await At(t,n)).toSorted((a,c)=>a.startTimeMs-c.startTimeMs);if(D(e,"--json")){console.log(JSON.stringify(o,null,2));return}console.log(`Trace ${n} in ${t.project}/${t.stage}`);let r=new Set(o.map((a)=>a.spanId)),s=Map.groupBy(o,(a)=>a.parentSpanId&&a.parentSpanId!==a.spanId&&r.has(a.parentSpanId)?a.parentSpanId:""),i=(a,c)=>{for(let d of s.get(a)??[])console.log(qi(d,c)),i(d.spanId,c+1)};i("",0)}function qi(e,n){let t=new Date(e.startTimeMs).toISOString().slice(11,23),o=" ".repeat(n),r=e.attributes?.["tool.name"],s=typeof r==="string"?`${e.name} ${r}`:e.name,i=`${t} ${e.status.padEnd(11)} ${o}`,a=`${i}${s} ${Cn(e.durationMs)}`;if(!e.error)return Un(a);let c=" ".repeat(i.length),d=e.error.replaceAll(/\r\n?|\n/g,`
|
|
425
425
|
${c} `);return Un(`${a}
|
package/dist/index.d.ts
CHANGED
|
@@ -755,7 +755,7 @@ type UpdateCronInput = {
|
|
|
755
755
|
* rules, core's executor registry and the SDK derive from. A leaf on purpose,
|
|
756
756
|
* so `schema.ts` can read it without pulling the rules' import graph.
|
|
757
757
|
*/
|
|
758
|
-
declare const SANDBOX_PROVIDERS: readonly ["sandbox", "lambda", "e2b", "daytona", "vercel", "cloudflare", "machine", "custom"];
|
|
758
|
+
declare const SANDBOX_PROVIDERS: readonly ["sandbox", "lambda", "e2b", "daytona", "vercel", "cloudflare", "worker", "machine", "custom"];
|
|
759
759
|
type SandboxProvider = (typeof SANDBOX_PROVIDERS)[number];
|
|
760
760
|
|
|
761
761
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{G,we,Le,Ne,Ue,Fe,W,K,de,ee,y,Be,I,Re,B,te,je,ne,z,He,Ze,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ft,ht,gt,yt,St,bt,vt,_t,wt,Rt,$t,Ct,Et,kt,pe,R,g}from"./chunk-
|
|
1
|
+
import{G,we,Le,Ne,Ue,Fe,W,K,de,ee,y,Be,I,Re,B,te,je,ne,z,He,Ze,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ft,ht,gt,yt,St,bt,vt,_t,wt,Rt,$t,Ct,Et,kt,pe,R,g}from"./chunk-gqyk7vva.js";import{m,qe,Z,C}from"./chunk-njxsdp91.js";export{m as BroodsAccountApiError,C as BroodsAccountClient,B as BroodsClient,je as BroodsWebSocketClient,I as DEFAULT_CORE_BASE_URL,Re as IngressAcceptedError,Le as MAX_OBSERVABILITY_BACKFILL,de as USER_TOKEN_HEADER,ee as USER_TOKEN_MAX_TTL_MS,y as USER_TOKEN_SECRET_ENV,je as WebSocketClient,je as WebsocketClient,Ze as defineAgent,Ve as defineBroods,Ge as defineCron,ft as defineDiscordChannel,et as defineDiscordConnection,ht as defineGitHubChannel,tt as defineGitHubConnection,gt as defineGoogleChatChannel,nt as defineGoogleChatConnection,We as defineHarness,yt as defineInstagramChannel,rt as defineInstagramConnection,St as defineLinearChannel,ot as defineLinearConnection,bt as defineMatrixChannel,st as defineMatrixConnection,Ke as defineMcp,vt as defineMessengerChannel,it as defineMessengerConnection,_t as definePancakeChannel,at as definePancakeConnection,Je as definePolicy,Ye as defineSandbox,Xe as defineSkill,wt as defineSlackChannel,ct as defineSlackConnection,Rt as defineTeamsChannel,lt as defineTeamsConnection,$t as defineTelegramChannel,ut as defineTelegramConnection,Ct as defineTwilioChannel,dt as defineTwilioConnection,Et as defineWhatsAppChannel,pt as defineWhatsAppConnection,Qe as defineWorkspace,kt as defineZaloChannel,mt as defineZaloConnection,He as env,qe as envPlaceholder,pe as isBroodsConfig,R as isConnectionDefinition,Ne as isLogLevel,Ue as isObservabilityClientMessage,g as isResource,Fe as isRootSpanKind,W as isSandboxLogId,K as isTraceId,te as normalizeHttpServiceUrl,we as readSseStream,Z as resolveEnvCredential,G as resolveRunEvents,Be as signUserToken,ne as toWebSocketBaseUrl,z as webSocketSubprotocols};
|