broods 0.31.0 → 0.33.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/README.md +7 -5
- package/dist/account.d.ts +41 -9
- package/dist/account.js +1 -1
- package/dist/chunk-0622rd68.js +2 -0
- package/dist/chunk-fctvcvbb.js +1 -0
- package/dist/chunk-pk8n8a1s.js +1 -0
- package/dist/chunk-pvpa68ca.js +5 -0
- package/dist/chunk-xk0frbxy.js +15 -0
- package/dist/cli/index.js +157 -91
- package/dist/index.d.ts +187 -107
- package/dist/index.js +1 -1
- package/package.json +13 -8
- package/dist/chunk-2tqw3gxy.js +0 -1
- package/dist/chunk-3qpgf0c1.js +0 -5
- package/dist/chunk-736tg90p.js +0 -1
- package/dist/chunk-e66afphr.js +0 -66
- package/dist/chunk-rx5qcgbh.js +0 -2
- package/dist/chunk-yy11cxjg.js +0 -2
- package/dist/chunk-zk2w6bee.js +0 -15
package/dist/index.d.ts
CHANGED
|
@@ -101,6 +101,20 @@ declare const MODEL_PROVIDERS: {
|
|
|
101
101
|
};
|
|
102
102
|
type AccountModelProviderName = keyof typeof MODEL_PROVIDERS;
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* OAuth 2.0 refresh-token grant for an external row. Core mints access tokens
|
|
106
|
+
* at connect time and sends `Authorization: Bearer <token>`, so a server
|
|
107
|
+
* whose tokens expire (Google's Workspace MCP endpoints) still works where a
|
|
108
|
+
* static header cannot. Secret fields hold ${NAME} refs on the row.
|
|
109
|
+
*/
|
|
110
|
+
interface McpOauth {
|
|
111
|
+
clientId: string;
|
|
112
|
+
clientSecret: string;
|
|
113
|
+
refreshToken: string;
|
|
114
|
+
/** Token endpoint, https only; core defaults to https://oauth2.googleapis.com/token. */
|
|
115
|
+
tokenUrl?: string;
|
|
116
|
+
}
|
|
117
|
+
|
|
104
118
|
/**
|
|
105
119
|
* Agent configuration: types for the per-agent settings object, input
|
|
106
120
|
* normalization, encryption helpers, patch-merge, and redaction.
|
|
@@ -193,6 +207,11 @@ interface AgentSubagentConfig {
|
|
|
193
207
|
interface AgentModelConfig extends LanguageModelCallOptions, Pick<RequestOptions, "maxRetries" | "timeout"> {
|
|
194
208
|
provider?: AccountModelProviderName;
|
|
195
209
|
modelId?: string;
|
|
210
|
+
/**
|
|
211
|
+
* Speech-to-text model for inbound audio, on the same provider and key as
|
|
212
|
+
* `modelId`. Defaults to the widest-container model the provider ships.
|
|
213
|
+
*/
|
|
214
|
+
transcriptionModelId?: string;
|
|
196
215
|
providerOptions?: AgentModelProviderOptions;
|
|
197
216
|
output?: AgentModelOutputConfig;
|
|
198
217
|
}
|
|
@@ -294,6 +313,12 @@ interface AgentMcpEntry {
|
|
|
294
313
|
needsApproval?: boolean;
|
|
295
314
|
/** Extra request headers; values resolved from account env vars at sync. */
|
|
296
315
|
headers?: Record<string, string>;
|
|
316
|
+
/**
|
|
317
|
+
* Overrides for the row's oauth credentials; values resolved from account
|
|
318
|
+
* env vars at sync, so the row's ${NAME} refs never reach the token
|
|
319
|
+
* endpoint. tokenUrl stays on the row, where registration checked it.
|
|
320
|
+
*/
|
|
321
|
+
oauth?: Partial<Omit<McpOauth, "tokenUrl">>;
|
|
297
322
|
[key: string]: unknown;
|
|
298
323
|
}
|
|
299
324
|
interface AgentChannelsConfig {
|
|
@@ -496,14 +521,6 @@ interface SandboxConfig {
|
|
|
496
521
|
options?: Record<string, unknown>;
|
|
497
522
|
}
|
|
498
523
|
|
|
499
|
-
/**
|
|
500
|
-
* Workspace-config validation for the Convex config plane. Ports core's
|
|
501
|
-
* former storage/workspace-config.ts normalizer so the public /v1/workspaces
|
|
502
|
-
* contract is unchanged. Workspace config holds no secrets (a roleArn is not
|
|
503
|
-
* a secret), so it is stored and returned in plaintext. Pure module — safe
|
|
504
|
-
* for the default Convex runtime. The public projection lives in
|
|
505
|
-
* ./responses.ts.
|
|
506
|
-
*/
|
|
507
524
|
declare const WORKSPACE_STORAGE_PROVIDERS: readonly ["s3"];
|
|
508
525
|
type WorkspaceStorageProvider = (typeof WORKSPACE_STORAGE_PROVIDERS)[number];
|
|
509
526
|
type WorkspaceStorageAuth = {
|
|
@@ -759,99 +776,6 @@ type WorkspaceConfigDoc = Doc<"workspaceConfigs">;
|
|
|
759
776
|
type SandboxConfigDoc = Doc<"sandboxConfigs">;
|
|
760
777
|
type CronDoc = Doc<"crons">;
|
|
761
778
|
|
|
762
|
-
/**
|
|
763
|
-
* Wire types for the public account-manage and harness APIs. These mirror
|
|
764
|
-
* the deployed API contract (docs/api-reference/openapi.yaml is the source
|
|
765
|
-
* of truth); they are intentionally independent of the runtime internals so
|
|
766
|
-
* the SDK keeps working when the runtime is ported.
|
|
767
|
-
*/
|
|
768
|
-
|
|
769
|
-
interface Account {
|
|
770
|
-
account: {
|
|
771
|
-
accountId: string;
|
|
772
|
-
username: string;
|
|
773
|
-
};
|
|
774
|
-
secret: string;
|
|
775
|
-
}
|
|
776
|
-
interface Agent {
|
|
777
|
-
accountId: string;
|
|
778
|
-
agentId: string;
|
|
779
|
-
name: string;
|
|
780
|
-
}
|
|
781
|
-
interface Sandbox {
|
|
782
|
-
sandboxId: string;
|
|
783
|
-
name: string;
|
|
784
|
-
}
|
|
785
|
-
interface Workspace {
|
|
786
|
-
workspaceId: string;
|
|
787
|
-
name: string;
|
|
788
|
-
}
|
|
789
|
-
/** A tool call held for user approval by an `ask`-mode sandbox. */
|
|
790
|
-
interface ToolApprovalSummary {
|
|
791
|
-
approvalId: string;
|
|
792
|
-
toolCallId: string;
|
|
793
|
-
toolName: string;
|
|
794
|
-
input: unknown;
|
|
795
|
-
}
|
|
796
|
-
interface AsyncStatus {
|
|
797
|
-
status: "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "completed" | "failed" | "expired" | "not_found";
|
|
798
|
-
requestedMode?: "reject" | "followup" | "collect" | "steer";
|
|
799
|
-
appliedMode?: "reject" | "followup" | "collect" | "steer";
|
|
800
|
-
appliedToEventId?: string;
|
|
801
|
-
result?: unknown;
|
|
802
|
-
response?: unknown;
|
|
803
|
-
error?: string;
|
|
804
|
-
/** True when `failed` was a deliberate /stop, not a fault. */
|
|
805
|
-
stoppedByUser?: boolean;
|
|
806
|
-
approvals?: ToolApprovalSummary[];
|
|
807
|
-
}
|
|
808
|
-
interface AsyncRequestAccepted {
|
|
809
|
-
statusUrl: string;
|
|
810
|
-
statusId: string;
|
|
811
|
-
eventId: string;
|
|
812
|
-
agentId: string;
|
|
813
|
-
status?: "accepted" | "queued" | "applied" | "processing";
|
|
814
|
-
requestedMode?: "reject" | "followup" | "collect" | "steer";
|
|
815
|
-
}
|
|
816
|
-
interface Cron {
|
|
817
|
-
accountId: string;
|
|
818
|
-
cronId: string;
|
|
819
|
-
name: string;
|
|
820
|
-
description?: string;
|
|
821
|
-
agentId: string;
|
|
822
|
-
events: ModelMessage[];
|
|
823
|
-
conversationKey?: string;
|
|
824
|
-
scheduleExpression: string;
|
|
825
|
-
timezone?: string;
|
|
826
|
-
status: CronStatus;
|
|
827
|
-
createdAt: string;
|
|
828
|
-
updatedAt: string;
|
|
829
|
-
lastInvokedAt?: string;
|
|
830
|
-
lastStatus?: CronLastStatus;
|
|
831
|
-
lastError?: string;
|
|
832
|
-
}
|
|
833
|
-
interface CronRun {
|
|
834
|
-
accountId: string;
|
|
835
|
-
cronId: string;
|
|
836
|
-
runId: string;
|
|
837
|
-
eventId: string;
|
|
838
|
-
conversationKey: string;
|
|
839
|
-
status: CronLastStatus;
|
|
840
|
-
result?: unknown;
|
|
841
|
-
error?: string;
|
|
842
|
-
startedAt: string;
|
|
843
|
-
completedAt?: string;
|
|
844
|
-
}
|
|
845
|
-
interface Skill {
|
|
846
|
-
path: string;
|
|
847
|
-
name: string;
|
|
848
|
-
description: string;
|
|
849
|
-
files?: Array<{
|
|
850
|
-
path: string;
|
|
851
|
-
size?: number;
|
|
852
|
-
}>;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
779
|
type StreamTextOptions = Parameters<typeof streamText>[0];
|
|
856
780
|
type JsonCallSettings = Partial<LanguageModelCallOptions & Pick<RequestOptions, "maxRetries" | "timeout">>;
|
|
857
781
|
type AgentRunModelOverrides = JsonCallSettings & Pick<StreamTextOptions, "providerOptions">;
|
|
@@ -890,8 +814,28 @@ declare function readSseStream(body: ReadableStream<Uint8Array>): AsyncGenerator
|
|
|
890
814
|
*/
|
|
891
815
|
|
|
892
816
|
type IngressMode = "reject" | "followup" | "collect" | "steer";
|
|
893
|
-
type IngressStatus = "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "completed" | "failed" | "expired";
|
|
817
|
+
type IngressStatus = "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "awaiting_input" | "completed" | "failed" | "expired";
|
|
818
|
+
/** One open `ask_questions` prompt while a run is `awaiting_input`. */
|
|
819
|
+
interface PendingQuestion {
|
|
820
|
+
/** Pass back as `answers[].statusId`. */
|
|
821
|
+
statusId: string;
|
|
822
|
+
/** After this the prompt settles as no_answer. */
|
|
823
|
+
answerBy: string;
|
|
824
|
+
questions: {
|
|
825
|
+
id: string;
|
|
826
|
+
header: string;
|
|
827
|
+
question: string;
|
|
828
|
+
options: {
|
|
829
|
+
label: string;
|
|
830
|
+
description?: string;
|
|
831
|
+
}[];
|
|
832
|
+
allowFreeText?: boolean;
|
|
833
|
+
}[];
|
|
834
|
+
}
|
|
894
835
|
type WebSocketStreamMessage = AgentStreamPart | {
|
|
836
|
+
type: "question-request";
|
|
837
|
+
questions: PendingQuestion[];
|
|
838
|
+
} | {
|
|
895
839
|
type: string;
|
|
896
840
|
[key: string]: unknown;
|
|
897
841
|
};
|
|
@@ -972,6 +916,100 @@ type WebSocketClientCancelMessage = {
|
|
|
972
916
|
};
|
|
973
917
|
type WebSocketClientMessage = WebSocketClientExecuteMessage | WebSocketClientControlMessage | WebSocketClientAttachMessage | WebSocketClientCancelMessage;
|
|
974
918
|
|
|
919
|
+
/**
|
|
920
|
+
* Wire types for the public account-manage and harness APIs. These mirror
|
|
921
|
+
* the deployed API contract (docs/api-reference/openapi.yaml is the source
|
|
922
|
+
* of truth); they are intentionally independent of the runtime internals so
|
|
923
|
+
* the SDK keeps working when the runtime is ported.
|
|
924
|
+
*/
|
|
925
|
+
|
|
926
|
+
interface Account {
|
|
927
|
+
account: {
|
|
928
|
+
accountId: string;
|
|
929
|
+
username: string;
|
|
930
|
+
};
|
|
931
|
+
secret: string;
|
|
932
|
+
}
|
|
933
|
+
interface Agent {
|
|
934
|
+
accountId: string;
|
|
935
|
+
agentId: string;
|
|
936
|
+
name: string;
|
|
937
|
+
}
|
|
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;
|
|
952
|
+
}
|
|
953
|
+
interface AsyncStatus {
|
|
954
|
+
status: "accepted" | "queued" | "applied" | "processing" | "awaiting_approval" | "awaiting_input" | "completed" | "failed" | "expired" | "not_found";
|
|
955
|
+
requestedMode?: "reject" | "followup" | "collect" | "steer";
|
|
956
|
+
appliedMode?: "reject" | "followup" | "collect" | "steer";
|
|
957
|
+
appliedToEventId?: string;
|
|
958
|
+
result?: unknown;
|
|
959
|
+
response?: unknown;
|
|
960
|
+
error?: string;
|
|
961
|
+
/** True when `failed` was a deliberate /stop, not a fault. */
|
|
962
|
+
stoppedByUser?: boolean;
|
|
963
|
+
approvals?: ToolApprovalSummary[];
|
|
964
|
+
questions?: PendingQuestion[];
|
|
965
|
+
}
|
|
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
|
+
interface Cron {
|
|
975
|
+
accountId: string;
|
|
976
|
+
cronId: string;
|
|
977
|
+
name: string;
|
|
978
|
+
description?: string;
|
|
979
|
+
agentId: string;
|
|
980
|
+
events: ModelMessage[];
|
|
981
|
+
conversationKey?: string;
|
|
982
|
+
scheduleExpression: string;
|
|
983
|
+
timezone?: string;
|
|
984
|
+
status: CronStatus;
|
|
985
|
+
createdAt: string;
|
|
986
|
+
updatedAt: string;
|
|
987
|
+
lastInvokedAt?: string;
|
|
988
|
+
lastStatus?: CronLastStatus;
|
|
989
|
+
lastError?: string;
|
|
990
|
+
}
|
|
991
|
+
interface CronRun {
|
|
992
|
+
accountId: string;
|
|
993
|
+
cronId: string;
|
|
994
|
+
runId: string;
|
|
995
|
+
eventId: string;
|
|
996
|
+
conversationKey: string;
|
|
997
|
+
status: CronLastStatus;
|
|
998
|
+
result?: unknown;
|
|
999
|
+
error?: string;
|
|
1000
|
+
startedAt: string;
|
|
1001
|
+
completedAt?: string;
|
|
1002
|
+
}
|
|
1003
|
+
interface Skill {
|
|
1004
|
+
path: string;
|
|
1005
|
+
name: string;
|
|
1006
|
+
description: string;
|
|
1007
|
+
files?: Array<{
|
|
1008
|
+
path: string;
|
|
1009
|
+
size?: number;
|
|
1010
|
+
}>;
|
|
1011
|
+
}
|
|
1012
|
+
|
|
975
1013
|
/**
|
|
976
1014
|
* Shared WebSocket wire-protocol types for the observability gateway, used by
|
|
977
1015
|
* the gateway, the SDK/CLI, and the dashboard. Pure types + tiny pure helpers,
|
|
@@ -1014,6 +1052,7 @@ type ObservabilitySubscribeMessage = {
|
|
|
1014
1052
|
backfill?: number;
|
|
1015
1053
|
liveOnly?: boolean;
|
|
1016
1054
|
minLevel?: LogLevel;
|
|
1055
|
+
sandboxId?: string;
|
|
1017
1056
|
};
|
|
1018
1057
|
type ObservabilityUnsubscribeMessage = {
|
|
1019
1058
|
type: "unsubscribe";
|
|
@@ -1046,6 +1085,11 @@ declare function isObservabilityClientMessage(v: unknown): v is ObservabilityCli
|
|
|
1046
1085
|
declare function isLogLevel(value: unknown): value is LogLevel;
|
|
1047
1086
|
/** Whether a span is a top-level run, each of which owns its own trace. */
|
|
1048
1087
|
declare function isRootSpanKind(kind: ObservabilitySpanRow["kind"]): boolean;
|
|
1088
|
+
/**
|
|
1089
|
+
* Narrow a wire value to a sandbox log id. Strict on purpose: the gateway
|
|
1090
|
+
* interpolates it into LogQL, so only the UUID shape core mints may pass.
|
|
1091
|
+
*/
|
|
1092
|
+
declare function isSandboxLogId(value: unknown): value is string;
|
|
1049
1093
|
|
|
1050
1094
|
/**
|
|
1051
1095
|
* Configurable client for running deployed agents over direct core SSE.
|
|
@@ -1183,7 +1227,7 @@ declare class BroodsClient {
|
|
|
1183
1227
|
getAsyncStatus(status: AsyncRequestAccepted | string, options?: {
|
|
1184
1228
|
agentId?: string;
|
|
1185
1229
|
}): Promise<AsyncStatus>;
|
|
1186
|
-
/** Poll async status until it reaches completed, failed, awaiting_approval, or timeout. */
|
|
1230
|
+
/** Poll async status until it reaches completed, failed, awaiting_approval, awaiting_input, or timeout. */
|
|
1187
1231
|
waitForAsyncStatus(status: AsyncRequestAccepted | string, options?: AsyncPollOptions & {
|
|
1188
1232
|
agentId?: string;
|
|
1189
1233
|
}): Promise<AsyncStatus>;
|
|
@@ -1404,6 +1448,18 @@ interface StageScope {
|
|
|
1404
1448
|
project: string;
|
|
1405
1449
|
stage: string;
|
|
1406
1450
|
}
|
|
1451
|
+
/**
|
|
1452
|
+
* OAuth 2.0 refresh-token grant on an external MCP row. The runtime mints and
|
|
1453
|
+
* refreshes access tokens and sends `Authorization: Bearer <token>` itself.
|
|
1454
|
+
* `clientSecret` and `refreshToken` must be `${NAME}` account env refs;
|
|
1455
|
+
* `tokenUrl` defaults to https://oauth2.googleapis.com/token.
|
|
1456
|
+
*/
|
|
1457
|
+
interface McpOauthInput {
|
|
1458
|
+
clientId: string;
|
|
1459
|
+
clientSecret: string;
|
|
1460
|
+
refreshToken: string;
|
|
1461
|
+
tokenUrl?: string;
|
|
1462
|
+
}
|
|
1407
1463
|
/** Public MCP server registration returned by the `/v1/mcp` routes (#331). */
|
|
1408
1464
|
interface AccountMcp {
|
|
1409
1465
|
accountId: string;
|
|
@@ -1418,6 +1474,7 @@ interface AccountMcp {
|
|
|
1418
1474
|
/** Hosted servers only: content hash of the uploaded bundle. */
|
|
1419
1475
|
sha256?: string;
|
|
1420
1476
|
headers?: Record<string, string>;
|
|
1477
|
+
oauth?: McpOauthInput;
|
|
1421
1478
|
allowedTools?: string[];
|
|
1422
1479
|
disabled: boolean;
|
|
1423
1480
|
status: string;
|
|
@@ -1437,6 +1494,7 @@ interface CreateMcpInput {
|
|
|
1437
1494
|
bundleStorageId?: string;
|
|
1438
1495
|
sha256?: string;
|
|
1439
1496
|
headers?: Record<string, string>;
|
|
1497
|
+
oauth?: McpOauthInput;
|
|
1440
1498
|
allowedTools?: string[];
|
|
1441
1499
|
}
|
|
1442
1500
|
/** Fields accepted by `PATCH /v1/mcp/{serverId}`; every field is optional. */
|
|
@@ -1448,6 +1506,7 @@ interface UpdateMcpInput {
|
|
|
1448
1506
|
bundleStorageId?: string;
|
|
1449
1507
|
sha256?: string;
|
|
1450
1508
|
headers?: Record<string, string>;
|
|
1509
|
+
oauth?: McpOauthInput;
|
|
1451
1510
|
allowedTools?: string[];
|
|
1452
1511
|
disabled?: boolean;
|
|
1453
1512
|
}
|
|
@@ -1757,7 +1816,7 @@ interface BroodsWebSocketClientOptions {
|
|
|
1757
1816
|
connectTimeoutMs?: number;
|
|
1758
1817
|
}
|
|
1759
1818
|
interface WebSocketConstructorLike {
|
|
1760
|
-
new (url: string): WebSocketLike;
|
|
1819
|
+
new (url: string, protocols?: string[]): WebSocketLike;
|
|
1761
1820
|
}
|
|
1762
1821
|
interface WebSocketLike {
|
|
1763
1822
|
readyState: number;
|
|
@@ -1786,6 +1845,13 @@ declare class BroodsWebSocketClient {
|
|
|
1786
1845
|
buildUrl(input: Pick<WebSocketRunInput, "agent" | "endpointId" | "projectSlug" | "stageSlug">): string;
|
|
1787
1846
|
private resolveWebSocket;
|
|
1788
1847
|
}
|
|
1848
|
+
/**
|
|
1849
|
+
* The credential travels as a `Sec-WebSocket-Protocol` entry rather than in
|
|
1850
|
+
* the URL, so it never lands in proxy or access logs. The gateway answers
|
|
1851
|
+
* with `broods.v1`, which is what completes a handshake that offered
|
|
1852
|
+
* subprotocols.
|
|
1853
|
+
*/
|
|
1854
|
+
declare function webSocketSubprotocols(apiKey: string): string[];
|
|
1789
1855
|
|
|
1790
1856
|
declare function toWebSocketBaseUrl(url: string): string;
|
|
1791
1857
|
|
|
@@ -1899,7 +1965,7 @@ interface McpDefinitionConfig {
|
|
|
1899
1965
|
* Hosted alternative to `url`: declare the server inline —
|
|
1900
1966
|
* `handler: createMcpHandler(...)` from @modelcontextprotocol/server,
|
|
1901
1967
|
* right next to the `defineMcp` call. The CLI bundles the defining module
|
|
1902
|
-
* and the tool-runner Lambda hosts it, one invoke per
|
|
1968
|
+
* and the tool-runner Lambda hosts it, one invoke per batch of requests.
|
|
1903
1969
|
*/
|
|
1904
1970
|
handler?: McpHandler;
|
|
1905
1971
|
/**
|
|
@@ -1908,6 +1974,20 @@ interface McpDefinitionConfig {
|
|
|
1908
1974
|
* `Bearer ${env("TOKEN")}` — never carry an inline secret.
|
|
1909
1975
|
*/
|
|
1910
1976
|
headers?: Record<string, string>;
|
|
1977
|
+
/**
|
|
1978
|
+
* OAuth 2.0 refresh-token grant for an external server whose access tokens
|
|
1979
|
+
* expire (Google's Workspace MCP endpoints). The runtime mints, caches and
|
|
1980
|
+
* refreshes access tokens and sends `Authorization: Bearer <token>` itself,
|
|
1981
|
+
* so do not also set an Authorization header. `clientSecret` and
|
|
1982
|
+
* `refreshToken` must be `env("NAME")` refs; `tokenUrl` defaults to
|
|
1983
|
+
* https://oauth2.googleapis.com/token.
|
|
1984
|
+
*/
|
|
1985
|
+
oauth?: {
|
|
1986
|
+
clientId: string | EnvRef;
|
|
1987
|
+
clientSecret: string | EnvRef;
|
|
1988
|
+
refreshToken: string | EnvRef;
|
|
1989
|
+
tokenUrl?: string;
|
|
1990
|
+
};
|
|
1911
1991
|
/** Tool names agents may use from this server; omit to allow all. */
|
|
1912
1992
|
allowedTools?: string[];
|
|
1913
1993
|
}
|
|
@@ -2298,5 +2378,5 @@ declare function isResource(value: unknown): value is AnyResource;
|
|
|
2298
2378
|
declare function isConnectionDefinition(value: unknown): value is AnyConnectionDefinition;
|
|
2299
2379
|
declare function isBroodsConfig(value: unknown): value is BroodsConfigDefinition;
|
|
2300
2380
|
|
|
2301
|
-
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, normalizeHttpServiceUrl, readSseStream, resolveEnvCredential, resolveRunEvents, toWebSocketBaseUrl };
|
|
2302
|
-
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, McpResource, ObservabilityBackfillMessage, ObservabilityClientMessage, ObservabilityErrorMessage, ObservabilityLogEntry, ObservabilityLogMessage, ObservabilityReadyMessage, ObservabilityServerMessage, ObservabilitySpanMessage, ObservabilitySpanRow, ObservabilitySubscribeMessage, ObservabilityUnsubscribeMessage, PancakeChannelInput, PancakeConnectionDefinition, PancakeConnectionInput, PancakeMessageSource, PancakeSource, 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 };
|
|
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 };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "broods",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.33.0",
|
|
4
4
|
"description": "CLI + TypeScript SDK for the broods agent platform.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agents",
|
|
@@ -54,28 +54,33 @@
|
|
|
54
54
|
"test": "bun test"
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"
|
|
58
|
-
"esbuild": "^0.28.2",
|
|
59
|
-
"zod": "^4.4.3"
|
|
57
|
+
"esbuild": "^0.28.2"
|
|
60
58
|
},
|
|
61
59
|
"devDependencies": {
|
|
62
|
-
"@ai-sdk/tui": "1.0.
|
|
60
|
+
"@ai-sdk/tui": "1.0.88",
|
|
63
61
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
64
62
|
"@chat-adapter/discord": "^4.38.1",
|
|
65
63
|
"@chat-adapter/github": "^4.38.1",
|
|
66
64
|
"@chat-adapter/slack": "^4.38.1",
|
|
67
65
|
"@chat-adapter/telegram": "^4.38.1",
|
|
68
66
|
"@modelcontextprotocol/client": "^2.0.0",
|
|
67
|
+
"@modelcontextprotocol/server": "2.0.0",
|
|
69
68
|
"@types/bun": "^1.3.14",
|
|
70
69
|
"@typescript/typescript6": "6.0.2",
|
|
71
|
-
"ai": "^7.0.
|
|
70
|
+
"ai": "^7.0.87",
|
|
72
71
|
"publint": "^0.3.23",
|
|
73
72
|
"rollup": "^4.62.4",
|
|
74
73
|
"rollup-plugin-dts": "^6.5.1",
|
|
75
|
-
"typescript": "^7.0.2"
|
|
74
|
+
"typescript": "^7.0.2",
|
|
75
|
+
"zod": "^4.4.3"
|
|
76
76
|
},
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"ai": "^7.0.
|
|
78
|
+
"ai": "^7.0.87"
|
|
79
|
+
},
|
|
80
|
+
"peerDependenciesMeta": {
|
|
81
|
+
"ai": {
|
|
82
|
+
"optional": true
|
|
83
|
+
}
|
|
79
84
|
},
|
|
80
85
|
"engines": {
|
|
81
86
|
"node": ">=22.15"
|
package/dist/chunk-2tqw3gxy.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{T as R,U as E}from"./chunk-yy11cxjg.js";import{V as o,pa as g}from"./chunk-zk2w6bee.js";import"./chunk-e66afphr.js";import"./chunk-rx5qcgbh.js";var y={project:o.string().optional(),stage:o.string().optional()},I={sandboxId:o.string().min(1),reservationKey:o.string().min(1)},h=o.boolean().describe("Must be true, after the owner has agreed to this delete."),S="'********' keeps a stored secret and null deletes a field: never send a placeholder you did not read from a get.",C=[{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:S,list:(e)=>e.listAgents(),get:(e,t)=>e.getAgent(t),create:(e,t)=>e.createAgent(t),update:(e,t,s)=>e.updateAgent(t,s),remove:(e,t)=>e.deleteAgent(t)},{singular:"cron",plural:"crons",key:"cronId",createHint:"Needs name, agentId, scheduleExpression (rate/cron/at) and input or events.",list:(e)=>e.listCrons(),get:(e,t)=>e.getCron(t),create:(e,t)=>e.createCron(t),update:(e,t,s)=>e.updateCron(t,s),remove:(e,t)=>e.deleteCron(t)},{singular:"sandbox",plural:"sandboxes",key:"sandboxId",updateHint:S,list:(e)=>e.listSandboxes(),get:(e,t)=>e.getSandbox(t),create:(e,t)=>e.createSandbox(t),update:(e,t,s)=>e.updateSandbox(t,s),remove:(e,t)=>e.deleteSandbox(t)},{singular:"workspace",plural:"workspaces",key:"workspaceId",list:(e)=>e.listWorkspaces(),get:(e,t)=>e.getWorkspace(t),create:(e,t)=>e.createWorkspace(t),update:(e,t,s)=>e.updateWorkspace(t,s),remove:(e,t)=>e.deleteWorkspace(t)},{singular:"policy",plural:"policies",key:"policyId",createHint:"Agent-runtime policy document (tool.call, skill.load), not API credential scoping.",list:(e)=>e.listPolicies(),get:(e,t)=>e.getPolicy(t),create:(e,t)=>e.createPolicy(t),update:(e,t,s)=>e.updatePolicy(t,s),remove:(e,t)=>e.deletePolicy(t)},{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:(e)=>e.listRoles(),get:(e,t)=>e.getRole(t),create:(e,t)=>e.createRole(t),update:(e,t,s)=>e.updateRole(t,s),remove:(e,t)=>e.deleteRole(t)},{singular:"channel",plural:"channels",key:"channelId",list:(e)=>e.listChannels(),get:(e,t)=>e.getChannel(t),create:(e,t)=>e.createChannel(t),update:(e,t,s)=>e.updateChannel(t,s),remove:(e,t)=>e.deleteChannel(t)},{singular:"skill",plural:"skills",key:"skillName",createHint:'source is "files" (base64), "json" or "github". The stored name comes from the SKILL.md frontmatter.',list:(e)=>e.listSkills(),get:(e,t)=>e.getSkill(t),create:(e,t)=>e.createSkill(t),remove:(e,t)=>e.deleteSkill(t)},{singular:"mcp",plural:"mcp",key:"serverId",scoped:!0,list:(e,t)=>e.listMcp(t),get:(e,t)=>e.getMcp(t),create:(e,t,s)=>e.createMcp(s,t),update:(e,t,s)=>e.updateMcp(t,s),remove:(e,t)=>e.deleteMcp(t)}];function Mt(e={}){let t=R()?new E({}):null;if(!t&&!e.cli)throw Error("broods mcp needs a credential: set BROODS_SESSION_TOKEN or BROODS_ACCOUNT_SECRET, or run `broods login`.");let s=new g({name:"broods",version:"1"},{capabilities:{tools:{}}});if(t){for(let r of C)k(s,t,r,e.scope??{});P(s,t)}if(e.cli)O(s,e.cli);if(e.allowDestructive)q(s,t,e.cli??null);return s}function M(e){return{content:[{type:"text",text:JSON.stringify(e??null,null,2)}]}}function A(e){return{content:[{type:"text",text:e instanceof Error?e.message:String(e)}],isError:!0}}function f(e,t){if(!e)throw Error(`Refusing without confirm:true. ${t}`)}async function a(e){try{return M(await e())}catch(t){return A(t)}}function _(e,t,s,r){if(!e.scoped)return;let n=s??t.project,c=r??t.stage;if(!n||!c)throw Error(`${e.plural} live in one stage, so this call needs both 'project' and 'stage'`);return{project:n,stage:c}}function k(e,t,s,r){let n=o.string().min(1).describe(`The ${s.key}.`),c=s.scoped?` ${s.plural} live in one stage, so this also takes 'project' and 'stage'.`:"",{list:d,get:p,create:m,update:v,remove:w}=s;if(d){let i=`List every ${s.singular} on the account.${c}`;if(s.scoped)e.registerTool(`list-${s.plural}`,{description:i,inputSchema:y},async({project:l,stage:u})=>await a(async()=>await d(t,_(s,r,l,u))));else e.registerTool(`list-${s.plural}`,{description:i,inputSchema:{}},async()=>await a(async()=>await d(t)))}if(p)e.registerTool(`get-${s.singular}`,{description:`Read one ${s.singular} by ${s.key}.`,inputSchema:{id:n}},async({id:i})=>await a(async()=>await p(t,i)));if(m){let i=`Create one ${s.singular}. 'body' is the request body the config plane documents.`+(s.createHint?` ${s.createHint}`:"")+c+" Prefer changing the broods/ manifest and deploying for anything the project already declares.",l=o.record(o.string(),o.unknown());if(s.scoped)e.registerTool(`create-${s.singular}`,{description:i,inputSchema:{body:l,...y}},async({body:u,project:b,stage:T})=>await a(async()=>await m(t,u,_(s,r,b,T))));else e.registerTool(`create-${s.singular}`,{description:i,inputSchema:{body:l}},async({body:u})=>await a(async()=>await m(t,u)))}if(v)e.registerTool(`update-${s.singular}`,{description:`Deep-merge a patch into one ${s.singular} and return the updated record, so there is no need to read it back.`+(s.updateHint?` ${s.updateHint}`:""),inputSchema:{id:n,body:o.record(o.string(),o.unknown())}},async({id:i,body:l})=>await a(async()=>await v(t,i,l)));if(w)e.registerTool(`delete-${s.singular}`,{description:`Delete one ${s.singular}. Requires confirm:true, and takes one ${s.key} per call: never loop this over a list.`+(s.deleteHint?` ${s.deleteHint}`:""),inputSchema:{id:n,confirm:h}},async({id:i,confirm:l})=>await a(async()=>(f(l,`Deleting ${s.singular} '${i}' goes away for good: name it, get the owner's agreement, then retry.`),{deleted:await w(t,i),id:i})))}function P(e,t){e.registerTool("list-cron-runs",{description:"Run history for one cron, newest first. Check this before telling anyone a cron fired.",inputSchema:{cronId:o.string().min(1),limit:o.number().int().positive().max(100).optional()}},async({cronId:r,limit:n})=>await a(async()=>await t.listCronRuns(r,n===void 0?{}:{limit:n})));let s=[["suspend-sandbox","Suspend a persistent sandbox reservation.",(r,n)=>t.suspendSandbox(r,n)],["resume-sandbox","Resume a suspended sandbox reservation.",(r,n)=>t.resumeSandbox(r,n)],["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.",(r,n)=>t.terminateSandbox(r,n)],["open-sandbox-terminal","Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox.",(r,n)=>t.openSandboxTerminal(r,n)]];for(let[r,n,c]of s)e.registerTool(r,{description:n,inputSchema:I},async({sandboxId:d,reservationKey:p})=>await a(async()=>await c(d,p)));e.registerTool("snapshot-sandbox",{description:"Snapshot a sandbox reservation into a reusable image (self-hosted provider).",inputSchema:{sandboxId:o.string().min(1),reservationKey:o.string().min(1),name:o.string().min(1)}},async({sandboxId:r,reservationKey:n,name:c})=>await a(async()=>await t.snapshotSandbox(r,n,c))),e.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:o.string().min(1).describe("The skillName."),body:o.record(o.string(),o.unknown())}},async({id:r,body:n})=>await a(async()=>await t.uploadSkill(r,n))),e.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 a(async()=>await t.listEnvVars())),e.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:o.string().min(1),value:o.string()}},async({name:r,value:n})=>await a(async()=>(await t.setEnvVar(r,n),{name:r,stored:!0}))),e.registerTool("delete-env-var",{description:"Delete one environment variable.",inputSchema:{name:o.string().min(1),confirm:h}},async({name:r,confirm:n})=>await a(async()=>(f(n,`Anything referencing \${${r}} breaks the moment this env var goes.`),{deleted:await t.deleteEnvVar(r),name:r}))),e.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:o.string().min(1),ttlSeconds:o.number().int().positive().max(43200).optional()}},async({roleId:r,ttlSeconds:n})=>await a(async()=>await t.assumeRole(r,n===void 0?{}:{ttlSeconds:n}))),e.registerTool("update-account",{description:"Rename this account or change its description. Everything else about an account is derived, not settable.",inputSchema:{username:o.string().optional(),description:o.string().nullable().optional()}},async({username:r,description:n})=>await a(async()=>await t.updateAccount({...r===void 0?{}:{username:r},...n===void 0?{}:{description:n}}))),e.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 a(async()=>await t.getAccount()))}function O(e,t){e.registerTool("list-orgs",{description:"Every organization this login can reach, with the current one marked.",inputSchema:{}},async()=>await a(async()=>{let s=await t.getOnboarding();return{currentOrgId:s.currentOrgId,orgs:s.orgs}})),e.registerTool("create-org",{description:"Create an organization and switch this login to it. Later calls act in the new org.",inputSchema:{name:o.string().min(1)}},async({name:s})=>await a(async()=>await t.createOnboardingOrg(s))),e.registerTool("select-org",{description:"Switch this login to another organization, by an orgId from list-orgs.",inputSchema:{orgId:o.string().min(1)}},async({orgId:s})=>await a(async()=>await t.selectOnboardingOrg(s))),e.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 a(async()=>await t.listProjects())),e.registerTool("list-stages",{description:"Every stage of one project, by project name.",inputSchema:{project:o.string().min(1)}},async({project:s})=>await a(async()=>await t.listStages(s))),e.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:o.string().min(1),name:o.string().min(1),from:o.string().optional().describe("Stage to clone architecture and env vars from.")}},async({project:s,name:r,from:n})=>await a(async()=>await t.createStage(s,r,n)))}function q(e,t,s){if(t)e.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:h}},async({confirm:r})=>await a(async()=>(f(r,"Everything holding the current secret breaks the moment this runs."),await t.rotateSecret())));if(s)e.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:o.string().min(1),confirm:h}},async({projectId:r,confirm:n})=>await a(async()=>(f(n,`Project '${r}' and everything under it goes away: name it, get the owner's agreement, then retry.`),await s.deleteProject(r))))}export{Mt as createBroodsMcpServer};
|
package/dist/chunk-3qpgf0c1.js
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
function k(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*D(e){let n=e.getReader(),t=new TextDecoder,o="";try{while(!0){let{done:r,value:s}=await n.read();if(r)break;o+=t.decode(s,{stream:!0});let i=o.split(`
|
|
2
|
-
`);o=i.pop()??"";for(let a of i)if(a.startsWith("data: "))yield a.slice(6)}}finally{n.releaseLock()}}import{mkdir as Q,readFile as ee,writeFile as ne}from"node:fs/promises";import{homedir as te}from"node:os";import{dirname as oe,join as re}from"node:path";var Ee="broods",De="_generated",h=re(te(),".broods","config.json"),N="broods.app",O="dashboard",se="gateway";async function Ne(){let e=process.env.BROODS_TOKEN,n=process.env.BROODS_BASE_URL;if(e&&n)return{baseUrl:d(n),token:e,createdAt:new Date().toISOString()};try{let t=JSON.parse(await ee(h,"utf8"));if(typeof t.baseUrl!=="string"||!t.baseUrl)return null;return t}catch{return null}}async function Oe(e){await Q(oe(h),{recursive:!0}),await ne(h,`${JSON.stringify(e,null,2)}
|
|
3
|
-
`,"utf8")}function T(){return process.env.BROODS_STAGE}function d(e){let n=e.length;while(n>0&&e.charCodeAt(n-1)===47)n-=1;return e.slice(0,n)}function Te(e){try{let n=new URL(e);if(!n.hostname.startsWith(`${O}.`))return;let t=n.hostname.slice(O.length+1);if(t!==N&&!t.endsWith(`.${N}`))return;return n.hostname=`${se}.${t}`,d(n.origin)}catch{return}}import{existsSync as U,readFileSync as E,statSync as ie}from"node:fs";import{join as W,resolve as M}from"node:path";var v=new Map,ae=new Set(Object.keys(process.env)),P=new Set;function I(e=process.cwd()){ce(e);let n=de();return{dashboardUrl:process.env.BROODS_DASHBOARD_URL??n?.dashboardUrl,baseUrl:process.env.BROODS_BASE_URL??n?.baseUrl,token:process.env.BROODS_TOKEN??n?.token,project:process.env.BROODS_PROJECT,stage:T()}}function $e(e,n=process.cwd()){let t=process.env[e];if(t===void 0)return!1;let o=M(n);for(let r of[".env.local",".env"]){let s=W(o,r);if(!U(s))continue;let i=_(E(s,"utf8"));if(i[e]!==void 0)return i[e]!==t}return!0}function ce(e){let n=M(e),t=process.env.BROODS_RELOAD_ENV==="1";for(let o of[".env",".env.local"]){let r=W(n,o);if(!U(r)){v.delete(r);continue}let s=ie(r).mtimeMs,i=v.get(r);if(i&&i.mtimeMs===s)continue;v.set(r,{mtimeMs:s});for(let[a,u]of Object.entries(_(E(r,"utf8"))))if(t||!ae.has(a)||P.has(a))process.env[a]=u,P.add(a)}}function _(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,s=r.indexOf("=");if(s<=0)continue;let i=r.slice(0,s).trim();if(!/^[A-Za-z_][A-Za-z0-9_]*$/.test(i))continue;n[i]=ue(r.slice(s+1).trim())}return n}function ue(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}function de(){try{let e=JSON.parse(E(h,"utf8"));if(typeof e.baseUrl!=="string"||typeof e.token!=="string")return null;return{baseUrl:d(e.baseUrl),...typeof e.dashboardUrl==="string"?{dashboardUrl:d(e.dashboardUrl)}:{},token:e.token}}catch{return null}}var x="https://gateway.broods.app";class B extends Error{accepted;constructor(e){super(`Ingress ${e.eventId} was accepted asynchronously with status ${e.status??"queued"}`);this.accepted=e;this.name="IngressAcceptedError"}}class le{baseUrl;apiKey;fetchImpl;constructor(e={}){I(),this.baseUrl=A(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||x),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}/webhooks/${t.join("/")}`}stageWebhookUrl(e,n,t){let o=[e,"dev",n,t].map(encodeURIComponent);return`${this.baseUrl}/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:(s)=>this.run({...s,agentName:o,agentId:r}),runAsync:(s)=>this.runAsync({...s,agentName:o,agentId:r}),stream:(s)=>this.stream({...s,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),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 s of r)if(t.push(s),s.type==="text-delta")o+=s.text;return{text:o,events:t}}async*stream(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o=K(t,"cli"),r=n?this.scopedUrl(e):this.baseUrl,s=await this.openStream(o,r);if(!s.ok)throw Error(`Run failed: ${s.status} ${await s.text()}`);if(s.status===202)throw new B(H(await s.json(),o));if(!s.body)throw Error("Run response has no body");for await(let i of D(s.body)){let a;try{a=JSON.parse(i)}catch{continue}if(a.type==="error")throw Error(`Agent run failed: ${he(a.error)}`);yield a}}async runAsync(e,n){let t=n?{...n,agentId:e.id,agentName:e.name}:e,o=K(t,"async"),r=n?this.scopedUrl(e,"/async"):`${this.baseUrl}/async`,s=await this.fetchJson(r,{method:"POST",headers:this.apiKeyHeaders(),body:JSON.stringify(o)});if(s.status!==202)throw Error(`Async run failed: ${s.status} ${await fe(s,"202 JSON")}`);let i=H(await s.json(),o);return{...i,conversationKey:o.conversationKey,poll:()=>this.getAsyncStatus(i),wait:(a)=>this.waitForAsyncStatus(i,a)}}async getAsyncStatus(e,n={}){let t=this.resolveStatusUrl(e,n),o=await this.fetchJson(t,{method:"GET",headers:this.apiKeyHeaders()});if(o.status===404)return{status:"not_found"};if(!o.ok)throw Error(`Status check failed: ${o.status} ${await o.text()}`);return await o.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,n);if(r.status==="awaiting_approval"||r.status==="completed"||r.status==="failed"||r.status==="expired"||r.status==="not_found")return r;await ye(o,n.signal)}throw Error("Polling timeout")}async createCron(e){let n=await this.fetchJson(`${this.baseUrl}/v1/crons`,{method:"POST",headers:this.apiKeyHeaders(),body:JSON.stringify(me(e))});if(n.status!==201)throw Error(`Create cron job failed: ${n.status} ${await p(n)}`);return await n.json()}async listCrons(){let e=await this.fetchJson(`${this.baseUrl}/v1/crons`,{method:"GET",headers:this.apiKeyHeaders()});if(!e.ok)throw Error(`List cron jobs failed: ${e.status} ${await p(e)}`);return(await e.json()).crons}async getCron(e){let n=await this.fetchJson(`${this.baseUrl}/v1/crons/${encodeURIComponent(e)}`,{method:"GET",headers:this.apiKeyHeaders()});if(n.status===404)return null;if(!n.ok)throw Error(`Get cron job failed: ${n.status} ${await p(n)}`);return await n.json()}async listCronRuns(e,n={}){let t=new URLSearchParams;if(n.limit!==void 0)t.set("limit",String(n.limit));let o=t.size>0?`?${t}`:"",r=await this.fetchJson(`${this.baseUrl}/v1/crons/${encodeURIComponent(e)}/runs${o}`,{method:"GET",headers:this.apiKeyHeaders()});if(!r.ok)throw Error(`List cron job runs failed: ${r.status} ${await p(r)}`);return(await r.json()).runs}async updateCron(e,n){let t=await this.fetchJson(`${this.baseUrl}/v1/crons/${encodeURIComponent(e)}`,{method:"PATCH",headers:this.apiKeyHeaders(),body:JSON.stringify(n)});if(!t.ok)throw Error(`Update cron job failed: ${t.status} ${await p(t)}`);return await t.json()}async deleteCron(e){let n=await this.fetchJson(`${this.baseUrl}/v1/crons/${encodeURIComponent(e)}`,{method:"DELETE",headers:this.apiKeyHeaders()});if(n.status===404)return!1;if(!n.ok)throw Error(`Delete cron job failed: ${n.status} ${await p(n)}`);return(await n.json()).deleted}scopedUrl(e,n=""){if(e.projectSlug&&e.stageSlug&&e.endpointId)return`${this.baseUrl}/v1/${encodeURIComponent(e.projectSlug)}/agents/${encodeURIComponent(e.stageSlug)}/${encodeURIComponent(e.endpointId)}${n}`;return`${this.baseUrl}${n}`}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 ${x} 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,headers:{"Content-Type":"application/json",...n.headers}})}catch(t){throw Error(`Cannot access the broods core service at ${e}. Cause: ${t instanceof Error?t.message:String(t)}`)}}resolveStatusUrl(e,n){if(typeof e!=="string")return e.statusUrl;if(/^https?:\/\//.test(e))return e;if(!n.agentId)throw Error("Polling by status id requires agentId.");return pe(this.baseUrl,e,n.agentId)}}function A(e){let n=e.trim(),t=/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(n)?n:`https://${n}`;return d(t)}function K(e,n){let t=e.eventId??`${n}-${Date.now()}`;return{agentId:e.agentId,eventId:t,conversationKey:e.conversationKey??t,events:k(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 H(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=ge(t);if(!o.statusId)throw Error("Async response statusUrl missing status id");let r=typeof e.eventId==="string"?e.eventId:o.statusId,s=e.status,i=e.requestedMode;return{statusUrl:t,statusId:o.statusId,eventId:r,agentId:o.agentId??n.agentId,...s==="accepted"||s==="queued"||s==="applied"||s==="processing"?{status:s}:{},...i==="reject"||i==="followup"||i==="collect"||i==="steer"?{requestedMode:i}:{}}}function ge(e){let n=new URL(e),t=n.pathname.match(/\/status\/([^/]+)$/);return{statusId:t?.[1]?decodeURIComponent(t[1]):void 0,agentId:n.searchParams.get("agentId")??void 0}}function pe(e,n,t){return`${A(e)}/status/${encodeURIComponent(n)}?agentId=${encodeURIComponent(t)}`}async function fe(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 routed /async to the direct streaming runner instead of the async handler.`;let o=await e.text();if(o.length<=2000)return o;return`${o.slice(0,2000)}... [truncated ${o.length-2000} chars]`}async function p(e){let n=await e.text();if(n.includes("Request body must include eventId and conversationKey"))return`${n}. Cron job APIs must be served by the configured baseUrl. Prefer defining stable cron jobs with defineCron(...) in broods/ and syncing with \`broods dev\` or \`broods deploy\`.`;return n}function me(e){if("agentId"in e)return e;let n=e.agent,t=typeof n==="string"?n:n.id,{agent:o,...r}=e;return{...r,agentId:t}}function ye(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 he(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}`}var Ce=2000,j=0,C=1;class Se{baseUrl;apiKey;WebSocketImpl;connectTimeoutMs;constructor(e={}){if(I(),this.baseUrl=F(e.baseUrl||e.host||process.env.BROODS_BASE_URL||process.env.BROODS_HOST||x),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??Ce}subscribe(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=Re(e),s=L(this.baseUrl),i=new t(o),a=!1,u=!1,l=setTimeout(()=>{if(!a)y(s)},this.connectTimeoutMs),w=(c=1000,R="client closed")=>{if(u)return;if(u=!0,clearTimeout(l),e.signal?.removeEventListener("abort",S),i.readyState===C||i.readyState===j)i.close(c,R)},y=(c)=>{n.onError?.(c),w(1011,"websocket error")},X=()=>{n.onDone?.(),w(1000,"done")},S=()=>{if(i.readyState===C)i.send(JSON.stringify({type:"cancel"}));y(Error("WebSocket run aborted."))};return e.signal?.addEventListener("abort",S,{once:!0}),i.onopen=()=>{if(a=!0,clearTimeout(l),e.signal?.aborted){S();return}i.send(JSON.stringify({type:"execute",agentId:r,events:k(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}:{}}))},i.onmessage=(c)=>{if(typeof c.data!=="string")return;let R=q(c.data);if(!R)return;let b=G(R,n);switch(n.onMessage?.(b),b.type){case"meta":n.onMeta?.(b);break;case"done":X();break;case"error":y(Error(J(b.error)));break}},i.onerror=()=>{y(s)},i.onclose=(c)=>{if(clearTimeout(l),e.signal?.removeEventListener("abort",S),u||c.code===1000)return;y(Error(c.reason||"WebSocket connection closed."))},{url:o,sendControl:function(c){if(i.readyState!==C)throw Error("WebSocket is not open");i.send(JSON.stringify({type:"control",...c}))},close:w}}attach(e,n={}){let t=this.resolveWebSocket(),o=this.buildUrl(e),r=new t(o),s=!1,i=(a=1000,u="client closed")=>{if(s)return;if(s=!0,r.readyState===C||r.readyState===j)r.close(a,u)};return r.onopen=()=>r.send(JSON.stringify({type:"attach",...e,signal:void 0,agent:void 0})),r.onmessage=(a)=>{if(typeof a.data!=="string")return;let u=q(a.data);if(!u)return;let l=G(u,n);if(n.onMessage?.(l),l.type==="done")n.onDone?.();if(l.type==="error")n.onError?.(Error(J(l.error)))},r.onerror=()=>n.onError?.(L(this.baseUrl)),r.onclose=(a)=>{if(!s&&a.code!==1000)n.onError?.(Error(a.reason||"WebSocket connection closed."))},{url:o,sendControl:function(a){if(r.readyState!==C)throw Error("WebSocket is not open");r.send(JSON.stringify({type:"control",...a}))},close:i}}async*stream(e){let n=[],t=!1,o=null,r=null,s=()=>{r?.(),r=null},i=this.subscribe(e,{onMessage:function(a){n.push(a),s()},onDone:function(){t=!0,s()},onError:function(a){o=a,s()}});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{i.close()}}buildUrl(e){let n=be(e),t=e.projectSlug??e.agent?.projectSlug,o=e.stageSlug??e.agent?.stageSlug,r=t?`/${t}`:"",s=o?`/${o}`:"";return`${ke(this.baseUrl)}/v1${r}/agents${s}/${encodeURIComponent(n)}/ws?token=${encodeURIComponent(this.apiKey)}`}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 Re(e){let n=e.agentId??e.agent?.id??e.endpointId;if(!n)throw Error("WebSocket run requires agent, agentId, or endpointId.");return n}function be(e){let n=e.endpointId??e.agent?.endpointId??e.agent?.id;if(!n)throw Error("WebSocket run requires agent or endpointId.");return n}function ke(e){let n=new URL(F(e));if(n.protocol==="https:")n.protocol="wss:";if(n.protocol==="http:")n.protocol="ws:";return d(n.toString())}function F(e){let n=e.trim();if(/^wss?:\/\//.test(n))return d(n);return A(n)}function L(e){return Error(`Cannot access the WebSocket service at ${e}.`)}function G(e,n){if(e.type!=="output")return e;let t=e;return n.onOutput?.(t),t.data}function q(e){try{let n=JSON.parse(e);return typeof n==="object"&&n!==null&&typeof n.type==="string"?n:null}catch{return null}}function J(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)}var z=Symbol.for("broods.resource"),V=Symbol.for("broods.config"),Y=Symbol.for("broods.connection"),Z=/^[A-Z][A-Z0-9_]{0,63}$/,ze=new Proxy((e)=>{if(!Z.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"&&Z.test(n))throw Error(`env.${n} is not supported; use env("${n}")`);return Reflect.get(e,n,t)}});function g(e,n,t,o){return{[z]:!0,kind:e,name:n,...t?{description:t}:{},config:o}}function f(e,n){let{partition:t,...o}=n;return{[Y]:!0,kind:"connection",type:e,...t?{partition:t}:{},config:o}}function m(e,n,t,o,r){return g("channelRecord",e,n,{...r,externalId:t,...o?{workspaceRef:o}:{}})}function Ve(e){return f("discord",e)}function Ye(e){return f("github",e)}function Xe(e){return f("pancake",e)}function Qe(e){return f("slack",e)}function en(e){return f("telegram",e)}function nn(e){return f("zalo",e)}function tn(e){let{name:n,description:t,channelId:o,guildId:r,...s}=e;return m(n,t,o,r,s)}function on(e){let{name:n,description:t,repo:o,...r}=e,[s,...i]=o.split("/");if(!s||i.length!==1||!i[0])throw Error(`Channel "${n}" repo must be "owner/name", not "${o}"`);return m(n,t,o,s,r)}function rn(e){let{name:n,description:t,conversationId:o,...r}=e;return m(n,t,o,void 0,r)}function sn(e){let{name:n,description:t,channelId:o,teamId:r,...s}=e;return m(n,t,o,r,s)}function an(e){let{name:n,description:t,chatId:o,...r}=e;return m(n,t,o,void 0,r)}function cn(e){let{name:n,description:t,chatId:o,...r}=e;return m(n,t,o,void 0,r)}function un(e){return{[V]:!0,config:e}}function dn(e){let{name:n,description:t,...o}=e;return g("agent",n,t,o)}function ln(e){return e}function gn(e){let{name:n,description:t,...o}=e;return g("workspace",n,t,o)}function pn(e){let{name:n,description:t,...o}=e;return g("sandbox",n,t,o)}function fn(e){let{name:n,description:t,...o}=e;return g("skill",n,t,o)}function mn(e){let{name:n,description:t,...o}=e;return g("mcp",n,t,o)}function yn(e){let{name:n,description:t,...o}=e;return g("policy",n,t,o)}function hn(e){let{name:n,description:t,...o}=e;return g("cron",n,t,o)}function Cn(e){return Boolean(e&&typeof e==="object"&&e[z])}function Sn(e){return Boolean(e&&typeof e==="object"&&e[Y])}function Rn(e){return Boolean(e&&typeof e==="object"&&e[V])}
|
|
5
|
-
export{k as a,D as b,Ee as c,De as d,h as e,Ne as f,Oe as g,T as h,d as i,Te as j,I as k,$e as l,x as m,B as n,le as o,A as p,Se as q,ke as r,ze as s,Ve as t,Ye as u,Xe as v,Qe as w,en as x,nn as y,tn as z,on as A,rn as B,sn as C,an as D,cn as E,un as F,dn as G,ln as H,gn as I,pn as J,fn as K,mn as L,yn as M,hn as N,Cn as O,Sn as P,Rn as Q};
|
package/dist/chunk-736tg90p.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{$ as k,W as _,X as q,Y as C,Z as P,_ as j,aa as D,ba as p,ca as v,da as z,ea as A,fa as M,ga as J,ha as L,ia as U,ja as x,ka as O,la as g,ma as F,na as X,oa as H,pa as Q}from"./chunk-zk2w6bee.js";import"./chunk-e66afphr.js";import"./chunk-rx5qcgbh.js";var re=class{_readBuffer;_started=!1;_closed=!1;constructor(r=O.stdin,o=O.stdout,a){this._stdin=r,this._stdout=o,this._readBuffer=new U({maxBufferSize:a?.maxBufferSize})}onclose;onerror;onmessage;_ondata=(r)=>{try{this._readBuffer.append(r),this.processReadBuffer()}catch(o){this.onerror?.(o),this.close().catch(()=>{})}};_onerror=(r)=>{this.onerror?.(r)};_onstdouterror=(r)=>{this.onerror?.(r),this.close().catch(()=>{})};async start(){if(this._started)throw Error("StdioServerTransport already started! If using Server class, note that connect() calls start() automatically.");this._started=!0,this._stdin.on("data",this._ondata),this._stdin.on("error",this._onerror),this._stdout.on("error",this._onstdouterror)}processReadBuffer(){while(!0)try{let r=this._readBuffer.readMessage();if(r===null)break;this.onmessage?.(r)}catch(r){this.onerror?.(r)}}async close(){if(this._closed)return;if(this._closed=!0,this._stdin.off("data",this._ondata),this._stdin.off("error",this._onerror),this._stdout.off("error",this._onstdouterror),this._stdin.listenerCount("data")===0)this._stdin.pause();this._readBuffer.clear(),this.onclose?.()}send(r){if(this._closed)return Promise.reject(Error("StdioServerTransport is closed"));return new Promise((o,a)=>{let d=x(r),t=!1,u=(w)=>{if(t)return;t=!0,this._stdout.off("error",u),this._stdout.off("drain",h),a(w)},h=()=>{if(t)return;t=!0,this._stdout.off("error",u),this._stdout.off("drain",h),o()};if(this._stdout.once("error",u),this._stdout.write(d)){if(t)return;t=!0,this._stdout.off("error",u),o()}else if(!t)this._stdout.once("drain",h)})}},W=3000,te=class{onclose;onerror;onmessage;_closed=!1;_pendingRequests=new Set;_drainWaiters=[];constructor(r,o,a){this._wire=r,this._onInstanceClose=o,this._outboundIntercept=a}async start(){}async send(r,o){if(z(r)||A(r)){let{id:a}=r;if(a!==void 0)this._settle(a)}if(this._closed)return;if(this._outboundIntercept?.(r)==="handled")return;return this._wire.send(r,o)}setProtocolVersion=(r)=>{this._wire.setProtocolVersion?.(r)};deliver(r,o){if(this._closed)return;if(p(r))this._pendingRequests.add(r.id);else if(v(r)&&r.method==="notifications/cancelled"){let a=r.params?.requestId;if(a!==void 0)this._settle(a)}this.onmessage?.(r,o)}async whenRequestsAnswered(r){if(this._closed||this._pendingRequests.size===0)return!0;return await new Promise((o)=>{let a=()=>{clearTimeout(d),o(!0)},d=setTimeout(()=>{this._drainWaiters=this._drainWaiters.filter((t)=>t!==a),o(!1)},r);this._drainWaiters.push(a)})}async close(){if(this._closed)return;this._closed=!0,this._pendingRequests.clear(),this._releaseDrainWaiters();try{this._onInstanceClose()}finally{this.onclose?.()}}_settle(r){if(this._pendingRequests.delete(r),this._pendingRequests.size===0)this._releaseDrainWaiters()}_releaseDrainWaiters(){let r=this._drainWaiters;this._drainWaiters=[];for(let o of r)o()}};function ne(r){let o=r.params;if(r.method==="initialize"&&!M(o)){let u=o!==null&&typeof o==="object"&&typeof o.protocolVersion==="string"?o.protocolVersion:void 0;return{kind:"legacy",reason:"initialize",...u!==void 0&&{requestedVersion:u}}}if(!j(o))return{kind:"legacy",reason:"no-claim"};let a=P(o),d=(a===void 0?[]:D(a))[0];if(d!==void 0)return{kind:"invalid-envelope",issue:d};let t=k(o);if(t===void 0||!_.includes(t))return{kind:"unsupported-revision",requested:t??"unknown"};return{kind:"modern",revision:t,classification:{era:"modern",revision:t}}}function ae(r,o={}){let a=o.legacy??"serve",d=o.transport??new re,t={phase:"opening"},u,h=!1,w=()=>h||t.phase==="closed",c=(e)=>{try{o.onerror?.(e)}catch{}},R=(e,n,i,s)=>d.send({jsonrpc:"2.0",id:e,error:{code:n,message:i,...s!==void 0&&{data:s}}}).catch((l)=>c(f(l))),y=new F(o.maxSubscriptions??g),Y=(e)=>{if(!v(e))return;let n=y.routeOutbound(e);if(n==="passthrough")return;for(let i of n)d.send({jsonrpc:"2.0",...i}).catch((s)=>c(f(s)));return"handled"},V=async(e)=>{if(p(e)&&e.method==="subscriptions/listen"){let n=P(e.params),i=j(e.params)?(n===void 0?[]:D(n))[0]:{key:"_meta",problem:"the per-request envelope is required on protocol revision 2026-07-28"},s=k(e.params),l;if(i!==void 0)l={jsonrpc:"2.0",id:e.id,error:{code:-32602,message:`Invalid _meta envelope: ${i.key}: ${i.problem}`}};else if(s===void 0||!_.includes(s)){let m=new C({supported:[..._],requested:s??"unknown"});l={jsonrpc:"2.0",id:e.id,error:{code:m.code,message:m.message,data:m.data}}}else l=y.serve(e);return await d.send("error"in l?l:{jsonrpc:"2.0",method:l.method,params:l.params}).catch((m)=>c(f(m))),!0}if(v(e)&&e.method==="notifications/cancelled"){let n=e.params?.requestId;if(n!==void 0&&y.cancel(n))return!0}return!1},T=(e,n,i)=>{let s=J({kind:"legacy",reason:n,...i!==void 0&&{requestedVersion:i}},_);if(s===void 0)return Promise.resolve();return c(Error(`Rejected 2025-era request on a modern-only stdio connection (${s.cell}): ${s.message}`)),R(e.id,s.code,s.message,s.data)},G=(e)=>{if(h||e===u)return;B()},S=async(e,n)=>{let i=await r({era:e}),s=i instanceof Q?i.server:i;if(e==="modern")L(s,n),X(s,_),y.setServerCapabilities(s.getCapabilities(),H(s));let l=new te(d,()=>G(l),e==="modern"?Y:void 0);return await i.connect(l),{product:i,channel:l}},E=(e)=>e.product.close().catch((n)=>c(f(n))),K=async(e)=>{u=e.channel;try{if(!await e.channel.whenRequestsAnswered(W))c(Error(`Discarded the probe instance with requests still unanswered after ${W}ms; continuing with the fallback`));await e.product.close()}catch(n){c(f(n))}finally{u=void 0}},Z=async(e)=>{if(t.phase==="closed")return;if(t.phase==="pinned"){if(t.era==="modern"&&p(e)&&e.method==="initialize"&&!M(e.params)){await T(e,"initialize",e.params!==null&&typeof e.params==="object"&&typeof e.params.protocolVersion==="string"?e.params.protocolVersion:void 0);return}if(t.era==="modern"&&await V(e))return;t.instance.channel.deliver(e);return}if(!p(e)&&!v(e)){c(Error("Discarded a JSON-RPC response received before the connection negotiated an era"));return}let n=ne(e);switch(n.kind){case"invalid-envelope":{let i=`Invalid _meta envelope for protocol revision 2026-07-28: ${n.issue.key}: ${n.issue.problem}`;if(p(e))await R(e.id,q.InvalidParams,i,{envelope:n.issue});else c(Error(`Discarded a notification with a malformed envelope: ${i}`));return}case"unsupported-revision":if(p(e)){let i=new C({supported:[..._],requested:n.requested});c(i),await R(e.id,i.code,i.message,i.data)}else c(Error(`Discarded a notification claiming unsupported protocol revision ${n.requested}`));return;case"modern":if(p(e)&&e.method==="server/discover"){if(t.phase==="probe"){t.instance.channel.deliver(e,{classification:n.classification});return}let i=await S("modern",n.revision);if(w()){await E(i);return}t={phase:"probe",instance:i},i.channel.deliver(e,{classification:n.classification});return}if(t.phase==="probe"){if(v(e)){t.instance.channel.deliver(e,{classification:n.classification});return}t={phase:"pinned",era:"modern",instance:t.instance}}else{let i=await S("modern",n.revision);if(w()){await E(i);return}t={phase:"pinned",era:"modern",instance:i}}if(await V(e))return;t.instance.channel.deliver(e,{classification:n.classification});return;case"legacy":{if(a==="reject"){if(p(e))await T(e,n.reason,n.requestedVersion);return}if(t.phase==="probe"){if(await K(t.instance),w())return;t={phase:"opening"}}let i=await S("legacy");if(w()){await E(i);return}t={phase:"pinned",era:"legacy",instance:i},t.instance.channel.deliver(e);return}}},I=[],b=!1,ee=async()=>{if(b)return;b=!0;try{while(I.length>0){let e=I.shift();try{await Z(e)}catch(n){if(p(e))await R(e.id,q.InternalError,"Internal server error");c(f(n))}}}finally{b=!1}},B=async()=>{if(h||t.phase==="closed")return;h=!0;let e=t;t={phase:"closed"};for(let n of y.teardownAll())await d.send(n).catch((i)=>c(f(i)));if(e.phase==="probe"||e.phase==="pinned")await e.instance.product.close().catch((n)=>c(f(n)));await d.close().catch((n)=>c(f(n)))};d.onmessage=(e)=>{I.push(e),ee()},d.onerror=(e)=>{if(c(e),t.phase==="probe"||t.phase==="pinned")t.instance.channel.onerror?.(e)},d.onclose=()=>{if(h||t.phase==="closed")return;h=!0;let e=t;if(t={phase:"closed"},e.phase==="probe"||e.phase==="pinned")e.instance.product.close().catch((n)=>c(f(n)))};let N=d.start().catch((e)=>{throw c(f(e)),e});return N.catch(()=>{}),{close:async()=>{await N.catch(()=>{}),await B()}}}function f(r){return r instanceof Error?r:Error(String(r))}export{re as StdioServerTransport,ae as serveStdio};
|