broods 0.36.0 → 0.36.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/{chunk-6s753azk.js → chunk-5jh5xqdy.js} +1 -1
- package/dist/{chunk-gvrqg36n.js → chunk-vfqvarac.js} +1 -1
- package/dist/{chunk-09w5n6hc.js → chunk-wg45zxe9.js} +1 -1
- package/dist/{chunk-r4wpy43p.js → chunk-z9eykngk.js} +4 -4
- package/dist/cli/index.js +3 -3
- package/package.json +1 -1
- /package/dist/{chunk-54pn8m91.js → chunk-3ryp98a2.js} +0 -0
- /package/dist/{chunk-s3cv33em.js → chunk-s6j5t96c.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{O}from"./chunk-54pn8m91.js";import{L,U}from"./chunk-mqsvqhkj.js";import"./chunk-s3cv33em.js";import{e,o,i,l,s}from"./cli/index.js";var R={project:e().optional(),stage:e().optional()},C={sandboxId:e().min(1),reservationKey:e().min(1)},v=i().describe("Must be true, after the owner has agreed to this delete."),E="'********' keeps a stored secret and null deletes a field: never send a placeholder you did not read from a get.",M=[{singular:"agent",plural:"agents",key:"agentId",createHint:"Needs name and config; a 409 returns the existing agentId.",deleteHint:"Deleting an agent also drops its runtime rows.",updateHint:E,list:(t)=>t.listAgents(),get:(t,r)=>t.getAgent(r),create:(t,r)=>t.createAgent(r),update:(t,r,n)=>t.updateAgent(r,n),remove:(t,r)=>t.deleteAgent(r)},{singular:"cron",plural:"crons",key:"cronId",createHint:"Needs name, agentId, scheduleExpression (rate/cron/at) and input or events.",list:(t)=>t.listCrons(),get:(t,r)=>t.getCron(r),create:(t,r)=>t.createCron(r),update:(t,r,n)=>t.updateCron(r,n),remove:(t,r)=>t.deleteCron(r)},{singular:"sandbox",plural:"sandboxes",key:"sandboxId",updateHint:E,list:(t)=>t.listSandboxes(),get:(t,r)=>t.getSandbox(r),create:(t,r)=>t.createSandbox(r),update:(t,r,n)=>t.updateSandbox(r,n),remove:(t,r)=>t.deleteSandbox(r)},{singular:"workspace",plural:"workspaces",key:"workspaceId",list:(t)=>t.listWorkspaces(),get:(t,r)=>t.getWorkspace(r),create:(t,r)=>t.createWorkspace(r),update:(t,r,n)=>t.updateWorkspace(r,n),remove:(t,r)=>t.deleteWorkspace(r)},{singular:"policy",plural:"policies",key:"policyId",createHint:"Agent-runtime policy document (tool.call, skill.load), not API credential scoping.",list:(t)=>t.listPolicies(),get:(t,r)=>t.getPolicy(r),create:(t,r)=>t.createPolicy(r),update:(t,r,n)=>t.updatePolicy(r,n),remove:(t,r)=>t.deletePolicy(r)},{singular:"role",plural:"roles",key:"roleId",createHint:"Needs name and a version-1 policy over the API namespace, e.g. agents:read. Account secret only.",list:(t)=>t.listRoles(),get:(t,r)=>t.getRole(r),create:(t,r)=>t.createRole(r),update:(t,r,n)=>t.updateRole(r,n),remove:(t,r)=>t.deleteRole(r)},{singular:"channel",plural:"channels",key:"channelId",list:(t)=>t.listChannels(),get:(t,r)=>t.getChannel(r),create:(t,r)=>t.createChannel(r),update:(t,r,n)=>t.updateChannel(r,n),remove:(t,r)=>t.deleteChannel(r)},{singular:"skill",plural:"skills",key:"skillName",createHint:'source is "files" (base64), "json" or "github". The stored name comes from the SKILL.md frontmatter.',list:(t)=>t.listSkills(),get:(t,r)=>t.getSkill(r),create:(t,r)=>t.createSkill(r),remove:(t,r)=>t.deleteSkill(r)},{singular:"mcp",plural:"mcp",key:"serverId",scoped:!0,list:(t,r)=>t.listMcp(r),get:(t,r)=>t.getMcp(r),create:(t,r,n)=>t.createMcp(n,r),update:(t,r,n)=>t.updateMcp(r,n),remove:(t,r)=>t.deleteMcp(r)}];function Pt(t={}){let r=L()?new U({}):null;if(!r&&!t.cli)throw Error("broods mcp needs a credential: set BROODS_SESSION_TOKEN or BROODS_ACCOUNT_SECRET, or run `broods login`.");let n=new O({name:"broods",version:"1"},{capabilities:{tools:{}}});if(r){for(let a of M)N(n,r,a,t.scope??{});j(n,r)}if(t.cli)P(n,t.cli);if(t.allowDestructive)q(n,r,t.cli??null);return n}function w(t,r){if(!t)throw Error(`Refusing without confirm:true. ${r}`)}async function d(t){try{return k(await t())}catch(r){return A(r)}}function A(t){return{content:[{type:"text",text:t instanceof Error?t.message:String(t)}],isError:!0}}function k(t){return{content:[{type:"text",text:JSON.stringify(t??null,null,2)}]}}function b(t,r,n,a){if(!t.scoped)return;let c=n??r.project,p=a??r.stage;if(!c||!p)throw Error(`${t.plural} live in one stage, so this call needs both 'project' and 'stage'`);return{project:c,stage:p}}function P(t,r){t.registerTool("list-orgs",{description:"Every organization this login can reach, with the current one marked.",inputSchema:{}},async()=>await d(async()=>{let n=await r.getOnboarding();return{currentOrgId:n.currentOrgId,orgs:n.orgs}})),t.registerTool("create-org",{description:"Create an organization and switch this login to it. Later calls act in the new org.",inputSchema:{name:e().min(1)}},async({name:n})=>await d(async()=>await r.createOnboardingOrg(n))),t.registerTool("select-org",{description:"Switch this login to another organization, by an orgId from list-orgs.",inputSchema:{orgId:e().min(1)}},async({orgId:n})=>await d(async()=>await r.selectOnboardingOrg(n))),t.registerTool("list-projects",{description:"Every project in the current org, empty ones last. Project names are not unique, so take the id from here.",inputSchema:{}},async()=>await d(async()=>await r.listProjects())),t.registerTool("list-stages",{description:"Every stage of one project, by project name.",inputSchema:{project:e().min(1)}},async({project:n})=>await d(async()=>await r.listStages(n))),t.registerTool("create-stage",{description:"Create a stage in a project, optionally cloning another stage's architecture and env vars. A project name that does not exist yet is created with it, which is the only way to make a project without deploying a manifest.",inputSchema:{project:e().min(1),name:e().min(1),from:e().optional().describe("Stage to clone architecture and env vars from.")}},async({project:n,name:a,from:c})=>await d(async()=>await r.createStage(n,a,c)))}function q(t,r,n){if(r)t.registerTool("rotate-secret",{description:"Rotate the account secret. The current secret stops working immediately and the new one is shown once, so this breaks every deployment and CI job still holding the old one. Requires confirm:true.",inputSchema:{confirm:v}},async({confirm:a})=>await d(async()=>(w(a,"Everything holding the current secret breaks the moment this runs."),await r.rotateSecret())));if(n)t.registerTool("delete-project",{description:"Delete a project and everything under it: stages, agents, canvas, env vars, crons and workspace files. Takes a projectId from list-projects and requires confirm:true.",inputSchema:{projectId:e().min(1),confirm:v}},async({projectId:a,confirm:c})=>await d(async()=>(w(c,`Project '${a}' and everything under it goes away: name it, get the owner's agreement, then retry.`),await n.deleteProject(a))))}function j(t,r){t.registerTool("list-cron-runs",{description:"Run history for one cron, newest first. Check this before telling anyone a cron fired.",inputSchema:{cronId:e().min(1),limit:o().int().positive().max(100).optional()}},async({cronId:a,limit:c})=>await d(async()=>await r.listCronRuns(a,c===void 0?{}:{limit:c})));let n=[["suspend-sandbox","Suspend a persistent sandbox reservation.",(a,c)=>r.suspendSandbox(a,c)],["resume-sandbox","Resume a suspended sandbox reservation.",(a,c)=>r.resumeSandbox(a,c)],["terminate-sandbox","Terminate a sandbox reservation and drop its live-instance row. Terminate only a sandbox you created, and never one holding state you did not put there.",(a,c)=>r.terminateSandbox(a,c)],["open-sandbox-terminal","Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox.",(a,c)=>r.openSandboxTerminal(a,c)]];for(let[a,c,p]of n)t.registerTool(a,{description:c,inputSchema:C},async({sandboxId:f,reservationKey:g})=>await d(async()=>await p(f,g)));t.registerTool("snapshot-sandbox",{description:"Snapshot a sandbox reservation into a reusable image (self-hosted provider).",inputSchema:{sandboxId:e().min(1),reservationKey:e().min(1),name:e().min(1)}},async({sandboxId:a,reservationKey:c,name:p})=>await d(async()=>await r.snapshotSandbox(a,c,p))),t.registerTool("upload-skill",{description:"Replace one skill's bundle wholesale (PUT, not a merge) by skillName. 'body' is the same source shape create-skill takes.",inputSchema:{id:e().min(1).describe("The skillName."),body:s(e(),l())}},async({id:a,body:c})=>await d(async()=>await r.uploadSkill(a,c))),t.registerTool("list-env-vars",{description:"List environment variable names. Values are write-only: the plane never returns them, so there is no read.",inputSchema:{}},async()=>await d(async()=>await r.listEnvVars())),t.registerTool("set-env-var",{description:"Create or replace one write-only environment variable. Reference it from a config as ${NAME} rather than inlining the value.",inputSchema:{name:e().min(1),value:e()}},async({name:a,value:c})=>await d(async()=>(await r.setEnvVar(a,c),{name:a,stored:!0}))),t.registerTool("delete-env-var",{description:"Delete one environment variable.",inputSchema:{name:e().min(1),confirm:v}},async({name:a,confirm:c})=>await d(async()=>(w(c,`Anything referencing \${${a}} breaks the moment this env var goes.`),{deleted:await r.deleteEnvVar(a),name:a}))),t.registerTool("assume-role",{description:"Exchange a role for a short-lived session token (default 1h, max 12h). Hand the returned token to whatever tool needs narrow access, as BROODS_SESSION_TOKEN. It is shown once and is not stored here.",inputSchema:{roleId:e().min(1),ttlSeconds:o().int().positive().max(43200).optional()}},async({roleId:a,ttlSeconds:c})=>await d(async()=>await r.assumeRole(a,c===void 0?{}:{ttlSeconds:c}))),t.registerTool("update-account",{description:"Rename this account or change its description. Everything else about an account is derived, not settable.",inputSchema:{username:e().optional(),description:e().nullable().optional()}},async({username:a,description:c})=>await d(async()=>await r.updateAccount({...a===void 0?{}:{username:a},...c===void 0?{}:{description:c}}))),t.registerTool("get-account",{description:"The account this server's credential resolves to. Run it first to confirm which tenant you are about to change.",inputSchema:{}},async()=>await d(async()=>await r.getAccount()))}function N(t,r,n,a){let c=e().min(1).describe(`The ${n.key}.`),p=n.scoped?` ${n.plural} live in one stage, so this also takes 'project' and 'stage'.`:"",{list:f,get:g,create:y,update:S,remove:_}=n;if(f){let u=`List every ${n.singular} on the account.${p}`;if(n.scoped)t.registerTool(`list-${n.plural}`,{description:u,inputSchema:R},async({project:h,stage:m})=>await d(async()=>await f(r,b(n,a,h,m))));else t.registerTool(`list-${n.plural}`,{description:u,inputSchema:{}},async()=>await d(async()=>await f(r)))}if(g)t.registerTool(`get-${n.singular}`,{description:`Read one ${n.singular} by ${n.key}.`,inputSchema:{id:c}},async({id:u})=>await d(async()=>await g(r,u)));if(y){let u=`Create one ${n.singular}. 'body' is the request body the config plane documents.`+(n.createHint?` ${n.createHint}`:"")+p+" Prefer changing the broods/ manifest and deploying for anything the project already declares.",h=s(e(),l());if(n.scoped)t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h,...R}},async({body:m,project:T,stage:I})=>await d(async()=>await y(r,m,b(n,a,T,I))));else t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h}},async({body:m})=>await d(async()=>await y(r,m)))}if(S)t.registerTool(`update-${n.singular}`,{description:`Deep-merge a patch into one ${n.singular} and return the updated record, so there is no need to read it back.`+(n.updateHint?` ${n.updateHint}`:""),inputSchema:{id:c,body:s(e(),l())}},async({id:u,body:h})=>await d(async()=>await S(r,u,h)));if(_)t.registerTool(`delete-${n.singular}`,{description:`Delete one ${n.singular}. Requires confirm:true, and takes one ${n.key} per call: never loop this over a list.`+(n.deleteHint?` ${n.deleteHint}`:""),inputSchema:{id:c,confirm:v}},async({id:u,confirm:h})=>await d(async()=>(w(h,`Deleting ${n.singular} '${u}' goes away for good: name it, get the owner's agreement, then retry.`),{deleted:await _(r,u),id:u})))}export{Pt as createBroodsMcpServer};
|
|
1
|
+
import{O}from"./chunk-3ryp98a2.js";import{L,U}from"./chunk-mqsvqhkj.js";import"./chunk-s6j5t96c.js";import{e,o,i,l,s}from"./cli/index.js";var R={project:e().optional(),stage:e().optional()},C={sandboxId:e().min(1),reservationKey:e().min(1)},v=i().describe("Must be true, after the owner has agreed to this delete."),E="'********' keeps a stored secret and null deletes a field: never send a placeholder you did not read from a get.",M=[{singular:"agent",plural:"agents",key:"agentId",createHint:"Needs name and config; a 409 returns the existing agentId.",deleteHint:"Deleting an agent also drops its runtime rows.",updateHint:E,list:(t)=>t.listAgents(),get:(t,r)=>t.getAgent(r),create:(t,r)=>t.createAgent(r),update:(t,r,n)=>t.updateAgent(r,n),remove:(t,r)=>t.deleteAgent(r)},{singular:"cron",plural:"crons",key:"cronId",createHint:"Needs name, agentId, scheduleExpression (rate/cron/at) and input or events.",list:(t)=>t.listCrons(),get:(t,r)=>t.getCron(r),create:(t,r)=>t.createCron(r),update:(t,r,n)=>t.updateCron(r,n),remove:(t,r)=>t.deleteCron(r)},{singular:"sandbox",plural:"sandboxes",key:"sandboxId",updateHint:E,list:(t)=>t.listSandboxes(),get:(t,r)=>t.getSandbox(r),create:(t,r)=>t.createSandbox(r),update:(t,r,n)=>t.updateSandbox(r,n),remove:(t,r)=>t.deleteSandbox(r)},{singular:"workspace",plural:"workspaces",key:"workspaceId",list:(t)=>t.listWorkspaces(),get:(t,r)=>t.getWorkspace(r),create:(t,r)=>t.createWorkspace(r),update:(t,r,n)=>t.updateWorkspace(r,n),remove:(t,r)=>t.deleteWorkspace(r)},{singular:"policy",plural:"policies",key:"policyId",createHint:"Agent-runtime policy document (tool.call, skill.load), not API credential scoping.",list:(t)=>t.listPolicies(),get:(t,r)=>t.getPolicy(r),create:(t,r)=>t.createPolicy(r),update:(t,r,n)=>t.updatePolicy(r,n),remove:(t,r)=>t.deletePolicy(r)},{singular:"role",plural:"roles",key:"roleId",createHint:"Needs name and a version-1 policy over the API namespace, e.g. agents:read. Account secret only.",list:(t)=>t.listRoles(),get:(t,r)=>t.getRole(r),create:(t,r)=>t.createRole(r),update:(t,r,n)=>t.updateRole(r,n),remove:(t,r)=>t.deleteRole(r)},{singular:"channel",plural:"channels",key:"channelId",list:(t)=>t.listChannels(),get:(t,r)=>t.getChannel(r),create:(t,r)=>t.createChannel(r),update:(t,r,n)=>t.updateChannel(r,n),remove:(t,r)=>t.deleteChannel(r)},{singular:"skill",plural:"skills",key:"skillName",createHint:'source is "files" (base64), "json" or "github". The stored name comes from the SKILL.md frontmatter.',list:(t)=>t.listSkills(),get:(t,r)=>t.getSkill(r),create:(t,r)=>t.createSkill(r),remove:(t,r)=>t.deleteSkill(r)},{singular:"mcp",plural:"mcp",key:"serverId",scoped:!0,list:(t,r)=>t.listMcp(r),get:(t,r)=>t.getMcp(r),create:(t,r,n)=>t.createMcp(n,r),update:(t,r,n)=>t.updateMcp(r,n),remove:(t,r)=>t.deleteMcp(r)}];function Pt(t={}){let r=L()?new U({}):null;if(!r&&!t.cli)throw Error("broods mcp needs a credential: set BROODS_SESSION_TOKEN or BROODS_ACCOUNT_SECRET, or run `broods login`.");let n=new O({name:"broods",version:"1"},{capabilities:{tools:{}}});if(r){for(let a of M)N(n,r,a,t.scope??{});j(n,r)}if(t.cli)P(n,t.cli);if(t.allowDestructive)q(n,r,t.cli??null);return n}function w(t,r){if(!t)throw Error(`Refusing without confirm:true. ${r}`)}async function d(t){try{return k(await t())}catch(r){return A(r)}}function A(t){return{content:[{type:"text",text:t instanceof Error?t.message:String(t)}],isError:!0}}function k(t){return{content:[{type:"text",text:JSON.stringify(t??null,null,2)}]}}function b(t,r,n,a){if(!t.scoped)return;let c=n??r.project,p=a??r.stage;if(!c||!p)throw Error(`${t.plural} live in one stage, so this call needs both 'project' and 'stage'`);return{project:c,stage:p}}function P(t,r){t.registerTool("list-orgs",{description:"Every organization this login can reach, with the current one marked.",inputSchema:{}},async()=>await d(async()=>{let n=await r.getOnboarding();return{currentOrgId:n.currentOrgId,orgs:n.orgs}})),t.registerTool("create-org",{description:"Create an organization and switch this login to it. Later calls act in the new org.",inputSchema:{name:e().min(1)}},async({name:n})=>await d(async()=>await r.createOnboardingOrg(n))),t.registerTool("select-org",{description:"Switch this login to another organization, by an orgId from list-orgs.",inputSchema:{orgId:e().min(1)}},async({orgId:n})=>await d(async()=>await r.selectOnboardingOrg(n))),t.registerTool("list-projects",{description:"Every project in the current org, empty ones last. Project names are not unique, so take the id from here.",inputSchema:{}},async()=>await d(async()=>await r.listProjects())),t.registerTool("list-stages",{description:"Every stage of one project, by project name.",inputSchema:{project:e().min(1)}},async({project:n})=>await d(async()=>await r.listStages(n))),t.registerTool("create-stage",{description:"Create a stage in a project, optionally cloning another stage's architecture and env vars. A project name that does not exist yet is created with it, which is the only way to make a project without deploying a manifest.",inputSchema:{project:e().min(1),name:e().min(1),from:e().optional().describe("Stage to clone architecture and env vars from.")}},async({project:n,name:a,from:c})=>await d(async()=>await r.createStage(n,a,c)))}function q(t,r,n){if(r)t.registerTool("rotate-secret",{description:"Rotate the account secret. The current secret stops working immediately and the new one is shown once, so this breaks every deployment and CI job still holding the old one. Requires confirm:true.",inputSchema:{confirm:v}},async({confirm:a})=>await d(async()=>(w(a,"Everything holding the current secret breaks the moment this runs."),await r.rotateSecret())));if(n)t.registerTool("delete-project",{description:"Delete a project and everything under it: stages, agents, canvas, env vars, crons and workspace files. Takes a projectId from list-projects and requires confirm:true.",inputSchema:{projectId:e().min(1),confirm:v}},async({projectId:a,confirm:c})=>await d(async()=>(w(c,`Project '${a}' and everything under it goes away: name it, get the owner's agreement, then retry.`),await n.deleteProject(a))))}function j(t,r){t.registerTool("list-cron-runs",{description:"Run history for one cron, newest first. Check this before telling anyone a cron fired.",inputSchema:{cronId:e().min(1),limit:o().int().positive().max(100).optional()}},async({cronId:a,limit:c})=>await d(async()=>await r.listCronRuns(a,c===void 0?{}:{limit:c})));let n=[["suspend-sandbox","Suspend a persistent sandbox reservation.",(a,c)=>r.suspendSandbox(a,c)],["resume-sandbox","Resume a suspended sandbox reservation.",(a,c)=>r.resumeSandbox(a,c)],["terminate-sandbox","Terminate a sandbox reservation and drop its live-instance row. Terminate only a sandbox you created, and never one holding state you did not put there.",(a,c)=>r.terminateSandbox(a,c)],["open-sandbox-terminal","Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox.",(a,c)=>r.openSandboxTerminal(a,c)]];for(let[a,c,p]of n)t.registerTool(a,{description:c,inputSchema:C},async({sandboxId:f,reservationKey:g})=>await d(async()=>await p(f,g)));t.registerTool("snapshot-sandbox",{description:"Snapshot a sandbox reservation into a reusable image (self-hosted provider).",inputSchema:{sandboxId:e().min(1),reservationKey:e().min(1),name:e().min(1)}},async({sandboxId:a,reservationKey:c,name:p})=>await d(async()=>await r.snapshotSandbox(a,c,p))),t.registerTool("upload-skill",{description:"Replace one skill's bundle wholesale (PUT, not a merge) by skillName. 'body' is the same source shape create-skill takes.",inputSchema:{id:e().min(1).describe("The skillName."),body:s(e(),l())}},async({id:a,body:c})=>await d(async()=>await r.uploadSkill(a,c))),t.registerTool("list-env-vars",{description:"List environment variable names. Values are write-only: the plane never returns them, so there is no read.",inputSchema:{}},async()=>await d(async()=>await r.listEnvVars())),t.registerTool("set-env-var",{description:"Create or replace one write-only environment variable. Reference it from a config as ${NAME} rather than inlining the value.",inputSchema:{name:e().min(1),value:e()}},async({name:a,value:c})=>await d(async()=>(await r.setEnvVar(a,c),{name:a,stored:!0}))),t.registerTool("delete-env-var",{description:"Delete one environment variable.",inputSchema:{name:e().min(1),confirm:v}},async({name:a,confirm:c})=>await d(async()=>(w(c,`Anything referencing \${${a}} breaks the moment this env var goes.`),{deleted:await r.deleteEnvVar(a),name:a}))),t.registerTool("assume-role",{description:"Exchange a role for a short-lived session token (default 1h, max 12h). Hand the returned token to whatever tool needs narrow access, as BROODS_SESSION_TOKEN. It is shown once and is not stored here.",inputSchema:{roleId:e().min(1),ttlSeconds:o().int().positive().max(43200).optional()}},async({roleId:a,ttlSeconds:c})=>await d(async()=>await r.assumeRole(a,c===void 0?{}:{ttlSeconds:c}))),t.registerTool("update-account",{description:"Rename this account or change its description. Everything else about an account is derived, not settable.",inputSchema:{username:e().optional(),description:e().nullable().optional()}},async({username:a,description:c})=>await d(async()=>await r.updateAccount({...a===void 0?{}:{username:a},...c===void 0?{}:{description:c}}))),t.registerTool("get-account",{description:"The account this server's credential resolves to. Run it first to confirm which tenant you are about to change.",inputSchema:{}},async()=>await d(async()=>await r.getAccount()))}function N(t,r,n,a){let c=e().min(1).describe(`The ${n.key}.`),p=n.scoped?` ${n.plural} live in one stage, so this also takes 'project' and 'stage'.`:"",{list:f,get:g,create:y,update:S,remove:_}=n;if(f){let u=`List every ${n.singular} on the account.${p}`;if(n.scoped)t.registerTool(`list-${n.plural}`,{description:u,inputSchema:R},async({project:h,stage:m})=>await d(async()=>await f(r,b(n,a,h,m))));else t.registerTool(`list-${n.plural}`,{description:u,inputSchema:{}},async()=>await d(async()=>await f(r)))}if(g)t.registerTool(`get-${n.singular}`,{description:`Read one ${n.singular} by ${n.key}.`,inputSchema:{id:c}},async({id:u})=>await d(async()=>await g(r,u)));if(y){let u=`Create one ${n.singular}. 'body' is the request body the config plane documents.`+(n.createHint?` ${n.createHint}`:"")+p+" Prefer changing the broods/ manifest and deploying for anything the project already declares.",h=s(e(),l());if(n.scoped)t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h,...R}},async({body:m,project:T,stage:I})=>await d(async()=>await y(r,m,b(n,a,T,I))));else t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h}},async({body:m})=>await d(async()=>await y(r,m)))}if(S)t.registerTool(`update-${n.singular}`,{description:`Deep-merge a patch into one ${n.singular} and return the updated record, so there is no need to read it back.`+(n.updateHint?` ${n.updateHint}`:""),inputSchema:{id:c,body:s(e(),l())}},async({id:u,body:h})=>await d(async()=>await S(r,u,h)));if(_)t.registerTool(`delete-${n.singular}`,{description:`Delete one ${n.singular}. Requires confirm:true, and takes one ${n.key} per call: never loop this over a list.`+(n.deleteHint?` ${n.deleteHint}`:""),inputSchema:{id:c,confirm:v}},async({id:u,confirm:h})=>await d(async()=>(w(h,`Deleting ${n.singular} '${u}' goes away for good: name it, get the owner's agreement, then retry.`),{deleted:await _(r,u),id:u})))}export{Pt as createBroodsMcpServer};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{C,a,D,z,B,V,Z,b,x,H,re,ne,me,fe,he,ge,oe,se,ye,ve,be,O}from"./chunk-
|
|
1
|
+
import{C,a,D,z,B,V,Z,b,x,H,re,ne,me,fe,he,ge,oe,se,ye,ve,be,O}from"./chunk-3ryp98a2.js";import"./chunk-s6j5t96c.js";var J=class{_readBuffer;_started=!1;_closed=!1;constructor(r=oe.stdin,o=oe.stdout,c){this._stdin=r,this._stdout=o,this._readBuffer=new he({maxBufferSize:c?.maxBufferSize})}onclose;onerror;onmessage;_ondata=(r)=>{try{this._readBuffer.append(r),this.processReadBuffer()}catch(o){this.onerror?.(o),this.close().catch(()=>{})}};_onerror=(r)=>{this.onerror?.(r)};_onstdouterror=(r)=>{this.onerror?.(r),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,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror),this._stdout.on("error",this._onstdouterror)}processReadBuffer(){while(!0)try{let r=this._readBuffer.readMessage();if(r===null)break;this.onmessage?.(r)}catch(r){this.onerror?.(r)}}async close(){if(this._closed)return;if(this._closed=!0,this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdout.off("error",this._onstdouterror),this._stdin.listenerCount("data")===0)this._stdin.pause();this._readBuffer.clear(),this.onclose?.()}send(r){if(this._closed)return Promise.reject(Error("StdioServerTransport is closed"));return new Promise((o,c)=>{let l=ge(r),t=!1,f=(_)=>{if(t)return;t=!0,this._stdout.off("error",f),this._stdout.off("drain",p),c(_)},p=()=>{if(t)return;t=!0,this._stdout.off("error",f),this._stdout.off("drain",p),o()};if(this._stdout.once("error",f),this._stdout.write(l)){if(t)return;t=!0,this._stdout.off("error",f),o()}else if(!t)this._stdout.once("drain",p)})}},k=3000,L=class{onclose;onerror;onmessage;_closed=!1;_pendingRequests=new Set;_drainWaiters=[];constructor(r,o,c){this._wire=r,this._onInstanceClose=o,this._outboundIntercept=c}async start(){}async send(r,o){if(H(r)||re(r)){let{id:c}=r;if(c!==void 0)this._settle(c)}if(this._closed)return;if(this._outboundIntercept?.(r)==="handled")return;return this._wire.send(r,o)}setProtocolVersion=(r)=>{this._wire.setProtocolVersion?.(r)};deliver(r,o){if(this._closed)return;if(b(r))this._pendingRequests.add(r.id);else if(x(r)&&r.method==="notifications/cancelled"){let c=r.params?.requestId;if(c!==void 0)this._settle(c)}this.onmessage?.(r,o)}async whenRequestsAnswered(r){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((t)=>t!==c),o(!1)},r);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(r){if(this._pendingRequests.delete(r),this._pendingRequests.size===0)this._releaseDrainWaiters()}_releaseDrainWaiters(){let r=this._drainWaiters;this._drainWaiters=[];for(let o of r)o()}};function U(r){let o=r.params;if(r.method==="initialize"&&!ne(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(!B(o))return{kind:"legacy",reason:"no-claim"};let c=z(o),l=(c===void 0?[]:Z(c))[0];if(l!==void 0)return{kind:"invalid-envelope",issue:l};let t=V(o);if(t===void 0||!C.includes(t))return{kind:"unsupported-revision",requested:t??"unknown"};return{kind:"modern",revision:t,classification:{era:"modern",revision:t}}}function Q(r,o={}){let c=o.legacy??"serve",l=o.transport??new J,t={phase:"opening"},f,p=!1,_=()=>p||t.phase==="closed",d=(e)=>{try{o.onerror?.(e)}catch{}},y=(e,n,i,s)=>l.send({jsonrpc:"2.0",id:e,error:{code:n,message:i,...s!==void 0&&{data:s}}}).catch((u)=>d(h(u))),w=new ye(o.maxSubscriptions??se),M=(e)=>{if(!x(e))return;let n=w.routeOutbound(e);if(n==="passthrough")return;for(let i of n)l.send({jsonrpc:"2.0",...i}).catch((s)=>d(h(s)));return"handled"},I=async(e)=>{if(b(e)&&e.method==="subscriptions/listen"){let n=z(e.params),i=B(e.params)?(n===void 0?[]:Z(n))[0]:{key:"_meta",problem:"the per-request envelope is required on protocol revision 2026-07-28"},s=V(e.params),u;if(i!==void 0)u={jsonrpc:"2.0",id:e.id,error:{code:-32602,message:`Invalid _meta envelope: ${i.key}: ${i.problem}`}};else if(s===void 0||!C.includes(s)){let v=new D({supported:[...C],requested:s??"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(x(e)&&e.method==="notifications/cancelled"){let n=e.params?.requestId;if(n!==void 0&&w.cancel(n))return!0}return!1},q=(e,n,i)=>{let s=me({kind:"legacy",reason:n,...i!==void 0&&{requestedVersion:i}},C);if(s===void 0)return Promise.resolve();return d(Error(`Rejected 2025-era request on a modern-only stdio connection (${s.cell}): ${s.message}`)),y(e.id,s.code,s.message,s.data)},T=(e)=>{if(p||e===f)return;P()},m=async(e,n)=>{let i=await r({era:e}),s=i instanceof O?i.server:i;if(e==="modern")fe(s,n),ve(s,C),w.setServerCapabilities(s.getCapabilities(),be(s));let u=new L(l,()=>T(u),e==="modern"?M:void 0);return await i.connect(u),{product:i,channel:u}},R=(e)=>e.product.close().catch((n)=>d(h(n))),N=async(e)=>{f=e.channel;try{if(!await e.channel.whenRequestsAnswered(k))d(Error(`Discarded the probe instance with requests still unanswered after ${k}ms; continuing with the fallback`));await e.product.close()}catch(n){d(h(n))}finally{f=void 0}},W=async(e)=>{if(t.phase==="closed")return;if(t.phase==="pinned"){if(t.era==="modern"&&b(e)&&e.method==="initialize"&&!ne(e.params)){await q(e,"initialize",e.params!==null&&typeof e.params==="object"&&typeof e.params.protocolVersion==="string"?e.params.protocolVersion:void 0);return}if(t.era==="modern"&&await I(e))return;t.instance.channel.deliver(e);return}if(!b(e)&&!x(e)){d(Error("Discarded a JSON-RPC response received before the connection negotiated an era"));return}let n=U(e);switch(n.kind){case"invalid-envelope":{let i=`Invalid _meta envelope for protocol revision 2026-07-28: ${n.issue.key}: ${n.issue.problem}`;if(b(e))await y(e.id,a.InvalidParams,i,{envelope:n.issue});else d(Error(`Discarded a notification with a malformed envelope: ${i}`));return}case"unsupported-revision":if(b(e)){let i=new D({supported:[...C],requested:n.requested});d(i),await y(e.id,i.code,i.message,i.data)}else d(Error(`Discarded a notification claiming unsupported protocol revision ${n.requested}`));return;case"modern":if(b(e)&&e.method==="server/discover"){if(t.phase==="probe"){t.instance.channel.deliver(e,{classification:n.classification});return}let i=await m("modern",n.revision);if(_()){await R(i);return}t={phase:"probe",instance:i},i.channel.deliver(e,{classification:n.classification});return}if(t.phase==="probe"){if(x(e)){t.instance.channel.deliver(e,{classification:n.classification});return}t={phase:"pinned",era:"modern",instance:t.instance}}else{let i=await m("modern",n.revision);if(_()){await R(i);return}t={phase:"pinned",era:"modern",instance:i}}if(await I(e))return;t.instance.channel.deliver(e,{classification:n.classification});return;case"legacy":{if(c==="reject"){if(b(e))await q(e,n.reason,n.requestedVersion);return}if(t.phase==="probe"){if(await N(t.instance),_())return;t={phase:"opening"}}let i=await m("legacy");if(_()){await R(i);return}t={phase:"pinned",era:"legacy",instance:i},t.instance.channel.deliver(e);return}}},S=[],E=!1,A=async()=>{if(E)return;E=!0;try{while(S.length>0){let e=S.shift();try{await W(e)}catch(n){if(b(e))await y(e.id,a.InternalError,"Internal server error");d(h(n))}}}finally{E=!1}},P=async()=>{if(p||t.phase==="closed")return;p=!0;let e=t;t={phase:"closed"};for(let n of w.teardownAll())await l.send(n).catch((i)=>d(h(i)));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),A()},l.onerror=(e)=>{if(d(e),t.phase==="probe"||t.phase==="pinned")t.instance.channel.onerror?.(e)},l.onclose=()=>{if(p||t.phase==="closed")return;p=!0;let e=t;if(t={phase:"closed"},e.phase==="probe"||e.phase==="pinned")e.instance.product.close().catch((n)=>d(h(n)))};let j=l.start().catch((e)=>{throw d(h(e)),e});return j.catch(()=>{}),{close:async()=>{await j.catch(()=>{}),await P()}}}function h(r){return r instanceof Error?r:Error(String(r))}export{Q as serveStdio};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import"./chunk-
|
|
1
|
+
import"./chunk-s6j5t96c.js";import{Pe,e,r,t,s}from"./cli/index.js";import{readFileSync as d}from"node:fs";import{dirname as m,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:r(e()).default([]),env:s(e(),e()).optional(),cwd:e().optional()}),w=t({mcpServers:s(e(),u).refine((n)=>Object.keys(n).length>0,"lists no MCP servers")});class y{#t=new Map;#e;#r;constructor(n,i){this.#r=n,this.#e=i}async callTool(n,i,o){return await(await this.#n(n)).callTool({name:i,arguments:o})}async listTools(n){return(await(await this.#n(n)).listTools()).tools}names(){return[...this.#r.keys()]}async stop(){let n=[...this.#t.values()];this.#t.clear(),await Promise.all(n.map((i)=>i.then((o)=>o.close()).catch(()=>{})))}#n(n){let i=this.#r.get(n);if(!i)return Promise.reject(Error(`no MCP server named "${n}" in the --mcp file`));let o=this.#t.get(n);if(o)return o;let c=(async()=>{this.#e(`mcp ${n}: ${[i.command,...i.args].join(" ")}`);let a=new h({...i,env:{...v(),...i.env},stderr:"inherit"});a.onclose=()=>{if(this.#e(`mcp ${n}: exited`),this.#t.get(n)===c)this.#t.delete(n)};let l=new g(f);return await l.connect(a),l})();return c.catch(()=>{if(this.#t.get(n)===c)this.#t.delete(n)}),this.#t.set(n,c),c}}function R(n){let i=p(n),o=w.safeParse(S(i));if(!o.success)throw Error(`${i}: ${Pe(o.error)}`);return new Map(Object.entries(o.data.mcpServers).map(([c,a])=>[c,a.cwd?{...a,cwd:p(m(i),a.cwd)}:a]))}function v(){let n={};for(let[i,o]of Object.entries(process.env))if(typeof o==="string")n[i]=o;return n}function S(n){try{return JSON.parse(d(n,"utf8"))}catch(i){throw Error(`could not read ${n}: ${i instanceof Error?i.message:String(i)}`)}}export{y as McpHost,R as readMcpServersFile};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{I}from"./chunk-q2n2mxeg.js";import{ce,le,e,o,i,l,r,t,u,S,s,p,n}from"./cli/index.js";import{spawn as V}from"node:child_process";import{hostname as ee}from"node:os";import{performance as L}from"node:perf_hooks";var j=["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"},replaced:{code:4409,reason:"Replaced by a newer connection"},unauthorized:{code:4401,reason:"Unauthorized; check BROODS_API_KEY"},unknownSandbox:{code:4404,reason:"No machine sandbox with that name in this account"}},N="/v1/machines/ws",
|
|
2
|
-
`));y({type:"result",id:
|
|
3
|
-
[output truncated]`:
|
|
4
|
-
`)[0]??"";return
|
|
1
|
+
import{I}from"./chunk-q2n2mxeg.js";import{ce,le,e,o,i,l,r,t,u,S,s,p,n}from"./cli/index.js";import{spawn as V}from"node:child_process";import{hostname as ee}from"node:os";import{performance as L}from"node:perf_hooks";var j=["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"},replaced:{code:4409,reason:"Replaced by a newer connection"},unauthorized:{code:4401,reason:"Unauthorized; check BROODS_API_KEY"},unknownSandbox:{code:4404,reason:"No machine sandbox with that name in this account"}},N="/v1/machines/ws",P=t({action:p(j),coordinate:r(o().int()).length(2).optional().describe("[x, y] in screenshot pixels for mouse actions."),start_coordinate:r(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:r(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.")}),H=P.extend({type:n("computer"),id:e()}),U=t({type:n("computer-result"),id:e(),text:e().optional(),image:t({data:e(),mediaType:e()}).optional(),app:e().optional(),error:e().optional()}),B=t({type:n("exec"),id:e(),code:e(),cwd:e().optional(),env:s(e(),e()).optional(),timeoutSeconds:o().positive(),outputLimitBytes:o().positive()}),K=t({type:n("hello"),sandbox:e().min(1),hostname:e().optional(),platform:e().optional(),computer:i().optional(),mcp:r(e()).optional()}),W=t({type:n("mcp-call"),id:e(),server:e(),tool:e(),args:s(e(),l())}),G=t({type:n("mcp-list"),id:e(),server:e()}),J=t({type:n("mcp-result"),id:e(),result:u({content:r(l())}).optional(),error:e().optional()}),q=t({type:n("mcp-tools"),id:e(),tools:r(u({name:e(),inputSchema:s(e(),l())})).optional(),error:e().optional()}),X=t({type:n("ready"),sandboxId:e()}),Y=t({type:n("result"),id:e(),exitCode:o().nullable(),stdout:e(),stderr:e(),durationMs:o(),timedOut:i(),truncated:i()}),Z=S("type",[H,B,W,G,X]),me=S("type",[U,K,J,q,Y]);function O(a){let c=new URL(N,a);return c.protocol=c.protocol==="https:"?"wss:":"ws:",c.toString()}function D(a){return Q(Z,a)}function Q(a,c){if(typeof c!=="string")return null;try{let d=a.safeParse(JSON.parse(c));return d.success?d.data:null}catch{return null}}var te=new Set([_.replaced.code,_.unauthorized.code,_.unknownSandbox.code]),R=72,T=30000,z=1000;function oe(a,c,d){return new Promise((y)=>{let m=L.now(),f=new C(a.outputLimitBytes),b=new C(a.outputLimitBytes),w=!1,x=!1,v=(F,E)=>{if(x)return;if(x=!0,clearTimeout(M),d?.removeEventListener("abort",k),E)b.append(Buffer.from(`${E}
|
|
2
|
+
`));y({type:"result",id:a.id,exitCode:F,stdout:f.text(),stderr:b.text(),durationMs:Math.round(L.now()-m),timedOut:w,truncated:f.truncated||b.truncated})},h=V("bash",["-lc",a.code],{cwd:a.cwd??c,env:{...process.env,...a.env},detached:!0,stdio:["ignore","pipe","pipe"]}),g=()=>{if(!h.pid)return;try{process.kill(-h.pid,"SIGKILL")}catch{h.kill("SIGKILL")}},M=setTimeout(()=>{w=!0,g()},a.timeoutSeconds*1000),k=()=>{g(),v(null,"stopped: the daemon closed its socket")};if(d?.addEventListener("abort",k,{once:!0}),h.stdout.on("data",(F)=>f.append(F)),h.stderr.on("data",(F)=>b.append(F)),h.on("error",(F)=>v(null,F.message)),h.on("close",(F)=>v(F)),d?.aborted)k()})}async function Fe(a){let c=le(),d=a.mcpFile?await ie(a.mcpFile,a.log):null,y=a.computer?await ne(a.log):null,m=z;try{while(!a.signal.aborted){let f=Date.now(),b=await ae(a,c,y,d);if(a.signal.aborted)return;if(te.has(b.code))throw Error(b.reason||`core closed the socket (${b.code})`);if(Date.now()-f>T)m=z;a.log(`disconnected (${b.reason||b.code}), reconnecting in ${Math.round(m/1000)}s`),await ce(m,a.signal),m=Math.min(m*2,T)}}finally{y?.stop(),await d?.stop()}}class C{#o=[];#e;#t=0;truncated=!1;constructor(a){this.#e=a}append(a){if(this.#t>=this.#e){this.truncated=!0;return}let c=this.#e-this.#t;if(a.byteLength>c){this.#o.push(a.subarray(0,c)),this.#t=this.#e,this.truncated=!0;return}this.#o.push(a),this.#t+=a.byteLength}text(){let a=Buffer.concat(this.#o).toString("utf8");return this.truncated?`${a}
|
|
3
|
+
[output truncated]`:a}}function re(a){let c=[a.action];if(a.coordinate)c.push(`at ${a.coordinate.join(",")}`);if(a.text!==void 0)c.push(JSON.stringify(A(a.text)));if(a.region)c.push(`region ${a.region.join(",")}`);return c.join(" ")}function A(a){let c=a.trim().split(`
|
|
4
|
+
`)[0]??"";return c.length>R?`${c.slice(0,R)}…`:c}async function ne(a){let{startDesktop:c}=await import("./chunk-5tnnqapc.js"),{display:d,driver:y,permissions:m}=await c(!1);if(a(`computer use on, ${d.width}x${d.height} screenshots`),!m.screenRecording||!m.accessibility)a(" screen recording or accessibility is missing, run `broods machine --doctor --request`");return y}async function ie(a,c){let{McpHost:d,readMcpServersFile:y}=await import("./chunk-wg45zxe9.js"),m=new d(y(a),c);return c(`mcp servers from ${a}: ${m.names().join(", ")}`),m}async function se(a,c,d){try{if(a.type==="mcp-list"){let m=await c.listTools(a.server);return d(` mcp ${a.server}: ${m.length} tools`),{type:"mcp-tools",id:a.id,tools:m}}d(` mcp ${a.server}.${a.tool}`);let y=await c.callTool(a.server,a.tool,a.args);return{type:"mcp-result",id:a.id,result:y}}catch(y){let m=y instanceof Error?y.message:String(y);return d(` mcp ${a.server}: ${m}`),{type:a.type==="mcp-call"?"mcp-result":"mcp-tools",id:a.id,error:m}}}function ae(a,c,d,y){return new Promise((m)=>{let f=new c(O(a.baseUrl),I(a.apiKey)),b=new AbortController,w=()=>f.close(1000,"daemon stopped"),x=(h)=>{if(f.readyState===f.OPEN)f.send(JSON.stringify(h))},v=(h,g)=>{a.signal.removeEventListener("abort",w),b.abort(),m({code:h,reason:g})};a.signal.addEventListener("abort",w,{once:!0}),f.onopen=()=>x({type:"hello",sandbox:a.sandbox,hostname:ee(),platform:process.platform,computer:d!==null,mcp:y?.names()}),f.onmessage=(h)=>{let g=D(h.data);if(g?.type==="ready"){a.log(`connected as ${a.sandbox} (${g.sandboxId})`);return}if(g?.type==="computer"&&d){a.log(` ${re(g)}`),d.run(g).then((M)=>{if(M.error)a.log(` error: ${M.error}`);x(M)});return}if((g?.type==="mcp-call"||g?.type==="mcp-list")&&y){se(g,y,a.log).then(x);return}if(g?.type!=="exec")return;a.log(`$ ${A(g.code)}`),oe(g,a.cwd,b.signal).then((M)=>{a.log(` exit ${M.exitCode??"none"} in ${M.durationMs}ms${M.timedOut?" (timed out)":""}`),x(M)})},f.onerror=()=>v(1006,"connection failed"),f.onclose=(h)=>v(h.code,h.reason)})}export{Fe as runMachineDaemon};
|
package/dist/cli/index.js
CHANGED
|
@@ -161,7 +161,7 @@ Reason: ${(O=a.approval.reason)!=null?O:"denied"}`}}}function Qm(a,m,b,x){switch
|
|
|
161
161
|
`).flatMap((W)=>k_(W,x));return[D,...B.map((W)=>T_(W,x,b.color)),Z]}function T_(a,m,b){let x=Rr(a,m),C=" ".repeat(Math.max(0,m-Jt(x)));return`${b}│${dt.reset} ${x}${C} ${b}│${dt.reset}`}function k_(a,m){if(a.length===0)return[""];let b=[],x=a;while(Jt(x)>m){let C=M_(x,m);b.push(x.slice(0,C).trimEnd()),x=x.slice(C).trimStart()}return b.push(x),b}function M_(a,m){let x=Rr(a,m+1).lastIndexOf(" ");if(x>0)return x;return Rr(a,m).length}function $_(a){var m,b;let x="usage"in a?a.usage:void 0,C="messageMetadata"in a?(m=a.messageMetadata)==null?void 0:m.usage:void 0,O="messageMetadata"in a?(b=a.messageMetadata)==null?void 0:b.performance:void 0;return{totalTokens:wh(x!=null?x:C),outputTokens:vs(x!=null?x:C),outputTokensPerSecond:O==null?void 0:O.outputTokensPerSecond}}function C_(a){var m;let b=a;return{totalTokens:wh(b==null?void 0:b.usage),outputTokens:vs(b==null?void 0:b.usage),outputTokensPerSecond:(m=b==null?void 0:b.performance)==null?void 0:m.outputTokensPerSecond}}function wh(a){let m=a==null?void 0:a.totalTokens;if(typeof m==="number")return m;if(typeof(m==null?void 0:m.total)==="number")return m.total;let b=R_(a),x=vs(a);if(b!=null&&x!=null)return b+x;return}function R_(a){let m=a==null?void 0:a.inputTokens;if(typeof m==="number")return m;if(typeof(m==null?void 0:m.total)==="number")return m.total;return a==null?void 0:a.promptTokens}function vs(a){let m=a==null?void 0:a.outputTokens;if(typeof m==="number")return m;if(typeof(m==null?void 0:m.total)==="number")return m.total;return a==null?void 0:a.completionTokens}function xh(a,m){if(a==null)return;let b=`${a.toLocaleString()} ${a===1?"token":"tokens"}`,x=A_(a,m);return x==null?b:`${b} ${x}`}function A_(a,m){if(m==null||m<=0||!Number.isFinite(m))return;return`${Math.round(a/m*100).toLocaleString()}%`}function P_(a,m){if(m==="outputTokensPerSecond")return O_(a.outputTokensPerSecond);return xh(a.outputTokens)}function O_(a){if(a==null)return;return`${N_(a)} tok/s`}function N_(a){return Number.isInteger(a)?a.toLocaleString():a.toLocaleString(void 0,{maximumFractionDigits:1})}function fo(a){let m=a.toString("utf8");switch(m){case"\f":return{type:"ctrl-l"};case"\x03":return{type:"ctrl-c"};case"\x1B":return{type:"escape"};case"\r":case`
|
|
162
162
|
`:return{type:"enter"};case"":case"\b":return{type:"backspace"};case"\x1B[A":return{type:"up"};case"\x1B[B":return{type:"down"};case"\x1B[5~":return{type:"page-up"};case"\x1B[6~":return{type:"page-down"};default:if(m>=" "&&m!=="")return{type:"character",value:m};return{type:"ignore"}}}var j_="outputTokensPerSecond",z_=class{constructor(a){this.chatId=Tr();var m,b,x,C;this.agent=a.agent,this.transport=a.transport,this.renderer=(m=U_(a))!=null?m:D_(a),this.title=a.title,this.tools=(b=a.tools)!=null?b:"auto-collapsed",this.reasoning=(x=a.reasoning)!=null?x:"auto-collapsed",this.responseStatistics=(C=a.responseStatistics)!=null?C:j_,this.contextSize=a.contextSize,this.sandbox=a.sandbox}async run(){let a=this.title,m=[],b=0,x=()=>`message-${++b}`,C,O=!1,z=!1;while(!0){if(!z){if(C==null){if(!this.renderer.readPrompt){if(O)return;throw Error("No prompt was provided and the renderer does not support prompt input.")}try{C=await this.renderer.readPrompt({title:a})}catch(Z){if(ah(Z))return;throw Z}if(C==null)return}m.push(B_(x(),C)),O=!0}let D=await this.streamMessages([...m],x);try{let Z=await this.renderer.renderStream(D,{title:a,submittedPrompt:C,continueSession:Boolean(this.renderer.readPrompt),tools:this.tools,reasoning:this.reasoning,responseStatistics:this.responseStatistics,contextSize:this.contextSize,waitForExit:!1});if(Z&&Z.parts.length>0){let L=F_(Z);if(L.length>0){if(!this.renderer.readToolApproval)throw Error("Tool approval was requested, but the renderer does not support tool approval input.");for(let B of L){let W=await this.renderer.readToolApproval(B,{title:a});q_(Z,B,W)}rh(m,Z,z),z=!0,C=void 0;continue}rh(m,Z,z)}}catch(Z){if(ah(Z))return;throw Z}z=!1,C=void 0}}async streamMessages(a,m){let b=new AbortController,x=()=>b.abort();if(this.transport)return{uiMessageStream:await this.transport.sendMessages({trigger:"submit-message",chatId:this.chatId,messageId:void 0,messages:a,abortSignal:b.signal}),message:ds(a),abort:x};let C=this.agent,O=await C.stream({prompt:await ro(a,{tools:C.tools}),abortSignal:b.signal,options:void 0,experimental_sandbox:this.sandbox});return{uiMessageStream:L_(O.fullStream,m,a),message:ds(a),abort:x}}};function D_(a){return a.tools===void 0&&a.reasoning===void 0&&a.responseStatistics===void 0&&a.contextSize===void 0?new us:new us({tools:a.tools,reasoning:a.reasoning,responseStatistics:a.responseStatistics,contextSize:a.contextSize})}function U_(a){if(a.renderer)return a.renderer;if(!a.screen&&!a.userInput)return;return new us({tools:a.tools,reasoning:a.reasoning,responseStatistics:a.responseStatistics,contextSize:a.contextSize,input:a.userInput,output:a.screen})}async function*L_(a,m,b=[]){var x,C;let O=new Set,z=new Set,D=new Set,Z,L,B=!1;yield{type:"start",messageId:(C=(x=ds(b))==null?void 0:x.id)!=null?C:m()};for await(let W of a)switch(W.type){case"text-start":O.add(W.id),yield{type:"text-start",id:W.id,providerMetadata:W.providerMetadata};break;case"text-delta":if(!O.has(W.id))O.add(W.id),yield{type:"text-start",id:W.id,providerMetadata:W.providerMetadata};yield{type:"text-delta",id:W.id,delta:W.text,providerMetadata:W.providerMetadata};break;case"text-end":O.delete(W.id),yield{type:"text-end",id:W.id,providerMetadata:W.providerMetadata};break;case"reasoning-start":z.add(W.id),yield{type:"reasoning-start",id:W.id,providerMetadata:W.providerMetadata};break;case"reasoning-delta":if(!z.has(W.id))z.add(W.id),yield{type:"reasoning-start",id:W.id,providerMetadata:W.providerMetadata};yield{type:"reasoning-delta",id:W.id,delta:W.text,providerMetadata:W.providerMetadata};break;case"reasoning-end":z.delete(W.id),yield{type:"reasoning-end",id:W.id,providerMetadata:W.providerMetadata};break;case"tool-input-start":yield{type:"tool-input-start",toolCallId:W.id,toolName:W.toolName,providerExecuted:W.providerExecuted,providerMetadata:W.providerMetadata,toolMetadata:W.toolMetadata,dynamic:W.dynamic,title:W.title};break;case"tool-input-delta":yield{type:"tool-input-delta",toolCallId:W.id,inputTextDelta:W.delta};break;case"tool-call":D.add(W.toolCallId),yield{type:"tool-input-available",toolCallId:W.toolCallId,toolName:W.toolName,input:W.input,providerExecuted:W.providerExecuted,providerMetadata:W.providerMetadata,toolMetadata:W.toolMetadata,dynamic:W.dynamic,title:W.title};break;case"tool-approval-request":if(!D.has(W.toolCall.toolCallId))D.add(W.toolCall.toolCallId),yield{type:"tool-input-available",toolCallId:W.toolCall.toolCallId,toolName:W.toolCall.toolName,input:W.toolCall.input,providerExecuted:W.toolCall.providerExecuted,providerMetadata:W.toolCall.providerMetadata,toolMetadata:W.toolCall.toolMetadata,dynamic:W.toolCall.dynamic,title:W.toolCall.title};yield{type:"tool-approval-request",approvalId:W.approvalId,toolCallId:W.toolCall.toolCallId,isAutomatic:W.isAutomatic};break;case"tool-approval-response":yield{type:"tool-approval-response",approvalId:W.approvalId,approved:W.approved,reason:W.reason,providerExecuted:W.providerExecuted};break;case"tool-result":yield{type:"tool-output-available",toolCallId:W.toolCallId,output:W.output,providerExecuted:W.providerExecuted,providerMetadata:W.providerMetadata,toolMetadata:W.toolMetadata,dynamic:W.dynamic,preliminary:W.preliminary};break;case"tool-error":yield{type:"tool-output-error",toolCallId:W.toolCallId,errorText:nh(W.error),providerExecuted:W.providerExecuted,providerMetadata:W.providerMetadata,toolMetadata:W.toolMetadata,dynamic:W.dynamic};break;case"tool-output-denied":yield{type:"tool-output-denied",toolCallId:W.toolCallId};break;case"source":if(W.sourceType==="url")yield{type:"source-url",sourceId:W.id,url:W.url,title:W.title,providerMetadata:W.providerMetadata};else yield{type:"source-document",sourceId:W.id,mediaType:W.mediaType,title:W.title,filename:W.filename,providerMetadata:W.providerMetadata};break;case"file":yield{type:"file",url:oh(W.file.mediaType,W.file.base64),mediaType:W.file.mediaType,providerMetadata:W.providerMetadata};break;case"reasoning-file":yield{type:"reasoning-file",url:oh(W.file.mediaType,W.file.base64),mediaType:W.file.mediaType,providerMetadata:W.providerMetadata};break;case"start-step":yield{type:"start-step"};break;case"finish-step":Z=W.usage,L=W.performance,yield{type:"finish-step"};break;case"finish":yield*th(O,z),B=!0,yield{type:"finish",finishReason:W.finishReason,messageMetadata:Z_(Z!=null?Z:W.totalUsage,L)};break;case"abort":yield{type:"abort",reason:W.reason};break;case"error":yield{type:"error",errorText:nh(W.error)};break}if(!B)yield*th(O,z),yield{type:"finish"}}function Z_(a,m){if((a==null?void 0:a.totalTokens)==null&&(a==null?void 0:a.outputTokens)==null&&(m==null?void 0:m.outputTokensPerSecond)==null)return;return{...(a==null?void 0:a.totalTokens)==null&&(a==null?void 0:a.outputTokens)==null?{}:{usage:{...a.totalTokens==null?{}:{totalTokens:a.totalTokens},...a.outputTokens==null?{}:{outputTokens:a.outputTokens}}},...(m==null?void 0:m.outputTokensPerSecond)==null?{}:{performance:{outputTokensPerSecond:m.outputTokensPerSecond}}}}function*th(a,m){for(let b of a)yield{type:"text-end",id:b};a.clear();for(let b of m)yield{type:"reasoning-end",id:b};m.clear()}function B_(a,m){return{id:a,role:"user",parts:[{type:"text",text:m}]}}function rh(a,m,b){var x;if(b&&((x=a.at(-1))==null?void 0:x.role)==="assistant"){a[a.length-1]=m;return}a.push(m)}function ds(a){let m=a.at(-1);return(m==null?void 0:m.role)==="assistant"?m:void 0}function F_(a){let m=[];for(let[b,x]of a.parts.entries()){if(!st(x)||x.state!=="approval-requested"||x.approval.isAutomatic===!0)continue;m.push({approvalId:x.approval.id,toolCallId:x.toolCallId,toolName:Kt(x),title:x.title,input:x.input,providerExecuted:x.providerExecuted,messageId:a.id,partIndex:b})}return m}function q_(a,m,b){let x=a.parts[m.partIndex];if(!x||!st(x)||x.toolCallId!==m.toolCallId)throw Error(`Could not find tool approval request ${m.approvalId}.`);x.state="approval-responded",x.approval={id:m.approvalId,approved:b.approved,...b.reason?{reason:b.reason}:{}}}function nh(a){if(a instanceof Error)return a.message;if(typeof a==="string")return a;return JSON.stringify(a)}function oh(a,m){return`data:${a};base64,${m}`}function ah(a){return a instanceof Error&&a.message==="Interrupted"}async function _h(a){await new z_(a).run()}async function Sh(a){if(a.prompt!==void 0)W_(a.prompt);await _h({title:`broods · ${a.agent.name}`,tools:"full",transport:new Eh(a.client,a.agent)})}async function Ih(a){let m=Dm({stream:Th(a.client.stream(a.agent,{input:a.prompt}),void 0,()=>{})});for await(let b of m)process.stdout.write(b);process.stdout.write(`
|
|
163
163
|
`)}async function W_(a){let m=process.stdin.listenerCount("data"),b=Date.now()+1e4;while(process.stdin.listenerCount("data")<=m){if(Date.now()>b)return;await new Promise((x)=>setTimeout(x,20))}process.stdin.emit("data",Buffer.from(a)),process.stdin.emit("data",Buffer.from("\r"))}class Eh{client;agent;conversationKey=`tui-${Tr()}`;sentApprovals=new Set;sentUserTurns=0;constructor(a,m){this.client=a;this.agent=m}async reconnectToStream(){return null}async sendMessages(a){let m=this.pendingEvents(await ro(a.messages));if(m.events.length===0)throw Error("Nothing new to send: the agent already saw this turn.");let b=this.client.stream(this.agent,{conversationKey:this.conversationKey,events:m.events});return Bm({stream:Th(b,a.abortSignal,m.commit),originalMessages:a.messages,generateMessageId:Tr,sendSources:!0})}pendingEvents(a){let m=[],b=[],x=0;for(let C of a){if(C.role==="user"){if(x+=1,x>this.sentUserTurns)m.push(C);continue}if(C.role!=="tool")continue;for(let O of C.content)if(O.type==="tool-approval-response"&&!this.sentApprovals.has(O.approvalId))b.push(O)}if(b.length>0)m.push({role:"tool",content:b});return{events:m,commit:()=>{this.sentUserTurns=x;for(let C of b)this.sentApprovals.add(C.approvalId)}}}}function V_(a){return new Promise((m)=>{if(!a)return;let b=()=>m({done:!0,value:void 0});if(a.aborted)b();else a.addEventListener("abort",b,{once:!0})})}function Th(a,m,b){let x=!1,C=()=>void a.return(void 0);return new ReadableStream({pull:async function(O){let z=await Promise.race([a.next(),V_(m)]);if(m?.aborted){C(),O.close();return}if(!x)x=!0,b();if(z.done)O.close();else O.enqueue(z.value)},cancel:C})}import{existsSync as kh}from"node:fs";import{mkdir as G_,readFile as K_,writeFile as J_}from"node:fs/promises";import{dirname as Ch,join as ys,resolve as H_,sep as Qt}from"node:path";import{fileURLToPath as Y_}from"node:url";var bs=ys(Ch(k),"update-check.json"),X_=86400000,Q_="https://registry.npmjs.org/broods/latest",eS=2000;function ws(a,m){let b=$h(a),x=$h(m);for(let C=0;C<3;C+=1){let O=b[C]??0,z=x[C]??0;if(O!==z)return O>z}return!Mh(a)&&Mh(m)}async function xs(a={}){let m=await nS(),b=a.maxAgeMs??X_;if(m&&Date.now()-m.checkedAt<b)return m.latest;let x=await tS();if(x===null)return m?.latest??null;return await oS({checkedAt:Date.now(),latest:x}),x}function Rh(a=H_(process.cwd()),m=Y_(import.meta.url)){let b=`${Qt}node_modules${Qt}`,x=m.lastIndexOf(b),C=x===-1?null:m.slice(0,x),O=C===null?m.startsWith(`${a}${Qt}`):a===C||a.startsWith(`${C}${Qt}`),D=m.includes(`${Qt}.bun${Qt}install${Qt}global${Qt}`)||O&&rS(C??a)?"bun":"npm",Z=D==="bun"?"add":"install";return{manager:D,global:!O,command:D,args:O?[Z,"broods@latest"]:[Z,"-g","broods@latest"]}}async function tS(){try{let a=await fetch(Q_,{signal:AbortSignal.timeout(eS),headers:{accept:"application/json"}});if(!a.ok)return null;let m=await a.json();return typeof m.version==="string"?m.version:null}catch{return null}}function rS(a){return kh(ys(a,"bun.lock"))||kh(ys(a,"bun.lockb"))}function Mh(a){return a.includes("-")}async function nS(){try{let a=JSON.parse(await K_(bs,"utf8"));if(typeof a.latest!=="string")return null;if(typeof a.checkedAt!=="number")return null;return{checkedAt:a.checkedAt,latest:a.latest}}catch{return null}}function $h(a){let[m]=a.trim().replace(/^v/,"").split("-");return(m??"").split(".").slice(0,3).map((b)=>Number.parseInt(b,10)||0)}async function oS(a){try{await G_(Ch(bs),{recursive:!0}),await J_(bs,`${JSON.stringify(a)}
|
|
164
|
-
`,"utf8")}catch{}}var Ah={name:"broods",version:"0.36.
|
|
164
|
+
`,"utf8")}catch{}}var Ah={name:"broods",version:"0.36.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","pack:check":"bun run build && publint && attw --pack .",test:"bun test"},dependencies:{"@modelcontextprotocol/client":"^2.0.0",esbuild:"^0.28.2"},devDependencies:{"@ai-sdk/tui":"1.0.100","@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.0.0","@types/bun":"^1.3.14","@typescript/typescript6":"6.0.2",ai:"^7.0.99",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.99"},peerDependenciesMeta:{ai:{optional:!0}},engines:{node:">=22.15"}};var Ph=`---
|
|
165
165
|
name: broods
|
|
166
166
|
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.
|
|
167
167
|
---
|
|
@@ -474,7 +474,7 @@ ${ft("stage")}`);let z=f(),D=Se(a,"--dashboard-url")??z.dashboardUrl??Ot,Z=xo(a)
|
|
|
474
474
|
|
|
475
475
|
${ft("env")}`);if(D&&!b)throw Error(`broods env ${m} needs a variable name.
|
|
476
476
|
|
|
477
|
-
${ft("env")}`);let{manifest:Z,config:L}=await zt({project:Se(a,"--project"),stage:Se(a,"--stage"),command:"dev"}),B=await xt(Se(a,"--base-url")??L.baseUrl),W=new Ye({baseUrl:B.baseUrl,token:B.token}),Y=`${Z.project}/${Z.stage}`;if(z){await XS(W,Z,Y);return}if(x){let oe=await W.listEnv(Z.project,Z.stage);if(oe.length===0){console.log(`No environment variables set for ${Y}.`);return}console.log(`Environment variables for ${Y} (values hidden):`);for(let ye of oe)console.log(` ${ye.name}`);return}if(O){let oe=await W.getEnv(Z.project,Z.stage,b);if(oe===null){console.error(`${b} is not set for ${Y}`),process.exitCode=1;return}console.log(oe);return}if(C){await W.removeEnv(Z.project,Z.stage,b),console.log(`Removed ${b} from ${Y}`);return}let H=await gi(b);await W.setEnv(Z.project,Z.stage,b,H),console.log(`Stored ${b} for ${Y}`)}async function XS(a,m,b){let x=await $s(a,m);if(x.length===0){console.log('No env("NAME") references in this project.');return}let C=await Hh(a,m,x);if(C.length>0)Oo(C);let O=bn(x,"synced").length;console.log(C.length>0?`${O} other referenced variable(s) already in step with ${b}.`:`${O} referenced variable(s) already in step with ${b}.`);let z=bn(x,"stage-only");if(z.length>0)console.log(`${z.length} referenced variable(s) live only on ${b}: ${z.join(", ")}`);let D=bn(x,"unresolved");if(D.length>0)Ve(`⚠ ${D.length} referenced variable(s) with no value here or on ${b}: ${D.join(", ")}. Put them in .env.local, or run \`broods env set <NAME>\`.`)}function _o(){f();let a=process.env.BROODS_API_KEY??"";if(!a)throw Error("BROODS_API_KEY is not set. Run `broods deploy` first, or set the key in .env.local.");let m=process.env.BROODS_BASE_URL??process.env.BROODS_HOST??P;return{apiKey:a,baseUrl:m}}function Cs(a){if(Xe(a,"--all"))return"DEBUG";let m=Se(a,"--level");if(m===void 0&&Xe(a,"--level"))throw Error("Missing value for --level. Use DEBUG, INFO, WARN, or ERROR.");if(!m)return"WARN";let b=m.toUpperCase();if(b==="DEBUG")return"DEBUG";if(b==="INFO")return"INFO";if(b==="WARN"||b==="WARNING")return"WARN";if(b==="ERROR")return"ERROR";throw Error(`Unknown log level: ${m}. Use DEBUG, INFO, WARN, or ERROR.`)}async function QS(a){f();let m=Se(a,"--project")??process.env.BROODS_PROJECT,b=Se(a,"--stage")??_();if(!m)throw Error("Project name is required. Pass --project <name> or set BROODS_PROJECT in .env.local.");if(!b)throw Error("Stage name is required. Pass --stage <name> or set BROODS_STAGE in .env.local.");return{project:m,stage:b}}async function Rs(a,m){let b=await QS(a),x=await fi(m.baseUrl,m.apiKey);if(!x)return b;if(x.projectSlug!==b.project||x.stageSlug!==b.stage)console.log(`· reading ${x.projectSlug}/${x.stageSlug}. The runtime key is scoped there, not to ${b.project}/${b.stage}.`);return{project:x.projectSlug,stage:x.stageSlug}}function Yh(a){return a==="WARN"?" (--all for INFO too)":""}function As(a){let m=new Date(a.ts).toISOString().slice(11,23),b=a.level.padEnd(5),x=vS(a.message);return`${m} ${b} ${a.eventType} ${x}`}async function eI(a){let{apiKey:m,baseUrl:b}=_o(),{project:x,stage:C}=await Rs(a,{baseUrl:b,apiKey:m}),O=Cs(a),z=new AbortController,D=()=>z.abort();process.on("SIGINT",D),console.log(`Streaming live logs for ${x}/${C} [${O}+]`+Yh(O)+", Ctrl+C to stop");try{for await(let Z of $n({baseUrl:b,apiKey:m,project:x,stage:C},{backfill:0,minLevel:O,signal:z.signal}))console.log(As(Z))}catch(Z){if(!z.signal.aborted)console.error(Z instanceof Error?Z.message:String(Z)),process.exitCode=1}finally{process.off("SIGINT",D)}}async function tI(a){if(Xe(a,"--doctor")){await rI(Xe(a,"--request"));return}let m=Lt(a)[0];if(!m){console.log(Ms.machine),process.exitCode=1;return}let{runMachineDaemon:b}=await import("../chunk-
|
|
477
|
+
${ft("env")}`);let{manifest:Z,config:L}=await zt({project:Se(a,"--project"),stage:Se(a,"--stage"),command:"dev"}),B=await xt(Se(a,"--base-url")??L.baseUrl),W=new Ye({baseUrl:B.baseUrl,token:B.token}),Y=`${Z.project}/${Z.stage}`;if(z){await XS(W,Z,Y);return}if(x){let oe=await W.listEnv(Z.project,Z.stage);if(oe.length===0){console.log(`No environment variables set for ${Y}.`);return}console.log(`Environment variables for ${Y} (values hidden):`);for(let ye of oe)console.log(` ${ye.name}`);return}if(O){let oe=await W.getEnv(Z.project,Z.stage,b);if(oe===null){console.error(`${b} is not set for ${Y}`),process.exitCode=1;return}console.log(oe);return}if(C){await W.removeEnv(Z.project,Z.stage,b),console.log(`Removed ${b} from ${Y}`);return}let H=await gi(b);await W.setEnv(Z.project,Z.stage,b,H),console.log(`Stored ${b} for ${Y}`)}async function XS(a,m,b){let x=await $s(a,m);if(x.length===0){console.log('No env("NAME") references in this project.');return}let C=await Hh(a,m,x);if(C.length>0)Oo(C);let O=bn(x,"synced").length;console.log(C.length>0?`${O} other referenced variable(s) already in step with ${b}.`:`${O} referenced variable(s) already in step with ${b}.`);let z=bn(x,"stage-only");if(z.length>0)console.log(`${z.length} referenced variable(s) live only on ${b}: ${z.join(", ")}`);let D=bn(x,"unresolved");if(D.length>0)Ve(`⚠ ${D.length} referenced variable(s) with no value here or on ${b}: ${D.join(", ")}. Put them in .env.local, or run \`broods env set <NAME>\`.`)}function _o(){f();let a=process.env.BROODS_API_KEY??"";if(!a)throw Error("BROODS_API_KEY is not set. Run `broods deploy` first, or set the key in .env.local.");let m=process.env.BROODS_BASE_URL??process.env.BROODS_HOST??P;return{apiKey:a,baseUrl:m}}function Cs(a){if(Xe(a,"--all"))return"DEBUG";let m=Se(a,"--level");if(m===void 0&&Xe(a,"--level"))throw Error("Missing value for --level. Use DEBUG, INFO, WARN, or ERROR.");if(!m)return"WARN";let b=m.toUpperCase();if(b==="DEBUG")return"DEBUG";if(b==="INFO")return"INFO";if(b==="WARN"||b==="WARNING")return"WARN";if(b==="ERROR")return"ERROR";throw Error(`Unknown log level: ${m}. Use DEBUG, INFO, WARN, or ERROR.`)}async function QS(a){f();let m=Se(a,"--project")??process.env.BROODS_PROJECT,b=Se(a,"--stage")??_();if(!m)throw Error("Project name is required. Pass --project <name> or set BROODS_PROJECT in .env.local.");if(!b)throw Error("Stage name is required. Pass --stage <name> or set BROODS_STAGE in .env.local.");return{project:m,stage:b}}async function Rs(a,m){let b=await QS(a),x=await fi(m.baseUrl,m.apiKey);if(!x)return b;if(x.projectSlug!==b.project||x.stageSlug!==b.stage)console.log(`· reading ${x.projectSlug}/${x.stageSlug}. The runtime key is scoped there, not to ${b.project}/${b.stage}.`);return{project:x.projectSlug,stage:x.stageSlug}}function Yh(a){return a==="WARN"?" (--all for INFO too)":""}function As(a){let m=new Date(a.ts).toISOString().slice(11,23),b=a.level.padEnd(5),x=vS(a.message);return`${m} ${b} ${a.eventType} ${x}`}async function eI(a){let{apiKey:m,baseUrl:b}=_o(),{project:x,stage:C}=await Rs(a,{baseUrl:b,apiKey:m}),O=Cs(a),z=new AbortController,D=()=>z.abort();process.on("SIGINT",D),console.log(`Streaming live logs for ${x}/${C} [${O}+]`+Yh(O)+", Ctrl+C to stop");try{for await(let Z of $n({baseUrl:b,apiKey:m,project:x,stage:C},{backfill:0,minLevel:O,signal:z.signal}))console.log(As(Z))}catch(Z){if(!z.signal.aborted)console.error(Z instanceof Error?Z.message:String(Z)),process.exitCode=1}finally{process.off("SIGINT",D)}}async function tI(a){if(Xe(a,"--doctor")){await rI(Xe(a,"--request"));return}let m=Lt(a)[0];if(!m){console.log(Ms.machine),process.exitCode=1;return}let{runMachineDaemon:b}=await import("../chunk-z9eykngk.js"),{apiKey:x,baseUrl:C}=_o(),O=qe(Se(a,"--cwd")??process.cwd()),z=Xe(a,"--computer"),D=Se(a,"--mcp"),Z=new AbortController,L=()=>Z.abort();process.on("SIGINT",L),console.log(`Connecting ${m} to ${C} (cwd ${O}${z?", computer use on":""}), Ctrl+C to stop`);try{await b({apiKey:x,baseUrl:C,computer:z,cwd:O,log:(B)=>console.log(B),mcpFile:D?qe(D):void 0,sandbox:m,signal:Z.signal})}catch(B){console.error(B instanceof Error?B.message:String(B)),process.exitCode=1}finally{process.off("SIGINT",L)}}async function rI(a){try{let{startDesktop:m}=await import("../chunk-5tnnqapc.js"),{display:b,driver:x,permissions:C}=await m(a);x.stop();let O=(z)=>z?"granted":"missing";if(console.log(`screenshot frame ${b.width}x${b.height} (scale ${b.scale.toFixed(2)})`),console.log(`screen recording ${O(C.screenRecording)}`),console.log(`accessibility ${O(C.accessibility)}`),!C.screenRecording||!C.accessibility)console.log(a?"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(m){console.error(m instanceof Error?m.message:String(m)),process.exitCode=1}}async function nI(a){let{apiKey:m,baseUrl:b}=_o(),{project:x,stage:C}=await Rs(a,{baseUrl:b,apiKey:m}),O=Se(a,"--sandbox");if(Xe(a,"--sandbox")&&!G(O))throw Error("--sandbox needs the instance log id, the UUID shown in the dashboard Instances sheet.");let z=O?"DEBUG":Cs(a),D=Number(Se(a,"--limit")??Se(a,"-n")??100),Z=Xe(a,"--json"),L=new AbortController,B=()=>L.abort();process.on("SIGINT",B),console.log(`Logs for ${x}/${C}`+(O?` sandbox ${O}`:"")+` [${z}+]`+Yh(z)+` (backfill ${D}), Ctrl+C to stop`);try{for await(let W of $n({baseUrl:b,apiKey:m,project:x,stage:C},{backfill:D,minLevel:z,...O?{sandboxId:O}:{},signal:L.signal}))if(Z)console.log(JSON.stringify(W));else console.log(As(W))}catch(W){if(!L.signal.aborted)console.error(W instanceof Error?W.message:String(W)),process.exitCode=1}finally{process.off("SIGINT",B)}}async function oI(a){let[m,b]=Lt(a);if(!m){console.log(ft("agent"));return}if(m==="list"||m==="ls"){await aI(a);return}if(m==="get"){await sI(b,a);return}throw Error(`Unknown agent subcommand: ${m}
|
|
478
478
|
|
|
479
479
|
${ft("agent")}`)}async function Xh(a){let{manifest:m,config:b}=await zt({project:Se(a,"--project"),stage:Se(a,"--stage"),command:"dev"}),x=await xt(Se(a,"--base-url")??b.baseUrl),C=await new Ye({baseUrl:x.baseUrl,token:x.token}).getManifest(m.project,m.stage),O=m.resources.filter((z)=>z.kind==="agent").map((z)=>({name:z.name,config:z.config??{},agentId:C?.ids.agents[z.name]}));return{manifest:m,agents:O}}async function aI(a){let{manifest:m,agents:b}=await Xh(a);if(b.length===0){console.log(`No agents declared in ${m.project}/${m.stage}.`);return}console.log(`Agents in ${m.project}/${m.stage}:`);for(let x of b){let C=Qh(x.config),O=x.config.publicAccess===!0?"public":"private",z=x.agentId?x.agentId:"not deployed";console.log(` ${x.name} [${O}] ${C} (${z})`)}}async function sI(a,m){if(!a)throw Error(`Missing agent name.
|
|
480
480
|
|
|
@@ -521,4 +521,4 @@ export const myAgent = defineAgent({
|
|
|
521
521
|
// only reachable via internal endpoints or channel webhooks.
|
|
522
522
|
publicAccess: true,
|
|
523
523
|
});
|
|
524
|
-
`}function cI(a,m){if(a==="status")throw Error("status was renamed to whoami. Run `broods whoami`.");if(m.includes("--env"))throw Error("--env was renamed to --stage. Pass --stage <name> instead.");f();let b=process.env.BROODS_ENVIRONMENT;if(b!==void 0&&process.env.BROODS_STAGE===void 0)throw Error(`BROODS_ENVIRONMENT was renamed to BROODS_STAGE. Rename the key in .env.local (it is currently set to "${b}").`)}async function uI(){let a=f(),[{createBroodsMcpServer:m},{serveStdio:b},x]=await Promise.all([import("../chunk-
|
|
524
|
+
`}function cI(a,m){if(a==="status")throw Error("status was renamed to whoami. Run `broods whoami`.");if(m.includes("--env"))throw Error("--env was renamed to --stage. Pass --stage <name> instead.");f();let b=process.env.BROODS_ENVIRONMENT;if(b!==void 0&&process.env.BROODS_STAGE===void 0)throw Error(`BROODS_ENVIRONMENT was renamed to BROODS_STAGE. Rename the key in .env.local (it is currently set to "${b}").`)}async function uI(){let a=f(),[{createBroodsMcpServer:m},{serveStdio:b},x]=await Promise.all([import("../chunk-5jh5xqdy.js"),import("../chunk-vfqvarac.js"),K()]),C=x?new Ye({baseUrl:x.baseUrl,token:x.token}):null,O=m({allowDestructive:process.env.BROODS_MCP_ALLOW_DESTRUCTIVE==="1"&&N("BROODS_MCP_ALLOW_DESTRUCTIVE"),cli:C,scope:{project:a.project,stage:a.stage}});b(()=>O),await new Promise((z)=>{process.stdin.on("close",z)})}bS().catch((a)=>{console.error(a instanceof Error?a.message:String(a)),process.exit(1)});export{ce,le,_e,y,ue,de,Re,Pe,Ee,j,q,pe,Q,e,Te,ee,te,o,i,E,Ie,l,r,t,u,c,S,T,s,p,n,d,M,A};
|
package/package.json
CHANGED
|
File without changes
|
|
File without changes
|