broods 0.49.3 → 0.50.0

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
@@ -888,10 +888,14 @@ declare const WORKSPACE_STORAGE_PROVIDERS: readonly ["s3"];
888
888
  type WorkspaceStorageProvider = (typeof WORKSPACE_STORAGE_PROVIDERS)[number];
889
889
  type WorkspaceStorageAuth = {
890
890
  type: "managed";
891
- } | {
891
+ }
892
+ /**
893
+ * The role's trust policy requires the account's Broods-assigned
894
+ * sts:ExternalId (`storageTrust.ts`); a customer never sets one here.
895
+ */
896
+ | {
892
897
  type: "assumeRole";
893
898
  roleArn: string;
894
- externalId?: string;
895
899
  } | {
896
900
  type: "r2";
897
901
  /** `${NAME}` ref to the parent R2 token's access key id. */
@@ -1774,6 +1778,13 @@ interface BroodsClientOptions {
1774
1778
  host?: string;
1775
1779
  /** Runtime key used as the Bearer token for direct runtime calls. */
1776
1780
  apiKey?: string;
1781
+ /**
1782
+ * The signed-in user's token, sent beside the runtime key on every call.
1783
+ * Pass a function to get a fresh one per call (a browser fetches it from
1784
+ * your backend, which signs it with `signUserToken`). An agent that
1785
+ * requires one refuses the runtime key without it.
1786
+ */
1787
+ userToken?: string | (() => string | Promise<string>);
1777
1788
  fetch?: typeof fetch;
1778
1789
  }
1779
1790
  type AgentHandle = {
@@ -1786,6 +1797,7 @@ type AgentHandle = {
1786
1797
  declare class BroodsClient {
1787
1798
  private readonly baseUrl;
1788
1799
  private readonly apiKey?;
1800
+ private readonly userToken?;
1789
1801
  private readonly fetchImpl;
1790
1802
  constructor(options?: BroodsClientOptions);
1791
1803
  /** Return the public provider webhook URL for a generated channel reference. */
@@ -1848,11 +1860,52 @@ declare class BroodsClient {
1848
1860
  private openStream;
1849
1861
  private fetchCore;
1850
1862
  private apiKeyHeaders;
1863
+ private userTokenHeaders;
1851
1864
  private fetchJson;
1852
1865
  private resolveStatusUrl;
1853
1866
  }
1854
1867
  declare function normalizeHttpServiceUrl(value: string): string;
1855
1868
 
1869
+ /** The HTTP header a token rides on. */
1870
+ declare const USER_TOKEN_HEADER = "x-broods-user-token";
1871
+ /** A token naming a later expiry is refused: it is a bearer for its whole life. */
1872
+ declare const USER_TOKEN_MAX_TTL_MS: number;
1873
+
1874
+ /**
1875
+ * Server-side signing of end-user tokens. The runtime key (`bsk_`) sits in a
1876
+ * frontend, so it cannot say who is using it; your backend, which knows the
1877
+ * signed-in user, signs a short-lived token with the stage's signing secret
1878
+ * (`bsig_`, from the dashboard's Runtime key tab) and hands it to the
1879
+ * frontend. Core then keeps every conversation that request touches under
1880
+ * that user, so one visitor can never read or steer another's. Never ship the
1881
+ * signing secret to a browser.
1882
+ */
1883
+
1884
+ /**
1885
+ * The env var `signUserToken` reads the signing secret from, and the one
1886
+ * `broods dev` / `broods deploy` write it to in `.env.local`.
1887
+ */
1888
+ declare const USER_TOKEN_SECRET_ENV = "BROODS_USER_TOKEN_SECRET";
1889
+ interface SignUserTokenInput {
1890
+ /** Your own id for the signed-in user. Letters, digits and `._@+=-`, at most 128. */
1891
+ userId: string;
1892
+ /**
1893
+ * The conversation keys this user may use. Omit to allow any key, which
1894
+ * still lands under this user only.
1895
+ */
1896
+ conversations?: string[];
1897
+ /** Lifetime in ms. Defaults to 10 minutes, at most 60. */
1898
+ ttlMs?: number;
1899
+ /** The stage's `bsig_` signing secret. Defaults to `BROODS_USER_TOKEN_SECRET`. */
1900
+ secret?: string;
1901
+ }
1902
+ /**
1903
+ * A user token for the runtime key: pass it as `userToken` to `BroodsClient`
1904
+ * or `BroodsWebSocketClient`, or send it in the `X-Broods-User-Token` header.
1905
+ * @throws when no signing secret is set or an input is out of range
1906
+ */
1907
+ declare function signUserToken(input: SignUserTokenInput): Promise<string>;
1908
+
1856
1909
  /**
1857
1910
  * Connections: external accounts an agent acts through, one of each type per
1858
1911
  * Broods account. `broods connect <type>` opens the provider's sign-in; the
@@ -2285,6 +2338,18 @@ interface RotateSecretResult {
2285
2338
  account: BroodsAccount;
2286
2339
  secret: string;
2287
2340
  }
2341
+ /**
2342
+ * Result of `GET /v1/account/storage-trust`: what a workspace's own AWS role
2343
+ * must trust. Broods assigns `externalId` per account and sends it on every
2344
+ * AssumeRole of an `assumeRole` workspace's role; it is never set in config.
2345
+ */
2346
+ interface StorageTrust {
2347
+ externalId: string;
2348
+ /** The Broods AWS principal to trust; absent on a deployment with no AWS. */
2349
+ principalArn?: string;
2350
+ /** A ready-to-paste trust policy JSON; absent on a deployment with no AWS. */
2351
+ trustPolicy?: string;
2352
+ }
2288
2353
  /** Result of `DELETE /v1/account`: the account and all account-scoped data are removed; `cleanup` reports per-resource deletion counts. */
2289
2354
  interface DeleteAccountResult {
2290
2355
  deleted: boolean;
@@ -2334,6 +2399,8 @@ declare class BroodsAccountClient {
2334
2399
  constructor(options?: BroodsAccountClientOptions);
2335
2400
  /** The account this secret belongs to. Its `accountId` is the first segment of channel webhook URLs. */
2336
2401
  getAccount(): Promise<BroodsAccount>;
2402
+ /** The external id and Broods principal this account's own storage roles must trust. */
2403
+ getStorageTrust(): Promise<StorageTrust>;
2337
2404
  /** Update account metadata (username/description). Returns null when the account is gone. Runtime config is managed through the agent endpoints. */
2338
2405
  updateAccount(patch: {
2339
2406
  username?: string;
@@ -2444,7 +2511,7 @@ declare class BroodsAccountClient {
2444
2511
  resumeSandbox(sandboxId: string, reservationKey: string): Promise<SandboxLifecycleResult>;
2445
2512
  /** Terminate a persistent sandbox reservation and drop its live-instance row. Throws on 404/403/409. */
2446
2513
  terminateSandbox(sandboxId: string, reservationKey: string): Promise<SandboxLifecycleResult>;
2447
- /** Snapshot a persistent sandbox reservation into an image any sandbox of that provider can pin with `snapshot` (`sandbox`, `daytona`, `e2b`, `vercel`, or `lambda`, which answers `building` until its image build lands). Throws on 404/403/409. */
2514
+ /** Snapshot a persistent sandbox reservation into an image any sandbox of that provider on the same stage can pin with `snapshot` (`sandbox`, `daytona`, `e2b`, `vercel`, or `lambda`, which answers `building` until its image build lands). The snapshot is locked to the stage of the sandbox it was taken from: pinning it on another stage throws a 400. Throws on 404/403/409. */
2448
2515
  snapshotSandbox(sandboxId: string, reservationKey: string, name: string): Promise<SandboxSnapshotResult>;
2449
2516
  /** Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox (`sandbox`/`lambda`/`cloudflare` providers). Throws on 404/403/409. */
2450
2517
  openSandboxTerminal(sandboxId: string, reservationKey: string): Promise<SandboxTerminalTicket>;
@@ -2570,6 +2637,8 @@ type WebSocketRunInput = {
2570
2637
  /** Defaults to "steer": join the live run at its next step boundary. */
2571
2638
  mode?: "reject" | "followup" | "collect" | "steer";
2572
2639
  idempotencyKey?: string;
2640
+ /** This socket's user token, over the client's `userToken`. */
2641
+ userToken?: string;
2573
2642
  } & (AgentRunEventInput | AgentRunAnswerInput) & AgentRunOverrides;
2574
2643
  type WebSocketAttachInput = Omit<WebSocketClientAttachMessage, "type"> & {
2575
2644
  endpointId?: string;
@@ -2577,6 +2646,8 @@ type WebSocketAttachInput = Omit<WebSocketClientAttachMessage, "type"> & {
2577
2646
  projectSlug?: string;
2578
2647
  stageSlug?: string;
2579
2648
  signal?: AbortSignal;
2649
+ /** This socket's user token, over the client's `userToken`. */
2650
+ userToken?: string;
2580
2651
  };
2581
2652
  interface WebSocketHandlers {
2582
2653
  /**
@@ -2605,6 +2676,13 @@ interface BroodsWebSocketClientOptions {
2605
2676
  host?: string;
2606
2677
  /** Runtime key used as the WebSocket token. Defaults to BROODS_API_KEY from the environment or local .env files. */
2607
2678
  apiKey?: string;
2679
+ /**
2680
+ * The signed-in user's token (from `signUserToken` on your backend). Each
2681
+ * socket carries it from its upgrade on; an agent that requires one refuses
2682
+ * the runtime key without it. Tokens are short-lived, so a long-lived client
2683
+ * passes a fresh one per run as `userToken` on the input instead.
2684
+ */
2685
+ userToken?: string;
2608
2686
  WebSocket?: WebSocketConstructorLike;
2609
2687
  connectTimeoutMs?: number;
2610
2688
  }
@@ -2628,6 +2706,7 @@ interface WebSocketLike {
2628
2706
  declare class BroodsWebSocketClient {
2629
2707
  private readonly baseUrl;
2630
2708
  private readonly apiKey;
2709
+ private readonly userToken?;
2631
2710
  private readonly WebSocketImpl?;
2632
2711
  private readonly connectTimeoutMs;
2633
2712
  constructor(options?: BroodsWebSocketClientOptions);
@@ -2641,11 +2720,11 @@ declare class BroodsWebSocketClient {
2641
2720
  declare function toWebSocketBaseUrl(url: string): string;
2642
2721
  /**
2643
2722
  * The credential travels as a `Sec-WebSocket-Protocol` entry rather than in
2644
- * the URL, so it never lands in proxy or access logs. The gateway answers
2645
- * with `broods.v1`, which is what completes a handshake that offered
2646
- * subprotocols.
2723
+ * the URL, so it never lands in proxy or access logs, and so does the user
2724
+ * token. The gateway answers with `broods.v1`, which is what completes a
2725
+ * handshake that offered subprotocols.
2647
2726
  */
2648
- declare function webSocketSubprotocols(apiKey: string): string[];
2727
+ declare function webSocketSubprotocols(apiKey: string, userToken?: string): string[];
2649
2728
 
2650
2729
  /**
2651
2730
  * Resource definition helpers for the code-first `broods/` project folder.
@@ -3340,5 +3419,5 @@ declare function isBroodsConfig(value: unknown): value is BroodsConfigDefinition
3340
3419
  declare function isConnectionDefinition(value: unknown): value is AnyConnectionDefinition;
3341
3420
  declare function isResource(value: unknown): value is AnyResource;
3342
3421
 
3343
- 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, defineGoogleChatChannel, defineGoogleChatConnection, defineHarness, defineInstagramChannel, defineInstagramConnection, defineLinearChannel, defineLinearConnection, defineMatrixChannel, defineMatrixConnection, defineMcp, defineMessengerChannel, defineMessengerConnection, definePancakeChannel, definePancakeConnection, definePolicy, defineSandbox, defineSkill, defineSlackChannel, defineSlackConnection, defineTeamsChannel, defineTeamsConnection, defineTelegramChannel, defineTelegramConnection, defineTwilioChannel, defineTwilioConnection, defineWhatsAppChannel, defineWhatsAppConnection, defineWorkspace, defineZaloChannel, defineZaloConnection, env, envPlaceholder, isBroodsConfig, isConnectionDefinition, isLogLevel, isObservabilityClientMessage, isResource, isRootSpanKind, isSandboxLogId, isTraceId, normalizeHttpServiceUrl, readSseStream, resolveEnvCredential, resolveRunEvents, toWebSocketBaseUrl, webSocketSubprotocols };
3344
- export type { Account, AccountAgent, AccountChannel, AccountEnvVar, AccountMcp, AccountPolicy, AccountRole, AccountSandbox, AccountWorkspace, Agent, AgentChannelsConfig, AgentCodeHookConfig, AgentConfig, AgentConfigDoc, AgentContinueInput, AgentDefinitionConfig, AgentDiscordChannelConfig, AgentGitHubChannelConfig, AgentGoogleChatChannelConfig, AgentHandle, AgentHookEventName, AgentHooks, AgentHooksConfig, AgentInstagramChannelConfig, AgentLinearChannelConfig, AgentMatrixChannelConfig, AgentMessengerChannelConfig, AgentPancakeChannelConfig, AgentProviderSettings, AgentReference, AgentResource, AgentRunAnswerInput, AgentRunEventInput, AgentRunInput, AgentRunModelOverrides, AgentRunOverrides, AgentRunResult, AgentSkillsDefinitionConfig, AgentSlackChannelConfig, AgentStreamPart, AgentSubagentDefinitionConfig, AgentTeamsChannelConfig, AgentTelegramChannelConfig, AgentTwilioChannelConfig, AgentWebhookHookConfig, AgentWhatsAppChannelConfig, AgentWorkspaceInput, AgentWorkspaceRef, AgentWorkspaceRefInput, AgentZaloChannelConfig, AnyConnectionDefinition, AnyResource, AssumeRoleResult, AsyncAgentRun, AsyncPollOptions, AsyncRequestAccepted, AsyncStatus, AuditEvent, AuditPage, AuditPrincipalLink, AuditSink, AuditVerification, BroodsAccount, BroodsAccountClientOptions, BroodsClientOptions, BroodsConfigDefinition, BroodsProjectConfig, BroodsWebSocketClientOptions, ChannelAgentInput, ChannelDefinitionConfig, ChannelMessageReceived, ChannelPartition, ChannelRecordConfig, ChannelReference, ChannelReplyIn, ChannelResource, ChannelType, CliManifest, CliManifestResource, ConfigPatch, Connection, ConnectionCode, ConnectionDefinition, ConnectionStart, ConnectionStartResult, ConnectionType, CreateAgentResult, 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, GoogleChatChannelInput, GoogleChatConnectionDefinition, GoogleChatConnectionInput, GoogleChatMessageSource, GoogleChatSource, HarnessDefinition, HarnessType, HookAgentConfig, HookContext, Id, IngressMode, IngressStatus, InstagramChannelInput, InstagramConnectionDefinition, InstagramConnectionInput, InstagramMessageSource, InstagramSource, LinearChannelInput, LinearConnectionDefinition, LinearConnectionInput, LinearMessageSource, LinearSource, LogLevel, MatrixChannelInput, MatrixConnectionDefinition, MatrixConnectionInput, MatrixMessageSource, MatrixSource, McpDefinitionConfig, McpHandler, McpOauthInput, McpResource, McpRuntime, MessengerChannelInput, MessengerConnectionDefinition, MessengerConnectionInput, MessengerMessageSource, MessengerSource, ObservabilityBackfillMessage, ObservabilityClientMessage, ObservabilityErrorMessage, ObservabilityFetchTraceMessage, ObservabilityLogEntry, ObservabilityLogMessage, ObservabilityReadyMessage, ObservabilityServerMessage, ObservabilitySpanMessage, ObservabilitySpanRow, ObservabilitySubscribeMessage, ObservabilityUnsubscribeMessage, PancakeChannelInput, PancakeConnectionDefinition, PancakeConnectionInput, PancakeMessageSource, PancakeSource, PendingQuestion, PolicyDefinitionConfig, PolicyDocument, PolicyResource, ProjectDoc, ProviderConfigInput, ProviderSettingsInput, QuestionAnswer, ResourceApi, ResourceDefinition, ResourceInput, ResourceKind, RotateSecretResult, Sandbox, SandboxConfig, SandboxConfigDoc, SandboxDefinitionConfig, SandboxDefinitionOptions, SandboxExecRequest, SandboxExecResponse, SandboxLifecycleResult, SandboxProvider, SandboxResource, SandboxSnapshotResult, SandboxTerminalTicket, Skill, SkillDefinitionConfig, SkillResource, SkillUploadInput, SlackChannelInput, SlackConnectionDefinition, SlackConnectionInput, SlackMessageSource, SlackSource, StageDoc, StageScope, TaskWaitingOn, TeamsChannelInput, TeamsConnectionDefinition, TeamsConnectionInput, TeamsMessageSource, TeamsSource, TelegramChannelInput, TelegramConnectionDefinition, TelegramConnectionInput, TelegramMessageSource, TelegramSource, ToolApprovalSummary, TwilioChannelInput, TwilioConnectionDefinition, TwilioConnectionInput, TwilioMessageSource, TwilioSource, UpdateAgentInput, UpdateCronInput, UpdateMcpInput, WebSocketAttachInput, WebSocketClientAttachMessage, WebSocketClientCancelMessage, WebSocketClientControlMessage, WebSocketClientExecuteMessage, WebSocketClientMessage, WebSocketConstructorLike, WebSocketHandlers, WebSocketLike, WebSocketOutputMessage, WebSocketRunInput, WebSocketServerMessage, WebSocketStreamMessage, WebSocketSubscription, WhatsAppChannelInput, WhatsAppConnectionDefinition, WhatsAppConnectionInput, WhatsAppMessageSource, WhatsAppSource, Workspace, WorkspaceConfig, WorkspaceConfigDoc, WorkspaceDefinitionConfig, WorkspaceFileEntry, WorkspaceIsolation, WorkspaceResource, WorkspaceStorageDefinition, ZaloChannelInput, ZaloConnectionDefinition, ZaloConnectionInput, ZaloMessageSource, ZaloSource };
3422
+ export { BroodsAccountApiError, BroodsAccountClient, BroodsClient, BroodsWebSocketClient, DEFAULT_CORE_BASE_URL, IngressAcceptedError, MAX_OBSERVABILITY_BACKFILL, USER_TOKEN_HEADER, USER_TOKEN_MAX_TTL_MS, USER_TOKEN_SECRET_ENV, BroodsWebSocketClient as WebSocketClient, BroodsWebSocketClient as WebsocketClient, defineAgent, defineBroods, defineCron, defineDiscordChannel, defineDiscordConnection, defineGitHubChannel, defineGitHubConnection, defineGoogleChatChannel, defineGoogleChatConnection, defineHarness, defineInstagramChannel, defineInstagramConnection, defineLinearChannel, defineLinearConnection, defineMatrixChannel, defineMatrixConnection, defineMcp, defineMessengerChannel, defineMessengerConnection, definePancakeChannel, definePancakeConnection, definePolicy, defineSandbox, defineSkill, defineSlackChannel, defineSlackConnection, defineTeamsChannel, defineTeamsConnection, defineTelegramChannel, defineTelegramConnection, defineTwilioChannel, defineTwilioConnection, defineWhatsAppChannel, defineWhatsAppConnection, defineWorkspace, defineZaloChannel, defineZaloConnection, env, envPlaceholder, isBroodsConfig, isConnectionDefinition, isLogLevel, isObservabilityClientMessage, isResource, isRootSpanKind, isSandboxLogId, isTraceId, normalizeHttpServiceUrl, readSseStream, resolveEnvCredential, resolveRunEvents, signUserToken, toWebSocketBaseUrl, webSocketSubprotocols };
3423
+ export type { Account, AccountAgent, AccountChannel, AccountEnvVar, AccountMcp, AccountPolicy, AccountRole, AccountSandbox, AccountWorkspace, Agent, AgentChannelsConfig, AgentCodeHookConfig, AgentConfig, AgentConfigDoc, AgentContinueInput, AgentDefinitionConfig, AgentDiscordChannelConfig, AgentGitHubChannelConfig, AgentGoogleChatChannelConfig, AgentHandle, AgentHookEventName, AgentHooks, AgentHooksConfig, AgentInstagramChannelConfig, AgentLinearChannelConfig, AgentMatrixChannelConfig, AgentMessengerChannelConfig, AgentPancakeChannelConfig, AgentProviderSettings, AgentReference, AgentResource, AgentRunAnswerInput, AgentRunEventInput, AgentRunInput, AgentRunModelOverrides, AgentRunOverrides, AgentRunResult, AgentSkillsDefinitionConfig, AgentSlackChannelConfig, AgentStreamPart, AgentSubagentDefinitionConfig, AgentTeamsChannelConfig, AgentTelegramChannelConfig, AgentTwilioChannelConfig, AgentWebhookHookConfig, AgentWhatsAppChannelConfig, AgentWorkspaceInput, AgentWorkspaceRef, AgentWorkspaceRefInput, AgentZaloChannelConfig, AnyConnectionDefinition, AnyResource, AssumeRoleResult, AsyncAgentRun, AsyncPollOptions, AsyncRequestAccepted, AsyncStatus, AuditEvent, AuditPage, AuditPrincipalLink, AuditSink, AuditVerification, BroodsAccount, BroodsAccountClientOptions, BroodsClientOptions, BroodsConfigDefinition, BroodsProjectConfig, BroodsWebSocketClientOptions, ChannelAgentInput, ChannelDefinitionConfig, ChannelMessageReceived, ChannelPartition, ChannelRecordConfig, ChannelReference, ChannelReplyIn, ChannelResource, ChannelType, CliManifest, CliManifestResource, ConfigPatch, Connection, ConnectionCode, ConnectionDefinition, ConnectionStart, ConnectionStartResult, ConnectionType, CreateAgentResult, 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, GoogleChatChannelInput, GoogleChatConnectionDefinition, GoogleChatConnectionInput, GoogleChatMessageSource, GoogleChatSource, HarnessDefinition, HarnessType, HookAgentConfig, HookContext, Id, IngressMode, IngressStatus, InstagramChannelInput, InstagramConnectionDefinition, InstagramConnectionInput, InstagramMessageSource, InstagramSource, LinearChannelInput, LinearConnectionDefinition, LinearConnectionInput, LinearMessageSource, LinearSource, LogLevel, MatrixChannelInput, MatrixConnectionDefinition, MatrixConnectionInput, MatrixMessageSource, MatrixSource, McpDefinitionConfig, McpHandler, McpOauthInput, McpResource, McpRuntime, MessengerChannelInput, MessengerConnectionDefinition, MessengerConnectionInput, MessengerMessageSource, MessengerSource, ObservabilityBackfillMessage, ObservabilityClientMessage, ObservabilityErrorMessage, ObservabilityFetchTraceMessage, ObservabilityLogEntry, ObservabilityLogMessage, ObservabilityReadyMessage, ObservabilityServerMessage, ObservabilitySpanMessage, ObservabilitySpanRow, ObservabilitySubscribeMessage, ObservabilityUnsubscribeMessage, PancakeChannelInput, PancakeConnectionDefinition, PancakeConnectionInput, PancakeMessageSource, PancakeSource, PendingQuestion, PolicyDefinitionConfig, PolicyDocument, PolicyResource, ProjectDoc, ProviderConfigInput, ProviderSettingsInput, QuestionAnswer, ResourceApi, ResourceDefinition, ResourceInput, ResourceKind, RotateSecretResult, Sandbox, SandboxConfig, SandboxConfigDoc, SandboxDefinitionConfig, SandboxDefinitionOptions, SandboxExecRequest, SandboxExecResponse, SandboxLifecycleResult, SandboxProvider, SandboxResource, SandboxSnapshotResult, SandboxTerminalTicket, SignUserTokenInput, Skill, SkillDefinitionConfig, SkillResource, SkillUploadInput, SlackChannelInput, SlackConnectionDefinition, SlackConnectionInput, SlackMessageSource, SlackSource, StageDoc, StageScope, StorageTrust, TaskWaitingOn, TeamsChannelInput, TeamsConnectionDefinition, TeamsConnectionInput, TeamsMessageSource, TeamsSource, TelegramChannelInput, TelegramConnectionDefinition, TelegramConnectionInput, TelegramMessageSource, TelegramSource, ToolApprovalSummary, TwilioChannelInput, TwilioConnectionDefinition, TwilioConnectionInput, TwilioMessageSource, TwilioSource, UpdateAgentInput, UpdateCronInput, UpdateMcpInput, WebSocketAttachInput, WebSocketClientAttachMessage, WebSocketClientCancelMessage, WebSocketClientControlMessage, WebSocketClientExecuteMessage, WebSocketClientMessage, WebSocketConstructorLike, WebSocketHandlers, WebSocketLike, WebSocketOutputMessage, WebSocketRunInput, WebSocketServerMessage, WebSocketStreamMessage, WebSocketSubscription, WhatsAppChannelInput, WhatsAppConnectionDefinition, WhatsAppConnectionInput, WhatsAppMessageSource, WhatsAppSource, Workspace, WorkspaceConfig, WorkspaceConfigDoc, WorkspaceDefinitionConfig, WorkspaceFileEntry, WorkspaceIsolation, WorkspaceResource, WorkspaceStorageDefinition, ZaloChannelInput, ZaloConnectionDefinition, ZaloConnectionInput, ZaloMessageSource, ZaloSource };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{V,ge,Me,Pe,Ne,je,G,Ie,T,ye,B,J,xe,Y,E,qe,De,Le,Ue,Be,Fe,Ze,He,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ht,ft,gt,yt,St,bt,vt,_t,ie,w,g}from"./chunk-6kgtx9kv.js";import{m,Ae,Z,R}from"./chunk-bb3jfhv3.js";export{m as BroodsAccountApiError,R as BroodsAccountClient,B as BroodsClient,xe as BroodsWebSocketClient,T as DEFAULT_CORE_BASE_URL,ye as IngressAcceptedError,Me as MAX_OBSERVABILITY_BACKFILL,xe as WebSocketClient,xe as WebsocketClient,De as defineAgent,Le as defineBroods,Ue as defineCron,ct as defineDiscordChannel,We as defineDiscordConnection,lt as defineGitHubChannel,Ke as defineGitHubConnection,ut as defineGoogleChatChannel,Je as defineGoogleChatConnection,Be as defineHarness,dt as defineInstagramChannel,Ye as defineInstagramConnection,pt as defineLinearChannel,Xe as defineLinearConnection,mt as defineMatrixChannel,Qe as defineMatrixConnection,Fe as defineMcp,ht as defineMessengerChannel,et as defineMessengerConnection,ft as definePancakeChannel,tt as definePancakeConnection,Ze as definePolicy,He as defineSandbox,Ve as defineSkill,gt as defineSlackChannel,nt as defineSlackConnection,yt as defineTeamsChannel,rt as defineTeamsConnection,St as defineTelegramChannel,ot as defineTelegramConnection,bt as defineTwilioChannel,st as defineTwilioConnection,vt as defineWhatsAppChannel,it as defineWhatsAppConnection,Ge as defineWorkspace,_t as defineZaloChannel,at as defineZaloConnection,qe as env,Ae as envPlaceholder,ie as isBroodsConfig,w as isConnectionDefinition,Pe as isLogLevel,Ne as isObservabilityClientMessage,g as isResource,je as isRootSpanKind,G as isSandboxLogId,Ie as isTraceId,J as normalizeHttpServiceUrl,ge as readSseStream,Z as resolveEnvCredential,V as resolveRunEvents,Y as toWebSocketBaseUrl,E as webSocketSubprotocols};
1
+ import{G,_e,Le,Me,Ue,Fe,K,Ne,ue,Q,y,Be,I,we,B,ee,je,te,z,He,Ze,Ve,Ge,Ke,We,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ft,ht,gt,yt,St,bt,vt,_t,wt,Rt,$t,Ct,kt,Et,de,R,g}from"./chunk-rv0n0evv.js";import{m,qe,Z,C}from"./chunk-njxsdp91.js";export{m as BroodsAccountApiError,C as BroodsAccountClient,B as BroodsClient,je as BroodsWebSocketClient,I as DEFAULT_CORE_BASE_URL,we as IngressAcceptedError,Le as MAX_OBSERVABILITY_BACKFILL,ue as USER_TOKEN_HEADER,Q as USER_TOKEN_MAX_TTL_MS,y as USER_TOKEN_SECRET_ENV,je as WebSocketClient,je as WebsocketClient,Ze as defineAgent,Ve as defineBroods,Ge as defineCron,ft as defineDiscordChannel,et as defineDiscordConnection,ht as defineGitHubChannel,tt as defineGitHubConnection,gt as defineGoogleChatChannel,nt as defineGoogleChatConnection,Ke as defineHarness,yt as defineInstagramChannel,rt as defineInstagramConnection,St as defineLinearChannel,ot as defineLinearConnection,bt as defineMatrixChannel,st as defineMatrixConnection,We as defineMcp,vt as defineMessengerChannel,it as defineMessengerConnection,_t as definePancakeChannel,at as definePancakeConnection,Je as definePolicy,Ye as defineSandbox,Xe as defineSkill,wt as defineSlackChannel,ct as defineSlackConnection,Rt as defineTeamsChannel,lt as defineTeamsConnection,$t as defineTelegramChannel,ut as defineTelegramConnection,Ct as defineTwilioChannel,dt as defineTwilioConnection,kt as defineWhatsAppChannel,pt as defineWhatsAppConnection,Qe as defineWorkspace,Et as defineZaloChannel,mt as defineZaloConnection,He as env,qe as envPlaceholder,de as isBroodsConfig,R as isConnectionDefinition,Me as isLogLevel,Ue as isObservabilityClientMessage,g as isResource,Fe as isRootSpanKind,K as isSandboxLogId,Ne as isTraceId,ee as normalizeHttpServiceUrl,_e as readSseStream,Z as resolveEnvCredential,G as resolveRunEvents,Be as signUserToken,te as toWebSocketBaseUrl,z as webSocketSubprotocols};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "broods",
3
- "version": "0.49.3",
3
+ "version": "0.50.0",
4
4
  "description": "CLI + TypeScript SDK for the broods agent platform.",
5
5
  "keywords": [
6
6
  "agents",
@@ -1 +0,0 @@
1
- import{P,i,F,N,X,Q,ee,b,I,te,ae,ce,Se,be,ve,_e,le,ue,we,Re,$e,j}from"./chunk-kx38nst5.js";var D=Symbol("swallowsErrorsAfterClose"),z=class{_readBuffer;_started=!1;_closed=!1;constructor(t=le.stdin,o=le.stdout,c){this._stdin=t,this._stdout=o,this._readBuffer=new ve({maxBufferSize:c?.maxBufferSize})}onclose;onerror;onmessage;_ondata=(t)=>{try{this._readBuffer.append(t),this.processReadBuffer()}catch(o){this.onerror?.(o),this.close().catch(()=>{})}};_onerror=(t)=>{this.onerror?.(t)};_onstdouterror=(t)=>{if(this._closed)return;this.onerror?.(t),this.close().catch(()=>{})};_onstdinclose=()=>{this.close().catch(()=>{})};async start(){if(this._started)throw Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0;for(let t of this._stdout.listeners("error"))if(t[D])this._stdout.off("error",t);if(this._stdin.readableEnded||this._stdin.destroyed)setImmediate(this._onstdinclose);this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror),this._stdin.on("end",this._onstdinclose),this._stdin.on("close",this._onstdinclose),this._stdout.on("error",this._onstdouterror)}processReadBuffer(){while(!0)try{let t=this._readBuffer.readMessage();if(t===null)break;this.onmessage?.(t)}catch(t){this.onerror?.(t)}}async close(){if(this._closed)return;if(this._closed=!0,this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdin.off("end",this._onstdinclose),this._stdin.off("close",this._onstdinclose),this._onstdouterror[D]=!0,this._stdin.listenerCount("data")===0)this._stdin.pause();this._readBuffer.clear(),this.onclose?.()}send(t){if(this._closed)return Promise.reject(Error("StdioServerTransport is closed"));return new Promise((o,c)=>{let l=_e(t),r=!1,f=(_)=>{if(r)return;r=!0,this._stdout.off("error",f),this._stdout.off("drain",p),c(_)},p=()=>{if(r)return;r=!0,this._stdout.off("error",f),this._stdout.off("drain",p),o()};if(this._stdout.once("error",f),this._stdout.write(l)){if(r)return;r=!0,this._stdout.off("error",f),o()}else if(!r)this._stdout.once("drain",p)})}},M=3000,J=class{onclose;onerror;onmessage;_closed=!1;_pendingRequests=new Set;_drainWaiters=[];constructor(t,o,c){this._wire=t,this._onInstanceClose=o,this._outboundIntercept=c}async start(){}async send(t,o){if(te(t)||ae(t)){let{id:c}=t;if(c!==void 0)this._settle(c)}if(this._closed)return;if(this._outboundIntercept?.(t)==="handled")return;return this._wire.send(t,o)}setProtocolVersion=(t)=>{this._wire.setProtocolVersion?.(t)};deliver(t,o){if(this._closed)return;if(b(t))this._pendingRequests.add(t.id);else if(I(t)&&t.method==="notifications/cancelled"){let c=t.params?.requestId;if(c!==void 0)this._settle(c)}this.onmessage?.(t,o)}async whenRequestsAnswered(t){if(this._closed||this._pendingRequests.size===0)return!0;return await new Promise((o)=>{let c=()=>{clearTimeout(l),o(!0)},l=setTimeout(()=>{this._drainWaiters=this._drainWaiters.filter((r)=>r!==c),o(!1)},t);this._drainWaiters.push(c)})}async close(){if(this._closed)return;this._closed=!0,this._pendingRequests.clear(),this._releaseDrainWaiters();try{this._onInstanceClose()}finally{this.onclose?.()}}_settle(t){if(this._pendingRequests.delete(t),this._pendingRequests.size===0)this._releaseDrainWaiters()}_releaseDrainWaiters(){let t=this._drainWaiters;this._drainWaiters=[];for(let o of t)o()}};function L(t){let o=t.params;if(t.method==="initialize"&&!ce(o)){let f=o!==null&&typeof o==="object"&&typeof o.protocolVersion==="string"?o.protocolVersion:void 0;return{kind:"legacy",reason:"initialize",...f!==void 0&&{requestedVersion:f}}}if(!X(o))return{kind:"legacy",reason:"no-claim"};let c=N(o),l=(c===void 0?[]:ee(c))[0];if(l!==void 0)return{kind:"invalid-envelope",issue:l};let r=Q(o);if(r===void 0||!P.includes(r))return{kind:"unsupported-revision",requested:r??"unknown"};return{kind:"modern",revision:r,classification:{era:"modern",revision:r}}}function H(t,o={}){let c=o.legacy??"serve",l=o.transport??new z,r={phase:"opening"},f,p=!1,_=()=>p||r.phase==="closed",d=(e)=>{try{o.onerror?.(e)}catch{}},y=(e,n,s,a)=>l.send({jsonrpc:"2.0",id:e,error:{code:n,message:s,...a!==void 0&&{data:a}}}).catch((u)=>d(h(u))),w=new we(o.maxSubscriptions??ue),V=(e)=>{if(!I(e))return;let n=w.routeOutbound(e);if(n==="passthrough")return;for(let s of n)l.send({jsonrpc:"2.0",...s}).catch((a)=>d(h(a)));return"handled"},q=async(e)=>{if(b(e)&&e.method==="subscriptions/listen"){let n=N(e.params),s=X(e.params)?(n===void 0?[]:ee(n))[0]:{key:"_meta",problem:"the per-request envelope is required on protocol revision 2026-07-28"},a=Q(e.params),u;if(s!==void 0)u={jsonrpc:"2.0",id:e.id,error:{code:-32602,message:`Invalid _meta envelope: ${s.key}: ${s.problem}`}};else if(a===void 0||!P.includes(a)){let v=new F({supported:[...P],requested:a??"unknown"});u={jsonrpc:"2.0",id:e.id,error:{code:v.code,message:v.message,data:v.data}}}else u=w.serve(e);return await l.send("error"in u?u:{jsonrpc:"2.0",method:u.method,params:u.params}).catch((v)=>d(h(v))),!0}if(I(e)&&e.method==="notifications/cancelled"){let n=e.params?.requestId;if(n!==void 0&&w.cancel(n))return!0}return!1},C=(e,n,s)=>{let a=Se({kind:"legacy",reason:n,...s!==void 0&&{requestedVersion:s}},P);if(a===void 0)return Promise.resolve();return d(Error(`Rejected 2025-era request on a modern-only stdio connection (${a.cell}): ${a.message}`)),y(e.id,a.code,a.message,a.data)},T=(e)=>{if(p||e===f)return;O()},m=async(e,n)=>{let s=await t({era:e}),a=s instanceof j?s.server:s;if(e==="modern")be(a,n),Re(a,P),w.setServerCapabilities(a.getCapabilities(),$e(a));let u=new J(l,()=>T(u),e==="modern"?V:void 0);return await s.connect(u),{product:s,channel:u}},R=(e)=>e.product.close().catch((n)=>d(h(n))),B=async(e)=>{f=e.channel;try{if(!await e.channel.whenRequestsAnswered(M))d(Error(`Discarded the probe instance with requests still unanswered after ${M}ms; continuing with the fallback`));await e.product.close()}catch(n){d(h(n))}finally{f=void 0}},A=async(e)=>{if(r.phase==="closed")return;if(r.phase==="pinned"){if(r.era==="modern"&&b(e)&&e.method==="initialize"&&!ce(e.params)){await C(e,"initialize",e.params!==null&&typeof e.params==="object"&&typeof e.params.protocolVersion==="string"?e.params.protocolVersion:void 0);return}if(r.era==="modern"&&await q(e))return;if(_())return;r.instance.channel.deliver(e);return}if(!b(e)&&!I(e)){d(Error("Discarded a JSON-RPC response received before the connection negotiated an era"));return}let n=L(e);switch(n.kind){case"invalid-envelope":{let s=`Invalid _meta envelope for protocol revision 2026-07-28: ${n.issue.key}: ${n.issue.problem}`;if(b(e))await y(e.id,i.InvalidParams,s,{envelope:n.issue});else d(Error(`Discarded a notification with a malformed envelope: ${s}`));return}case"unsupported-revision":if(b(e)){let s=new F({supported:[...P],requested:n.requested});d(s),await y(e.id,s.code,s.message,s.data)}else d(Error(`Discarded a notification claiming unsupported protocol revision ${n.requested}`));return;case"modern":if(b(e)&&e.method==="server/discover"){if(r.phase==="probe"){r.instance.channel.deliver(e,{classification:n.classification});return}let s=await m("modern",n.revision);if(_()){await R(s);return}r={phase:"probe",instance:s},s.channel.deliver(e,{classification:n.classification});return}if(r.phase==="probe"){if(I(e)){r.instance.channel.deliver(e,{classification:n.classification});return}r={phase:"pinned",era:"modern",instance:r.instance}}else{let s=await m("modern",n.revision);if(_()){await R(s);return}r={phase:"pinned",era:"modern",instance:s}}if(await q(e))return;if(_())return;r.instance.channel.deliver(e,{classification:n.classification});return;case"legacy":{if(c==="reject"){if(b(e))await C(e,n.reason,n.requestedVersion);return}if(r.phase==="probe"){if(await B(r.instance),_())return;r={phase:"opening"}}let s=await m("legacy");if(_()){await R(s);return}r={phase:"pinned",era:"legacy",instance:s},r.instance.channel.deliver(e);return}}},S=[],E=!1,W=async()=>{if(E)return;E=!0;try{while(S.length>0){let e=S.shift();try{await A(e)}catch(n){if(b(e))await y(e.id,i.InternalError,"Internal server error");d(h(n))}}}finally{E=!1}},O=async()=>{if(p||r.phase==="closed")return;p=!0;let e=r;r={phase:"closed"};for(let n of w.teardownAll())await l.send(n).catch((s)=>d(h(s)));if(e.phase==="probe"||e.phase==="pinned")await e.instance.product.close().catch((n)=>d(h(n)));await l.close().catch((n)=>d(h(n)))};l.onmessage=(e)=>{S.push(e),W()},l.onerror=(e)=>{if(d(e),r.phase==="probe"||r.phase==="pinned")r.instance.channel.onerror?.(e)},l.onclose=()=>{if(p||r.phase==="closed")return;p=!0;let e=r;if(r={phase:"closed"},e.phase==="probe"||e.phase==="pinned")e.instance.product.close().catch((n)=>d(h(n)))};let k=l.start().catch((e)=>{throw d(h(e)),e});return k.catch(()=>{}),{close:async()=>{await k.catch(()=>{}),await O()}}}function h(t){return t instanceof Error?t:Error(String(t))}export{H as serveStdio};
@@ -1,5 +0,0 @@
1
- function V(e){if(e.events&&e.input!==void 0)throw Error("Run input accepts either `input` or `events`, not both");if(e.events&&e.events.length>0)return e.events;if(typeof e.input==="string")return[{role:"user",content:[{type:"text",text:e.input}]}];throw Error("Run input requires `input` (string) or a non-empty `events` array")}async function*ge(e){let n=e.getReader(),t=new TextDecoder,o="";try{while(!0){let{done:r,value:i}=await n.read();if(r)break;o+=t.decode(i,{stream:!0});let s=o.split(`
2
- `);o=s.pop()??"";for(let a of s)if(a.startsWith("data: "))yield a.slice(6)}}finally{await n.cancel().catch(()=>{return}),n.releaseLock()}}var Me=500,Ce=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/,he=/^(?!0{32}$)[0-9a-f]{32}$/;function Pe(e){return e==="DEBUG"||e==="INFO"||e==="WARN"||e==="ERROR"}function Ne(e){if(typeof e!=="object"||e===null)return!1;let n=e;if(n.type==="subscribe")return Se(n);if(n.type==="unsubscribe")return k(n.stream);if(n.type==="fetchTrace")return Ie(n.traceId);return!1}function je(e){return e==="task"||e==="cron"||e==="subtask"}function G(e){return typeof e==="string"&&Ce.test(e)}function Ie(e){return typeof e==="string"&&he.test(e)}function k(e){return e==="logs"||e==="traces"}function Se(e){let n=e.stream;if(!k(n))return!1;let t=e.backfill;if(t!==void 0&&(typeof t!=="number"||!Number.isSafeInteger(t)||t<0||t>500))return!1;if(e.liveOnly!==void 0&&typeof e.liveOnly!=="boolean")return!1;let o=e.minLevel;if(o!==void 0&&!Pe(o))return!1;let r=e.sandboxId;return r===void 0||n==="logs"&&G(r)}import{readFileSync as Re}from"node:fs";import{chmod as H,mkdir as be,writeFile as Ae}from"node:fs/promises";import{homedir as ke}from"node:os";import{dirname as D,join as ve}from"node:path";var y="broods",_="_generated",O=ve(ke(),".broods","config.json"),N="broods.app",P="dashboard",we="gateway";function z(e){let n=process.env.BROODS_TOKEN,t=e??process.env.BROODS_BASE_URL;if(n&&t)return{baseUrl:f(t),token:n,createdAt:new Date().toISOString()};let o=j();if(!o)return null;if(t)return o.logins[f(t)]??null;let r=process.env.BROODS_DASHBOARD_URL;if(r){let i=f(r);return Object.values(o.logins).find((s)=>s.dashboardUrl===i)??null}return o.logins[o.current]??null}async function W(e){let n=j()?.logins??{},t={current:e.baseUrl,logins:{...n,[e.baseUrl]:e}};await be(D(O),{recursive:!0,mode:448}),await H(D(O),448),await K(O,`${JSON.stringify(t,null,2)}
3
- `)}async function K(e,n){await Ae(e,n,{encoding:"utf8",mode:384}),await H(e,384)}function v(){return process.env.BROODS_STAGE}function f(e){let n=e.length;while(n>0&&e.charCodeAt(n-1)===47)n-=1;return e.slice(0,n)}function L(e){try{let n=new URL(e);if(!n.hostname.startsWith(`${P}.`))return;let t=n.hostname.slice(P.length+1);if(t!==N&&!t.endsWith(`.${N}`))return;return n.hostname=`${we}.${t}`,f(n.origin)}catch{return}}function j(){try{let e=JSON.parse(Re(O,"utf8"));if(typeof e.current!=="string"||!e.logins)return null;return{current:e.current,logins:e.logins}}catch{return null}}import{existsSync as F,readFileSync as Z,statSync as Ee}from"node:fs";import{join as X,resolve as Q}from"node:path";var A=new Map,Te=new Set(Object.keys(process.env)),q=new Set;function h(e=process.cwd()){Oe(e);let n=z();return{dashboardUrl:process.env.BROODS_DASHBOARD_URL??n?.dashboardUrl,baseUrl:process.env.BROODS_BASE_URL??n?.baseUrl,token:n?.token,project:process.env.BROODS_PROJECT,stage:v()}}function U(){let e={};for(let[n,t]of Object.entries(process.env))if(typeof t==="string"&&!n.startsWith("BROODS_"))e[n]=t;return e}function M(e,n=process.cwd()){let t=process.env[e];if(t===void 0)return!1;let o=Q(n);for(let r of[".env.local",".env"]){let i=X(o,r);if(!F(i))continue;let s=ee(Z(i,"utf8"));if(s[e]!==void 0)return s[e]!==t}return!0}function Oe(e){let n=Q(e),t=process.env.BROODS_RELOAD_ENV==="1";for(let o of[".env",".env.local"]){let r=X(n,o);if(!F(r)){A.delete(r);continue}let i=Ee(r).mtimeMs,s=A.get(r);if(s&&s.mtimeMs===i)continue;A.set(r,{mtimeMs:i});for(let[a,c]of Object.entries(ee(Z(r,"utf8"))))if(t||!Te.has(a)||q.has(a))process.env[a]=c,q.add(a)}}function ee(e){let n={};for(let t of e.split(/\r?\n/)){let o=t.trim();if(!o||o.startsWith("#"))continue;let r=o.startsWith("export ")?o.slice(7).trim():o,i=r.indexOf("=");if(i<=0)continue;let s=r.slice(0,i).trim();if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(s))continue;n[s]=_e(r.slice(i+1).trim())}return n}function _e(e){if(e.startsWith('"')&&e.endsWith('"'))return e.slice(1,-1).replace(/\\n/g,`
4
- `).replace(/\\"/g,'"');if(e.startsWith("'")&&e.endsWith("'"))return e.slice(1,-1);let n=e.indexOf(" #");return n>=0?e.slice(0,n).trimEnd():e}var T="https://gateway.broods.app";class ye extends Error{accepted;constructor(e){super(`Ingress ${e.eventId} was accepted asynchronously with status ${e.status??"queued"}`);this.accepted=e;this.name="IngressAcceptedError"}}class B{baseUrl;apiKey;fetchImpl;constructor(e={}){h(),this.baseUrl=J(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||T),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||void 0,this.fetchImpl=e.fetch??fetch}channelWebhookUrl(e){return`${this.baseUrl}${e.webhookPath.startsWith("/")?"":"/"}${e.webhookPath}`}accountWebhookUrl(e,n){let t=[e,n].map(encodeURIComponent);return`${this.baseUrl}/v1/webhooks/${t.join("/")}`}stageWebhookUrl(e,n,t){let o=[e,"dev",n,t].map(encodeURIComponent);return`${this.baseUrl}/v1/webhooks/${o.join("/")}`}agent(e,n){if(typeof e==="string"){let o=e,r=n??"";if(!r)throw Error(`Agent ${o} is missing a generated id. Run broods dev --once or broods deploy to sync it first.`);return{id:r,run:(i)=>this.run({...i,agentName:o,agentId:r}),runAsync:(i)=>this.runAsync({...i,agentName:o,agentId:r}),continue:(i)=>this.continue({...i,agentId:r}),stream:(i)=>this.stream({...i,agentName:o,agentId:r})}}let t=e;if(!t.id)throw Error(`Agent ${t.name} is missing a generated id. Run broods dev --once or broods deploy to sync it first.`);return{id:t.id,run:(o)=>this.run(t,o),runAsync:(o)=>this.runAsync(t,o),continue:(o)=>this.continue(t,o),stream:(o)=>this.stream(t,o)}}async run(e,n){let t=[],o="",r=n?this.stream(e,n):this.stream(e);for await(let i of r)if(t.push(i),i.type==="text-delta")o+=i.text;return{text:o,events:t}}async*stream(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o=ne(t,"cli"),r=n?this.scopedUrl(e):`${this.baseUrl}/v1/runs`,i=await this.openStream(o,r);if(!i.ok)throw Error(`Run failed: ${i.status} ${await i.text()}`);if(i.status===202)throw new ye(te(await i.json(),o));if(!i.body)throw Error("Run response has no body");for await(let s of ge(i.body)){let a;try{a=JSON.parse(s)}catch{continue}if(a.type==="error")throw Error(`Agent run failed: ${$e(a.error)}`);yield a}}async runAsync(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o={...ne(t,"async"),background:!0},r=n?this.scopedUrl(e):`${this.baseUrl}/v1/runs`;return this.postAcceptedRun(r,o,"Async run")}async continue(e,n){let t=n?e:null,o=n??e,r={agentId:t?t.id:e.agentId,eventId:o.eventId??`continue-${crypto.randomUUID()}`,conversationKey:o.conversationKey,continue:!0},i=t?this.scopedUrl(t):`${this.baseUrl}/v1/runs`;return this.postAcceptedRun(i,r,"Continue")}async getAsyncStatus(e){let n=this.resolveStatusUrl(e),t=await this.fetchJson(n,{method:"GET",headers:this.apiKeyHeaders()});if(t.status===404)return{status:"not_found"};if(!t.ok)throw Error(`Status check failed: ${t.status} ${await t.text()}`);return await t.json()}async waitForAsyncStatus(e,n={}){let t=Date.now()+(n.timeoutMs??180000),o=n.intervalMs??2000;while(Date.now()<t){if(n.signal?.aborted)throw Error("Async status polling aborted.");let r=await this.getAsyncStatus(e);if(r.status==="awaiting_approval"||r.status==="awaiting_input"||r.status==="completed"||r.status==="failed"||r.status==="expired"||r.status==="not_found")return r;await en(o,n.signal)}throw Error("Polling timeout")}scopedUrl(e){if(e.projectSlug&&e.stageSlug&&e.endpointId)return`${this.baseUrl}/v1/projects/${encodeURIComponent(e.projectSlug)}/stages/${encodeURIComponent(e.stageSlug)}/agents/${encodeURIComponent(e.endpointId)}`;return`${this.baseUrl}/v1/runs`}asyncAgentRun(e,n){return{...e,conversationKey:n,poll:()=>this.getAsyncStatus(e),wait:(t)=>this.waitForAsyncStatus(e,t)}}async postAcceptedRun(e,n,t){let o=await this.fetchJson(e,{method:"POST",headers:this.apiKeyHeaders(),body:JSON.stringify(n)});if(o.status!==202)throw Error(`${t} failed: ${o.status} ${await ze(o,"202 JSON")}`);return this.asyncAgentRun(te(await o.json(),n),n.conversationKey)}async openStream(e,n){if(this.apiKey)return await this.fetchCore(e,n,{Authorization:`Bearer ${this.apiKey}`});throw Error(`BroodsClient streams directly from the core service at ${this.baseUrl}. Provide apiKey. For a self-hosted core service, set host/baseUrl or BROODS_HOST/BROODS_BASE_URL.`)}async fetchCore(e,n,t){try{return await this.fetchImpl(n,{method:"POST",headers:{"Content-Type":"application/json",Accept:"text/event-stream",...t},body:JSON.stringify(e)})}catch(o){throw Error(`Cannot access the broods core service at ${n}. The SDK uses ${T} by default; set host/baseUrl or BROODS_HOST/BROODS_BASE_URL to your own core service URL if your account uses a custom deployment. Cause: ${o instanceof Error?o.message:String(o)}`)}}apiKeyHeaders(){if(!this.apiKey)throw Error("BroodsClient requires apiKey or BROODS_API_KEY.");return{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`}}async fetchJson(e,n){try{return await this.fetchImpl(e,n)}catch(t){throw Error(`Cannot access the broods core service at ${e}. Cause: ${t instanceof Error?t.message:String(t)}`)}}resolveStatusUrl(e){if(typeof e!=="string")return e.statusUrl;if(/^https?:\/\//.test(e))return e;return nn(this.baseUrl,e)}}function J(e){let n=e.trim(),t=/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(n)?n:`https://${n}`;return f(t)}function ne(e,n){let t=e.eventId??`${n}-${crypto.randomUUID()}`;return{agentId:e.agentId,eventId:t,conversationKey:e.conversationKey??t,events:V(e),...e.mode!==void 0?{mode:e.mode}:{},...e.idempotencyKey!==void 0?{idempotencyKey:e.idempotencyKey}:{},...e.system!==void 0?{system:e.system}:{},...e.model!==void 0?{model:e.model}:{}}}function $e(e){if(typeof e==="string")return e;if(!e||typeof e!=="object")return String(e);let n=e,t=n.data?.error?.message??n.message??n.responseBody??JSON.stringify(e),o=n.name?`${n.name}: `:"",r=n.statusCode?` (HTTP ${n.statusCode})`:"";return`${o}${t}${r}`}function te(e,n){if(!e||typeof e!=="object")throw Error("Async response must be an object");let t=e.statusUrl;if(typeof t!=="string"||t.length===0)throw Error("Async response missing statusUrl");let o=e.runId;if(typeof o!=="string"||o.length===0)throw Error("Async response missing runId");let r=typeof e.eventId==="string"?e.eventId:o,{status:i,requestedMode:s}=e;return{statusUrl:t,runId:o,eventId:r,agentId:n.agentId,...i==="accepted"||i==="queued"||i==="applied"||i==="processing"?{status:i}:{},...s==="reject"||s==="followup"||s==="collect"||s==="steer"?{requestedMode:s}:{}}}async function ze(e,n){if((e.headers.get("content-type")??"").toLowerCase().includes("text/event-stream"))return await e.body?.cancel().catch(()=>{}),`expected ${n}, but the server returned an SSE stream. This usually means the core deployment ignored the background flag and ran the request on the direct streaming runner.`;let o=await e.text();if(o.length<=2000)return o;return`${o.slice(0,2000)}... [truncated ${o.length-2000} chars]`}function en(e,n){return new Promise((t,o)=>{if(n?.aborted){o(Error("Async status polling aborted."));return}let r=setTimeout(t,e);n?.addEventListener("abort",()=>{clearTimeout(r),o(Error("Async status polling aborted."))},{once:!0})})}function nn(e,n){return`${J(e)}/v1/runs/${encodeURIComponent(n)}`}var tn=2000,oe=0,R=1;class xe{baseUrl;apiKey;WebSocketImpl;connectTimeoutMs;constructor(e={}){if(h(),this.baseUrl=ue(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||T),this.apiKey=e.apiKey||process.env.BROODS_API_KEY||"",!this.apiKey)throw Error("BroodsWebSocketClient requires apiKey or BROODS_API_KEY.");this.WebSocketImpl=e.WebSocket,this.connectTimeoutMs=e.connectTimeoutMs??tn}subscribe(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=on(e),i=ce(this.baseUrl),s=new t(o,E(this.apiKey)),a=!1,c=!1,d=setTimeout(()=>{if(!a)S(i)},this.connectTimeoutMs),m=(p=1000,I="client closed")=>{if(c)return;if(c=!0,clearTimeout(d),e.signal?.removeEventListener("abort",b),s.readyState===R||s.readyState===oe)s.close(p,I)},S=(p)=>{n.onError?.(p),m(1011,"websocket error")},me=()=>{n.onDone?.(),m(1000,"done")},b=()=>{if(s.readyState===R)s.send(JSON.stringify({type:"cancel"}));S(Error("WebSocket run aborted."))};return e.signal?.addEventListener("abort",b,{once:!0}),s.onopen=()=>{if(a=!0,clearTimeout(d),e.signal?.aborted){b();return}s.send(JSON.stringify({type:"execute",agentId:r,...e.answers?{answers:e.answers}:{events:V(e)},sessionId:e.sessionId,...e.eventId!==void 0?{eventId:e.eventId}:{},...e.mode!==void 0?{mode:e.mode}:{},...e.idempotencyKey!==void 0?{idempotencyKey:e.idempotencyKey}:{},...e.system!==void 0?{system:e.system}:{},...e.model!==void 0?{model:e.model}:{}}))},s.onmessage=(p)=>{if(typeof p.data!=="string")return;let I=se(p.data);if(!I)return;let x=ae(I,n);switch(n.onMessage?.(x),x.type){case"meta":n.onMeta?.(x);break;case"done":me();break;case"error":S(Error(re(x.error)));break}},s.onerror=()=>{S(i)},s.onclose=(p)=>{if(clearTimeout(d),e.signal?.removeEventListener("abort",b),c||p.code===1000)return;S(Error(p.reason||"WebSocket connection closed."))},{url:o,sendControl:function(p){if(s.readyState!==R)throw Error("WebSocket is not open");s.send(JSON.stringify({type:"control",...p}))},close:m}}attach(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=new t(o,E(this.apiKey)),i=!1,s=(c=1000,d="client closed")=>{if(i)return;if(i=!0,e.signal?.removeEventListener("abort",a),r.readyState===R||r.readyState===oe)r.close(c,d)},a=()=>{s(1000,"aborted"),n.onError?.(Error("WebSocket attach aborted."))};if(e.signal?.aborted)a();else e.signal?.addEventListener("abort",a,{once:!0});return r.onopen=()=>{if(i)return;r.send(JSON.stringify({type:"attach",...e,signal:void 0,agent:void 0}))},r.onmessage=(c)=>{if(i||typeof c.data!=="string")return;let d=se(c.data);if(!d)return;let m=ae(d,n);if(i)return;if(n.onMessage?.(m),i)return;if(m.type==="done")n.onDone?.();if(m.type==="error")n.onError?.(Error(re(m.error)))},r.onerror=()=>{if(i)return;s(1011,"websocket error"),n.onError?.(ce(this.baseUrl))},r.onclose=(c)=>{if(e.signal?.removeEventListener("abort",a),!i&&c.code!==1000)n.onError?.(Error(c.reason||"WebSocket connection closed."))},{url:o,sendControl:function(c){if(r.readyState!==R)throw Error("WebSocket is not open");r.send(JSON.stringify({type:"control",...c}))},close:s}}async*stream(e){let n=[],t=!1,o=null,r=null,i=()=>{r?.(),r=null},s=this.subscribe(e,{onMessage:function(a){n.push(a),i()},onDone:function(){t=!0,i()},onError:function(a){o=a,i()}});try{while(!0){if(n.length>0){yield n.shift();continue}if(o)throw o;if(t)return;await new Promise((a)=>{r=a})}}finally{s.close()}}buildUrl(e){let n=rn(e),t=e.projectSlug??e.agent?.projectSlug,o=e.stageSlug??e.agent?.stageSlug,r=t&&o?`/projects/${encodeURIComponent(t)}/stages/${encodeURIComponent(o)}`:"";return`${Y(this.baseUrl)}/v1${r}/agents/${encodeURIComponent(n)}/ws`}resolveWebSocket(){let e=this.WebSocketImpl??globalThis.WebSocket;if(!e)throw Error("WebSocket is not available. Pass a WebSocket implementation in BroodsWebSocketClient options.");return e}}function Y(e){let n=new URL(ue(e));if(n.protocol==="https:")n.protocol="wss:";if(n.protocol==="http:")n.protocol="ws:";return f(n.toString())}function E(e){return["broods.v1",`broods.token.${e}`]}function re(e){if(typeof e==="string")return e;if(e&&typeof e==="object"&&typeof e.message==="string")return e.message;return e===void 0?"WebSocket stream error.":JSON.stringify(e)}function ue(e){let n=e.trim();if(/^wss?:\/\//.test(n))return f(n);return J(n)}function se(e){try{let n=JSON.parse(e);return typeof n==="object"&&n!==null&&typeof n.type==="string"?n:null}catch{return null}}function on(e){let n=e.agentId??e.agent?.id??e.endpointId;if(!n)throw Error("WebSocket run requires agent, agentId, or endpointId.");return n}function rn(e){let n=e.endpointId??e.agent?.endpointId??e.agent?.id;if(!n)throw Error("WebSocket run requires agent or endpointId.");return n}function ae(e,n){if(e.type!=="output")return e;let t=e;return n.onOutput?.(t),t.data}function ce(e){return Error(`Cannot access the WebSocket service at ${e}.`)}var pe=Symbol.for("broods.resource"),de=Symbol.for("broods.config"),fe=Symbol.for("broods.connection"),le=/^[A-Z][A-Z0-9_]{0,63}$/,qe=new Proxy((e)=>{if(!le.test(e))throw Error("env name must match /^[A-Z][A-Z0-9_]*$/ and be at most 64 characters.");return{__beeblastEnv:!0,name:e}},{get:function(e,n,t){if(typeof n==="string"&&le.test(n))throw Error(`env.${n} is not supported; use env("${n}")`);return Reflect.get(e,n,t)}});function De(e){let{name:n,description:t,...o}=e;return C("agent",n,t,o)}function Le(e){return{[de]:!0,config:e}}function Ue(e){let{name:n,description:t,...o}=e;return C("cron",n,t,o)}function Be(e){return e}function Fe(e){let{name:n,description:t,...o}=e;return C("mcp",n,t,o)}function Ze(e){let{name:n,description:t,...o}=e;return C("policy",n,t,o)}function He(e){let{name:n,description:t,...o}=e;return C("sandbox",n,t,o)}function Ve(e){let{name:n,description:t,...o}=e;return C("skill",n,t,o)}function Ge(e){let{name:n,description:t,...o}=e;return C("workspace",n,t,o)}function We(e){return l("discord",e)}function Ke(e){return l("github",e)}function Je(e){return l("gchat",e)}function Ye(e){return l("instagram",e)}function Xe(e){return l("linear",e)}function Qe(e){return l("matrix",e)}function et(e){return l("messenger",e)}function tt(e){return l("pancake",e)}function nt(e){return l("slack",e)}function rt(e){return l("teams",e)}function ot(e){return l("telegram",e)}function st(e){return l("twilio",e)}function it(e){return l("whatsapp",e)}function at(e){return l("zalo",e)}function ct(e){let{name:n,description:t,channelId:o,guildId:r,...i}=e;return u(n,t,o,r,i)}function lt(e){let{name:n,description:t,repo:o,...r}=e,[i,...s]=o.split("/");if(!i||s.length!==1||!s[0])throw Error(`Channel "${n}" repo must be "owner/name", not "${o}"`);return u(n,t,o,i,r)}function ut(e){let{name:n,description:t,spaceName:o,...r}=e;return u(n,t,o,void 0,r)}function dt(e){let{name:n,description:t,igsid:o,...r}=e;return u(n,t,o,void 0,r)}function pt(e){let{name:n,description:t,team:o,...r}=e;return u(n,t,o,void 0,r)}function mt(e){let{name:n,description:t,channelId:o,...r}=e;return u(n,t,o,void 0,r)}function ht(e){let{name:n,description:t,psid:o,...r}=e;return u(n,t,o,void 0,r)}function ft(e){let{name:n,description:t,conversationId:o,...r}=e;return u(n,t,o,void 0,r)}function gt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function yt(e){let{name:n,description:t,channelId:o,teamId:r,...i}=e;return u(n,t,o,r,i)}function St(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function bt(e){let{name:n,description:t,from:o,...r}=e;return u(n,t,o,void 0,r)}function vt(e){let{name:n,description:t,waId:o,...r}=e;return u(n,t,o,void 0,r)}function _t(e){let{name:n,description:t,chatId:o,...r}=e;return u(n,t,o,void 0,r)}function ie(e){return Boolean(e&&typeof e==="object"&&e[de])}function w(e){return Boolean(e&&typeof e==="object"&&e[fe])}function g(e){return Boolean(e&&typeof e==="object"&&e[pe])}function u(e,n,t,o,r){return C("channelRecord",e,n,{...r,externalId:t,...o?{workspaceRef:o}:{}})}function l(e,n){let{partition:t,...o}=n;return{[fe]:!0,kind:"connection",type:e,...t?{partition:t}:{},config:o}}function C(e,n,t,o){return{[pe]:!0,kind:e,name:n,...t?{description:t}:{},config:o}}
5
- export{V,ge,Me,Pe,Ne,je,G,Ie,y,_,O,z,W,K,v,f,L,h,U,M,T,ye,B,J,xe,Y,E,qe,De,Le,Ue,Be,Fe,Ze,He,Ve,Ge,We,Ke,Je,Ye,Xe,Qe,et,tt,nt,rt,ot,st,it,at,ct,lt,ut,dt,pt,mt,ht,ft,gt,yt,St,bt,vt,_t,ie,w,g};
@@ -1,2 +0,0 @@
1
- var d=/^[A-Z][A-Z0-9_]*$/;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 Ae(e){if(!d.test(e)||e.length>64)throw Error("envPlaceholder name must match /^[A-Z][A-Z0-9_]*$/ and be at most 64 characters.");return`\${${e}}`}function Z(){return o("BROODS_SESSION_TOKEN")??o("BROODS_ACCOUNT_SECRET")}class R{baseUrl;bearerToken;fetchImpl;constructor(e={}){let t=e.baseUrl??o("BROODS_BASE_URL")??"https://gateway.broods.app",n=e.sessionToken??e.accountSecret??Z();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}/v1/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 listConnections(){return(await this.request("GET","/v1/account/connections"))?.connections??[]}async getConnection(e){return await this.request("GET",`/v1/account/connections/${e}`)}async startConnection(e,t){let n=await this.request("POST",`/v1/account/connections/${e}/start`,t);if(!n)throw new m("POST",`/v1/account/connections/${e}/start`,404,"This deployment has no /v1/account/connections yet");return n}async connect(e,t){let n=await this.request("PUT",`/v1/account/connections/${e}`,t);if(!n)throw new m("PUT",`/v1/account/connections/${e}`,404,"This deployment has no /v1/account/connections yet");return n}async disconnect(e){return(await this.request("DELETE",`/v1/account/connections/${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){let s=`/v1/workspaces/${encodeURIComponent(e)}/files`,r=await this.request("PATCH",s,{path:t,newPath:n});if(!r)throw new m("PATCH",s,404,"Workspace not found");return r.renamed}async deleteWorkspaceFile(e,t){return(await this.request("DELETE",`/v1/workspaces/${encodeURIComponent(e)}/files`,{path:t}))?.deleted??0}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${a(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${a(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 c=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(e)),u=Array.from(new Uint8Array(c)).map((l)=>l.toString(16).padStart(2,"0")).join("");return{bundleStorageId:r,sha256:u}}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}audit={list:async(e={})=>{let t=await this.request("GET",`/v1/audit${i(e)}`);if(!t)throw new m("GET","/v1/audit",404,"Not found");return t},verify:async(e={})=>{let t=await this.request("GET",`/v1/audit/verify${i(e)}`);if(!t)throw new m("GET","/v1/audit/verify",404,"Not found");return t},getSink:async()=>await this.request("GET","/v1/audit/sink"),setSink:async(e)=>{let t=await this.request("PUT","/v1/audit/sink",e);if(!t)throw new m("PUT","/v1/audit/sink",404,"Not found");return t},deleteSink:async()=>(await this.request("DELETE","/v1/audit/sink"))?.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()}}function o(e){return typeof process<"u"?process?.env?.[e]:void 0}function i(e){let t=new URLSearchParams;for(let[n,s]of Object.entries(e))if(s!==void 0)t.set(n,String(s));return t.size>0?`?${t.toString()}`:""}function a(e){return`?${new URLSearchParams({project:e.project,stage:e.stage}).toString()}`}
2
- export{m,Ae,Z,R};