broods 0.44.0 → 0.44.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/README.md +6 -6
- package/dist/account.d.ts +7 -7
- package/dist/chunk-4j35s4p8.js +1 -0
- package/dist/{chunk-ee92fs0x.js → chunk-b3q14j68.js} +1 -1
- package/dist/{chunk-t0fvmbkd.js → chunk-hdcy74kj.js} +3 -3
- package/dist/{chunk-qyq5kyz9.js → chunk-hxky9s3f.js} +1 -1
- package/dist/{chunk-g9yebag8.js → chunk-kjccsy1h.js} +1 -1
- package/dist/{chunk-naxtmb6t.js → chunk-n890pdvc.js} +6 -6
- package/dist/{chunk-dcjq5a2g.js → chunk-r86n05ec.js} +1 -1
- package/dist/{chunk-dmax7s31.js → chunk-wq1x460w.js} +2 -2
- package/dist/cli/index.js +64 -61
- package/dist/index.d.ts +10 -10
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7ddy2nyy.js +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1606,7 +1606,7 @@ interface BroodsClientOptions {
|
|
|
1606
1606
|
baseUrl?: string;
|
|
1607
1607
|
/** Hostname or URL of the core service. `gateway.broods.app` becomes `https://gateway.broods.app`. */
|
|
1608
1608
|
host?: string;
|
|
1609
|
-
/**
|
|
1609
|
+
/** Runtime key used as the Bearer token for direct runtime calls. */
|
|
1610
1610
|
apiKey?: string;
|
|
1611
1611
|
fetch?: typeof fetch;
|
|
1612
1612
|
}
|
|
@@ -1767,11 +1767,11 @@ type ConfigPatch<T> = T extends readonly unknown[] ? T : T extends object ? {
|
|
|
1767
1767
|
interface BroodsAccountClientOptions {
|
|
1768
1768
|
/** Base URL of the broods gateway. Falls back to `BROODS_BASE_URL`, then `https://gateway.broods.app`. */
|
|
1769
1769
|
baseUrl?: string;
|
|
1770
|
-
/** Account
|
|
1770
|
+
/** Account key used as the Bearer token. Falls back to `BROODS_ACCOUNT_SECRET`. */
|
|
1771
1771
|
accountSecret?: string;
|
|
1772
1772
|
/**
|
|
1773
1773
|
* Short-lived `fp_sts_` role session token (from {@link BroodsAccountClient.assumeRole})
|
|
1774
|
-
* used as the Bearer instead of the account
|
|
1774
|
+
* used as the Bearer instead of the account key. The session can only do
|
|
1775
1775
|
* what its role's policy allows. Falls back to `BROODS_SESSION_TOKEN`.
|
|
1776
1776
|
*/
|
|
1777
1777
|
sessionToken?: string;
|
|
@@ -1857,7 +1857,7 @@ interface AccountPolicy {
|
|
|
1857
1857
|
/**
|
|
1858
1858
|
* Public account-role record returned by the roles routes. The policy uses the
|
|
1859
1859
|
* API action namespace (`"agents:read"`, `"crons:write"`, ...); `projectId` and
|
|
1860
|
-
* `stageId` bound which
|
|
1860
|
+
* `stageId` bound which runtime keys may assume the role.
|
|
1861
1861
|
*/
|
|
1862
1862
|
interface AccountRole {
|
|
1863
1863
|
accountId: string;
|
|
@@ -2019,7 +2019,7 @@ interface SkillUploadInput {
|
|
|
2019
2019
|
}>;
|
|
2020
2020
|
url?: string;
|
|
2021
2021
|
}
|
|
2022
|
-
/** Result of `POST /v1/account/rotate-secret`. The returned `secret` is shown once; the old
|
|
2022
|
+
/** Result of `POST /v1/account/rotate-secret`. The returned `secret` is the new account key, shown once; the old key stops working immediately. */
|
|
2023
2023
|
interface RotateSecretResult {
|
|
2024
2024
|
account: BroodsAccount;
|
|
2025
2025
|
secret: string;
|
|
@@ -2055,7 +2055,7 @@ declare class BroodsAccountApiError extends Error {
|
|
|
2055
2055
|
declare function envPlaceholder(name: string): string;
|
|
2056
2056
|
/**
|
|
2057
2057
|
* The credential the environment supplies, with a role session winning over
|
|
2058
|
-
* the account
|
|
2058
|
+
* the account key. The constructor throws through this same resolution, so
|
|
2059
2059
|
* callers that can run without an account credential (`broods mcp` with only a
|
|
2060
2060
|
* stored login) probe here instead of catching the constructor.
|
|
2061
2061
|
*/
|
|
@@ -2080,14 +2080,14 @@ declare class BroodsAccountClient {
|
|
|
2080
2080
|
}): Promise<BroodsAccount | null>;
|
|
2081
2081
|
/**
|
|
2082
2082
|
* Exchange a role for a short-lived `fp_sts_` session token. Callable with
|
|
2083
|
-
* the account
|
|
2083
|
+
* the account key, a CLI login token, or a runtime key (the latter
|
|
2084
2084
|
* only into roles scoped to the key's own project/stage). Construct a new
|
|
2085
2085
|
* client with `{ sessionToken: result.token }` to act as the role.
|
|
2086
2086
|
*/
|
|
2087
2087
|
assumeRole(roleId: string, options?: {
|
|
2088
2088
|
ttlSeconds?: number;
|
|
2089
2089
|
}): Promise<AssumeRoleResult>;
|
|
2090
|
-
/** Rotate the account
|
|
2090
|
+
/** Rotate the account key. The returned `secret` is the new key, shown once, and the current key stops working immediately, so persist it before the process exits. */
|
|
2091
2091
|
rotateSecret(): Promise<RotateSecretResult>;
|
|
2092
2092
|
/** Delete this account and cascade-clean every account-scoped resource. `cleanup` reports per-resource deletion counts. */
|
|
2093
2093
|
deleteAccount(): Promise<DeleteAccountResult>;
|
|
@@ -2314,7 +2314,7 @@ interface BroodsWebSocketClientOptions {
|
|
|
2314
2314
|
baseUrl?: string;
|
|
2315
2315
|
/** Hostname or URL of the core service. `gateway.broods.app` becomes `https://gateway.broods.app`. */
|
|
2316
2316
|
host?: string;
|
|
2317
|
-
/**
|
|
2317
|
+
/** Runtime key used as the WebSocket token. Defaults to BROODS_API_KEY from the environment or local .env files. */
|
|
2318
2318
|
apiKey?: string;
|
|
2319
2319
|
WebSocket?: WebSocketConstructorLike;
|
|
2320
2320
|
connectTimeoutMs?: number;
|
|
@@ -2917,7 +2917,7 @@ type AgentDefinitionConfig = EnvRefString<Pick<AgentConfig, "agent" | "model" |
|
|
|
2917
2917
|
policies?: readonly (PolicyResource | string)[];
|
|
2918
2918
|
/**
|
|
2919
2919
|
* Opt the agent into the public runtime endpoint (SSE/WebSocket via the
|
|
2920
|
-
*
|
|
2920
|
+
* runtime key). Off by default: when unset the public endpoint
|
|
2921
2921
|
* refuses requests for this agent. Reach a private agent through an
|
|
2922
2922
|
* internal endpoint or a channel webhook. See issue #65.
|
|
2923
2923
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{V,ge,Me,Pe,Ne,je,G,Ie,E,ye,F,J,xe,Y,z,qe,De,Le,Ue,Fe,Be,Ze,He,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ht,ft,gt,yt,St,bt,vt,_t,ie,w,g}from"./chunk-
|
|
1
|
+
import{V,ge,Me,Pe,Ne,je,G,Ie,E,ye,F,J,xe,Y,z,qe,De,Le,Ue,Fe,Be,Ze,He,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ht,ft,gt,yt,St,bt,vt,_t,ie,w,g}from"./chunk-hdcy74kj.js";import{m,Ae,Z,R}from"./chunk-a3f2xzbr.js";export{m as BroodsAccountApiError,R as BroodsAccountClient,F as BroodsClient,xe as BroodsWebSocketClient,E as DEFAULT_CORE_BASE_URL,ye as IngressAcceptedError,Me as MAX_OBSERVABILITY_BACKFILL,xe as WebSocketClient,xe as WebsocketClient,De as defineAgent,Le as defineBroods,Ue as defineCron,ct as defineDiscordChannel,We as defineDiscordConnection,lt as defineGitHubChannel,Ke as defineGitHubConnection,ut as defineGoogleChatChannel,Je as defineGoogleChatConnection,Fe as defineHarness,dt as defineInstagramChannel,Ye as defineInstagramConnection,pt as defineLinearChannel,Xe as defineLinearConnection,mt as defineMatrixChannel,Qe as defineMatrixConnection,Be as defineMcp,ht as defineMessengerChannel,et as defineMessengerConnection,ft as definePancakeChannel,tt as definePancakeConnection,Ze as definePolicy,He as defineSandbox,Ve as defineSkill,gt as defineSlackChannel,nt as defineSlackConnection,yt as defineTeamsChannel,rt as defineTeamsConnection,St as defineTelegramChannel,ot as defineTelegramConnection,bt as defineTwilioChannel,st as defineTwilioConnection,vt as defineWhatsAppChannel,it as defineWhatsAppConnection,Ge as defineWorkspace,_t as defineZaloChannel,at as defineZaloConnection,qe as env,Ae as envPlaceholder,ie as isBroodsConfig,w as isConnectionDefinition,Pe as isLogLevel,Ne as isObservabilityClientMessage,g as isResource,je as isRootSpanKind,G as isSandboxLogId,Ie as isTraceId,J as normalizeHttpServiceUrl,ge as readSseStream,Z as resolveEnvCredential,V as resolveRunEvents,Y as toWebSocketBaseUrl,z as webSocketSubprotocols};
|
package/package.json
CHANGED
package/dist/chunk-7ddy2nyy.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{j}from"./chunk-dcjq5a2g.js";import{Z,R}from"./chunk-a3f2xzbr.js";import{e,o,a,l,s}from"./chunk-naxtmb6t.js";var E={project:e().optional(),stage:e().optional()},M={sandboxId:e().min(1),reservationKey:e().min(1)},v=a().describe("Must be true, after the owner has agreed to this delete."),b="'********' keeps a stored secret and null deletes a field: never send a placeholder you did not read from a get.",A=[{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:b,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:b,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=Z()?new R({}):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 j({name:"broods",version:"1"},{capabilities:{tools:{}}});if(r){for(let i of A)x(n,r,i,t.scope??{});N(n,r)}if(t.cli)O(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 P(await t())}catch(r){return k(r)}}function k(t){return{content:[{type:"text",text:t instanceof Error?t.message:String(t)}],isError:!0}}function P(t){return{content:[{type:"text",text:JSON.stringify(t??null,null,2)}]}}function T(t,r,n,i){if(!t.scoped)return;let c=n??r.project,p=i??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 O(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:i,from:c})=>await d(async()=>await r.createStage(n,i,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:i})=>await d(async()=>(w(i,"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:i,confirm:c})=>await d(async()=>(w(c,`Project '${i}' and everything under it goes away: name it, get the owner's agreement, then retry.`),await n.deleteProject(i))))}function N(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:i,limit:c})=>await d(async()=>await r.listCronRuns(i,c===void 0?{}:{limit:c})));let n=[["suspend-sandbox","Suspend a persistent sandbox reservation.",(i,c)=>r.suspendSandbox(i,c)],["resume-sandbox","Resume a suspended sandbox reservation.",(i,c)=>r.resumeSandbox(i,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.",(i,c)=>r.terminateSandbox(i,c)],["open-sandbox-terminal","Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox.",(i,c)=>r.openSandboxTerminal(i,c)]];for(let[i,c,p]of n)t.registerTool(i,{description:c,inputSchema:M},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:i,reservationKey:c,name:p})=>await d(async()=>await r.snapshotSandbox(i,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:i,body:c})=>await d(async()=>await r.uploadSkill(i,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:i,value:c})=>await d(async()=>(await r.setEnvVar(i,c),{name:i,stored:!0}))),t.registerTool("delete-env-var",{description:"Delete one environment variable.",inputSchema:{name:e().min(1),confirm:v}},async({name:i,confirm:c})=>await d(async()=>(w(c,`Anything referencing \${${i}} breaks the moment this env var goes.`),{deleted:await r.deleteEnvVar(i),name:i}))),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:i,ttlSeconds:c})=>await d(async()=>await r.assumeRole(i,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:i,description:c})=>await d(async()=>await r.updateAccount({...i===void 0?{}:{username:i},...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 x(t,r,n,i){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:E},async({project:h,stage:m})=>await d(async()=>await f(r,T(n,i,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,...E}},async({body:m,project:I,stage:C})=>await d(async()=>await y(r,m,T(n,i,I,C))));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};
|