broods 0.33.2 → 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[];
@@ -505,6 +502,7 @@ interface SandboxNetworkConfig {
505
502
  */
506
503
  interface SandboxConfig {
507
504
  provider: SandboxProvider;
505
+ fallbackProvider?: SandboxProvider;
508
506
  size?: SandboxSize;
509
507
  snapshot?: string;
510
508
  runtimes?: RuntimeName[];
@@ -566,9 +564,6 @@ declare const API_POLICY_ACTIONS: readonly ["account:read", "account:write", "ag
566
564
  type AgentPolicyAction = (typeof AGENT_POLICY_ACTIONS)[number];
567
565
  type ApiPolicyAction = (typeof API_POLICY_ACTIONS)[number];
568
566
  type PolicyAction = AgentPolicyAction | ApiPolicyAction;
569
- /**
570
- * One optional predicate on a policy rule.
571
- */
572
567
  interface PolicyCondition {
573
568
  attribute: string;
574
569
  operator: PolicyConditionOperator;
@@ -585,9 +580,6 @@ interface PolicyDocument {
585
580
  rules: PolicyRule[];
586
581
  }
587
582
  type PolicyEffect = "allow" | "deny";
588
- /**
589
- * Resource selector fields supported by policy rules.
590
- */
591
583
  interface PolicyResourceSelector {
592
584
  toolNames?: string[];
593
585
  /** MCP registration ids, for scoping tool.call rules per server (#331). */
@@ -600,9 +592,6 @@ interface PolicyResourceSelector {
600
592
  /** Config-plane resource ids for API-action rules; "*" matches every id. */
601
593
  resourceIds?: string[];
602
594
  }
603
- /**
604
- * One allow/deny rule inside a policy document.
605
- */
606
595
  interface PolicyRule {
607
596
  id: string;
608
597
  effect: PolicyEffect;
@@ -612,7 +601,7 @@ interface PolicyRule {
612
601
  }
613
602
 
614
603
  /**
615
- * 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
616
605
  * normalizers core's `shared/domain/channel-record.ts` re-exports. Kept free
617
606
  * of Convex imports so the rules stay unit-testable; the public projection
618
607
  * lives in ./responses.ts.
@@ -621,10 +610,7 @@ interface PolicyRule {
621
610
  declare const CHANNEL_REPLY_TARGETS: readonly ["thread", "source"];
622
611
  type ChannelReplyIn = (typeof CHANNEL_REPLY_TARGETS)[number];
623
612
 
624
- /**
625
- * Telegram channel adapter implementated as a ChannelAdapter.
626
- * Implements Telegram auth, message normalization, and reply actions through the Chat SDK Telegram adapter.
627
- */
613
+ /** Telegram channel adapter. */
628
614
 
629
615
  interface TelegramSource {
630
616
  chatId: number;
@@ -637,8 +623,8 @@ interface TelegramSource {
637
623
  }
638
624
 
639
625
  /**
640
- * GitHub channel adapter.
641
- * 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.
642
628
  */
643
629
 
644
630
  interface GitHubSource {
@@ -653,10 +639,7 @@ interface GitHubSource {
653
639
  target: "issue" | "issue_comment" | "pull_request" | "pull_request_review_comment";
654
640
  }
655
641
 
656
- /**
657
- * Slack channel adapter.
658
- * Handle request verification, inbound normalization, and Slack Web API reply actions here.
659
- */
642
+ /** Slack channel adapter. */
660
643
 
661
644
  interface SlackSource {
662
645
  teamId: string;
@@ -671,10 +654,7 @@ interface SlackSource {
671
654
  userId?: string;
672
655
  }
673
656
 
674
- /**
675
- * Discord channel adapter.
676
- * Verify interaction signatures, normalize slash commands, and send replies through Chat SDK's Discord adapter.
677
- */
657
+ /** Discord channel adapter. */
678
658
 
679
659
  interface DiscordSource {
680
660
  applicationId: string;
@@ -690,7 +670,6 @@ interface DiscordSource {
690
670
 
691
671
  /**
692
672
  * Pancake channel adapter.
693
- * Keep Pancake webhook normalization and outbound message API calls here.
694
673
  *
695
674
  * Per-conversation policy (e.g. skipping human-owned conversations by tag) is
696
675
  * not baked in: the parsed source carries `tagIds` so a user `onMessageReceived`
@@ -709,10 +688,7 @@ interface PancakeSource {
709
688
  tagIds?: string[];
710
689
  }
711
690
 
712
- /**
713
- * Zalo channel adapter.
714
- * Keep official Zalo Bot API webhook normalization and outbound API calls here.
715
- */
691
+ /** Zalo channel adapter, on the official Zalo Bot API. */
716
692
 
717
693
  declare const ZALO_CHAT_TYPES: readonly ["PRIVATE", "GROUP"];
718
694
  type ZaloChatType = (typeof ZALO_CHAT_TYPES)[number];
@@ -727,7 +703,7 @@ interface ZaloSource {
727
703
  }
728
704
 
729
705
  /**
730
- * 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
731
707
  * backend (cliSync.ts, cliHttp.ts) and the SDK/CLI (packages/broods).
732
708
  *
733
709
  * This file is intentionally type-only with no runtime imports so the SDK can
@@ -935,20 +911,13 @@ interface Agent {
935
911
  agentId: string;
936
912
  name: string;
937
913
  }
938
- interface Sandbox {
939
- sandboxId: string;
940
- name: string;
941
- }
942
- interface Workspace {
943
- workspaceId: string;
944
- name: string;
945
- }
946
- /** A tool call held for user approval by an `ask`-mode sandbox. */
947
- interface ToolApprovalSummary {
948
- approvalId: string;
949
- toolCallId: string;
950
- toolName: string;
951
- 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";
952
921
  }
953
922
  interface AsyncStatus {
954
923
  status: "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "awaiting_input" | "completed" | "failed" | "expired" | "not_found";
@@ -963,14 +932,6 @@ interface AsyncStatus {
963
932
  approvals?: ToolApprovalSummary[];
964
933
  questions?: PendingQuestion[];
965
934
  }
966
- interface AsyncRequestAccepted {
967
- statusUrl: string;
968
- statusId: string;
969
- eventId: string;
970
- agentId: string;
971
- status?: "accepted" | "queued" | "applied" | "processing";
972
- requestedMode?: "reject" | "followup" | "collect" | "steer";
973
- }
974
935
  interface Cron {
975
936
  accountId: string;
976
937
  cronId: string;
@@ -1000,6 +961,10 @@ interface CronRun {
1000
961
  startedAt: string;
1001
962
  completedAt?: string;
1002
963
  }
964
+ interface Sandbox {
965
+ sandboxId: string;
966
+ name: string;
967
+ }
1003
968
  interface Skill {
1004
969
  path: string;
1005
970
  name: string;
@@ -1009,14 +974,25 @@ interface Skill {
1009
974
  size?: number;
1010
975
  }>;
1011
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
+ }
1012
988
 
1013
989
  /**
1014
990
  * Shared WebSocket wire-protocol types for the observability gateway, used by
1015
991
  * the gateway, the SDK/CLI, and the dashboard. Pure types + tiny pure helpers,
1016
992
  * zero runtime deps. Kept separate from the agent-test websocket-contracts.
1017
993
  */
1018
- type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
1019
994
  declare const MAX_OBSERVABILITY_BACKFILL = 500;
995
+ type LogLevel = "DEBUG" | "INFO" | "WARN" | "ERROR";
1020
996
  type ObservabilityLogEntry = {
1021
997
  ts: number;
1022
998
  level: LogLevel;
@@ -1058,7 +1034,11 @@ type ObservabilityUnsubscribeMessage = {
1058
1034
  type: "unsubscribe";
1059
1035
  stream: "logs" | "traces";
1060
1036
  };
1061
- type ObservabilityClientMessage = ObservabilitySubscribeMessage | ObservabilityUnsubscribeMessage;
1037
+ type ObservabilityFetchTraceMessage = {
1038
+ type: "fetchTrace";
1039
+ traceId: string;
1040
+ };
1041
+ type ObservabilityClientMessage = ObservabilitySubscribeMessage | ObservabilityUnsubscribeMessage | ObservabilityFetchTraceMessage;
1062
1042
  type ObservabilityReadyMessage = {
1063
1043
  type: "ready";
1064
1044
  };
@@ -1066,6 +1046,8 @@ type ObservabilityBackfillMessage = {
1066
1046
  type: "backfill";
1067
1047
  stream: "logs" | "traces";
1068
1048
  entries: ObservabilityLogEntry[] | ObservabilitySpanRow[];
1049
+ more?: boolean;
1050
+ error?: string;
1069
1051
  };
1070
1052
  type ObservabilityLogMessage = {
1071
1053
  type: "log";
@@ -1080,9 +1062,9 @@ type ObservabilityErrorMessage = {
1080
1062
  error: string;
1081
1063
  };
1082
1064
  type ObservabilityServerMessage = ObservabilityReadyMessage | ObservabilityBackfillMessage | ObservabilityLogMessage | ObservabilitySpanMessage | ObservabilityErrorMessage;
1083
- declare function isObservabilityClientMessage(v: unknown): v is ObservabilityClientMessage;
1084
1065
  /** Narrow an unknown wire value to a LogLevel. */
1085
1066
  declare function isLogLevel(value: unknown): value is LogLevel;
1067
+ declare function isObservabilityClientMessage(v: unknown): v is ObservabilityClientMessage;
1086
1068
  /** Whether a span is a top-level run, each of which owns its own trace. */
1087
1069
  declare function isRootSpanKind(kind: ObservabilitySpanRow["kind"]): boolean;
1088
1070
  /**
@@ -1090,6 +1072,8 @@ declare function isRootSpanKind(kind: ObservabilitySpanRow["kind"]): boolean;
1090
1072
  * interpolates it into LogQL, so only the UUID shape core mints may pass.
1091
1073
  */
1092
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;
1093
1077
 
1094
1078
  /**
1095
1079
  * Configurable client for running deployed agents over direct core SSE.
@@ -1099,7 +1083,7 @@ declare function isSandboxLogId(value: unknown): value is string;
1099
1083
  declare const DEFAULT_CORE_BASE_URL = "https://gateway.broods.app";
1100
1084
  /**
1101
1085
  * Input for a single agent run. The core direct API is event-based (a list of
1102
- * 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
1103
1087
  * for multimodal content (images/files), ephemeral system messages, or
1104
1088
  * tool-approval responses. `input` is a shorthand for a single user text message
1105
1089
  * and is wrapped into one user event. Provide exactly one of the two.
@@ -1194,8 +1178,8 @@ declare class BroodsClient {
1194
1178
  channelWebhookUrl(ref: ChannelReference): string;
1195
1179
  /**
1196
1180
  * Return the provider webhook URL for an account's channel. The URL names no
1197
- * agent — every channel of one type in an account shares it — so this is what
1198
- * 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.
1199
1183
  */
1200
1184
  accountWebhookUrl(accountId: string, channelType: ChannelReference["type"]): string;
1201
1185
  /**
@@ -1260,18 +1244,18 @@ declare function normalizeHttpServiceUrl(value: string): string;
1260
1244
  * This is the DYNAMIC counterpart to the config-first `broods dev` / `broods
1261
1245
  * deploy` flow: `broods dev` syncs the predefined resources declared in your
1262
1246
  * `broods/` folder, while `BroodsAccountClient` creates and mutates the full
1263
- * account config plane at runtime — agents, sandboxes (config + lifecycle),
1247
+ * account config plane at runtime: agents, sandboxes (config + lifecycle),
1264
1248
  * workspaces (config + files), tools, policies, skills, crons, and the account
1265
- * itself — e.g. a multi-tenant app provisioning one agent per customer from its
1266
- * own backend.
1249
+ * itself. One caller is a multi-tenant app provisioning one agent per customer
1250
+ * from its own backend.
1267
1251
  *
1268
1252
  * Kept intentionally standalone (import from `broods/account`): pure fetch,
1269
- * 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
1270
1254
  * runtimes such as Convex actions, Cloudflare Workers, and the browser-less
1271
1255
  * server runtimes, as well as Node and Bun.
1272
1256
  *
1273
1257
  * Auth: every call sends `Authorization: Bearer {accountSecret}` to
1274
- * `{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
1275
1259
  * `assumeRole()`, limited to what the role's policy allows. Secrets inside
1276
1260
  * agent configs are encrypted at rest by the platform and come back redacted
1277
1261
  * (`********`) on reads.
@@ -1319,8 +1303,6 @@ interface AccountEnvVar {
1319
1303
  name: string;
1320
1304
  updatedAt: number;
1321
1305
  }
1322
- /** Build a validated account env-var reference for use in an agent config. */
1323
- declare function envPlaceholder(name: string): string;
1324
1306
  /** Fields accepted by `PATCH /v1/agents/{id}`. `config` is deep-merged; `null` values delete keys. */
1325
1307
  interface UpdateAgentInput {
1326
1308
  name?: string;
@@ -1391,8 +1373,8 @@ interface AssumeRoleResult {
1391
1373
  expiresAt: string;
1392
1374
  }
1393
1375
  /**
1394
- * One real place a team talks — a Slack channel, a Discord channel, a repo —
1395
- * 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
1396
1378
  * answers there and with what instructions, workspaces and policies.
1397
1379
  */
1398
1380
  interface AccountChannel {
@@ -1423,14 +1405,14 @@ interface ChannelRecordConfig {
1423
1405
  /** Added to whatever the agent already carries. Each policy holds its own mode. */
1424
1406
  policies?: string[];
1425
1407
  /**
1426
- * 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,
1427
1409
  * so it also covers sandbox tools (`bash`, `read`, …) that `config.tools`
1428
1410
  * cannot name. Narrowing only; unknown names are ignored.
1429
1411
  */
1430
1412
  denyTools?: string[];
1431
1413
  /**
1432
1414
  * Where the reply lands. `source` answers wherever the message came from, and
1433
- * 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
1434
1416
  * gives the runtime a second place to reply.
1435
1417
  */
1436
1418
  replyIn?: ChannelReplyIn;
@@ -1559,6 +1541,8 @@ declare class BroodsAccountApiError extends Error {
1559
1541
  readonly body: string;
1560
1542
  constructor(method: string, path: string, status: number, body: string);
1561
1543
  }
1544
+ /** Build a validated account env-var reference for use in an agent config. */
1545
+ declare function envPlaceholder(name: string): string;
1562
1546
  /**
1563
1547
  * The credential the environment supplies, with a role session winning over
1564
1548
  * the account secret. The constructor throws through this same resolution, so
@@ -1845,6 +1829,7 @@ declare class BroodsWebSocketClient {
1845
1829
  buildUrl(input: Pick<WebSocketRunInput, "agent" | "endpointId" | "projectSlug" | "stageSlug">): string;
1846
1830
  private resolveWebSocket;
1847
1831
  }
1832
+ declare function toWebSocketBaseUrl(url: string): string;
1848
1833
  /**
1849
1834
  * The credential travels as a `Sec-WebSocket-Protocol` entry rather than in
1850
1835
  * the URL, so it never lands in proxy or access logs. The gateway answers
@@ -1853,15 +1838,10 @@ declare class BroodsWebSocketClient {
1853
1838
  */
1854
1839
  declare function webSocketSubprotocols(apiKey: string): string[];
1855
1840
 
1856
- declare function toWebSocketBaseUrl(url: string): string;
1857
-
1858
1841
  /**
1859
1842
  * Resource definition helpers for the code-first `broods/` project folder.
1860
1843
  *
1861
- * Layout: markers, then types (env refs, project config, resource primitives,
1862
- * per-kind config surfaces, per-kind resource aliases), then the env runtime
1863
- * value, the resource constructors, and the type guards. Every runtime function
1864
- * here is synchronous.
1844
+ * Every runtime function here is synchronous.
1865
1845
  */
1866
1846
 
1867
1847
  declare const RESOURCE_MARKER: unique symbol;
@@ -1919,7 +1899,7 @@ type SandboxDefinitionOptions = Record<string, unknown> & {
1919
1899
  reservationKey?: string;
1920
1900
  };
1921
1901
  /**
1922
- * Code-first sandbox config surface. Mirrors core's `SandboxConfig` but lets
1902
+ * Code-first sandbox config input. Mirrors core's `SandboxConfig` but lets
1923
1903
  * `envVars` values be `env("NAME")` references (compiled to `${NAME}` placeholders
1924
1904
  * at sync time, exactly like provider `apiKey`). Add overrides here if more
1925
1905
  * sandbox fields should accept env refs.
@@ -1945,14 +1925,14 @@ type PolicyDefinitionConfig = Omit<PolicyDocument, "version"> & {
1945
1925
  };
1946
1926
  /**
1947
1927
  * Fetch-style MCP handler for a hosted server: what
1948
- * `createMcpHandler(...)` from @modelcontextprotocol/server returns —
1949
- * 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`.
1950
1930
  */
1951
1931
  type McpHandler = ((request: Request) => Response | Promise<Response>) | {
1952
1932
  fetch(request: Request): Response | Promise<Response>;
1953
1933
  };
1954
1934
  /**
1955
- * MCP server registration (#331) — external (`url`) or hosted (`handler`).
1935
+ * MCP server registration (#331), either external (`url`) or hosted (`handler`).
1956
1936
  * Either way the server's tools are offered as `<name>__<tool>`; an external
1957
1937
  * row is dialed over the stateless HTTP transport (spec 2026-07-28) at agent
1958
1938
  * registration time. The name namespaces those tools, so it must be 1-32
@@ -1962,7 +1942,7 @@ interface McpDefinitionConfig {
1962
1942
  /** External server's MCP endpoint; http(s), no embedded credentials. */
1963
1943
  url?: string;
1964
1944
  /**
1965
- * Hosted alternative to `url`: declare the server inline —
1945
+ * Hosted alternative to `url`: declare the server inline as
1966
1946
  * `handler: createMcpHandler(...)` from @modelcontextprotocol/server,
1967
1947
  * right next to the `defineMcp` call. The CLI bundles the defining module
1968
1948
  * and the tool-runner Lambda hosts it, one invoke per batch of requests.
@@ -1970,8 +1950,8 @@ interface McpDefinitionConfig {
1970
1950
  handler?: McpHandler;
1971
1951
  /**
1972
1952
  * Extra request headers. Credential-bearing headers (Authorization,
1973
- * X-Api-Key, ...) must reference an account env var — e.g.
1974
- * `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.
1975
1955
  */
1976
1956
  headers?: Record<string, string>;
1977
1957
  /**
@@ -2052,8 +2032,8 @@ type ZaloConnectionDefinition = ConnectionDefinition<"zalo", ZaloConnectionInput
2052
2032
  type AnyConnectionDefinition = TelegramConnectionDefinition | GitHubConnectionDefinition | SlackConnectionDefinition | DiscordConnectionDefinition | PancakeConnectionDefinition | ZaloConnectionDefinition;
2053
2033
  /**
2054
2034
  * One real place a team talks: a Slack channel, a Discord channel, a repo. It
2055
- * narrows and adds — instructions append, policies union, tools and workspaces
2056
- * 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
2057
2037
  * connection it belongs to, so `platform` is never written by hand.
2058
2038
  */
2059
2039
  type ChannelDefinitionConfig = {
@@ -2148,8 +2128,8 @@ interface HookContext {
2148
2128
  config: Record<string, unknown>;
2149
2129
  /**
2150
2130
  * Mutable per-request scratchpad shared across this agent request's hooks.
2151
- * Seed it in an early hook (e.g. `onStart`) and read or modify it later —
2152
- * 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`
2153
2133
  * see the same state. Keep it JSON-serializable. `onMessageReceived`,
2154
2134
  * delayed background replies, and each subagent's own run get fresh state.
2155
2135
  */
@@ -2205,7 +2185,7 @@ type ChannelMessageReceived = {
2205
2185
  * preferred so the serialized source is valid as an object-literal value.
2206
2186
  *
2207
2187
  * Subagent runs fire hooks too: a registered subagent runs its own hooks, a
2208
- * prompt-only (virtual) subagent inherits this bundle — always with fresh
2188
+ * prompt-only (virtual) subagent inherits this bundle, always with fresh
2209
2189
  * `ctx.state`. `onSubagentFinish` fires on the parent with the parent's state.
2210
2190
  */
2211
2191
  interface AgentHooks {
@@ -2269,9 +2249,9 @@ interface AgentHooks {
2269
2249
  }>;
2270
2250
  }
2271
2251
  /**
2272
- * 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`
2273
2253
  * (not `Omit`) so the SDK input type does NOT inherit `AgentConfig`'s
2274
- * `[key: string]: unknown` index signature — which would otherwise disable
2254
+ * `[key: string]: unknown` index signature, which would otherwise disable
2275
2255
  * TypeScript's excess-property checks and silently accept typos like
2276
2256
  * `workspace:` instead of `workspaces:`. Add a key here when core's `AgentConfig`
2277
2257
  * gains a new top-level field that should be code-definable.
@@ -2308,8 +2288,8 @@ type AgentDefinitionConfig = EnvRefString<Pick<AgentConfig, "agent" | "model" |
2308
2288
  policies?: readonly (PolicyResource | string)[];
2309
2289
  /**
2310
2290
  * Opt the agent into the public runtime endpoint (SSE/WebSocket via the
2311
- * stage runtime key). Off by default — secured: when unset the public
2312
- * 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
2313
2293
  * internal endpoint or a channel webhook. See issue #65.
2314
2294
  */
2315
2295
  publicAccess?: boolean;
@@ -2320,8 +2300,8 @@ type CronDefinitionConfig = Omit<CreateCronInput, "agentId" | "name"> & {
2320
2300
  type AgentResource<Name extends string = string> = ResourceDefinition<"agent", Name, AgentDefinitionConfig>;
2321
2301
  /**
2322
2302
  * Code-first workspace config. Says `partitioned` where storage says
2323
- * `isolation`: the flag permits a split, it does not perform one — a channel's
2324
- * `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.
2325
2305
  */
2326
2306
  type WorkspaceDefinitionConfig = Omit<WorkspaceConfig, "isolation"> & {
2327
2307
  /** Allow this workspace to be split into per-conversation folders. */
@@ -2336,8 +2316,8 @@ type CronResource<Name extends string = string> = ResourceDefinition<"cron", Nam
2336
2316
  type ChannelResource<Name extends string = string> = ResourceDefinition<"channelRecord", Name, ChannelDefinitionConfig>;
2337
2317
  type AnyResource = AgentResource | WorkspaceResource | SandboxResource | CronResource | SkillResource | McpResource | PolicyResource | ChannelResource;
2338
2318
  /**
2339
- * References an account/environment variable resolved on the SERVER at runtime —
2340
- * 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
2341
2321
  * `convex env set` model). It is a deferred reference, never read from your local
2342
2322
  * environment and never baked into the deployed config:
2343
2323
  *
@@ -2353,6 +2333,21 @@ type AnyResource = AgentResource | WorkspaceResource | SandboxResource | CronRes
2353
2333
  * pushes matching `.env.local` values first, so a local value is enough there.
2354
2334
  */
2355
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>;
2356
2351
  declare function defineDiscordConnection(config: DiscordConnectionInput): DiscordConnectionDefinition;
2357
2352
  declare function defineGitHubConnection(config: GitHubConnectionInput): GitHubConnectionDefinition;
2358
2353
  declare function definePancakeConnection(config: PancakeConnectionInput): PancakeConnectionDefinition;
@@ -2365,18 +2360,9 @@ declare function definePancakeChannel<const Name extends string>(input: Resource
2365
2360
  declare function defineSlackChannel<const Name extends string>(input: ResourceInput<Name, SlackChannelInput>): ChannelResource<Name>;
2366
2361
  declare function defineTelegramChannel<const Name extends string>(input: ResourceInput<Name, TelegramChannelInput>): ChannelResource<Name>;
2367
2362
  declare function defineZaloChannel<const Name extends string>(input: ResourceInput<Name, ZaloChannelInput>): ChannelResource<Name>;
2368
- declare function defineBroods(config: BroodsProjectConfig): BroodsConfigDefinition;
2369
- declare function defineAgent<const Name extends string>(input: ResourceInput<Name, AgentDefinitionConfig>): AgentResource<Name>;
2370
- declare function defineHarness<const Definition extends HarnessDefinition>(definition: Definition): Definition;
2371
- declare function defineWorkspace<const Name extends string>(input: ResourceInput<Name, WorkspaceDefinitionConfig>): WorkspaceResource<Name>;
2372
- declare function defineSandbox<const Name extends string>(input: ResourceInput<Name, SandboxDefinitionConfig>): SandboxResource<Name>;
2373
- declare function defineSkill<const Name extends string>(input: ResourceInput<Name, SkillDefinitionConfig>): SkillResource<Name>;
2374
- declare function defineMcp<const Name extends string>(input: ResourceInput<Name, McpDefinitionConfig>): McpResource<Name>;
2375
- declare function definePolicy<const Name extends string>(input: ResourceInput<Name, PolicyDefinitionConfig>): PolicyResource<Name>;
2376
- declare function defineCron<const Name extends string>(input: ResourceInput<Name, CronDefinitionConfig>): CronResource<Name>;
2377
- declare function isResource(value: unknown): value is AnyResource;
2378
- declare function isConnectionDefinition(value: unknown): value is AnyConnectionDefinition;
2379
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;
2380
2366
 
2381
- 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, normalizeHttpServiceUrl, readSseStream, resolveEnvCredential, resolveRunEvents, toWebSocketBaseUrl, webSocketSubprotocols };
2382
- 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, 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 };
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 };
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,Ce,xe,Te,ke,V,C,me,q,W,Ie,D,K,Pe,Me,Ae,ze,Oe,Ne,je,qe,De,Le,Ue,Fe,Be,Ve,Ze,He,We,Ke,Ge,Je,Ye,Xe,h,_,ne}from"./chunk-pvpa68ca.js";import{$e,m,L,U}from"./chunk-0622rd68.js";export{m as BroodsAccountApiError,U as BroodsAccountClient,q as BroodsClient,Ie as BroodsWebSocketClient,C as DEFAULT_CORE_BASE_URL,me as IngressAcceptedError,Ce as MAX_OBSERVABILITY_BACKFILL,Ie as WebSocketClient,Ie as WebsocketClient,Ze as defineAgent,Ve as defineBroods,Xe as defineCron,qe as defineDiscordChannel,Me as defineDiscordConnection,De as defineGitHubChannel,Ae as defineGitHubConnection,He as defineHarness,Je as defineMcp,Le as definePancakeChannel,ze as definePancakeConnection,Ye as definePolicy,Ke as defineSandbox,Ge as defineSkill,Ue as defineSlackChannel,Oe as defineSlackConnection,Fe as defineTelegramChannel,Ne as defineTelegramConnection,We as defineWorkspace,Be as defineZaloChannel,je as defineZaloConnection,Pe as env,$e as envPlaceholder,ne as isBroodsConfig,_ as isConnectionDefinition,Te as isLogLevel,xe as isObservabilityClientMessage,h as isResource,ke as isRootSpanKind,V as isSandboxLogId,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.2",
3
+ "version": "0.33.4",
4
4
  "description": "CLI + TypeScript SDK for the broods agent platform.",
5
5
  "keywords": [
6
6
  "agents",
@@ -1,2 +0,0 @@
1
- var u=/^[A-Z][A-Z0-9_]*$/;function $e(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{$e,m,L,U};
@@ -1 +0,0 @@
1
- import{N}from"./chunk-ttrs3r94.js";import{L,U}from"./chunk-0622rd68.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};