broods 0.33.3 → 0.33.4

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/index.d.ts CHANGED
@@ -140,7 +140,7 @@ interface AgentConfig {
140
140
  /**
141
141
  * Tool names withheld for this run, applied after the tool set is built.
142
142
  * Set by a channel record; a channel can take a tool away, never add one.
143
- * Names that are not present are simply ignored.
143
+ * Names that are not present are ignored.
144
144
  */
145
145
  denyTools?: string[];
146
146
  skills?: AgentSkillsConfig;
@@ -492,9 +492,6 @@ interface SandboxLifecycleConfig {
492
492
  idleTimeoutSeconds?: number;
493
493
  maxLifetimeSeconds?: number;
494
494
  }
495
- /**
496
- * Provider-normalized sandbox network policy.
497
- */
498
495
  interface SandboxNetworkConfig {
499
496
  mode: NetworkMode;
500
497
  allowDomains?: string[];
@@ -567,9 +564,6 @@ declare const API_POLICY_ACTIONS: readonly ["account:read", "account:write", "ag
567
564
  type AgentPolicyAction = (typeof AGENT_POLICY_ACTIONS)[number];
568
565
  type ApiPolicyAction = (typeof API_POLICY_ACTIONS)[number];
569
566
  type PolicyAction = AgentPolicyAction | ApiPolicyAction;
570
- /**
571
- * One optional predicate on a policy rule.
572
- */
573
567
  interface PolicyCondition {
574
568
  attribute: string;
575
569
  operator: PolicyConditionOperator;
@@ -586,9 +580,6 @@ interface PolicyDocument {
586
580
  rules: PolicyRule[];
587
581
  }
588
582
  type PolicyEffect = "allow" | "deny";
589
- /**
590
- * Resource selector fields supported by policy rules.
591
- */
592
583
  interface PolicyResourceSelector {
593
584
  toolNames?: string[];
594
585
  /** MCP registration ids, for scoping tool.call rules per server (#331). */
@@ -601,9 +592,6 @@ interface PolicyResourceSelector {
601
592
  /** Config-plane resource ids for API-action rules; "*" matches every id. */
602
593
  resourceIds?: string[];
603
594
  }
604
- /**
605
- * One allow/deny rule inside a policy document.
606
- */
607
595
  interface PolicyRule {
608
596
  id: string;
609
597
  effect: PolicyEffect;
@@ -613,7 +601,7 @@ interface PolicyRule {
613
601
  }
614
602
 
615
603
  /**
616
- * Channel record validation for the config plane — the single home of the
604
+ * Channel record validation for the config plane, the single home of the
617
605
  * normalizers core's `shared/domain/channel-record.ts` re-exports. Kept free
618
606
  * of Convex imports so the rules stay unit-testable; the public projection
619
607
  * lives in ./responses.ts.
@@ -622,10 +610,7 @@ interface PolicyRule {
622
610
  declare const CHANNEL_REPLY_TARGETS: readonly ["thread", "source"];
623
611
  type ChannelReplyIn = (typeof CHANNEL_REPLY_TARGETS)[number];
624
612
 
625
- /**
626
- * Telegram channel adapter implementated as a ChannelAdapter.
627
- * Implements Telegram auth, message normalization, and reply actions through the Chat SDK Telegram adapter.
628
- */
613
+ /** Telegram channel adapter. */
629
614
 
630
615
  interface TelegramSource {
631
616
  chatId: number;
@@ -638,8 +623,8 @@ interface TelegramSource {
638
623
  }
639
624
 
640
625
  /**
641
- * GitHub channel adapter.
642
- * Keep Broods-specific event filtering/source mapping here; delegate GitHub auth and API calls to Chat SDK.
626
+ * GitHub channel adapter. Event filtering and source mapping live here; auth and
627
+ * API calls go through the Chat SDK.
643
628
  */
644
629
 
645
630
  interface GitHubSource {
@@ -654,10 +639,7 @@ interface GitHubSource {
654
639
  target: "issue" | "issue_comment" | "pull_request" | "pull_request_review_comment";
655
640
  }
656
641
 
657
- /**
658
- * Slack channel adapter.
659
- * Handle request verification, inbound normalization, and Slack Web API reply actions here.
660
- */
642
+ /** Slack channel adapter. */
661
643
 
662
644
  interface SlackSource {
663
645
  teamId: string;
@@ -672,10 +654,7 @@ interface SlackSource {
672
654
  userId?: string;
673
655
  }
674
656
 
675
- /**
676
- * Discord channel adapter.
677
- * Verify interaction signatures, normalize slash commands, and send replies through Chat SDK's Discord adapter.
678
- */
657
+ /** Discord channel adapter. */
679
658
 
680
659
  interface DiscordSource {
681
660
  applicationId: string;
@@ -691,7 +670,6 @@ interface DiscordSource {
691
670
 
692
671
  /**
693
672
  * Pancake channel adapter.
694
- * Keep Pancake webhook normalization and outbound message API calls here.
695
673
  *
696
674
  * Per-conversation policy (e.g. skipping human-owned conversations by tag) is
697
675
  * not baked in: the parsed source carries `tagIds` so a user `onMessageReceived`
@@ -710,10 +688,7 @@ interface PancakeSource {
710
688
  tagIds?: string[];
711
689
  }
712
690
 
713
- /**
714
- * Zalo channel adapter.
715
- * Keep official Zalo Bot API webhook normalization and outbound API calls here.
716
- */
691
+ /** Zalo channel adapter, on the official Zalo Bot API. */
717
692
 
718
693
  declare const ZALO_CHAT_TYPES: readonly ["PRIVATE", "GROUP"];
719
694
  type ZaloChatType = (typeof ZALO_CHAT_TYPES)[number];
@@ -728,7 +703,7 @@ interface ZaloSource {
728
703
  }
729
704
 
730
705
  /**
731
- * Canonical CLI manifest wire types — the single source of truth shared by the
706
+ * Canonical CLI manifest wire types, the single source of truth shared by the
732
707
  * backend (cliSync.ts, cliHttp.ts) and the SDK/CLI (packages/broods).
733
708
  *
734
709
  * This file is intentionally type-only with no runtime imports so the SDK can
@@ -936,20 +911,13 @@ interface Agent {
936
911
  agentId: string;
937
912
  name: string;
938
913
  }
939
- interface Sandbox {
940
- sandboxId: string;
941
- name: string;
942
- }
943
- interface Workspace {
944
- workspaceId: string;
945
- name: string;
946
- }
947
- /** A tool call held for user approval by an `ask`-mode sandbox. */
948
- interface ToolApprovalSummary {
949
- approvalId: string;
950
- toolCallId: string;
951
- toolName: string;
952
- input: unknown;
914
+ interface AsyncRequestAccepted {
915
+ statusUrl: string;
916
+ statusId: string;
917
+ eventId: string;
918
+ agentId: string;
919
+ status?: "accepted" | "queued" | "applied" | "processing";
920
+ requestedMode?: "reject" | "followup" | "collect" | "steer";
953
921
  }
954
922
  interface AsyncStatus {
955
923
  status: "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "awaiting_input" | "completed" | "failed" | "expired" | "not_found";
@@ -964,14 +932,6 @@ interface AsyncStatus {
964
932
  approvals?: ToolApprovalSummary[];
965
933
  questions?: PendingQuestion[];
966
934
  }
967
- interface AsyncRequestAccepted {
968
- statusUrl: string;
969
- statusId: string;
970
- eventId: string;
971
- agentId: string;
972
- status?: "accepted" | "queued" | "applied" | "processing";
973
- requestedMode?: "reject" | "followup" | "collect" | "steer";
974
- }
975
935
  interface Cron {
976
936
  accountId: string;
977
937
  cronId: string;
@@ -1001,6 +961,10 @@ interface CronRun {
1001
961
  startedAt: string;
1002
962
  completedAt?: string;
1003
963
  }
964
+ interface Sandbox {
965
+ sandboxId: string;
966
+ name: string;
967
+ }
1004
968
  interface Skill {
1005
969
  path: string;
1006
970
  name: string;
@@ -1010,14 +974,25 @@ interface Skill {
1010
974
  size?: number;
1011
975
  }>;
1012
976
  }
977
+ /** A tool call held for user approval by an `ask`-mode sandbox. */
978
+ interface ToolApprovalSummary {
979
+ approvalId: string;
980
+ toolCallId: string;
981
+ toolName: string;
982
+ input: unknown;
983
+ }
984
+ interface Workspace {
985
+ workspaceId: string;
986
+ name: string;
987
+ }
1013
988
 
1014
989
  /**
1015
990
  * Shared WebSocket wire-protocol types for the observability gateway, used by
1016
991
  * the gateway, the SDK/CLI, and the dashboard. Pure types + tiny pure helpers,
1017
992
  * zero runtime deps. Kept separate from the agent-test websocket-contracts.
1018
993
  */
1019
- type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
1020
994
  declare const MAX_OBSERVABILITY_BACKFILL = 500;
995
+ type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
1021
996
  type ObservabilityLogEntry = {
1022
997
  ts: number;
1023
998
  level: LogLevel;
@@ -1087,18 +1062,18 @@ type ObservabilityErrorMessage = {
1087
1062
  error: string;
1088
1063
  };
1089
1064
  type ObservabilityServerMessage = ObservabilityReadyMessage | ObservabilityBackfillMessage | ObservabilityLogMessage | ObservabilitySpanMessage | ObservabilityErrorMessage;
1090
- declare function isObservabilityClientMessage(v: unknown): v is ObservabilityClientMessage;
1091
1065
  /** Narrow an unknown wire value to a LogLevel. */
1092
1066
  declare function isLogLevel(value: unknown): value is LogLevel;
1067
+ declare function isObservabilityClientMessage(v: unknown): v is ObservabilityClientMessage;
1093
1068
  /** Whether a span is a top-level run, each of which owns its own trace. */
1094
1069
  declare function isRootSpanKind(kind: ObservabilitySpanRow["kind"]): boolean;
1095
- /** Whether a value is a real trace id a log line can be followed to. */
1096
- declare function isTraceId(value: unknown): value is string;
1097
1070
  /**
1098
1071
  * Narrow a wire value to a sandbox log id. Strict on purpose: the gateway
1099
1072
  * interpolates it into LogQL, so only the UUID shape core mints may pass.
1100
1073
  */
1101
1074
  declare function isSandboxLogId(value: unknown): value is string;
1075
+ /** Whether a value is a real trace id a log line can be followed to. */
1076
+ declare function isTraceId(value: unknown): value is string;
1102
1077
 
1103
1078
  /**
1104
1079
  * Configurable client for running deployed agents over direct core SSE.
@@ -1108,7 +1083,7 @@ declare function isSandboxLogId(value: unknown): value is string;
1108
1083
  declare const DEFAULT_CORE_BASE_URL = "https://gateway.broods.app";
1109
1084
  /**
1110
1085
  * Input for a single agent run. The core direct API is event-based (a list of
1111
- * Vercel AI SDK model messages), so `events` is the full-fidelity form — use it
1086
+ * Vercel AI SDK model messages), so `events` is the full-fidelity form. Use it
1112
1087
  * for multimodal content (images/files), ephemeral system messages, or
1113
1088
  * tool-approval responses. `input` is a shorthand for a single user text message
1114
1089
  * and is wrapped into one user event. Provide exactly one of the two.
@@ -1203,8 +1178,8 @@ declare class BroodsClient {
1203
1178
  channelWebhookUrl(ref: ChannelReference): string;
1204
1179
  /**
1205
1180
  * Return the provider webhook URL for an account's channel. The URL names no
1206
- * agent — every channel of one type in an account shares it — so this is what
1207
- * to paste into the provider when several agents sit behind the same app.
1181
+ * agent, since every channel of one type in an account shares it, so this is
1182
+ * what to paste into the provider when several agents sit behind the same app.
1208
1183
  */
1209
1184
  accountWebhookUrl(accountId: string, channelType: ChannelReference["type"]): string;
1210
1185
  /**
@@ -1269,18 +1244,18 @@ declare function normalizeHttpServiceUrl(value: string): string;
1269
1244
  * This is the DYNAMIC counterpart to the config-first `broods dev` / `broods
1270
1245
  * deploy` flow: `broods dev` syncs the predefined resources declared in your
1271
1246
  * `broods/` folder, while `BroodsAccountClient` creates and mutates the full
1272
- * account config plane at runtime — agents, sandboxes (config + lifecycle),
1247
+ * account config plane at runtime: agents, sandboxes (config + lifecycle),
1273
1248
  * workspaces (config + files), tools, policies, skills, crons, and the account
1274
- * itself — e.g. a multi-tenant app provisioning one agent per customer from its
1275
- * own backend.
1249
+ * itself. One caller is a multi-tenant app provisioning one agent per customer
1250
+ * from its own backend.
1276
1251
  *
1277
1252
  * Kept intentionally standalone (import from `broods/account`): pure fetch,
1278
- * no Node built-ins, no `.env` file loading — so it runs in edge/worker
1253
+ * no Node built-ins, no `.env` file loading, so it runs in edge/worker
1279
1254
  * runtimes such as Convex actions, Cloudflare Workers, and the browser-less
1280
1255
  * server runtimes, as well as Node and Bun.
1281
1256
  *
1282
1257
  * Auth: every call sends `Authorization: Bearer {accountSecret}` to
1283
- * `{baseUrl}/v1/...` — or a short-lived `fp_sts_` role session token from
1258
+ * `{baseUrl}/v1/...`, or a short-lived `fp_sts_` role session token from
1284
1259
  * `assumeRole()`, limited to what the role's policy allows. Secrets inside
1285
1260
  * agent configs are encrypted at rest by the platform and come back redacted
1286
1261
  * (`********`) on reads.
@@ -1328,8 +1303,6 @@ interface AccountEnvVar {
1328
1303
  name: string;
1329
1304
  updatedAt: number;
1330
1305
  }
1331
- /** Build a validated account env-var reference for use in an agent config. */
1332
- declare function envPlaceholder(name: string): string;
1333
1306
  /** Fields accepted by `PATCH /v1/agents/{id}`. `config` is deep-merged; `null` values delete keys. */
1334
1307
  interface UpdateAgentInput {
1335
1308
  name?: string;
@@ -1400,8 +1373,8 @@ interface AssumeRoleResult {
1400
1373
  expiresAt: string;
1401
1374
  }
1402
1375
  /**
1403
- * One real place a team talks — a Slack channel, a Discord channel, a repo —
1404
- * bound to an agent. The runtime reads it on the inbound webhook to decide who
1376
+ * One real place a team talks, bound to an agent: a Slack channel, a Discord
1377
+ * channel, a repo. The runtime reads it on the inbound webhook to decide who
1405
1378
  * answers there and with what instructions, workspaces and policies.
1406
1379
  */
1407
1380
  interface AccountChannel {
@@ -1432,14 +1405,14 @@ interface ChannelRecordConfig {
1432
1405
  /** Added to whatever the agent already carries. Each policy holds its own mode. */
1433
1406
  policies?: string[];
1434
1407
  /**
1435
- * Tool names withheld in this channel, applied after the tool set is built —
1408
+ * Tool names withheld in this channel, applied after the tool set is built,
1436
1409
  * so it also covers sandbox tools (`bash`, `read`, …) that `config.tools`
1437
1410
  * cannot name. Narrowing only; unknown names are ignored.
1438
1411
  */
1439
1412
  denyTools?: string[];
1440
1413
  /**
1441
1414
  * Where the reply lands. `source` answers wherever the message came from, and
1442
- * threads only when the message already did. Slack only — no other provider
1415
+ * threads only when the message already did. Slack only. No other provider
1443
1416
  * gives the runtime a second place to reply.
1444
1417
  */
1445
1418
  replyIn?: ChannelReplyIn;
@@ -1568,6 +1541,8 @@ declare class BroodsAccountApiError extends Error {
1568
1541
  readonly body: string;
1569
1542
  constructor(method: string, path: string, status: number, body: string);
1570
1543
  }
1544
+ /** Build a validated account env-var reference for use in an agent config. */
1545
+ declare function envPlaceholder(name: string): string;
1571
1546
  /**
1572
1547
  * The credential the environment supplies, with a role session winning over
1573
1548
  * the account secret. The constructor throws through this same resolution, so
@@ -1854,6 +1829,7 @@ declare class BroodsWebSocketClient {
1854
1829
  buildUrl(input: Pick<WebSocketRunInput, "agent" | "endpointId" | "projectSlug" | "stageSlug">): string;
1855
1830
  private resolveWebSocket;
1856
1831
  }
1832
+ declare function toWebSocketBaseUrl(url: string): string;
1857
1833
  /**
1858
1834
  * The credential travels as a `Sec-WebSocket-Protocol` entry rather than in
1859
1835
  * the URL, so it never lands in proxy or access logs. The gateway answers
@@ -1862,15 +1838,10 @@ declare class BroodsWebSocketClient {
1862
1838
  */
1863
1839
  declare function webSocketSubprotocols(apiKey: string): string[];
1864
1840
 
1865
- declare function toWebSocketBaseUrl(url: string): string;
1866
-
1867
1841
  /**
1868
1842
  * Resource definition helpers for the code-first `broods/` project folder.
1869
1843
  *
1870
- * Layout: markers, then types (env refs, project config, resource primitives,
1871
- * per-kind config surfaces, per-kind resource aliases), then the env runtime
1872
- * value, the resource constructors, and the type guards. Every runtime function
1873
- * here is synchronous.
1844
+ * Every runtime function here is synchronous.
1874
1845
  */
1875
1846
 
1876
1847
  declare const RESOURCE_MARKER: unique symbol;
@@ -1928,7 +1899,7 @@ type SandboxDefinitionOptions = Record<string, unknown> & {
1928
1899
  reservationKey?: string;
1929
1900
  };
1930
1901
  /**
1931
- * Code-first sandbox config surface. Mirrors core's `SandboxConfig` but lets
1902
+ * Code-first sandbox config input. Mirrors core's `SandboxConfig` but lets
1932
1903
  * `envVars` values be `env("NAME")` references (compiled to `${NAME}` placeholders
1933
1904
  * at sync time, exactly like provider `apiKey`). Add overrides here if more
1934
1905
  * sandbox fields should accept env refs.
@@ -1954,14 +1925,14 @@ type PolicyDefinitionConfig = Omit<PolicyDocument, "version"> & {
1954
1925
  };
1955
1926
  /**
1956
1927
  * Fetch-style MCP handler for a hosted server: what
1957
- * `createMcpHandler(...)` from @modelcontextprotocol/server returns —
1958
- * either the request function itself or an object exposing it as `fetch`.
1928
+ * `createMcpHandler(...)` from @modelcontextprotocol/server returns: either
1929
+ * the request function itself or an object exposing it as `fetch`.
1959
1930
  */
1960
1931
  type McpHandler = ((request: Request) => Response | Promise<Response>) | {
1961
1932
  fetch(request: Request): Response | Promise<Response>;
1962
1933
  };
1963
1934
  /**
1964
- * MCP server registration (#331) — external (`url`) or hosted (`handler`).
1935
+ * MCP server registration (#331), either external (`url`) or hosted (`handler`).
1965
1936
  * Either way the server's tools are offered as `<name>__<tool>`; an external
1966
1937
  * row is dialed over the stateless HTTP transport (spec 2026-07-28) at agent
1967
1938
  * registration time. The name namespaces those tools, so it must be 1-32
@@ -1971,7 +1942,7 @@ interface McpDefinitionConfig {
1971
1942
  /** External server's MCP endpoint; http(s), no embedded credentials. */
1972
1943
  url?: string;
1973
1944
  /**
1974
- * Hosted alternative to `url`: declare the server inline —
1945
+ * Hosted alternative to `url`: declare the server inline as
1975
1946
  * `handler: createMcpHandler(...)` from @modelcontextprotocol/server,
1976
1947
  * right next to the `defineMcp` call. The CLI bundles the defining module
1977
1948
  * and the tool-runner Lambda hosts it, one invoke per batch of requests.
@@ -1979,8 +1950,8 @@ interface McpDefinitionConfig {
1979
1950
  handler?: McpHandler;
1980
1951
  /**
1981
1952
  * Extra request headers. Credential-bearing headers (Authorization,
1982
- * X-Api-Key, ...) must reference an account env var — e.g.
1983
- * `Bearer ${env("TOKEN")}` — never carry an inline secret.
1953
+ * X-Api-Key, ...) must reference an account env var, e.g.
1954
+ * `Bearer ${env("TOKEN")}`. Never carry an inline secret.
1984
1955
  */
1985
1956
  headers?: Record<string, string>;
1986
1957
  /**
@@ -2061,8 +2032,8 @@ type ZaloConnectionDefinition = ConnectionDefinition<"zalo", ZaloConnectionInput
2061
2032
  type AnyConnectionDefinition = TelegramConnectionDefinition | GitHubConnectionDefinition | SlackConnectionDefinition | DiscordConnectionDefinition | PancakeConnectionDefinition | ZaloConnectionDefinition;
2062
2033
  /**
2063
2034
  * One real place a team talks: a Slack channel, a Discord channel, a repo. It
2064
- * narrows and adds — instructions append, policies union, tools and workspaces
2065
- * only narrow — and never grants what a bound agent lacks. It names the
2035
+ * narrows and adds, and never grants what a bound agent lacks: instructions
2036
+ * append, policies union, tools and workspaces only narrow. It names the
2066
2037
  * connection it belongs to, so `platform` is never written by hand.
2067
2038
  */
2068
2039
  type ChannelDefinitionConfig = {
@@ -2157,8 +2128,8 @@ interface HookContext {
2157
2128
  config: Record<string, unknown>;
2158
2129
  /**
2159
2130
  * Mutable per-request scratchpad shared across this agent request's hooks.
2160
- * Seed it in an early hook (e.g. `onStart`) and read or modify it later —
2161
- * every loop hook, `onSubagentFinish`, and the reply's `onMessageSending`
2131
+ * Seed it in an early hook (e.g. `onStart`) and read or modify it later.
2132
+ * Every loop hook, `onSubagentFinish`, and the reply's `onMessageSending`
2162
2133
  * see the same state. Keep it JSON-serializable. `onMessageReceived`,
2163
2134
  * delayed background replies, and each subagent's own run get fresh state.
2164
2135
  */
@@ -2214,7 +2185,7 @@ type ChannelMessageReceived = {
2214
2185
  * preferred so the serialized source is valid as an object-literal value.
2215
2186
  *
2216
2187
  * Subagent runs fire hooks too: a registered subagent runs its own hooks, a
2217
- * prompt-only (virtual) subagent inherits this bundle — always with fresh
2188
+ * prompt-only (virtual) subagent inherits this bundle, always with fresh
2218
2189
  * `ctx.state`. `onSubagentFinish` fires on the parent with the parent's state.
2219
2190
  */
2220
2191
  interface AgentHooks {
@@ -2278,9 +2249,9 @@ interface AgentHooks {
2278
2249
  }>;
2279
2250
  }
2280
2251
  /**
2281
- * Code-first agent config surface. Built from an explicit `Pick` of `AgentConfig`
2252
+ * Code-first agent config input. Built from an explicit `Pick` of `AgentConfig`
2282
2253
  * (not `Omit`) so the SDK input type does NOT inherit `AgentConfig`'s
2283
- * `[key: string]: unknown` index signature — which would otherwise disable
2254
+ * `[key: string]: unknown` index signature, which would otherwise disable
2284
2255
  * TypeScript's excess-property checks and silently accept typos like
2285
2256
  * `workspace:` instead of `workspaces:`. Add a key here when core's `AgentConfig`
2286
2257
  * gains a new top-level field that should be code-definable.
@@ -2317,8 +2288,8 @@ type AgentDefinitionConfig = EnvRefString<Pick<AgentConfig, "agent" | "model" |
2317
2288
  policies?: readonly (PolicyResource | string)[];
2318
2289
  /**
2319
2290
  * Opt the agent into the public runtime endpoint (SSE/WebSocket via the
2320
- * stage runtime key). Off by default — secured: when unset the public
2321
- * endpoint refuses requests for this agent. Reach a private agent through an
2291
+ * stage runtime key). Off by default: when unset the public endpoint
2292
+ * refuses requests for this agent. Reach a private agent through an
2322
2293
  * internal endpoint or a channel webhook. See issue #65.
2323
2294
  */
2324
2295
  publicAccess?: boolean;
@@ -2329,8 +2300,8 @@ type CronDefinitionConfig = Omit<CreateCronInput, "agentId" | "name"> & {
2329
2300
  type AgentResource<Name extends string = string> = ResourceDefinition<"agent", Name, AgentDefinitionConfig>;
2330
2301
  /**
2331
2302
  * Code-first workspace config. Says `partitioned` where storage says
2332
- * `isolation`: the flag permits a split, it does not perform one — a channel's
2333
- * `partition` decides which folder a run actually mounts.
2303
+ * `isolation`: the flag permits a split, it does not perform one. A channel's
2304
+ * `partition` decides which folder a run mounts.
2334
2305
  */
2335
2306
  type WorkspaceDefinitionConfig = Omit<WorkspaceConfig, "isolation"> & {
2336
2307
  /** Allow this workspace to be split into per-conversation folders. */
@@ -2345,8 +2316,8 @@ type CronResource<Name extends string = string> = ResourceDefinition<"cron", Nam
2345
2316
  type ChannelResource<Name extends string = string> = ResourceDefinition<"channelRecord", Name, ChannelDefinitionConfig>;
2346
2317
  type AnyResource = AgentResource | WorkspaceResource | SandboxResource | CronResource | SkillResource | McpResource | PolicyResource | ChannelResource;
2347
2318
  /**
2348
- * References an account/environment variable resolved on the SERVER at runtime —
2349
- * set it with `broods env set <NAME>` or in the dashboard (the Convex-style
2319
+ * References an account/environment variable resolved on the SERVER at runtime.
2320
+ * Set it with `broods env set <NAME>` or in the dashboard (the Convex-style
2350
2321
  * `convex env set` model). It is a deferred reference, never read from your local
2351
2322
  * environment and never baked into the deployed config:
2352
2323
  *
@@ -2362,6 +2333,21 @@ type AnyResource = AgentResource | WorkspaceResource | SandboxResource | CronRes
2362
2333
  * pushes matching `.env.local` values first, so a local value is enough there.
2363
2334
  */
2364
2335
  declare const env: EnvAccessor;
2336
+ /**
2337
+ * Shared builder behind every `define*` helper below. The public helpers are
2338
+ * thin, per-kind typed front doors: each pins its `kind` (the discriminant the
2339
+ * sync/codegen pipeline switches on) and splits the flat authoring input back
2340
+ * into the `{ name, description?, config }` shape the manifest wire format uses.
2341
+ */
2342
+ declare function defineAgent<const Name extends string>(input: ResourceInput<Name, AgentDefinitionConfig>): AgentResource<Name>;
2343
+ declare function defineBroods(config: BroodsProjectConfig): BroodsConfigDefinition;
2344
+ declare function defineCron<const Name extends string>(input: ResourceInput<Name, CronDefinitionConfig>): CronResource<Name>;
2345
+ declare function defineHarness<const Definition extends HarnessDefinition>(definition: Definition): Definition;
2346
+ declare function defineMcp<const Name extends string>(input: ResourceInput<Name, McpDefinitionConfig>): McpResource<Name>;
2347
+ declare function definePolicy<const Name extends string>(input: ResourceInput<Name, PolicyDefinitionConfig>): PolicyResource<Name>;
2348
+ declare function defineSandbox<const Name extends string>(input: ResourceInput<Name, SandboxDefinitionConfig>): SandboxResource<Name>;
2349
+ declare function defineSkill<const Name extends string>(input: ResourceInput<Name, SkillDefinitionConfig>): SkillResource<Name>;
2350
+ declare function defineWorkspace<const Name extends string>(input: ResourceInput<Name, WorkspaceDefinitionConfig>): WorkspaceResource<Name>;
2365
2351
  declare function defineDiscordConnection(config: DiscordConnectionInput): DiscordConnectionDefinition;
2366
2352
  declare function defineGitHubConnection(config: GitHubConnectionInput): GitHubConnectionDefinition;
2367
2353
  declare function definePancakeConnection(config: PancakeConnectionInput): PancakeConnectionDefinition;
@@ -2374,18 +2360,9 @@ declare function definePancakeChannel<const Name extends string>(input: Resource
2374
2360
  declare function defineSlackChannel<const Name extends string>(input: ResourceInput<Name, SlackChannelInput>): ChannelResource<Name>;
2375
2361
  declare function defineTelegramChannel<const Name extends string>(input: ResourceInput<Name, TelegramChannelInput>): ChannelResource<Name>;
2376
2362
  declare function defineZaloChannel<const Name extends string>(input: ResourceInput<Name, ZaloChannelInput>): ChannelResource<Name>;
2377
- declare function defineBroods(config: BroodsProjectConfig): BroodsConfigDefinition;
2378
- declare function defineAgent<const Name extends string>(input: ResourceInput<Name, AgentDefinitionConfig>): AgentResource<Name>;
2379
- declare function defineHarness<const Definition extends HarnessDefinition>(definition: Definition): Definition;
2380
- declare function defineWorkspace<const Name extends string>(input: ResourceInput<Name, WorkspaceDefinitionConfig>): WorkspaceResource<Name>;
2381
- declare function defineSandbox<const Name extends string>(input: ResourceInput<Name, SandboxDefinitionConfig>): SandboxResource<Name>;
2382
- declare function defineSkill<const Name extends string>(input: ResourceInput<Name, SkillDefinitionConfig>): SkillResource<Name>;
2383
- declare function defineMcp<const Name extends string>(input: ResourceInput<Name, McpDefinitionConfig>): McpResource<Name>;
2384
- declare function definePolicy<const Name extends string>(input: ResourceInput<Name, PolicyDefinitionConfig>): PolicyResource<Name>;
2385
- declare function defineCron<const Name extends string>(input: ResourceInput<Name, CronDefinitionConfig>): CronResource<Name>;
2386
- declare function isResource(value: unknown): value is AnyResource;
2387
- declare function isConnectionDefinition(value: unknown): value is AnyConnectionDefinition;
2388
2363
  declare function isBroodsConfig(value: unknown): value is BroodsConfigDefinition;
2364
+ declare function isConnectionDefinition(value: unknown): value is AnyConnectionDefinition;
2365
+ declare function isResource(value: unknown): value is AnyResource;
2389
2366
 
2390
2367
  export { BroodsAccountApiError, BroodsAccountClient, BroodsClient, BroodsWebSocketClient, DEFAULT_CORE_BASE_URL, IngressAcceptedError, MAX_OBSERVABILITY_BACKFILL, BroodsWebSocketClient as WebSocketClient, BroodsWebSocketClient as WebsocketClient, defineAgent, defineBroods, defineCron, defineDiscordChannel, defineDiscordConnection, defineGitHubChannel, defineGitHubConnection, defineHarness, defineMcp, definePancakeChannel, definePancakeConnection, definePolicy, defineSandbox, defineSkill, defineSlackChannel, defineSlackConnection, defineTelegramChannel, defineTelegramConnection, defineWorkspace, defineZaloChannel, defineZaloConnection, env, envPlaceholder, isBroodsConfig, isConnectionDefinition, isLogLevel, isObservabilityClientMessage, isResource, isRootSpanKind, isSandboxLogId, isTraceId, normalizeHttpServiceUrl, readSseStream, resolveEnvCredential, resolveRunEvents, toWebSocketBaseUrl, webSocketSubprotocols };
2391
2368
  export type { Account, AccountAgent, AccountChannel, AccountEnvVar, AccountMcp, AccountPolicy, AccountRole, AccountSandbox, AccountWorkspace, Agent, AgentChannelsConfig, AgentCodeHookConfig, AgentConfig, AgentConfigDoc, AgentDefinitionConfig, AgentDiscordChannelConfig, AgentGitHubChannelConfig, AgentHandle, AgentHookEventName, AgentHooks, AgentHooksConfig, AgentPancakeChannelConfig, AgentProviderSettings, AgentReference, AgentResource, AgentRunEventInput, AgentRunInput, AgentRunModelOverrides, AgentRunOverrides, AgentRunResult, AgentSkillsDefinitionConfig, AgentSlackChannelConfig, AgentStreamPart, AgentSubagentDefinitionConfig, AgentTelegramChannelConfig, AgentWebhookHookConfig, AgentWorkspaceInput, AgentWorkspaceRef, AgentWorkspaceRefInput, AgentZaloChannelConfig, AnyConnectionDefinition, AnyResource, AssumeRoleResult, AsyncAgentRun, AsyncPollOptions, AsyncRequestAccepted, AsyncStatus, BroodsAccount, BroodsAccountClientOptions, BroodsClientOptions, BroodsConfigDefinition, BroodsProjectConfig, BroodsWebSocketClientOptions, ChannelAgentInput, ChannelDefinitionConfig, ChannelMessageReceived, ChannelPartition, ChannelRecordConfig, ChannelReference, ChannelReplyIn, ChannelResource, ChannelType, CliManifest, CliManifestResource, ConnectionDefinition, CreateAgentResult, CreateClientCronInput, CreateCronInput, CreateMcpInput, Cron, CronDefinitionConfig, CronDoc, CronLastStatus, CronResource, CronRun, CronStatus, DeleteAccountResult, DiscordChannelInput, DiscordConnectionDefinition, DiscordConnectionInput, DiscordMessageSource, DiscordSource, Doc, EnvAccessor, EnvRef, EnvRefString, GeneratedIds, GitHubChannelInput, GitHubConnectionDefinition, GitHubConnectionInput, GitHubMessageSource, GitHubSource, HarnessDefinition, HarnessType, HookContext, Id, IngressMode, IngressStatus, LogLevel, McpDefinitionConfig, McpHandler, McpOauthInput, McpResource, ObservabilityBackfillMessage, ObservabilityClientMessage, ObservabilityErrorMessage, ObservabilityFetchTraceMessage, ObservabilityLogEntry, ObservabilityLogMessage, ObservabilityReadyMessage, ObservabilityServerMessage, ObservabilitySpanMessage, ObservabilitySpanRow, ObservabilitySubscribeMessage, ObservabilityUnsubscribeMessage, PancakeChannelInput, PancakeConnectionDefinition, PancakeConnectionInput, PancakeMessageSource, PancakeSource, PendingQuestion, PolicyDefinitionConfig, PolicyDocument, PolicyResource, ProjectDoc, ProviderConfigInput, ProviderSettingsInput, ResourceApi, ResourceDefinition, ResourceInput, ResourceKind, RotateSecretResult, Sandbox, SandboxConfig, SandboxConfigDoc, SandboxDefinitionConfig, SandboxDefinitionOptions, SandboxLifecycleResult, SandboxResource, SandboxSnapshotResult, SandboxTerminalTicket, Skill, SkillDefinitionConfig, SkillResource, SkillUploadInput, SlackChannelInput, SlackConnectionDefinition, SlackConnectionInput, SlackMessageSource, SlackSource, StageDoc, StageScope, TelegramChannelInput, TelegramConnectionDefinition, TelegramConnectionInput, TelegramMessageSource, TelegramSource, ToolApprovalSummary, UpdateAgentInput, UpdateCronInput, UpdateMcpInput, WebSocketAttachInput, WebSocketClientAttachMessage, WebSocketClientCancelMessage, WebSocketClientControlMessage, WebSocketClientExecuteMessage, WebSocketClientMessage, WebSocketConstructorLike, WebSocketHandlers, WebSocketLike, WebSocketOutputMessage, WebSocketRunInput, WebSocketServerMessage, WebSocketStreamMessage, WebSocketSubscription, Workspace, WorkspaceConfig, WorkspaceConfigDoc, WorkspaceDefinitionConfig, WorkspaceFileEntry, WorkspaceResource, ZaloChannelInput, ZaloConnectionDefinition, ZaloConnectionInput, ZaloMessageSource, ZaloSource };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{B,pe,xe,ke,Te,Pe,Ie,V,C,me,q,W,$e,D,K,Me,Ae,ze,Oe,Ne,je,qe,De,Le,Ue,Fe,Be,Ve,Ze,He,We,Ke,Ge,Je,Ye,Xe,Qe,h,_,ne}from"./chunk-rea5p7sh.js";import{Ce,m,L,U}from"./chunk-9emkj9m1.js";export{m as BroodsAccountApiError,U as BroodsAccountClient,q as BroodsClient,$e as BroodsWebSocketClient,C as DEFAULT_CORE_BASE_URL,me as IngressAcceptedError,xe as MAX_OBSERVABILITY_BACKFILL,$e as WebSocketClient,$e as WebsocketClient,He as defineAgent,Ze as defineBroods,Qe as defineCron,De as defineDiscordChannel,Ae as defineDiscordConnection,Le as defineGitHubChannel,ze as defineGitHubConnection,We as defineHarness,Ye as defineMcp,Ue as definePancakeChannel,Oe as definePancakeConnection,Xe as definePolicy,Ge as defineSandbox,Je as defineSkill,Fe as defineSlackChannel,Ne as defineSlackConnection,Be as defineTelegramChannel,je as defineTelegramConnection,Ke as defineWorkspace,Ve as defineZaloChannel,qe as defineZaloConnection,Me as env,Ce as envPlaceholder,ne as isBroodsConfig,_ as isConnectionDefinition,Te as isLogLevel,ke as isObservabilityClientMessage,h as isResource,Pe as isRootSpanKind,V as isSandboxLogId,Ie as isTraceId,W as normalizeHttpServiceUrl,pe as readSseStream,L as resolveEnvCredential,B as resolveRunEvents,K as toWebSocketBaseUrl,D as webSocketSubprotocols};
1
+ import{B,pe,xe,Te,ke,Pe,V,Ie,C,me,q,W,$e,K,D,Me,Ae,ze,Oe,Ne,je,qe,De,Le,Ue,Fe,Be,Ve,Ze,He,We,Ke,Ge,Je,Ye,Xe,Qe,ne,_,h}from"./chunk-7xc63gnm.js";import{m,Ce,L,U}from"./chunk-mqwt5n8x.js";export{m as BroodsAccountApiError,U as BroodsAccountClient,q as BroodsClient,$e as BroodsWebSocketClient,C as DEFAULT_CORE_BASE_URL,me as IngressAcceptedError,xe as MAX_OBSERVABILITY_BACKFILL,$e as WebSocketClient,$e as WebsocketClient,Ae as defineAgent,ze as defineBroods,Oe as defineCron,Ke as defineDiscordChannel,Fe as defineDiscordConnection,Ge as defineGitHubChannel,Be as defineGitHubConnection,Ne as defineHarness,je as defineMcp,Je as definePancakeChannel,Ve as definePancakeConnection,qe as definePolicy,De as defineSandbox,Le as defineSkill,Ye as defineSlackChannel,Ze as defineSlackConnection,Xe as defineTelegramChannel,He as defineTelegramConnection,Ue as defineWorkspace,Qe as defineZaloChannel,We as defineZaloConnection,Me as env,Ce as envPlaceholder,ne as isBroodsConfig,_ as isConnectionDefinition,Te as isLogLevel,ke as isObservabilityClientMessage,h as isResource,Pe as isRootSpanKind,V as isSandboxLogId,Ie as isTraceId,W as normalizeHttpServiceUrl,pe as readSseStream,L as resolveEnvCredential,B as resolveRunEvents,K as toWebSocketBaseUrl,D as webSocketSubprotocols};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "broods",
3
- "version": "0.33.3",
3
+ "version": "0.33.4",
4
4
  "description": "CLI + TypeScript SDK for the broods agent platform.",
5
5
  "keywords": [
6
6
  "agents",
@@ -1 +0,0 @@
1
- import{N}from"./chunk-rjx0qg7x.js";import{L,U}from"./chunk-9emkj9m1.js";import{e,o,i,l,s}from"./cli/index.js";var R={project:e().optional(),stage:e().optional()},M={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.",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: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 qt(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 N({name:"broods",version:"1"},{capabilities:{tools:{}}});if(r){for(let a of A)O(n,r,a,t.scope??{});q(n,r)}if(t.cli)j(n,t.cli);if(t.allowDestructive)x(n,r,t.cli??null);return n}function k(t){return{content:[{type:"text",text:JSON.stringify(t??null,null,2)}]}}function P(t){return{content:[{type:"text",text:t instanceof Error?t.message:String(t)}],isError:!0}}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 P(r)}}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 O(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})))}function q(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: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: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 j(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 x(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))))}export{qt as createBroodsMcpServer};
@@ -1,2 +0,0 @@
1
- var u=/^[A-Z][A-Z0-9_]*$/;function Ce(e){if(!u.test(e)||e.length>64)throw Error("envPlaceholder name must match /^[A-Z][A-Z0-9_]*$/ and be at most 64 characters.");return`\${${e}}`}class m extends Error{status;body;constructor(e,t,n,s){super(`${e} ${t} failed with ${n}: ${s}`);this.name="BroodsAccountApiError",this.status=n,this.body=s}}function L(){return o("BROODS_SESSION_TOKEN")??o("BROODS_ACCOUNT_SECRET")}function o(e){return typeof process<"u"?process?.env?.[e]:void 0}function i(e){return`?${new URLSearchParams({project:e.project,stage:e.stage}).toString()}`}class U{baseUrl;bearerToken;fetchImpl;constructor(e={}){let t=e.baseUrl??o("BROODS_BASE_URL")??"https://gateway.broods.app",n=e.sessionToken??e.accountSecret??L();if(!n)throw Error("BroodsAccountClient requires an accountSecret or sessionToken (or BROODS_ACCOUNT_SECRET / BROODS_SESSION_TOKEN).");let s=t.length;while(s>0&&t.charCodeAt(s-1)===47)s-=1;this.baseUrl=t.slice(0,s),this.bearerToken=n,this.fetchImpl=e.fetch??fetch}async getAccount(){let e=await this.request("GET","/v1/account");if(!e)throw new m("GET","/v1/account",404,"Account not found");return e.account}async updateAccount(e){return(await this.request("PATCH","/v1/account",e))?.account??null}async assumeRole(e,t={}){let n=await this.request("POST","/v1/account/assume-role",{roleId:e,...t.ttlSeconds!==void 0?{ttlSeconds:t.ttlSeconds}:{}});if(!n)throw new m("POST","/v1/account/assume-role",404,"Role not found");return n}async rotateSecret(){let e=await this.request("POST","/v1/account/rotate-secret");if(!e)throw new m("POST","/v1/account/rotate-secret",404,"Account not found");return e}async deleteAccount(){return await this.request("DELETE","/v1/account")??{deleted:!1}}webhookUrl(e,t){let n=[e,t].map(encodeURIComponent);return`${this.baseUrl}/webhooks/${n.join("/")}`}async listAgents(){return(await this.request("GET","/v1/agents"))?.agents??[]}async createAgent(e){let t=await this.request("POST","/v1/agents",e);if(!t)throw new m("POST","/v1/agents",404,"Not found");return t}async getAgent(e){return await this.request("GET",`/v1/agents/${encodeURIComponent(e)}`)}async updateAgent(e,t){return await this.request("PATCH",`/v1/agents/${encodeURIComponent(e)}`,t)}async deleteAgent(e){return(await this.request("DELETE",`/v1/agents/${encodeURIComponent(e)}`))?.deleted??!1}async listEnvVars(){return(await this.request("GET","/v1/env"))?.env??[]}async setEnvVar(e,t){await this.request("PUT",`/v1/env/${encodeURIComponent(e)}`,{value:t})}async deleteEnvVar(e){return(await this.request("DELETE",`/v1/env/${encodeURIComponent(e)}`))?.deleted??!1}async listCrons(){return(await this.request("GET","/v1/crons"))?.crons??[]}async createCron(e){let t=await this.request("POST","/v1/crons",e);if(!t)throw new m("POST","/v1/crons",404,"Not found");return t}async getCron(e){return await this.request("GET",`/v1/crons/${encodeURIComponent(e)}`)}async updateCron(e,t){return await this.request("PATCH",`/v1/crons/${encodeURIComponent(e)}`,t)}async deleteCron(e){return(await this.request("DELETE",`/v1/crons/${encodeURIComponent(e)}`))?.deleted??!1}async listCronRuns(e,t={}){let n=t.limit!==void 0?`?limit=${t.limit}`:"";return(await this.request("GET",`/v1/crons/${encodeURIComponent(e)}/runs${n}`))?.runs??[]}async listWorkspaces(){return(await this.request("GET","/v1/workspaces"))?.workspaces??[]}async createWorkspace(e){let t=await this.request("POST","/v1/workspaces",e);if(!t)throw new m("POST","/v1/workspaces",404,"Not found");return t}async getWorkspace(e){return await this.request("GET",`/v1/workspaces/${encodeURIComponent(e)}`)}async updateWorkspace(e,t){return await this.request("PATCH",`/v1/workspaces/${encodeURIComponent(e)}`,t)}async deleteWorkspace(e){return(await this.request("DELETE",`/v1/workspaces/${encodeURIComponent(e)}`))?.deleted??!1}async listWorkspaceFiles(e){return(await this.request("GET",`/v1/workspaces/${encodeURIComponent(e)}/files`))?.files??[]}async getWorkspaceFileUrl(e,t){let n=`?path=${encodeURIComponent(t)}`;return(await this.request("GET",`/v1/workspaces/${encodeURIComponent(e)}/files${n}`))?.url??null}async uploadWorkspaceFile(e,t){let n=`/v1/workspaces/${encodeURIComponent(e)}/files`,s=await this.request("POST",n,t);if(!s)throw new m("POST",n,404,"Workspace not found");return s.file}async renameWorkspaceFile(e,t,n){return(await this.request("PATCH",`/v1/workspaces/${encodeURIComponent(e)}/files`,{path:t,newPath:n}))?.renamed??!1}async deleteWorkspaceFile(e,t){return(await this.request("DELETE",`/v1/workspaces/${encodeURIComponent(e)}/files`,{path:t}))?.deleted??!1}async listSandboxes(){return(await this.request("GET","/v1/sandboxes"))?.sandboxes??[]}async createSandbox(e){let t=await this.request("POST","/v1/sandboxes",e);if(!t)throw new m("POST","/v1/sandboxes",404,"Not found");return t}async getSandbox(e){return await this.request("GET",`/v1/sandboxes/${encodeURIComponent(e)}`)}async updateSandbox(e,t){return await this.request("PATCH",`/v1/sandboxes/${encodeURIComponent(e)}`,t)}async deleteSandbox(e){return(await this.request("DELETE",`/v1/sandboxes/${encodeURIComponent(e)}`))?.deleted??!1}async suspendSandbox(e,t){return await this.sandboxAction(e,"suspend",{reservationKey:t})}async resumeSandbox(e,t){return await this.sandboxAction(e,"resume",{reservationKey:t})}async terminateSandbox(e,t){return await this.sandboxAction(e,"terminate",{reservationKey:t})}async snapshotSandbox(e,t,n){return await this.sandboxAction(e,"snapshot",{reservationKey:t,name:n})}async openSandboxTerminal(e,t){return await this.sandboxAction(e,"terminal",{reservationKey:t})}async listMcp(e){let t=`/v1/mcp${i(e)}`,n=await this.request("GET",t);if(!n)throw new m("GET",t,404,"Not found");return n.servers??[]}async createMcp(e,t){let n=`/v1/mcp${i(e)}`,s=await this.request("POST",n,t);if(!s)throw new m("POST",n,404,"Not found");return s}async uploadMcpBundle(e){let n=await this.request("POST","/v1/mcp/uploads");if(!n?.uploadUrl)throw new m("POST","/v1/mcp/uploads",502,"response omitted uploadUrl");let s=await this.fetchImpl(n.uploadUrl,{method:"POST",headers:{"Content-Type":"application/javascript"},body:e});if(!s.ok)throw new m("POST","/v1/mcp/uploads",s.status,await s.text());let{storageId:r}=await s.json();if(!r)throw new m("POST","/v1/mcp/uploads",502,"upload response omitted storageId");let a=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(e)),c=Array.from(new Uint8Array(a)).map((l)=>l.toString(16).padStart(2,"0")).join("");return{bundleStorageId:r,sha256:c}}async getMcp(e){return await this.request("GET",`/v1/mcp/${encodeURIComponent(e)}`)}async updateMcp(e,t){return await this.request("PATCH",`/v1/mcp/${encodeURIComponent(e)}`,t)}async deleteMcp(e){return(await this.request("DELETE",`/v1/mcp/${encodeURIComponent(e)}`))?.deleted??!1}async listPolicies(){return(await this.request("GET","/v1/policies"))?.policies??[]}async createPolicy(e){let t=await this.request("POST","/v1/policies",e);if(!t)throw new m("POST","/v1/policies",404,"Not found");return t}async getPolicy(e){return await this.request("GET",`/v1/policies/${encodeURIComponent(e)}`)}async updatePolicy(e,t){return await this.request("PATCH",`/v1/policies/${encodeURIComponent(e)}`,t)}async deletePolicy(e){return(await this.request("DELETE",`/v1/policies/${encodeURIComponent(e)}`))?.deleted??!1}async listRoles(){return(await this.request("GET","/v1/roles"))?.roles??[]}async createRole(e){let t=await this.request("POST","/v1/roles",e);if(!t)throw new m("POST","/v1/roles",404,"Not found");return t}async getRole(e){return await this.request("GET",`/v1/roles/${encodeURIComponent(e)}`)}async updateRole(e,t){return await this.request("PATCH",`/v1/roles/${encodeURIComponent(e)}`,t)}async deleteRole(e){return(await this.request("DELETE",`/v1/roles/${encodeURIComponent(e)}`))?.deleted??!1}async listChannels(){return(await this.request("GET","/v1/channels"))?.channels??[]}async createChannel(e){let t=await this.request("POST","/v1/channels",e);if(!t)throw new m("POST","/v1/channels",404,"Not found");return t}async getChannel(e){return await this.request("GET",`/v1/channels/${encodeURIComponent(e)}`)}async updateChannel(e,t){return await this.request("PATCH",`/v1/channels/${encodeURIComponent(e)}`,t)}async deleteChannel(e){return(await this.request("DELETE",`/v1/channels/${encodeURIComponent(e)}`))?.deleted??!1}async listSkills(){return(await this.request("GET","/v1/skills"))?.skills??[]}async createSkill(e){let t=await this.request("POST","/v1/skills",e);if(!t)throw new m("POST","/v1/skills",404,"Not found");return t}async getSkill(e){return await this.request("GET",`/v1/skills/${encodeURIComponent(e)}`)}async uploadSkill(e,t){let n=`/v1/skills/${encodeURIComponent(e)}`,s=await this.request("PUT",n,t);if(!s)throw new m("PUT",n,404,"Skill not found");return s}async deleteSkill(e){return(await this.request("DELETE",`/v1/skills/${encodeURIComponent(e)}`))?.deleted??!1}async sandboxAction(e,t,n){let s=`/v1/sandboxes/${encodeURIComponent(e)}/${t}`,r=await this.request("POST",s,n);if(!r)throw new m("POST",s,404,"Sandbox not found");return r}async request(e,t,n){let s=await this.fetchImpl(`${this.baseUrl}${t}`,{method:e,headers:{Authorization:`Bearer ${this.bearerToken}`,...n!==void 0?{"Content-Type":"application/json"}:{}},...n!==void 0?{body:JSON.stringify(n)}:{}});if(s.status===404)return null;if(!s.ok)throw new m(e,t,s.status,await s.text());return await s.json()}}
2
- export{Ce,m,L,U};
File without changes