broods 0.40.1 → 0.42.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/LICENSE.md +1 -1
- package/dist/account.d.ts +161 -20
- package/dist/account.js +1 -1
- package/dist/chunk-6en45n1d.js +19 -0
- package/dist/{chunk-8bsz0vkr.js → chunk-7j1e8kv6.js} +3 -3
- package/dist/{chunk-3fdkn6mk.js → chunk-gerkxepr.js} +1 -1
- package/dist/{chunk-pf07c5ff.js → chunk-ghv3v607.js} +1 -1
- package/dist/{chunk-ymkt9r21.js → chunk-m42xgkbk.js} +1 -1
- package/dist/{chunk-p56s3q1t.js → chunk-p5134ra1.js} +7 -7
- package/dist/chunk-p7t6yawg.js +2 -0
- package/dist/{chunk-3gnqn6ap.js → chunk-t3g8jagy.js} +6 -6
- package/dist/chunk-zbp92p62.js +5 -0
- package/dist/{chunk-n0kwmhw4.js → chunk-zj2wzjc6.js} +1 -1
- package/dist/cli/index.js +59 -51
- package/dist/index.d.ts +311 -37
- package/dist/index.js +1 -1
- package/package.json +4 -4
- package/dist/chunk-5epfg4tw.js +0 -5
- package/dist/chunk-f294wr3z.js +0 -17
- package/dist/chunk-keg0nsm2.js +0 -2
package/LICENSE.md
CHANGED
package/dist/account.d.ts
CHANGED
|
@@ -8,12 +8,17 @@ declare const AGENT_HOOK_EVENT_NAMES: readonly ["agent.started", "agent.step.fin
|
|
|
8
8
|
type AgentHookEventName = (typeof AGENT_HOOK_EVENT_NAMES)[number];
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* Every Vercel AI SDK provider that ships language models,
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
11
|
+
* Every Vercel AI SDK provider that ships language models, the community
|
|
12
|
+
* providers on the same spec that take an API key (`cloudflare`, `llmgateway`,
|
|
13
|
+
* `ollama`, `openrouter`), and `custom` (any OpenAI-compatible endpoint).
|
|
14
|
+
* Image-, speech- and transcription-only providers are deliberately absent:
|
|
15
|
+
* they cannot back `config.model`.
|
|
15
16
|
*/
|
|
16
17
|
declare const MODEL_PROVIDERS: {
|
|
18
|
+
readonly alibaba: {
|
|
19
|
+
readonly label: "Alibaba Qwen";
|
|
20
|
+
readonly modelPlaceholder: "qwen3-max";
|
|
21
|
+
};
|
|
17
22
|
readonly anthropic: {
|
|
18
23
|
readonly label: "Anthropic";
|
|
19
24
|
readonly modelPlaceholder: "claude-sonnet-4-5-20250929";
|
|
@@ -34,6 +39,10 @@ declare const MODEL_PROVIDERS: {
|
|
|
34
39
|
readonly label: "Cerebras";
|
|
35
40
|
readonly modelPlaceholder: "llama3.1-8b";
|
|
36
41
|
};
|
|
42
|
+
readonly cloudflare: {
|
|
43
|
+
readonly label: "Cloudflare Workers AI";
|
|
44
|
+
readonly modelPlaceholder: "@cf/meta/llama-3.3-70b-instruct-fp8-fast";
|
|
45
|
+
};
|
|
37
46
|
readonly cohere: {
|
|
38
47
|
readonly label: "Cohere";
|
|
39
48
|
readonly modelPlaceholder: "command-a-03-2025";
|
|
@@ -62,6 +71,14 @@ declare const MODEL_PROVIDERS: {
|
|
|
62
71
|
readonly label: "Groq";
|
|
63
72
|
readonly modelPlaceholder: "llama-3.3-70b-versatile";
|
|
64
73
|
};
|
|
74
|
+
readonly huggingface: {
|
|
75
|
+
readonly label: "Hugging Face";
|
|
76
|
+
readonly modelPlaceholder: "meta-llama/Llama-3.3-70B-Instruct";
|
|
77
|
+
};
|
|
78
|
+
readonly llmgateway: {
|
|
79
|
+
readonly label: "LLM Gateway";
|
|
80
|
+
readonly modelPlaceholder: "openai/gpt-4.1-mini";
|
|
81
|
+
};
|
|
65
82
|
readonly minimax: {
|
|
66
83
|
readonly label: "MiniMax";
|
|
67
84
|
readonly modelPlaceholder: "MiniMax-M2.7";
|
|
@@ -70,13 +87,25 @@ declare const MODEL_PROVIDERS: {
|
|
|
70
87
|
readonly label: "Mistral";
|
|
71
88
|
readonly modelPlaceholder: "mistral-large-latest";
|
|
72
89
|
};
|
|
90
|
+
readonly moonshotai: {
|
|
91
|
+
readonly label: "Moonshot AI Kimi";
|
|
92
|
+
readonly modelPlaceholder: "kimi-k2.6";
|
|
93
|
+
};
|
|
94
|
+
readonly ollama: {
|
|
95
|
+
readonly label: "Ollama";
|
|
96
|
+
readonly modelPlaceholder: "gpt-oss:120b";
|
|
97
|
+
};
|
|
73
98
|
readonly openai: {
|
|
74
99
|
readonly label: "OpenAI";
|
|
75
100
|
readonly modelPlaceholder: "gpt-4.1-mini";
|
|
76
101
|
};
|
|
102
|
+
readonly openrouter: {
|
|
103
|
+
readonly label: "OpenRouter";
|
|
104
|
+
readonly modelPlaceholder: "anthropic/claude-sonnet-4.5";
|
|
105
|
+
};
|
|
77
106
|
readonly perplexity: {
|
|
78
107
|
readonly label: "Perplexity";
|
|
79
|
-
readonly modelPlaceholder: "
|
|
108
|
+
readonly modelPlaceholder: "low";
|
|
80
109
|
};
|
|
81
110
|
readonly togetherai: {
|
|
82
111
|
readonly label: "Together.ai";
|
|
@@ -98,6 +127,10 @@ declare const MODEL_PROVIDERS: {
|
|
|
98
127
|
readonly label: "xAI Grok";
|
|
99
128
|
readonly modelPlaceholder: "grok-4";
|
|
100
129
|
};
|
|
130
|
+
readonly zai: {
|
|
131
|
+
readonly label: "Z.ai GLM";
|
|
132
|
+
readonly modelPlaceholder: "glm-4.7";
|
|
133
|
+
};
|
|
101
134
|
};
|
|
102
135
|
type AccountModelProviderName = keyof typeof MODEL_PROVIDERS;
|
|
103
136
|
|
|
@@ -347,12 +380,16 @@ interface AgentMcpEntry {
|
|
|
347
380
|
}
|
|
348
381
|
interface AgentChannelsConfig {
|
|
349
382
|
telegram?: AgentTelegramChannelConfig;
|
|
383
|
+
gchat?: AgentGoogleChatChannelConfig;
|
|
350
384
|
github?: AgentGitHubChannelConfig;
|
|
351
385
|
slack?: AgentSlackChannelConfig;
|
|
352
386
|
discord?: AgentDiscordChannelConfig;
|
|
353
387
|
pancake?: AgentPancakeChannelConfig;
|
|
388
|
+
teams?: AgentTeamsChannelConfig;
|
|
389
|
+
twilio?: AgentTwilioChannelConfig;
|
|
354
390
|
zalo?: AgentZaloChannelConfig;
|
|
355
391
|
matrix?: AgentMatrixChannelConfig;
|
|
392
|
+
whatsapp?: AgentWhatsAppChannelConfig;
|
|
356
393
|
[key: string]: unknown;
|
|
357
394
|
}
|
|
358
395
|
/**
|
|
@@ -477,6 +514,89 @@ interface AgentZaloChannelConfig {
|
|
|
477
514
|
partition?: ChannelPartition;
|
|
478
515
|
[key: string]: unknown;
|
|
479
516
|
}
|
|
517
|
+
/**
|
|
518
|
+
* A Google Chat app on the HTTP endpoint connection. It posts as the service
|
|
519
|
+
* account in `credentials`, and a webhook is accepted when its Google-signed
|
|
520
|
+
* token names `endpointUrl` or `googleChatProjectNumber` as the audience.
|
|
521
|
+
*/
|
|
522
|
+
interface AgentGoogleChatChannelConfig {
|
|
523
|
+
allowedChannelIds?: string[];
|
|
524
|
+
allowedUserIds?: string[];
|
|
525
|
+
id?: string;
|
|
526
|
+
/** The service-account key JSON, as downloaded from Google Cloud. */
|
|
527
|
+
credentials?: string;
|
|
528
|
+
/** Audience when the app authenticates with "HTTP endpoint URL". */
|
|
529
|
+
endpointUrl?: string;
|
|
530
|
+
/** Audience when the app authenticates with "Project number". */
|
|
531
|
+
googleChatProjectNumber?: string;
|
|
532
|
+
/** `service-{projectNumber}@gcp-sa-gsuiteaddons.iam.gserviceaccount.com`, for an app built as a Workspace add-on. */
|
|
533
|
+
workspaceAddOnServiceAccountEmail?: string;
|
|
534
|
+
userName?: string;
|
|
535
|
+
trace?: "enabled" | "disabled";
|
|
536
|
+
partition?: ChannelPartition;
|
|
537
|
+
[key: string]: unknown;
|
|
538
|
+
}
|
|
539
|
+
/**
|
|
540
|
+
* A Microsoft Teams bot registered in Azure Bot Service, authenticated with a
|
|
541
|
+
* client secret. `appTenantId` is required unless `appType` is `MultiTenant`.
|
|
542
|
+
*/
|
|
543
|
+
interface AgentTeamsChannelConfig {
|
|
544
|
+
allowedChannelIds?: string[];
|
|
545
|
+
allowedUserIds?: string[];
|
|
546
|
+
id?: string;
|
|
547
|
+
apiUrl?: string;
|
|
548
|
+
appId?: string;
|
|
549
|
+
appPassword?: string;
|
|
550
|
+
appTenantId?: string;
|
|
551
|
+
appType?: "MultiTenant" | "SingleTenant";
|
|
552
|
+
userName?: string;
|
|
553
|
+
trace?: "enabled" | "disabled";
|
|
554
|
+
partition?: ChannelPartition;
|
|
555
|
+
[key: string]: unknown;
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* A Twilio number or Messaging Service for SMS and MMS. `authToken` checks
|
|
559
|
+
* Twilio's signature, which covers the exact public URL Twilio called, so
|
|
560
|
+
* `webhookUrl` is only set when that URL is not the broods webhook URL.
|
|
561
|
+
*/
|
|
562
|
+
interface AgentTwilioChannelConfig {
|
|
563
|
+
allowedChannelIds?: string[];
|
|
564
|
+
allowedUserIds?: string[];
|
|
565
|
+
id?: string;
|
|
566
|
+
accountSid?: string;
|
|
567
|
+
apiUrl?: string;
|
|
568
|
+
authToken?: string;
|
|
569
|
+
/** `MG...`. Replies go through the service instead of the number texted. */
|
|
570
|
+
messagingServiceSid?: string;
|
|
571
|
+
/** E.164 number, e.g. `+15551234567`. Messages to another number go to the agent holding it. */
|
|
572
|
+
phoneNumber?: string;
|
|
573
|
+
statusCallbackUrl?: string;
|
|
574
|
+
userName?: string;
|
|
575
|
+
/** The URL entered in the Twilio console, when it is not `{PUBLIC_BASE_URL}/v1/webhooks/...`. */
|
|
576
|
+
webhookUrl?: string;
|
|
577
|
+
trace?: "enabled" | "disabled";
|
|
578
|
+
partition?: ChannelPartition;
|
|
579
|
+
[key: string]: unknown;
|
|
580
|
+
}
|
|
581
|
+
/**
|
|
582
|
+
* A WhatsApp Business Cloud API number. `appSecret` signs every delivery and
|
|
583
|
+
* `verifyToken` answers Meta's subscription handshake.
|
|
584
|
+
*/
|
|
585
|
+
interface AgentWhatsAppChannelConfig {
|
|
586
|
+
allowedChannelIds?: string[];
|
|
587
|
+
allowedUserIds?: string[];
|
|
588
|
+
id?: string;
|
|
589
|
+
accessToken?: string;
|
|
590
|
+
apiUrl?: string;
|
|
591
|
+
apiVersion?: string;
|
|
592
|
+
appSecret?: string;
|
|
593
|
+
phoneNumberId?: string;
|
|
594
|
+
userName?: string;
|
|
595
|
+
verifyToken?: string;
|
|
596
|
+
trace?: "enabled" | "disabled";
|
|
597
|
+
partition?: ChannelPartition;
|
|
598
|
+
[key: string]: unknown;
|
|
599
|
+
}
|
|
480
600
|
|
|
481
601
|
/**
|
|
482
602
|
* Cron-job records and patch-merge helpers for the runtime. Input
|
|
@@ -612,7 +732,7 @@ declare const AGENT_POLICY_ACTIONS: readonly ["agent.invoke", "tool.call", "work
|
|
|
612
732
|
* resource route. Roles carry the same PolicyDocument shape as agent policies;
|
|
613
733
|
* each caller passes its action set to `normalizePolicyDocument`.
|
|
614
734
|
*/
|
|
615
|
-
declare const API_POLICY_ACTIONS: readonly ["account:read", "account:write", "agents:read", "agents:write", "channels:read", "channels:write", "crons:read", "crons:write", "env:read", "env:write", "hooks:read", "hooks:write", "mcp:read", "mcp:write", "policies:read", "policies:write", "sandboxes:read", "sandboxes:write", "skills:read", "skills:write", "
|
|
735
|
+
declare const API_POLICY_ACTIONS: readonly ["account:read", "account:write", "agents:read", "agents:write", "channels:read", "channels:write", "crons:read", "crons:write", "env:read", "env:write", "hooks:read", "hooks:write", "mcp:read", "mcp:write", "policies:read", "policies:write", "sandboxes:read", "sandboxes:write", "skills:read", "skills:write", "workspaces:read", "workspaces:write"];
|
|
616
736
|
type AgentPolicyAction = (typeof AGENT_POLICY_ACTIONS)[number];
|
|
617
737
|
type ApiPolicyAction = (typeof API_POLICY_ACTIONS)[number];
|
|
618
738
|
type PolicyAction = AgentPolicyAction | ApiPolicyAction;
|
|
@@ -662,6 +782,18 @@ interface PolicyRule {
|
|
|
662
782
|
declare const CHANNEL_REPLY_TARGETS: readonly ["thread", "source"];
|
|
663
783
|
type ChannelReplyIn = (typeof CHANNEL_REPLY_TARGETS)[number];
|
|
664
784
|
|
|
785
|
+
/**
|
|
786
|
+
* The core HTTP contract every handler speaks, plus generic request/response
|
|
787
|
+
* helpers. Handlers take a CoreRequest + RequestContext and return a Web
|
|
788
|
+
* Response; the transport edge (`src/server.ts`) builds the CoreRequest from
|
|
789
|
+
* a real request. Keep route-specific logic out of here.
|
|
790
|
+
*/
|
|
791
|
+
declare global {
|
|
792
|
+
interface BunFetchRequestInit {
|
|
793
|
+
timeout?: number | boolean;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
|
|
665
797
|
/**
|
|
666
798
|
* Wire types for the public account-manage and harness APIs. These mirror
|
|
667
799
|
* the deployed API contract (docs/api-reference/openapi.yaml is the source
|
|
@@ -731,6 +863,10 @@ interface Skill {
|
|
|
731
863
|
* (`********`) on reads.
|
|
732
864
|
*/
|
|
733
865
|
|
|
866
|
+
/** A config PATCH body: objects merge key by key, `null` deletes a key, arrays and scalars replace. */
|
|
867
|
+
type ConfigPatch<T> = T extends readonly unknown[] ? T : T extends object ? {
|
|
868
|
+
[K in keyof T]?: ConfigPatch<T[K]> | null;
|
|
869
|
+
} : T;
|
|
734
870
|
interface BroodsAccountClientOptions {
|
|
735
871
|
/** Base URL of the broods gateway. Falls back to `BROODS_BASE_URL`, then `https://gateway.broods.app`. */
|
|
736
872
|
baseUrl?: string;
|
|
@@ -778,7 +914,7 @@ interface AccountEnvVar {
|
|
|
778
914
|
interface UpdateAgentInput {
|
|
779
915
|
name?: string;
|
|
780
916
|
description?: string | null;
|
|
781
|
-
config?:
|
|
917
|
+
config?: ConfigPatch<AgentConfig>;
|
|
782
918
|
}
|
|
783
919
|
/** Public workspace record returned by the workspaces routes. */
|
|
784
920
|
interface AccountWorkspace {
|
|
@@ -921,9 +1057,11 @@ interface AccountMcp {
|
|
|
921
1057
|
stageId: string;
|
|
922
1058
|
name: string;
|
|
923
1059
|
description?: string;
|
|
924
|
-
transport: "http" | "hosted";
|
|
1060
|
+
transport: "http" | "hosted" | "machine";
|
|
925
1061
|
/** External servers only; a hosted row has no endpoint of its own. */
|
|
926
1062
|
url?: string;
|
|
1063
|
+
/** Machine servers only: the machine sandbox (by name) whose daemon serves it. */
|
|
1064
|
+
sandbox?: string;
|
|
927
1065
|
/** Hosted servers only: content hash of the uploaded bundle. */
|
|
928
1066
|
sha256?: string;
|
|
929
1067
|
headers?: Record<string, string>;
|
|
@@ -937,12 +1075,14 @@ interface AccountMcp {
|
|
|
937
1075
|
}
|
|
938
1076
|
/**
|
|
939
1077
|
* Fields accepted by `POST /v1/mcp`: `url` connects, `bundle` uploads inline
|
|
940
|
-
* (≤10 MB); a larger bundle goes through `uploadMcpBundle` first
|
|
1078
|
+
* (≤10 MB); a larger bundle goes through `uploadMcpBundle` first; `sandbox`
|
|
1079
|
+
* runs it on that machine sandbox's daemon.
|
|
941
1080
|
*/
|
|
942
1081
|
interface CreateMcpInput {
|
|
943
1082
|
name: string;
|
|
944
1083
|
description?: string;
|
|
945
1084
|
url?: string;
|
|
1085
|
+
sandbox?: string;
|
|
946
1086
|
bundle?: string;
|
|
947
1087
|
bundleStorageId?: string;
|
|
948
1088
|
sha256?: string;
|
|
@@ -955,6 +1095,7 @@ interface UpdateMcpInput {
|
|
|
955
1095
|
name?: string;
|
|
956
1096
|
description?: string;
|
|
957
1097
|
url?: string;
|
|
1098
|
+
sandbox?: string;
|
|
958
1099
|
bundle?: string;
|
|
959
1100
|
bundleStorageId?: string;
|
|
960
1101
|
sha256?: string;
|
|
@@ -1064,7 +1205,7 @@ declare class BroodsAccountClient {
|
|
|
1064
1205
|
createAgent(input: {
|
|
1065
1206
|
name: string;
|
|
1066
1207
|
description?: string;
|
|
1067
|
-
config:
|
|
1208
|
+
config: AgentConfig;
|
|
1068
1209
|
}): Promise<CreateAgentResult>;
|
|
1069
1210
|
getAgent(agentId: string): Promise<AccountAgent | null>;
|
|
1070
1211
|
/** PATCH an agent. `config` deep-merges into the stored config; `null` leaves delete keys. Returns null when the agent is gone. */
|
|
@@ -1089,13 +1230,13 @@ declare class BroodsAccountClient {
|
|
|
1089
1230
|
createWorkspace(input: {
|
|
1090
1231
|
name: string;
|
|
1091
1232
|
description?: string;
|
|
1092
|
-
config?:
|
|
1233
|
+
config?: WorkspaceConfig;
|
|
1093
1234
|
}): Promise<AccountWorkspace>;
|
|
1094
1235
|
getWorkspace(workspaceId: string): Promise<AccountWorkspace | null>;
|
|
1095
1236
|
updateWorkspace(workspaceId: string, patch: {
|
|
1096
1237
|
name?: string;
|
|
1097
1238
|
description?: string | null;
|
|
1098
|
-
config?:
|
|
1239
|
+
config?: ConfigPatch<WorkspaceConfig>;
|
|
1099
1240
|
}): Promise<AccountWorkspace | null>;
|
|
1100
1241
|
deleteWorkspace(workspaceId: string): Promise<boolean>;
|
|
1101
1242
|
/** Flat listing of every file in the workspace's S3-backed filesystem. Returns [] when the workspace is gone. */
|
|
@@ -1108,22 +1249,22 @@ declare class BroodsAccountClient {
|
|
|
1108
1249
|
contentBase64: string;
|
|
1109
1250
|
contentType?: string;
|
|
1110
1251
|
}): Promise<WorkspaceFileEntry>;
|
|
1111
|
-
/** Rename a workspace file or folder. Returns
|
|
1112
|
-
renameWorkspaceFile(workspaceId: string, path: string, newPath: string): Promise<
|
|
1113
|
-
/** Delete a workspace file or folder. Returns
|
|
1114
|
-
deleteWorkspaceFile(workspaceId: string, path: string): Promise<
|
|
1252
|
+
/** Rename a workspace file or folder. Returns how many objects moved; throws when the workspace or source path is gone. */
|
|
1253
|
+
renameWorkspaceFile(workspaceId: string, path: string, newPath: string): Promise<number>;
|
|
1254
|
+
/** Delete a workspace file or folder. Returns how many objects were deleted, 0 when the workspace or path is gone. */
|
|
1255
|
+
deleteWorkspaceFile(workspaceId: string, path: string): Promise<number>;
|
|
1115
1256
|
listSandboxes(): Promise<AccountSandbox[]>;
|
|
1116
1257
|
createSandbox(input: {
|
|
1117
1258
|
name: string;
|
|
1118
1259
|
description?: string;
|
|
1119
|
-
config?:
|
|
1260
|
+
config?: SandboxConfig;
|
|
1120
1261
|
}): Promise<AccountSandbox>;
|
|
1121
1262
|
getSandbox(sandboxId: string): Promise<AccountSandbox | null>;
|
|
1122
|
-
/** PATCH a sandbox config. `config`
|
|
1263
|
+
/** PATCH a sandbox config. `config` deep-merges into the stored config; `null` leaves delete keys. Returns null when the sandbox is gone. */
|
|
1123
1264
|
updateSandbox(sandboxId: string, patch: {
|
|
1124
1265
|
name?: string;
|
|
1125
1266
|
description?: string | null;
|
|
1126
|
-
config?:
|
|
1267
|
+
config?: ConfigPatch<SandboxConfig>;
|
|
1127
1268
|
}): Promise<AccountSandbox | null>;
|
|
1128
1269
|
deleteSandbox(sandboxId: string): Promise<boolean>;
|
|
1129
1270
|
/** Suspend a persistent sandbox reservation. Throws on 404/403/409 (missing sandbox, foreign reservation, or unsupported provider). */
|
|
@@ -1216,4 +1357,4 @@ declare class BroodsAccountClient {
|
|
|
1216
1357
|
}
|
|
1217
1358
|
|
|
1218
1359
|
export { BroodsAccountApiError, BroodsAccountClient, envPlaceholder, resolveEnvCredential };
|
|
1219
|
-
export type { AccountAgent, AccountChannel, AccountEnvVar, AccountMcp, AccountPolicy, AccountRole, AccountSandbox, AccountWorkspace, AssumeRoleResult, BroodsAccount, BroodsAccountClientOptions, ChannelRecordConfig, CreateAgentResult, CreateMcpInput, DeleteAccountResult, McpOauthInput, RotateSecretResult, SandboxLifecycleResult, SandboxSnapshotResult, SandboxTerminalTicket, SkillUploadInput, StageScope, UpdateAgentInput, UpdateMcpInput, WorkspaceFileEntry };
|
|
1360
|
+
export type { AccountAgent, AccountChannel, AccountEnvVar, AccountMcp, AccountPolicy, AccountRole, AccountSandbox, AccountWorkspace, AssumeRoleResult, BroodsAccount, BroodsAccountClientOptions, ChannelRecordConfig, ConfigPatch, CreateAgentResult, CreateMcpInput, DeleteAccountResult, McpOauthInput, RotateSecretResult, SandboxLifecycleResult, SandboxSnapshotResult, SandboxTerminalTicket, SkillUploadInput, StageScope, UpdateAgentInput, UpdateMcpInput, WorkspaceFileEntry };
|
package/dist/account.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{m,Ae,B,Z}from"./chunk-p7t6yawg.js";export{m as BroodsAccountApiError,Z as BroodsAccountClient,Ae as envPlaceholder,B as resolveEnvCredential};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import{getToolName as St,isToolUIPart as J,readUIMessageStream as wt}from"ai";import{convertToModelMessages as te,generateId as ee,getToolName as re,isToolUIPart as Q}from"ai";var H=String.fromCharCode(27),ve=new RegExp(`${H}\\[[0-?]*[ -/]*[@-~]`,"g"),M=new RegExp(`^${H}\\[[0-?]*[ -/]*[@-~]`);function h(t){let e=0,r=0;while(r<t.length){let s=t.slice(r).match(M);if(s){r+=s[0].length;continue}let a=t.codePointAt(r);if(a==null)break;let i=String.fromCodePoint(a);e+=K(a),r+=i.length}return e}function v(t,e){if(e<=0)return"";let r="",s=0,a=0;while(a<t.length&&s<e){let i=t.slice(a).match(M);if(i){r+=i[0],a+=i[0].length;continue}let o=t.codePointAt(a);if(o==null)break;let u=String.fromCodePoint(o),l=K(o);if(l>0&&s+l>e)break;r+=u,a+=u.length,s+=l}while(a<t.length){let i=t.slice(a).match(M);if(!i)break;r+=i[0],a+=i[0].length}return r}function K(t){if(t===9)return 4;if(t<32||t>=127&&t<160)return 0;if(at(t))return 0;return nt(t)?2:1}function at(t){return t>=768&&t<=879||t>=1155&&t<=1161||t>=1425&&t<=1469||t===1471||t>=1473&&t<=1474||t>=1476&&t<=1477||t===1479||t>=1552&&t<=1562||t>=1611&&t<=1631||t===1648||t>=1750&&t<=1756||t>=1759&&t<=1764||t>=1767&&t<=1768||t>=1770&&t<=1773||t===1809||t>=1840&&t<=1866||t>=1958&&t<=1968||t>=2027&&t<=2035||t>=2070&&t<=2073||t>=2075&&t<=2083||t>=2085&&t<=2087||t>=2089&&t<=2093||t>=2137&&t<=2139||t>=2259&&t<=2306||t===2362||t===2364||t>=2369&&t<=2376||t===2381||t>=2385&&t<=2391||t===8205||t>=65024&&t<=65039||t>=917760&&t<=917999}function nt(t){return t>=4352&&(t<=4447||t===9001||t===9002||t>=11904&&t<=42191&&t!==12351||t>=44032&&t<=55203||t>=63744&&t<=64255||t>=65040&&t<=65049||t>=65072&&t<=65135||t>=65280&&t<=65376||t>=65504&&t<=65510||t>=127744&&t<=128591||t>=129280&&t<=129535||t>=131072&&t<=262141)}function g(t,{multiline:e=!1}={}){let r="";for(let s of t){let a=s.charCodeAt(0);if(s===`
|
|
2
|
+
`&&e)r+=`
|
|
3
|
+
`;else if(s==="\t")r+=" ";else if(a<32||a>=127&&a<=159)r+=`\\u${a.toString(16).padStart(4,"0")}`;else r+=s}return r}var d={bold:"\x1B[1m",boldOff:"\x1B[22m",italic:"\x1B[3m",italicOff:"\x1B[23m"},it="─";function ot(t){let e=g(t,{multiline:!0}).split(`
|
|
4
|
+
`),r=[];for(let s=0;s<e.length;s+=1){let a=ut(e,s);if(a!=null){r.push(...pt(a)),s=a.endIndex-1;continue}r.push(lt(e[s]??""))}return r.join(`
|
|
5
|
+
`)}function lt(t){if(t.startsWith("### "))return p(`▶ ${t.slice(4)}`);if(t.startsWith("## "))return p(`■ ${t.slice(3)}`);if(t.startsWith("# "))return p(`█ ${t.slice(2)}`);let e=t.match(/^(\s*)[-+*]\s+(.*)$/);if(e){let[,r,s=""]=e;return p(`${r}•${s.length>0?` ${s}`:""}`)}if(/^\d+\. /.test(t))return p(t.replace(/^(\d+)\. /,"$1. "));if(t.startsWith("> "))return p(`│ ${t.slice(2)}`);return p(t)}function p(t){return t.replace(/`([^`]+)`/g,"$1").replace(/\*\*([^*\n]+)\*\*/g,`${d.bold}$1${d.boldOff}`).replace(/__([^_\n]+)__/g,`${d.bold}$1${d.boldOff}`).replace(/\*([^*\n]+)\*/g,`${d.italic}$1${d.italicOff}`).replace(/_([^_\n]+)_/g,`${d.italic}$1${d.italicOff}`)}function ut(t,e){let r=k(t[e]??"");if(r==null||r.length<2)return;let s=k(t[e+1]??"");if(s==null||s.length!==r.length)return;let a=ct(s);if(a==null)return;let i=[],o=e+2;while(o<t.length){let u=k(t[o]??"");if(u==null)break;i.push(dt(u,r.length)),o+=1}return{alignments:a,endIndex:o,header:r,rows:i}}function k(t){if(!t.includes("|"))return;let e=t.trim();if(e.startsWith("|"))e=e.slice(1);if(e.endsWith("|")&&!e.endsWith("\\|"))e=e.slice(0,-1);let r=[],s="";for(let a=0;a<e.length;a+=1){let i=e[a],o=e[a+1];if(i==="\\"&&o==="|"){s+="|",a+=1;continue}if(i==="|"){r.push(s.trim()),s="";continue}s+=i}return r.push(s.trim()),r}function ct(t){let e=[];for(let r of t){let s=r.match(/^(:)?-{3,}(:)?$/);if(s==null)return;let[,a,i]=s;e.push(a!=null&&i!=null?"center":i!=null?"right":"left")}return e}function dt(t,e){return Array.from({length:e},(r,s)=>t[s]??"")}function pt(t){let e=t.header.map((i)=>`${d.bold}${p(i)}${d.boldOff}`),r=t.rows.map((i)=>i.map(p)),s=[e,...r],a=t.alignments.map((i,o)=>Math.max(3,...s.map((u)=>h(u[o]??""))));return[E(e,a,t.alignments),a.map((i)=>it.repeat(i)).join(" "),...r.map((i)=>E(i,a,t.alignments))]}function E(t,e,r){return t.map((s,a)=>ht(s,e[a]??0,r[a]??"left")).join(" ")}function ht(t,e,r){let s=Math.max(0,e-h(t));if(r==="right")return`${" ".repeat(s)}${t}`;if(r==="center"){let a=Math.floor(s/2),i=s-a;return`${" ".repeat(a)}${t}${" ".repeat(i)}`}return`${t}${" ".repeat(s)}`}var j="─";function ft(t){let e=Math.max(20,t.width),r=Math.max(8,t.height),s=3,i=r-3-2,o=t.visibleBodyLines.slice(0,i);while(o.length<i)o.push("");return[A(e,t.title,t.rightTitle),...o.map((l)=>U(l,e)),R(e),A(e,t.inputActive?"Input":"Status"),U(t.inputActive?`> ${g(t.input)}${t.inputCursorVisible===!1?" ":"█"}`:g(t.status??"Streaming... ↑/↓ scroll · Ctrl+C quit"),e),R(e)].join(`
|
|
6
|
+
`)}function A(t,e,r){e=g(e),r=r==null?void 0:g(r);let s=Math.max(0,t-2),a=e?v(` ${e} `,s):"",i=r?v(` ${r} `,Math.max(0,s-h(a))):"",o=Math.max(0,s-h(a)-h(i));return`┌${a}${j.repeat(o)}${i}┐`}function R(t){return`└${j.repeat(t-2)}┘`}function U(t,e){let r=e-4,s=v(t,r),a=" ".repeat(Math.max(0,r-h(s)));return`│ ${s}${a} │`}var y="\x1B",mt=`${y}[H`,gt=`${y}[2J`,vt=`${y}[2K`,yt=`${y}[?2026h`,bt=`${y}[?2026l`,xt=class{#e;#r;#i;#c=!1;#d=!1;constructor(t,e){this.#r=t.write.bind(t),this.#e=e?.useSynchronizedUpdates??!0,t.write=(r,s,a)=>{if(!this.#c)this.#d=!0;return this.#r(r,s,a)}}present(t){let e=Tt(t),r=this.#i&&!this.#d?kt(this.#i,e):`${mt}${gt}${t}`;if(this.#i=e,this.#d=!1,r.length===0)return;this.#S(r)}reset(){this.#i=void 0}#S(t){this.#c=!0;try{if(!this.#e){this.#r(t);return}this.#r(`${yt}${t}${bt}`)}finally{this.#c=!1}}};function Tt(t){return{lines:t.split(`
|
|
7
|
+
`)}}function kt(t,e){let r="",s=Math.max(t.lines.length,e.lines.length);for(let a=0;a<s;a++){let i=e.lines[a];if(t.lines[a]===i)continue;r+=`${y}[${a+1};1H${vt}${i??""}`}return r}var Mt="outputTokensPerSecond",c={reset:"\x1B[0m",dim:"\x1B[2m",user:"\x1B[96m",assistant:"\x1B[92m",reasoning:"\x1B[94m",tool:"\x1B[95m",error:"\x1B[91m"},$t={user:{color:c.user,border:"─"},assistant:{color:c.assistant,border:"─"},reasoning:{color:c.reasoning,border:"·"},tool:{color:c.tool,border:"─"},error:{color:c.error,border:"─"}},Ct=500,It=new Intl.Segmenter(void 0,{granularity:"grapheme"}),m="↑/↓ · PgUp/PgDn · Esc/Ctrl+C",Bt="↑/↓ · PgUp/PgDn · q/Esc/Ctrl+C",b=`Processing input... ${m}`,L=`Processing tool results... ${m}`,S=`Streaming... ${m}`,O=`Executing tools... ${m}`,C=class{#e;#r;#i;#c;#d;#S;#F;#a=[];#u="";#g=!1;#p=0;#I="";#s=S;#w=!1;#n=!1;#h;#B;#f;#v;#y=!0;#b;#o;#x;#E;constructor(t){this.#e=t?.input??process.stdin,this.#r=t?.output??process.stdout,this.#i=t?.frameBuffer??new xt(this.#r),this.#c=t?.tools??"auto-collapsed",this.#d=t?.reasoning??"auto-collapsed",this.#S=t?.responseStatistics??Mt,this.#F=t?.contextSize,this.#B=t?.contextSize}async readPrompt(t){return this.#A(t),this.#g=!0,this.#u=t?.initialPrompt??"",this.#s=`Type a prompt and press Enter · ${m}`,this.#K(),this.#t(),await new Promise((e,r)=>{this.#o=(s)=>{let a=T(s);switch(a.type){case"character":this.#u+=a.value,this.#U(),this.#t();break;case"backspace":this.#u=Pt(this.#u),this.#U(),this.#t();break;case"enter":{let i=this.#u;this.#g=!1,this.#C(),this.#s=b,this.#N(i),this.#u="",this.#t(),this.#l(),e(i);break}case"up":case"down":this.#T(a.type);break;case"page-up":case"page-down":this.#$(a.type);break;case"ctrl-l":this.#k();break;case"escape":case"ctrl-c":this.#C(),this.#R(),r(w());break;case"ignore":break}},this.#M()})}async renderStream(t,e){this.#A(e),this.#g=!1,this.#s=b,this.#j(e?.submittedPrompt),this.#n=!1,this.#h=void 0,this.#f=void 0,this.#v=void 0;let r={tools:e?.tools??this.#c,reasoning:e?.reasoning??this.#d,responseStatistics:e?.responseStatistics??this.#S};this.#t();let s=new Promise((o)=>{this.#E=o});this.#o=(o)=>this.#H(o),this.#M();let a,i=Dt(this.#G(t.uiMessageStream));try{let o=wt({message:t.message,stream:i,onError:(u)=>this.#q("Error",At(u))});for await(let u of Et(o,s)){if(this.#n)break;a=u,this.#D(u,r)}if(!this.#n&&a&&this.#f!=null)this.#D(a,r)}finally{if(this.#E=void 0,this.#n)t.abort?.();if(this.#l(),this.#s=this.#n?"Interrupted":e?.continueSession?`Done · Enter another prompt · ${m}`:`Done · ${Bt}`,this.#t(),await this.#Z(e),this.#n||!e?.continueSession)this.#R()}if(this.#n)throw w();return a}async readToolApproval(t,e){return this.#A(e),this.#g=!1,this.#s=`Approve ${Ft(t)}? y/n · ${m}`,this.#n=!1,this.#t(),await new Promise((r,s)=>{this.#o=(a)=>{let i=T(a);switch(i.type){case"character":{let o=i.value.toLowerCase();if(o==="y")this.#s=`Approved · ${b}`,this.#l(),this.#t(),r({approved:!0});else if(o==="n")this.#s=`Denied · ${b}`,this.#l(),this.#t(),r({approved:!1,reason:"Denied by user."});break}case"up":case"down":this.#T(i.type);break;case"page-up":case"page-down":this.#$(i.type);break;case"ctrl-l":this.#k();break;case"escape":case"ctrl-c":this.#n=!0,this.#R(),s(w());break;default:break}},this.#M()})}#A(t){if(this.#I=t?.title??this.#I,this.#B=t?.contextSize??this.#F,this.#w)return;if(this.#w=!0,this.#i.reset(),this.#r.write("\x1B[?1049h\x1B[?25l"),this.#e.isTTY)this.#e.setRawMode?.(!0),this.#e.resume();this.#x=()=>this.#k(),this.#r.on("resize",this.#x)}#R(){if(this.#l(),this.#C(),!this.#w)return;if(this.#e.isTTY)this.#e.setRawMode?.(!1),this.#e.pause();if(this.#x)this.#r.off("resize",this.#x),this.#x=void 0;this.#r.write("\x1B[?25h\x1B[?1049l"),this.#i.reset(),this.#w=!1}#M(){if(this.#o)this.#e.on("data",this.#o)}#l(){if(this.#o)this.#e.off("data",this.#o),this.#o=void 0}#H(t){let e=T(t);switch(e.type){case"up":case"down":this.#T(e.type);break;case"page-up":case"page-down":this.#$(e.type);break;case"ctrl-l":this.#k();break;case"escape":case"ctrl-c":this.#n=!0,this.#E?.();break;default:break}}#T(t,e=1){let r=t==="up"?e:-e;this.#p=this.#_(this.#p+r),this.#t()}#$(t){this.#T(t==="page-up"?"up":"down",this.#W())}#K(){this.#C(),this.#U(),this.#b=setInterval(()=>{this.#y=!this.#y,this.#t()},Ct),this.#b.unref?.()}#C(){if(this.#b)clearInterval(this.#b),this.#b=void 0;this.#y=!0}#U(){this.#y=!0}#j(t){if(t==null)return;let e=this.#a.at(-1);if(e?.kind==="user"&&e.content===t)return;this.#N(t)}#N(t){let e=this.#m();this.#a.push({kind:"user",title:"User",content:t}),this.#O(e)}#D(t,e){let r=this.#m(),s=new Set,a=Jt(t.metadata);this.#h=a.totalTokens??this.#h,this.#f=a.outputTokens??this.#f,this.#v=a.outputTokensPerSecond??this.#v;for(let[i,o]of t.parts.entries()){let u=Nt(t.id,i);switch(o.type){case"text":{let l=o.text.trim();if(l.length===0)break;s.add(u),this.#L({id:u,kind:"assistant",title:"Assistant",rightTitle:Zt({totalTokens:this.#h,outputTokens:this.#f,outputTokensPerSecond:this.#v},e.responseStatistics),content:l});break}case"reasoning":{let l=o.text.trim();if(e.reasoning==="hidden"||l.length===0)break;s.add(u),this.#L({id:u,kind:"reasoning",title:"Reasoning",content:l,collapsed:W(t,i,e.reasoning,e)});break}default:if(J(o)){if(e.tools==="hidden")break;s.add(u),this.#L({id:u,...Rt(o,{mode:e.tools,collapsed:W(t,i,e.tools,e)})})}break}}this.#J(t.id,s),this.#O(r)}#L(t){let e=t.id?this.#a.find((r)=>r.id===t.id):void 0;if(e){let r=e.cache;e.kind=t.kind,e.title=t.title,e.rightTitle=t.rightTitle,e.content=t.content,e.collapsed=t.collapsed,e.cache=r&&G(t,r)?r:void 0;return}this.#a.push(t)}#J(t,e){let r=`${t}:`;this.#a=this.#a.filter((s)=>s.id==null||!s.id.startsWith(r)||e.has(s.id))}async*#G(t){let e=!1;for await(let r of qt(t)){let s=Ot(r,{hasPendingToolResults:e});if(r.type==="start-step")e=!1;else if(Wt(r))e=!0;if(s&&this.#s!==s)this.#s=s,this.#t();else if(Lt(r)&&this.#s!==S)this.#s=S,this.#t();if(r.type==="error")this.#q("Error",r.errorText);if(r.type==="finish"){let a=jt(r);this.#h=a.totalTokens,this.#f=a.outputTokens,this.#v=a.outputTokensPerSecond}yield r}}#q(t,e){let r=this.#m();this.#a.push({kind:"error",title:t,content:e}),this.#O(r)}#O(t){if(this.#p!==0){let e=this.#m()-t;this.#p=this.#_(this.#p+e)}this.#t()}#t(){let t=ft({width:this.#z(),height:this.#V(),title:this.#I,rightTitle:Z(this.#h,this.#B),visibleBodyLines:this.#Y(),input:this.#u,inputActive:this.#g,inputCursorVisible:this.#y,status:this.#s});this.#i.present(t)}#k(){this.#i.reset(),this.#t()}#Y(){if(this.#a.length===0)return["Waiting for input..."];let t=this.#W(),e=this.#m(),r=Math.max(0,e-t-this.#p),s=r+t,a=[],i=0;for(let o of this.#a){let u=F(o,this.#z()-4),l=i+u.length;if(l>r&&i<s)a.push(...u.slice(Math.max(0,r-i),s-i));if(a.length>=t)break;i=l}return a}#_(t){let e=Math.max(0,this.#m()-this.#W());return Math.min(Math.max(0,t),e)}#m(){if(this.#a.length===0)return 1;let t=0;for(let e of this.#a)t+=F(e,this.#z()-4).length;return t}#W(){return Math.max(1,this.#V()-5)}#z(){return Math.max(20,this.#r.columns??80)}#V(){return Math.max(8,this.#r.rows??24)}async#Z(t){if(t?.waitForExit===!1||!this.#e.isTTY||this.#n)return;await new Promise((e)=>{this.#o=(r)=>{let s=T(r);switch(s.type){case"up":case"down":this.#T(s.type);break;case"page-up":case"page-down":this.#$(s.type);break;case"ctrl-l":this.#k();break;case"escape":this.#l(),e();break;case"character":if(s.value==="q")this.#l(),e();break;case"ctrl-c":this.#l(),process.exitCode=130,e();break;default:break}},this.#M()})}};function w(){return Error("Interrupted")}async function*Et(t,e){let r=t[Symbol.asyncIterator](),s=e.then(()=>({done:!0,value:void 0}));while(!0){let a=await Promise.race([r.next(),s]);if(a.done)break;yield a.value}}function At(t){if(t instanceof Error)return t.message;if(typeof t==="string")return t;return JSON.stringify(t)}function Rt(t,e){let r=St(t),s=`Tool · ${t.title??r}`,a="input"in t?t.input:void 0,i=a===void 0?"Input: (streaming...)":`Input:
|
|
8
|
+
${z(a)}`,o=zt(t);if(e.collapsed)return{kind:"tool",title:s,rightTitle:o,content:"",collapsed:!0};switch(t.state){case"input-streaming":return{kind:"tool",title:s,rightTitle:o,content:i};case"input-available":return{kind:"tool",title:s,rightTitle:o,content:i};case"approval-requested":return{kind:"tool",title:s,rightTitle:o,content:i};case"approval-responded":return{kind:"tool",title:s,rightTitle:o,content:i};case"output-available":return{kind:"tool",title:s,rightTitle:o,content:`${i}
|
|
9
|
+
|
|
10
|
+
Output:
|
|
11
|
+
${z(t.output)}`};case"output-error":return{kind:"error",title:`Tool Error · ${t.title??r}`,rightTitle:o,content:`${i}
|
|
12
|
+
|
|
13
|
+
Error:
|
|
14
|
+
${t.errorText}`};case"output-denied":return{kind:"error",title:`Tool Denied · ${t.title??r}`,rightTitle:o,content:`${i}
|
|
15
|
+
|
|
16
|
+
Reason: ${t.approval.reason??"denied"}`}}}function W(t,e,r,s){switch(r){case"collapsed":return!0;case"auto-collapsed":return t.parts.slice(e+1).some((a)=>Ut(a,s));case"full":case"hidden":return!1}}function Ut(t,e){switch(t.type){case"text":return t.text.trim().length>0;case"reasoning":return e.reasoning!=="hidden"&&t.text.trim().length>0;default:return J(t)&&e.tools!=="hidden"}}function Lt(t){switch(t.type){case"text-start":case"text-delta":case"reasoning-start":case"reasoning-delta":case"tool-input-start":case"tool-input-delta":return!0;default:return!1}}function Ot(t,{hasPendingToolResults:e}){switch(t.type){case"start-step":return e?L:b;case"tool-output-available":case"tool-output-error":case"tool-output-denied":return L;case"tool-input-available":return O;case"tool-approval-response":return t.approved?O:void 0;default:return}}function Wt(t){switch(t.type){case"tool-output-available":case"tool-output-error":case"tool-output-denied":return!0;default:return!1}}function zt(t){switch(t.state){case"input-streaming":return"waiting";case"approval-requested":return"approval requested";case"input-available":return"executing";case"approval-responded":return t.approval.approved?"executing":"denied";case"output-available":case"output-error":return"done";case"output-denied":return"denied"}}function z(t){if(typeof t==="string")return t;return JSON.stringify(t,null,2)}function Ft(t){return`tool ${t.title??t.toolName}`}function Nt(t,e){return`${t}:${e}`}function Dt(t){if(t instanceof ReadableStream)return t;return new ReadableStream({async start(e){try{for await(let r of t)e.enqueue(r);e.close()}catch(r){e.error(r)}}})}async function*qt(t){if(t instanceof ReadableStream){let e=t.getReader();try{while(!0){let{done:r,value:s}=await e.read();if(r)return;yield s}}finally{e.releaseLock()}return}yield*t}function F(t,e){if(t.cache&&G(t,t.cache,e))return t.cache.lines;let r=_t(t,e);return t.cache={width:e,kind:t.kind,title:t.title,rightTitle:t.rightTitle,content:t.content,collapsed:t.collapsed===!0,lines:r},r}function G(t,e,r=e.width){return e.width===r&&e.kind===t.kind&&e.title===t.title&&e.rightTitle===t.rightTitle&&e.content===t.content&&e.collapsed===(t.collapsed===!0)}function _t(t,e){let r=$t[t.kind],s=Math.max(1,e-4),a=` ${g(t.title)} `,i=t.rightTitle?` ${g(t.rightTitle)} `:"";if(t.collapsed){let f=Math.max(0,e-2-a.length-i.length),rt=`${r.color}╭${a}${r.border.repeat(f)}${i}╮${c.reset}`,st=`${r.color}╰${r.border.repeat(Math.max(0,e-2))}╯${c.reset}`;return[rt,st]}let o=Math.max(0,e-2-a.length-i.length),u=`${r.color}╭${a}${r.border.repeat(o)}${i}╮${c.reset}`,l=`${r.color}╰${r.border.repeat(Math.max(0,e-2))}╯${c.reset}`,x=(t.content.length>0?ot(t.content):c.dim+"(streaming...)"+c.reset).split(`
|
|
17
|
+
`).flatMap((f)=>Ht(f,s));return[u,...x.map((f)=>Vt(f,s,r.color)),l]}function Vt(t,e,r){let s=v(t,e),a=" ".repeat(Math.max(0,e-h(s)));return`${r}│${c.reset} ${s}${a} ${r}│${c.reset}`}function Ht(t,e){if(t.length===0)return[""];let r=[],s=t;while(h(s)>e){let a=Kt(s,e);r.push(s.slice(0,a).trimEnd()),s=s.slice(a).trimStart()}return r.push(s),r}function Kt(t,e){let s=v(t,e+1).lastIndexOf(" ");if(s>0)return s;return v(t,e).length}function jt(t){let e="usage"in t?t.usage:void 0,r="messageMetadata"in t?t.messageMetadata?.usage:void 0,s="messageMetadata"in t?t.messageMetadata?.performance:void 0;return{totalTokens:Y(e??r),outputTokens:B(e??r),outputTokensPerSecond:s?.outputTokensPerSecond}}function Jt(t){let e=t;return{totalTokens:Y(e?.usage),outputTokens:B(e?.usage),outputTokensPerSecond:e?.performance?.outputTokensPerSecond}}function Y(t){let e=t?.totalTokens;if(typeof e==="number")return e;if(typeof e?.total==="number")return e.total;let r=Gt(t),s=B(t);if(r!=null&&s!=null)return r+s}function Gt(t){let e=t?.inputTokens;if(typeof e==="number")return e;if(typeof e?.total==="number")return e.total;return t?.promptTokens}function B(t){let e=t?.outputTokens;if(typeof e==="number")return e;if(typeof e?.total==="number")return e.total;return t?.completionTokens}function Z(t,e){if(t==null)return;let r=`${t.toLocaleString()} ${t===1?"token":"tokens"}`,s=Yt(t,e);return s==null?r:`${r} ${s}`}function Yt(t,e){if(e==null||e<=0||!Number.isFinite(e))return;return`${Math.round(t/e*100).toLocaleString()}%`}function Zt(t,e){if(e==="outputTokensPerSecond")return Qt(t.outputTokensPerSecond);return Z(t.outputTokens)}function Qt(t){if(t==null)return;return`${Xt(t)} tok/s`}function Xt(t){return Number.isInteger(t)?t.toLocaleString():t.toLocaleString(void 0,{maximumFractionDigits:1})}function Pt(t){let e=0;for(let{index:r}of It.segment(t))e=r;return t.slice(0,e)}function T(t){let e=t.toString("utf8");switch(e){case"\f":return{type:"ctrl-l"};case"\x03":return{type:"ctrl-c"};case"\x1B":return{type:"escape"};case"\r":case`
|
|
18
|
+
`:return{type:"enter"};case"":case"\b":return{type:"backspace"};case"\x1B[A":return{type:"up"};case"\x1B[B":return{type:"down"};case"\x1B[5~":return{type:"page-up"};case"\x1B[6~":return{type:"page-down"};default:if(e>=" "&&e!=="")return{type:"character",value:e};return{type:"ignore"}}}var se="outputTokensPerSecond",ae=class{constructor(t){this.chatId=ee(),this.agent=t.agent,this.transport=t.transport,this.renderer=ie(t)??ne(t),this.title=t.title,this.tools=t.tools??"auto-collapsed",this.reasoning=t.reasoning??"auto-collapsed",this.responseStatistics=t.responseStatistics??se,this.contextSize=t.contextSize,this.sandbox=t.sandbox}async run(){let t=this.title,e=[],r=0,s=()=>`message-${++r}`,a,i=!1,o=!1;while(!0){if(!o){if(a==null){if(!this.renderer.readPrompt){if(i)return;throw Error("No prompt was provided and the renderer does not support prompt input.")}try{a=await this.renderer.readPrompt({title:t})}catch(l){if(V(l))return;throw l}if(a==null)return}e.push(ue(s(),a)),i=!0}let u=await this.streamMessages([...e],s);try{let l=await this.renderer.renderStream(u,{title:t,submittedPrompt:a,continueSession:Boolean(this.renderer.readPrompt),tools:this.tools,reasoning:this.reasoning,responseStatistics:this.responseStatistics,contextSize:this.contextSize,waitForExit:!1});if(l&&l.parts.length>0){let n=ce(l);if(n.length>0){if(!this.renderer.readToolApproval)throw Error("Tool approval was requested, but the renderer does not support tool approval input.");for(let x of n){let f=await this.renderer.readToolApproval(x,{title:t});de(l,x,f)}D(e,l,o),o=!0,a=void 0;continue}D(e,l,o)}}catch(l){if(V(l))return;throw l}o=!1,a=void 0}}async streamMessages(t,e){let r=new AbortController,s=()=>r.abort();if(this.transport)return{uiMessageStream:await this.transport.sendMessages({trigger:"submit-message",chatId:this.chatId,messageId:void 0,messages:t,abortSignal:r.signal}),message:I(t),abort:s};let a=this.agent,i=await a.stream({prompt:await te(t,{tools:a.tools}),abortSignal:r.signal,options:void 0,experimental_sandbox:this.sandbox});return{uiMessageStream:oe(i.fullStream,e,t),message:I(t),abort:s}}};function ne(t){return t.tools===void 0&&t.reasoning===void 0&&t.responseStatistics===void 0&&t.contextSize===void 0?new C:new C({tools:t.tools,reasoning:t.reasoning,responseStatistics:t.responseStatistics,contextSize:t.contextSize})}function ie(t){if(t.renderer)return t.renderer;if(!t.screen&&!t.userInput)return;return new C({tools:t.tools,reasoning:t.reasoning,responseStatistics:t.responseStatistics,contextSize:t.contextSize,input:t.userInput,output:t.screen})}async function*oe(t,e,r=[]){let s=new Set,a=new Set,i=new Set,o,u,l=!1;yield{type:"start",messageId:I(r)?.id??e()};for await(let n of t)switch(n.type){case"text-start":s.add(n.id),yield{type:"text-start",id:n.id,providerMetadata:n.providerMetadata};break;case"text-delta":if(!s.has(n.id))s.add(n.id),yield{type:"text-start",id:n.id,providerMetadata:n.providerMetadata};yield{type:"text-delta",id:n.id,delta:n.text,providerMetadata:n.providerMetadata};break;case"text-end":s.delete(n.id),yield{type:"text-end",id:n.id,providerMetadata:n.providerMetadata};break;case"reasoning-start":a.add(n.id),yield{type:"reasoning-start",id:n.id,providerMetadata:n.providerMetadata};break;case"reasoning-delta":if(!a.has(n.id))a.add(n.id),yield{type:"reasoning-start",id:n.id,providerMetadata:n.providerMetadata};yield{type:"reasoning-delta",id:n.id,delta:n.text,providerMetadata:n.providerMetadata};break;case"reasoning-end":a.delete(n.id),yield{type:"reasoning-end",id:n.id,providerMetadata:n.providerMetadata};break;case"tool-input-start":yield{type:"tool-input-start",toolCallId:n.id,toolName:n.toolName,providerExecuted:n.providerExecuted,providerMetadata:n.providerMetadata,toolMetadata:n.toolMetadata,dynamic:n.dynamic,title:n.title};break;case"tool-input-delta":yield{type:"tool-input-delta",toolCallId:n.id,inputTextDelta:n.delta};break;case"tool-call":i.add(n.toolCallId),yield{type:"tool-input-available",toolCallId:n.toolCallId,toolName:n.toolName,input:n.input,providerExecuted:n.providerExecuted,providerMetadata:n.providerMetadata,toolMetadata:n.toolMetadata,dynamic:n.dynamic,title:n.title};break;case"tool-approval-request":if(!i.has(n.toolCall.toolCallId))i.add(n.toolCall.toolCallId),yield{type:"tool-input-available",toolCallId:n.toolCall.toolCallId,toolName:n.toolCall.toolName,input:n.toolCall.input,providerExecuted:n.toolCall.providerExecuted,providerMetadata:n.toolCall.providerMetadata,toolMetadata:n.toolCall.toolMetadata,dynamic:n.toolCall.dynamic,title:n.toolCall.title};yield{type:"tool-approval-request",approvalId:n.approvalId,toolCallId:n.toolCall.toolCallId,isAutomatic:n.isAutomatic};break;case"tool-approval-response":yield{type:"tool-approval-response",approvalId:n.approvalId,approved:n.approved,reason:n.reason,providerExecuted:n.providerExecuted};break;case"tool-result":yield{type:"tool-output-available",toolCallId:n.toolCallId,output:n.output,providerExecuted:n.providerExecuted,providerMetadata:n.providerMetadata,toolMetadata:n.toolMetadata,dynamic:n.dynamic,preliminary:n.preliminary};break;case"tool-error":yield{type:"tool-output-error",toolCallId:n.toolCallId,errorText:q(n.error),providerExecuted:n.providerExecuted,providerMetadata:n.providerMetadata,toolMetadata:n.toolMetadata,dynamic:n.dynamic};break;case"tool-output-denied":yield{type:"tool-output-denied",toolCallId:n.toolCallId};break;case"source":if(n.sourceType==="url")yield{type:"source-url",sourceId:n.id,url:n.url,title:n.title,providerMetadata:n.providerMetadata};else yield{type:"source-document",sourceId:n.id,mediaType:n.mediaType,title:n.title,filename:n.filename,providerMetadata:n.providerMetadata};break;case"file":yield{type:"file",url:_(n.file.mediaType,n.file.base64),mediaType:n.file.mediaType,providerMetadata:n.providerMetadata};break;case"reasoning-file":yield{type:"reasoning-file",url:_(n.file.mediaType,n.file.base64),mediaType:n.file.mediaType,providerMetadata:n.providerMetadata};break;case"start-step":yield{type:"start-step"};break;case"finish-step":o=n.usage,u=n.performance,yield{type:"finish-step"};break;case"finish":yield*N(s,a),l=!0,yield{type:"finish",finishReason:n.finishReason,messageMetadata:le(o??n.totalUsage,u)};break;case"abort":yield{type:"abort",reason:n.reason};break;case"error":yield{type:"error",errorText:q(n.error)};break}if(!l)yield*N(s,a),yield{type:"finish"}}function le(t,e){if(t?.totalTokens==null&&t?.outputTokens==null&&e?.outputTokensPerSecond==null)return;return{...t?.totalTokens==null&&t?.outputTokens==null?{}:{usage:{...t.totalTokens==null?{}:{totalTokens:t.totalTokens},...t.outputTokens==null?{}:{outputTokens:t.outputTokens}}},...e?.outputTokensPerSecond==null?{}:{performance:{outputTokensPerSecond:e.outputTokensPerSecond}}}}function*N(t,e){for(let r of t)yield{type:"text-end",id:r};t.clear();for(let r of e)yield{type:"reasoning-end",id:r};e.clear()}function ue(t,e){return{id:t,role:"user",parts:[{type:"text",text:e}]}}function D(t,e,r){if(r&&t.at(-1)?.role==="assistant"){t[t.length-1]=e;return}t.push(e)}function I(t){let e=t.at(-1);return e?.role==="assistant"?e:void 0}function ce(t){let e=[];for(let[r,s]of t.parts.entries()){if(!Q(s)||s.state!=="approval-requested"||s.approval.isAutomatic===!0)continue;e.push({approvalId:s.approval.id,toolCallId:s.toolCallId,toolName:re(s),title:s.title,input:s.input,providerExecuted:s.providerExecuted,messageId:t.id,partIndex:r})}return e}function de(t,e,r){let s=t.parts[e.partIndex];if(!s||!Q(s)||s.toolCallId!==e.toolCallId)throw Error(`Could not find tool approval request ${e.approvalId}.`);s.state="approval-responded",s.approval={id:e.approvalId,approved:r.approved,...r.reason?{reason:r.reason}:{}}}function q(t){if(t instanceof Error)return t.message;if(typeof t==="string")return t;return JSON.stringify(t)}function _(t,e){return`data:${t};base64,${e}`}function V(t){return t instanceof Error&&t.message==="Interrupted"}async function X(t){await new ae(t).run()}import{convertToModelMessages as pe,generateId as P,toTextStream as he,toUIMessageStream as fe}from"ai";async function $e(t){if(t.prompt!==void 0)me(t.prompt);await X({title:`broods · ${t.agent.name}`,tools:"full",transport:new tt(t.client,t.agent)})}async function Ce(t){let e=he({stream:et(t.client.stream(t.agent,{input:t.prompt}),void 0,()=>{})});for await(let r of e)process.stdout.write(r);process.stdout.write(`
|
|
19
|
+
`)}async function me(t){let e=process.stdin.listenerCount("data"),r=Date.now()+1e4;while(process.stdin.listenerCount("data")<=e){if(Date.now()>r)return;await new Promise((s)=>setTimeout(s,20))}process.stdin.emit("data",Buffer.from(t)),process.stdin.emit("data",Buffer.from("\r"))}class tt{client;agent;conversationKey=`tui-${P()}`;sentApprovals=new Set;sentUserTurns=0;constructor(t,e){this.client=t;this.agent=e}async reconnectToStream(){return null}async sendMessages(t){let e=this.pendingEvents(await pe(t.messages));if(e.events.length===0)throw Error("Nothing new to send: the agent already saw this turn.");let r=this.client.stream(this.agent,{conversationKey:this.conversationKey,events:e.events});return fe({stream:et(r,t.abortSignal,e.commit),originalMessages:t.messages,generateMessageId:P,sendSources:!0})}pendingEvents(t){let e=[],r=[],s=0;for(let a of t){if(a.role==="user"){if(s+=1,s>this.sentUserTurns)e.push(a);continue}if(a.role!=="tool")continue;for(let i of a.content)if(i.type==="tool-approval-response"&&!this.sentApprovals.has(i.approvalId))r.push(i)}if(r.length>0)e.push({role:"tool",content:r});return{events:e,commit:()=>{this.sentUserTurns=s;for(let a of r)this.sentApprovals.add(a.approvalId)}}}}function ge(t){return new Promise((e)=>{if(!t)return;let r=()=>e({done:!0,value:void 0});if(t.aborted)r();else t.addEventListener("abort",r,{once:!0})})}function et(t,e,r){let s=!1,a=()=>void t.return(void 0);return new ReadableStream({pull:async function(i){let o=await Promise.race([t.next(),ge(e)]);if(e?.aborted){a(),i.close();return}if(!s)s=!0,r();if(o.done)i.close();else i.enqueue(o.value)},cancel:a})}export{$e as runAgentTui,Ce as streamAgentText};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{L,
|
|
2
|
-
`));f({type:"result",id:i.id,exitCode:y,stdout:h.text(),stderr:w.text(),durationMs:Math.round(A.now()-m),timedOut:b,truncated:h.truncated||w.truncated})},F=te("bash",["-lc",i.code],{cwd:i.cwd??c,env:{...L(),...i.env},detached:!0,stdio:["ignore","pipe","pipe"]}),S=()=>{if(!F.pid)return;try{process.kill(-F.pid,"SIGKILL")}catch{F.kill("SIGKILL")}},v=setTimeout(()=>{b=!0,S()},i.timeoutSeconds*1000),g=()=>{S(),M(null,"stopped: the daemon closed its socket")};if(u?.addEventListener("abort",g,{once:!0}),F.stdout.on("data",(y)=>h.append(y)),F.stderr.on("data",(y)=>w.append(y)),F.on("error",(y)=>M(null,y.message)),F.on("close",(y)=>M(y)),u?.aborted)g()})}async function we(i){let c=fe(),u=crypto.randomUUID(),f=i.mcpFile?await ce(i.mcpFile,i.log):null,m=i.computer?await ae(i.log):null,h=I;try{while(!i.signal.aborted){let w=Date.now(),b;try{b=await i.credential()}catch(M){if(M instanceof q)throw M;i.log(`stage session unavailable (${M instanceof Error?M.message:String(M)}), retrying in ${Math.round(h/1000)}s`),await se(h,i.signal),h=Math.min(h*2,k);continue}let x=await pe(i,b,u,c,m,f);if(i.signal.aborted)return;if(re.has(x.code))throw Error(x.reason||`core closed the socket (${x.code})`);if(Date.now()-w>k)h=I;i.log(`disconnected (${x.reason||x.code}), reconnecting in ${Math.round(h/1000)}s`),await se(h,i.signal),h=Math.min(h*2,k)}}finally{m?.stop(),await f?.stop()}}class
|
|
1
|
+
import{L,E}from"./chunk-zbp92p62.js";import{e,o,a,l,n,t,d,R,s,p,r}from"./chunk-t3g8jagy.js";import{se,fe,q}from"./cli/index.js";import{spawn as te}from"node:child_process";import{hostname as oe}from"node:os";import{performance as A}from"node:perf_hooks";var N=["cursor_position","double_click","hold_key","key","left_click","left_click_drag","left_mouse_down","left_mouse_up","middle_click","mouse_move","right_click","screenshot","scroll","triple_click","type","wait","zoom"];var _={badFrame:{code:4400,reason:"Malformed frame"},occupied:{code:4423,reason:"Already connected from another daemon"},replaced:{code:4409,reason:"Replaced by a newer connection"},unauthorized:{code:4401,reason:"Unauthorized; run broods login"},unknownSandbox:{code:4404,reason:"No machine sandbox with that name in this account"}};var H="/v1/machines/ws",P=t({action:p(N),coordinate:n(o().int()).length(2).optional().describe("[x, y] in screenshot pixels for mouse actions."),start_coordinate:n(o().int()).length(2).optional().describe("[x, y] where a left_click_drag starts."),text:e().optional().describe("Text for type, the key chord for key and hold_key, or modifiers to hold during a click, drag or scroll."),scroll_direction:p(["down","left","right","up"]).optional(),scroll_amount:o().int().min(1).optional().describe("Scroll clicks, default 3."),duration:o().min(0).max(300).optional().describe("Seconds for wait and hold_key."),region:n(o().int()).length(4).optional().describe("[x0, y0, x1, y1] of the screenshot to zoom into."),repeat:o().int().min(1).max(100).optional().describe("How many times to press the key.")}),U=P.extend({type:r("computer"),id:e()}),B=t({type:r("computer-result"),id:e(),text:e().optional(),image:t({data:e(),mediaType:e()}).optional(),app:e().optional(),error:e().optional()}),W=t({type:r("exec"),id:e(),code:e(),cwd:e().optional(),env:s(e(),e()).optional(),timeoutSeconds:o().positive(),outputLimitBytes:o().positive()}),G=t({type:r("hello"),sandbox:e().min(1),hostname:e().optional(),platform:e().optional(),computer:a().optional(),mcp:n(e()).optional(),instance:e().optional(),force:a().optional()}),J=t({type:r("mcp-call"),id:e(),server:e(),tool:e(),args:s(e(),l())}),K=t({type:r("mcp-list"),id:e(),server:e()}),X=t({type:r("mcp-result"),id:e(),result:d({content:n(l())}).optional(),error:e().optional()}),Y=t({type:r("mcp-tools"),id:e(),tools:n(d({name:e(),inputSchema:s(e(),l())})).optional(),error:e().optional()}),Z=t({type:r("ready"),sandboxId:e()}),Q=t({type:r("result"),id:e(),exitCode:o().nullable(),stdout:e(),stderr:e(),durationMs:o(),timedOut:a(),truncated:a()}),V=R("type",[U,W,J,K,Z]),ue=R("type",[B,G,X,Y,Q]);function T(i){let c=new URL(H,i);return c.protocol=c.protocol==="https:"?"wss:":"ws:",c.toString()}function D(i){return ee(V,i)}function ee(i,c){if(typeof c!=="string")return null;try{let u=i.safeParse(JSON.parse(c));return u.success?u.data:null}catch{return null}}var re=new Set([_.occupied.code,_.replaced.code,_.unauthorized.code,_.unknownSandbox.code]),z=72,k=30000,I=1000;function ne(i,c,u){return new Promise((f)=>{let m=A.now(),h=new C(i.outputLimitBytes),w=new C(i.outputLimitBytes),b=!1,x=!1,M=(y,O)=>{if(x)return;if(x=!0,clearTimeout(v),u?.removeEventListener("abort",g),O)w.append(Buffer.from(`${O}
|
|
2
|
+
`));f({type:"result",id:i.id,exitCode:y,stdout:h.text(),stderr:w.text(),durationMs:Math.round(A.now()-m),timedOut:b,truncated:h.truncated||w.truncated})},F=te("bash",["-lc",i.code],{cwd:i.cwd??c,env:{...L(),...i.env},detached:!0,stdio:["ignore","pipe","pipe"]}),S=()=>{if(!F.pid)return;try{process.kill(-F.pid,"SIGKILL")}catch{F.kill("SIGKILL")}},v=setTimeout(()=>{b=!0,S()},i.timeoutSeconds*1000),g=()=>{S(),M(null,"stopped: the daemon closed its socket")};if(u?.addEventListener("abort",g,{once:!0}),F.stdout.on("data",(y)=>h.append(y)),F.stderr.on("data",(y)=>w.append(y)),F.on("error",(y)=>M(null,y.message)),F.on("close",(y)=>M(y)),u?.aborted)g()})}async function we(i){let c=fe(),u=crypto.randomUUID(),f=i.mcpFile?await ce(i.mcpFile,i.log):null,m=i.computer?await ae(i.log):null,h=I;try{while(!i.signal.aborted){let w=Date.now(),b;try{b=await i.credential()}catch(M){if(M instanceof q)throw M;i.log(`stage session unavailable (${M instanceof Error?M.message:String(M)}), retrying in ${Math.round(h/1000)}s`),await se(h,i.signal),h=Math.min(h*2,k);continue}let x=await pe(i,b,u,c,m,f);if(i.signal.aborted)return;if(re.has(x.code))throw Error(x.reason||`core closed the socket (${x.code})`);if(Date.now()-w>k)h=I;i.log(`disconnected (${x.reason||x.code}), reconnecting in ${Math.round(h/1000)}s`),await se(h,i.signal),h=Math.min(h*2,k)}}finally{m?.stop(),await f?.stop()}}class C{#o=[];#e;#t=0;truncated=!1;constructor(i){this.#e=i}append(i){if(this.#t>=this.#e){this.truncated=!0;return}let c=this.#e-this.#t;if(i.byteLength>c){this.#o.push(i.subarray(0,c)),this.#t=this.#e,this.truncated=!0;return}this.#o.push(i),this.#t+=i.byteLength}text(){let i=Buffer.concat(this.#o).toString("utf8");return this.truncated?`${i}
|
|
3
3
|
[output truncated]`:i}}function ie(i){let c=[i.action];if(i.coordinate)c.push(`at ${i.coordinate.join(",")}`);if(i.text!==void 0)c.push(JSON.stringify(j(i.text)));if(i.region)c.push(`region ${i.region.join(",")}`);return c.join(" ")}function j(i){let c=i.trim().split(`
|
|
4
|
-
`)[0]??"";return c.length>z?`${c.slice(0,z)}…`:c}async function ae(i){let{startDesktop:c}=await import("./chunk-5tnnqapc.js"),{display:u,driver:f,permissions:m}=await c(!1);if(i(`computer use on, ${u.width}x${u.height} screenshots`),!m.screenRecording||!m.accessibility)i(" screen recording or accessibility is missing, run `broods machine --doctor --request`");return f}async function ce(i,c){let{McpHost:u,readMcpServersFile:f}=await import("./chunk-
|
|
4
|
+
`)[0]??"";return c.length>z?`${c.slice(0,z)}…`:c}async function ae(i){let{startDesktop:c}=await import("./chunk-5tnnqapc.js"),{display:u,driver:f,permissions:m}=await c(!1);if(i(`computer use on, ${u.width}x${u.height} screenshots`),!m.screenRecording||!m.accessibility)i(" screen recording or accessibility is missing, run `broods machine --doctor --request`");return f}async function ce(i,c){let{McpHost:u,readMcpServersFile:f}=await import("./chunk-zj2wzjc6.js"),m=new u(f(i),c);return c(`mcp servers from ${i}: ${m.names().join(", ")}`),m}async function le(i,c,u){try{if(i.type==="mcp-list"){let m=await c.listTools(i.server);return u(` mcp ${i.server}: ${m.length} tools`),{type:"mcp-tools",id:i.id,tools:m}}u(` mcp ${i.server}.${i.tool}`);let f=await c.callTool(i.server,i.tool,i.args);return{type:"mcp-result",id:i.id,result:f}}catch(f){let m=f instanceof Error?f.message:String(f);return u(` mcp ${i.server}: ${m}`),{type:i.type==="mcp-call"?"mcp-result":"mcp-tools",id:i.id,error:m}}}function pe(i,c,u,f,m,h){return new Promise((w)=>{let b=new f(T(i.baseUrl),E(c)),x=new AbortController,M=()=>b.close(1000,"daemon stopped"),F=(v)=>{if(b.readyState===b.OPEN)b.send(JSON.stringify(v))},S=(v,g)=>{i.signal.removeEventListener("abort",M),x.abort(),w({code:v,reason:g})};i.signal.addEventListener("abort",M,{once:!0}),b.onopen=()=>F({type:"hello",sandbox:i.sandbox,hostname:oe(),platform:process.platform,computer:m!==null,mcp:h?.names(),instance:u,force:i.force}),b.onmessage=(v)=>{let g=D(v.data);if(g?.type==="ready"){i.log(`connected as ${i.sandbox} (${g.sandboxId})`);return}if(g?.type==="computer"&&m){i.log(` ${ie(g)}`),m.run(g).then((y)=>{if(y.error)i.log(` error: ${y.error}`);F(y)});return}if((g?.type==="mcp-call"||g?.type==="mcp-list")&&h){le(g,h,i.log).then(F);return}if(g?.type!=="exec")return;i.log(`$ ${j(g.code)}`),ne(g,i.cwd,x.signal).then((y)=>{i.log(` exit ${y.exitCode??"none"} in ${y.durationMs}ms${y.timedOut?" (timed out)":""}`),F(y)})},b.onerror=()=>S(1006,"connection failed"),b.onclose=(v)=>S(v.code,v.reason)})}export{we as runMachineDaemon};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{y,de,pe,
|
|
1
|
+
import{y,de,pe,Ce}from"./chunk-t3g8jagy.js";var c=()=>{let a={string:{unit:"characters",verb:"to have"},file:{unit:"bytes",verb:"to have"},array:{unit:"items",verb:"to have"},set:{unit:"items",verb:"to have"},map:{unit:"entries",verb:"to have"}};function n(t){return a[t]??null}let d={regex:"input",email:"email address",url:"URL",emoji:"emoji",uuid:"UUID",uuidv4:"UUIDv4",uuidv6:"UUIDv6",nanoid:"nanoid",guid:"GUID",cuid:"cuid",cuid2:"cuid2",ulid:"ULID",xid:"XID",ksuid:"KSUID",datetime:"ISO datetime",date:"ISO date",time:"ISO time",duration:"ISO duration",ipv4:"IPv4 address",ipv6:"IPv6 address",mac:"MAC address",cidrv4:"IPv4 range",cidrv6:"IPv6 range",base64:"base64-encoded string",base64url:"base64url-encoded string",json_string:"JSON string",e164:"E.164 number",jwt:"JWT",template_literal:"input"},o={nan:"NaN"};return(t)=>{switch(t.code){case"invalid_type":{let e=o[t.expected]??t.expected,r=Ce(t.input),l=o[r]??r;return`Invalid input: expected ${e}, received ${l}`}case"invalid_value":if(t.values.length===1)return`Invalid input: expected ${pe(t.values[0])}`;return`Invalid option: expected one of ${de(t.values,"|")}`;case"too_big":{let e=t.inclusive?"<=":"<",r=n(t.origin);if(r)return`Too big: expected ${t.origin??"value"} to have ${e}${t.maximum.toString()} ${r.unit??"elements"}`;return`Too big: expected ${t.origin??"value"} to be ${e}${t.maximum.toString()}`}case"too_small":{let e=t.inclusive?">=":">",r=n(t.origin);if(r)return`Too small: expected ${t.origin} to have ${e}${t.minimum.toString()} ${r.unit}`;return`Too small: expected ${t.origin} to be ${e}${t.minimum.toString()}`}case"invalid_format":{let e=t;if(e.format==="starts_with")return`Invalid string: must start with "${e.prefix}"`;if(e.format==="ends_with")return`Invalid string: must end with "${e.suffix}"`;if(e.format==="includes")return`Invalid string: must include "${e.includes}"`;if(e.format==="regex")return`Invalid string: must match pattern ${e.pattern}`;return`Invalid ${d[e.format]??t.format}`}case"not_multiple_of":return`Invalid number: must be a multiple of ${t.divisor}`;case"unrecognized_keys":return`Unrecognized key${t.keys.length>1?"s":""}: ${de(t.keys,", ")}`;case"invalid_key":return`Invalid key in ${t.origin}`;case"invalid_union":if(t.options&&Array.isArray(t.options)&&t.options.length>0)return`Invalid discriminator value. Expected ${t.options.map((r)=>`'${r}'`).join(" | ")}`;return"Invalid input";case"invalid_element":return`Invalid value in ${t.origin}`;default:return"Invalid input"}}};function i(){return{localeError:c()}}y(i());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{T,i,F,M,X,Q,ee,b,P,te,ae,ce,Se,be,ve,_e,le,ue,we,Re,$e,N}from"./chunk-p5134ra1.js";var z=class{_readBuffer;_started=!1;_closed=!1;constructor(r=le.stdin,s=le.stdout,c){this._stdin=r,this._stdout=s,this._readBuffer=new ve({maxBufferSize:c?.maxBufferSize})}onclose;onerror;onmessage;_ondata=(r)=>{try{this._readBuffer.append(r),this.processReadBuffer()}catch(s){this.onerror?.(s),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((s,c)=>{let l=_e(r),t=!1,f=(_)=>{if(t)return;t=!0,this._stdout.off("error",f),this._stdout.off("drain",p),c(_)},p=()=>{if(t)return;t=!0,this._stdout.off("error",f),this._stdout.off("drain",p),s()};if(this._stdout.once("error",f),this._stdout.write(l)){if(t)return;t=!0,this._stdout.off("error",f),s()}else if(!t)this._stdout.once("drain",p)})}},j=3000,A=class{onclose;onerror;onmessage;_closed=!1;_pendingRequests=new Set;_drainWaiters=[];constructor(r,s,c){this._wire=r,this._onInstanceClose=s,this._outboundIntercept=c}async start(){}async send(r,s){if(te(r)||ae(r)){let{id:c}=r;if(c!==void 0)this._settle(c)}if(this._closed)return;if(this._outboundIntercept?.(r)==="handled")return;return this._wire.send(r,s)}setProtocolVersion=(r)=>{this._wire.setProtocolVersion?.(r)};deliver(r,s){if(this._closed)return;if(b(r))this._pendingRequests.add(r.id);else if(P(r)&&r.method==="notifications/cancelled"){let c=r.params?.requestId;if(c!==void 0)this._settle(c)}this.onmessage?.(r,s)}async whenRequestsAnswered(r){if(this._closed||this._pendingRequests.size===0)return!0;return await new Promise((s)=>{let c=()=>{clearTimeout(l),s(!0)},l=setTimeout(()=>{this._drainWaiters=this._drainWaiters.filter((t)=>t!==c),s(!1)},r);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(r){if(this._pendingRequests.delete(r),this._pendingRequests.size===0)this._releaseDrainWaiters()}_releaseDrainWaiters(){let r=this._drainWaiters;this._drainWaiters=[];for(let s of r)s()}};function J(r){let s=r.params;if(r.method==="initialize"&&!ce(s)){let f=s!==null&&typeof s==="object"&&typeof s.protocolVersion==="string"?s.protocolVersion:void 0;return{kind:"legacy",reason:"initialize",...f!==void 0&&{requestedVersion:f}}}if(!X(s))return{kind:"legacy",reason:"no-claim"};let c=M(s),l=(c===void 0?[]:ee(c))[0];if(l!==void 0)return{kind:"invalid-envelope",issue:l};let t=Q(s);if(t===void 0||!T.includes(t))return{kind:"unsupported-revision",requested:t??"unknown"};return{kind:"modern",revision:t,classification:{era:"modern",revision:t}}}function g(r,s={}){let c=s.legacy??"serve",l=s.transport??new z,t={phase:"opening"},f,p=!1,_=()=>p||t.phase==="closed",d=(e)=>{try{s.onerror?.(e)}catch{}},y=(e,n,o,a)=>l.send({jsonrpc:"2.0",id:e,error:{code:n,message:o,...a!==void 0&&{data:a}}}).catch((u)=>d(h(u))),w=new we(s.maxSubscriptions??ue),k=(e)=>{if(!P(e))return;let n=w.routeOutbound(e);if(n==="passthrough")return;for(let o of n)l.send({jsonrpc:"2.0",...o}).catch((a)=>d(h(a)));return"handled"},I=async(e)=>{if(b(e)&&e.method==="subscriptions/listen"){let n=M(e.params),o=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(o!==void 0)u={jsonrpc:"2.0",id:e.id,error:{code:-32602,message:`Invalid _meta envelope: ${o.key}: ${o.problem}`}};else if(a===void 0||!T.includes(a)){let v=new F({supported:[...T],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(P(e)&&e.method==="notifications/cancelled"){let n=e.params?.requestId;if(n!==void 0&&w.cancel(n))return!0}return!1},q=(e,n,o)=>{let a=Se({kind:"legacy",reason:n,...o!==void 0&&{requestedVersion:o}},T);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)},D=(e)=>{if(p||e===f)return;C()},m=async(e,n)=>{let o=await r({era:e}),a=o instanceof N?o.server:o;if(e==="modern")be(a,n),Re(a,T),w.setServerCapabilities(a.getCapabilities(),$e(a));let u=new A(l,()=>D(u),e==="modern"?k:void 0);return await o.connect(u),{product:o,channel:u}},R=(e)=>e.product.close().catch((n)=>d(h(n))),V=async(e)=>{f=e.channel;try{if(!await e.channel.whenRequestsAnswered(j))d(Error(`Discarded the probe instance with requests still unanswered after ${j}ms; continuing with the fallback`));await e.product.close()}catch(n){d(h(n))}finally{f=void 0}},B=async(e)=>{if(t.phase==="closed")return;if(t.phase==="pinned"){if(t.era==="modern"&&b(e)&&e.method==="initialize"&&!ce(e.params)){await q(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 I(e))return;t.instance.channel.deliver(e);return}if(!b(e)&&!P(e)){d(Error("Discarded a JSON-RPC response received before the connection negotiated an era"));return}let n=J(e);switch(n.kind){case"invalid-envelope":{let o=`Invalid _meta envelope for protocol revision 2026-07-28: ${n.issue.key}: ${n.issue.problem}`;if(b(e))await y(e.id,i.InvalidParams,o,{envelope:n.issue});else d(Error(`Discarded a notification with a malformed envelope: ${o}`));return}case"unsupported-revision":if(b(e)){let o=new F({supported:[...T],requested:n.requested});d(o),await y(e.id,o.code,o.message,o.data)}else d(Error(`Discarded a notification claiming unsupported protocol revision ${n.requested}`));return;case"modern":if(b(e)&&e.method==="server/discover"){if(t.phase==="probe"){t.instance.channel.deliver(e,{classification:n.classification});return}let o=await m("modern",n.revision);if(_()){await R(o);return}t={phase:"probe",instance:o},o.channel.deliver(e,{classification:n.classification});return}if(t.phase==="probe"){if(P(e)){t.instance.channel.deliver(e,{classification:n.classification});return}t={phase:"pinned",era:"modern",instance:t.instance}}else{let o=await m("modern",n.revision);if(_()){await R(o);return}t={phase:"pinned",era:"modern",instance:o}}if(await I(e))return;t.instance.channel.deliver(e,{classification:n.classification});return;case"legacy":{if(c==="reject"){if(b(e))await q(e,n.reason,n.requestedVersion);return}if(t.phase==="probe"){if(await V(t.instance),_())return;t={phase:"opening"}}let o=await m("legacy");if(_()){await R(o);return}t={phase:"pinned",era:"legacy",instance:o},t.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 B(e)}catch(n){if(b(e))await y(e.id,i.InternalError,"Internal server error");d(h(n))}}}finally{E=!1}},C=async()=>{if(p||t.phase==="closed")return;p=!0;let e=t;t={phase:"closed"};for(let n of w.teardownAll())await l.send(n).catch((o)=>d(h(o)));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),t.phase==="probe"||t.phase==="pinned")t.instance.channel.onerror?.(e)},l.onclose=()=>{if(p||t.phase==="closed")return;p=!0;let e=t;if(t={phase:"closed"},e.phase==="probe"||e.phase==="pinned")e.instance.product.close().catch((n)=>d(h(n)))};let O=l.start().catch((e)=>{throw d(h(e)),e});return O.catch(()=>{}),{close:async()=>{await O.catch(()=>{}),await C()}}}function h(r){return r instanceof Error?r:Error(String(r))}export{g as serveStdio};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N}from"./chunk-p56s3q1t.js";import{B,Z}from"./chunk-keg0nsm2.js";import{e,o,a,l,s}from"./chunk-3gnqn6ap.js";var R={project:e().optional(),stage:e().optional()},C={sandboxId:e().min(1),reservationKey:e().min(1)},v=a().describe("Must be true, after the owner has agreed to this delete."),E="'********' keeps a stored secret and null deletes a field: never send a placeholder you did not read from a get.",M=[{singular:"agent",plural:"agents",key:"agentId",createHint:"Needs name and config; a 409 returns the existing agentId.",deleteHint:"Deleting an agent also drops its runtime rows.",updateHint:E,list:(t)=>t.listAgents(),get:(t,r)=>t.getAgent(r),create:(t,r)=>t.createAgent(r),update:(t,r,n)=>t.updateAgent(r,n),remove:(t,r)=>t.deleteAgent(r)},{singular:"cron",plural:"crons",key:"cronId",createHint:"Needs name, agentId, scheduleExpression (rate/cron/at) and input or events.",list:(t)=>t.listCrons(),get:(t,r)=>t.getCron(r),create:(t,r)=>t.createCron(r),update:(t,r,n)=>t.updateCron(r,n),remove:(t,r)=>t.deleteCron(r)},{singular:"sandbox",plural:"sandboxes",key:"sandboxId",updateHint:E,list:(t)=>t.listSandboxes(),get:(t,r)=>t.getSandbox(r),create:(t,r)=>t.createSandbox(r),update:(t,r,n)=>t.updateSandbox(r,n),remove:(t,r)=>t.deleteSandbox(r)},{singular:"workspace",plural:"workspaces",key:"workspaceId",list:(t)=>t.listWorkspaces(),get:(t,r)=>t.getWorkspace(r),create:(t,r)=>t.createWorkspace(r),update:(t,r,n)=>t.updateWorkspace(r,n),remove:(t,r)=>t.deleteWorkspace(r)},{singular:"policy",plural:"policies",key:"policyId",createHint:"Agent-runtime policy document (tool.call, skill.load), not API credential scoping.",list:(t)=>t.listPolicies(),get:(t,r)=>t.getPolicy(r),create:(t,r)=>t.createPolicy(r),update:(t,r,n)=>t.updatePolicy(r,n),remove:(t,r)=>t.deletePolicy(r)},{singular:"role",plural:"roles",key:"roleId",createHint:"Needs name and a version-1 policy over the API namespace, e.g. agents:read. Account secret only.",list:(t)=>t.listRoles(),get:(t,r)=>t.getRole(r),create:(t,r)=>t.createRole(r),update:(t,r,n)=>t.updateRole(r,n),remove:(t,r)=>t.deleteRole(r)},{singular:"channel",plural:"channels",key:"channelId",list:(t)=>t.listChannels(),get:(t,r)=>t.getChannel(r),create:(t,r)=>t.createChannel(r),update:(t,r,n)=>t.updateChannel(r,n),remove:(t,r)=>t.deleteChannel(r)},{singular:"skill",plural:"skills",key:"skillName",createHint:'source is "files" (base64), "json" or "github". The stored name comes from the SKILL.md frontmatter.',list:(t)=>t.listSkills(),get:(t,r)=>t.getSkill(r),create:(t,r)=>t.createSkill(r),remove:(t,r)=>t.deleteSkill(r)},{singular:"mcp",plural:"mcp",key:"serverId",scoped:!0,list:(t,r)=>t.listMcp(r),get:(t,r)=>t.getMcp(r),create:(t,r,n)=>t.createMcp(n,r),update:(t,r,n)=>t.updateMcp(r,n),remove:(t,r)=>t.deleteMcp(r)}];function Pt(t={}){let r=B()?new Z({}):null;if(!r&&!t.cli)throw Error("broods mcp needs a credential: set BROODS_SESSION_TOKEN or BROODS_ACCOUNT_SECRET, or run `broods login`.");let n=new N({name:"broods",version:"1"},{capabilities:{tools:{}}});if(r){for(let i of M)j(n,r,i,t.scope??{});q(n,r)}if(t.cli)P(n,t.cli);if(t.allowDestructive)O(n,r,t.cli??null);return n}function w(t,r){if(!t)throw Error(`Refusing without confirm:true. ${r}`)}async function d(t){try{return k(await t())}catch(r){return A(r)}}function A(t){return{content:[{type:"text",text:t instanceof Error?t.message:String(t)}],isError:!0}}function k(t){return{content:[{type:"text",text:JSON.stringify(t??null,null,2)}]}}function b(t,r,n,i){if(!t.scoped)return;let c=n??r.project,p=i??r.stage;if(!c||!p)throw Error(`${t.plural} live in one stage, so this call needs both 'project' and 'stage'`);return{project:c,stage:p}}function P(t,r){t.registerTool("list-orgs",{description:"Every organization this login can reach, with the current one marked.",inputSchema:{}},async()=>await d(async()=>{let n=await r.getOnboarding();return{currentOrgId:n.currentOrgId,orgs:n.orgs}})),t.registerTool("create-org",{description:"Create an organization and switch this login to it. Later calls act in the new org.",inputSchema:{name:e().min(1)}},async({name:n})=>await d(async()=>await r.createOnboardingOrg(n))),t.registerTool("select-org",{description:"Switch this login to another organization, by an orgId from list-orgs.",inputSchema:{orgId:e().min(1)}},async({orgId:n})=>await d(async()=>await r.selectOnboardingOrg(n))),t.registerTool("list-projects",{description:"Every project in the current org, empty ones last. Project names are not unique, so take the id from here.",inputSchema:{}},async()=>await d(async()=>await r.listProjects())),t.registerTool("list-stages",{description:"Every stage of one project, by project name.",inputSchema:{project:e().min(1)}},async({project:n})=>await d(async()=>await r.listStages(n))),t.registerTool("create-stage",{description:"Create a stage in a project, optionally cloning another stage's architecture and env vars. A project name that does not exist yet is created with it, which is the only way to make a project without deploying a manifest.",inputSchema:{project:e().min(1),name:e().min(1),from:e().optional().describe("Stage to clone architecture and env vars from.")}},async({project:n,name:i,from:c})=>await d(async()=>await r.createStage(n,i,c)))}function O(t,r,n){if(r)t.registerTool("rotate-secret",{description:"Rotate the account secret. The current secret stops working immediately and the new one is shown once, so this breaks every deployment and CI job still holding the old one. Requires confirm:true.",inputSchema:{confirm:v}},async({confirm:i})=>await d(async()=>(w(i,"Everything holding the current secret breaks the moment this runs."),await r.rotateSecret())));if(n)t.registerTool("delete-project",{description:"Delete a project and everything under it: stages, agents, canvas, env vars, crons and workspace files. Takes a projectId from list-projects and requires confirm:true.",inputSchema:{projectId:e().min(1),confirm:v}},async({projectId:i,confirm:c})=>await d(async()=>(w(c,`Project '${i}' and everything under it goes away: name it, get the owner's agreement, then retry.`),await n.deleteProject(i))))}function q(t,r){t.registerTool("list-cron-runs",{description:"Run history for one cron, newest first. Check this before telling anyone a cron fired.",inputSchema:{cronId:e().min(1),limit:o().int().positive().max(100).optional()}},async({cronId:i,limit:c})=>await d(async()=>await r.listCronRuns(i,c===void 0?{}:{limit:c})));let n=[["suspend-sandbox","Suspend a persistent sandbox reservation.",(i,c)=>r.suspendSandbox(i,c)],["resume-sandbox","Resume a suspended sandbox reservation.",(i,c)=>r.resumeSandbox(i,c)],["terminate-sandbox","Terminate a sandbox reservation and drop its live-instance row. Terminate only a sandbox you created, and never one holding state you did not put there.",(i,c)=>r.terminateSandbox(i,c)],["open-sandbox-terminal","Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox.",(i,c)=>r.openSandboxTerminal(i,c)]];for(let[i,c,p]of n)t.registerTool(i,{description:c,inputSchema:C},async({sandboxId:f,reservationKey:g})=>await d(async()=>await p(f,g)));t.registerTool("snapshot-sandbox",{description:"Snapshot a sandbox reservation into a reusable image (self-hosted provider).",inputSchema:{sandboxId:e().min(1),reservationKey:e().min(1),name:e().min(1)}},async({sandboxId:i,reservationKey:c,name:p})=>await d(async()=>await r.snapshotSandbox(i,c,p))),t.registerTool("upload-skill",{description:"Replace one skill's bundle wholesale (PUT, not a merge) by skillName. 'body' is the same source shape create-skill takes.",inputSchema:{id:e().min(1).describe("The skillName."),body:s(e(),l())}},async({id:i,body:c})=>await d(async()=>await r.uploadSkill(i,c))),t.registerTool("list-env-vars",{description:"List environment variable names. Values are write-only: the plane never returns them, so there is no read.",inputSchema:{}},async()=>await d(async()=>await r.listEnvVars())),t.registerTool("set-env-var",{description:"Create or replace one write-only environment variable. Reference it from a config as ${NAME} rather than inlining the value.",inputSchema:{name:e().min(1),value:e()}},async({name:i,value:c})=>await d(async()=>(await r.setEnvVar(i,c),{name:i,stored:!0}))),t.registerTool("delete-env-var",{description:"Delete one environment variable.",inputSchema:{name:e().min(1),confirm:v}},async({name:i,confirm:c})=>await d(async()=>(w(c,`Anything referencing \${${i}} breaks the moment this env var goes.`),{deleted:await r.deleteEnvVar(i),name:i}))),t.registerTool("assume-role",{description:"Exchange a role for a short-lived session token (default 1h, max 12h). Hand the returned token to whatever tool needs narrow access, as BROODS_SESSION_TOKEN. It is shown once and is not stored here.",inputSchema:{roleId:e().min(1),ttlSeconds:o().int().positive().max(43200).optional()}},async({roleId:i,ttlSeconds:c})=>await d(async()=>await r.assumeRole(i,c===void 0?{}:{ttlSeconds:c}))),t.registerTool("update-account",{description:"Rename this account or change its description. Everything else about an account is derived, not settable.",inputSchema:{username:e().optional(),description:e().nullable().optional()}},async({username:i,description:c})=>await d(async()=>await r.updateAccount({...i===void 0?{}:{username:i},...c===void 0?{}:{description:c}}))),t.registerTool("get-account",{description:"The account this server's credential resolves to. Run it first to confirm which tenant you are about to change.",inputSchema:{}},async()=>await d(async()=>await r.getAccount()))}function j(t,r,n,i){let c=e().min(1).describe(`The ${n.key}.`),p=n.scoped?` ${n.plural} live in one stage, so this also takes 'project' and 'stage'.`:"",{list:f,get:g,create:y,update:S,remove:_}=n;if(f){let u=`List every ${n.singular} on the account.${p}`;if(n.scoped)t.registerTool(`list-${n.plural}`,{description:u,inputSchema:R},async({project:h,stage:m})=>await d(async()=>await f(r,b(n,i,h,m))));else t.registerTool(`list-${n.plural}`,{description:u,inputSchema:{}},async()=>await d(async()=>await f(r)))}if(g)t.registerTool(`get-${n.singular}`,{description:`Read one ${n.singular} by ${n.key}.`,inputSchema:{id:c}},async({id:u})=>await d(async()=>await g(r,u)));if(y){let u=`Create one ${n.singular}. 'body' is the request body the config plane documents.`+(n.createHint?` ${n.createHint}`:"")+p+" Prefer changing the broods/ manifest and deploying for anything the project already declares.",h=s(e(),l());if(n.scoped)t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h,...R}},async({body:m,project:T,stage:I})=>await d(async()=>await y(r,m,b(n,i,T,I))));else t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h}},async({body:m})=>await d(async()=>await y(r,m)))}if(S)t.registerTool(`update-${n.singular}`,{description:`Deep-merge a patch into one ${n.singular} and return the updated record, so there is no need to read it back.`+(n.updateHint?` ${n.updateHint}`:""),inputSchema:{id:c,body:s(e(),l())}},async({id:u,body:h})=>await d(async()=>await S(r,u,h)));if(_)t.registerTool(`delete-${n.singular}`,{description:`Delete one ${n.singular}. Requires confirm:true, and takes one ${n.key} per call: never loop this over a list.`+(n.deleteHint?` ${n.deleteHint}`:""),inputSchema:{id:c,confirm:v}},async({id:u,confirm:h})=>await d(async()=>(w(h,`Deleting ${n.singular} '${u}' goes away for good: name it, get the owner's agreement, then retry.`),{deleted:await _(r,u),id:u})))}export{Pt as createBroodsMcpServer};
|
|
1
|
+
import{N}from"./chunk-p5134ra1.js";import{B,Z}from"./chunk-p7t6yawg.js";import{e,o,a,l,s}from"./chunk-t3g8jagy.js";var R={project:e().optional(),stage:e().optional()},C={sandboxId:e().min(1),reservationKey:e().min(1)},v=a().describe("Must be true, after the owner has agreed to this delete."),E="'********' keeps a stored secret and null deletes a field: never send a placeholder you did not read from a get.",M=[{singular:"agent",plural:"agents",key:"agentId",createHint:"Needs name and config; a 409 returns the existing agentId.",deleteHint:"Deleting an agent also drops its runtime rows.",updateHint:E,list:(t)=>t.listAgents(),get:(t,r)=>t.getAgent(r),create:(t,r)=>t.createAgent(r),update:(t,r,n)=>t.updateAgent(r,n),remove:(t,r)=>t.deleteAgent(r)},{singular:"cron",plural:"crons",key:"cronId",createHint:"Needs name, agentId, scheduleExpression (rate/cron/at) and input or events.",list:(t)=>t.listCrons(),get:(t,r)=>t.getCron(r),create:(t,r)=>t.createCron(r),update:(t,r,n)=>t.updateCron(r,n),remove:(t,r)=>t.deleteCron(r)},{singular:"sandbox",plural:"sandboxes",key:"sandboxId",updateHint:E,list:(t)=>t.listSandboxes(),get:(t,r)=>t.getSandbox(r),create:(t,r)=>t.createSandbox(r),update:(t,r,n)=>t.updateSandbox(r,n),remove:(t,r)=>t.deleteSandbox(r)},{singular:"workspace",plural:"workspaces",key:"workspaceId",list:(t)=>t.listWorkspaces(),get:(t,r)=>t.getWorkspace(r),create:(t,r)=>t.createWorkspace(r),update:(t,r,n)=>t.updateWorkspace(r,n),remove:(t,r)=>t.deleteWorkspace(r)},{singular:"policy",plural:"policies",key:"policyId",createHint:"Agent-runtime policy document (tool.call, skill.load), not API credential scoping.",list:(t)=>t.listPolicies(),get:(t,r)=>t.getPolicy(r),create:(t,r)=>t.createPolicy(r),update:(t,r,n)=>t.updatePolicy(r,n),remove:(t,r)=>t.deletePolicy(r)},{singular:"role",plural:"roles",key:"roleId",createHint:"Needs name and a version-1 policy over the API namespace, e.g. agents:read. Account secret only.",list:(t)=>t.listRoles(),get:(t,r)=>t.getRole(r),create:(t,r)=>t.createRole(r),update:(t,r,n)=>t.updateRole(r,n),remove:(t,r)=>t.deleteRole(r)},{singular:"channel",plural:"channels",key:"channelId",list:(t)=>t.listChannels(),get:(t,r)=>t.getChannel(r),create:(t,r)=>t.createChannel(r),update:(t,r,n)=>t.updateChannel(r,n),remove:(t,r)=>t.deleteChannel(r)},{singular:"skill",plural:"skills",key:"skillName",createHint:'source is "files" (base64), "json" or "github". The stored name comes from the SKILL.md frontmatter.',list:(t)=>t.listSkills(),get:(t,r)=>t.getSkill(r),create:(t,r)=>t.createSkill(r),remove:(t,r)=>t.deleteSkill(r)},{singular:"mcp",plural:"mcp",key:"serverId",scoped:!0,list:(t,r)=>t.listMcp(r),get:(t,r)=>t.getMcp(r),create:(t,r,n)=>t.createMcp(n,r),update:(t,r,n)=>t.updateMcp(r,n),remove:(t,r)=>t.deleteMcp(r)}];function Pt(t={}){let r=B()?new Z({}):null;if(!r&&!t.cli)throw Error("broods mcp needs a credential: set BROODS_SESSION_TOKEN or BROODS_ACCOUNT_SECRET, or run `broods login`.");let n=new N({name:"broods",version:"1"},{capabilities:{tools:{}}});if(r){for(let i of M)j(n,r,i,t.scope??{});q(n,r)}if(t.cli)P(n,t.cli);if(t.allowDestructive)O(n,r,t.cli??null);return n}function w(t,r){if(!t)throw Error(`Refusing without confirm:true. ${r}`)}async function d(t){try{return k(await t())}catch(r){return A(r)}}function A(t){return{content:[{type:"text",text:t instanceof Error?t.message:String(t)}],isError:!0}}function k(t){return{content:[{type:"text",text:JSON.stringify(t??null,null,2)}]}}function b(t,r,n,i){if(!t.scoped)return;let c=n??r.project,p=i??r.stage;if(!c||!p)throw Error(`${t.plural} live in one stage, so this call needs both 'project' and 'stage'`);return{project:c,stage:p}}function P(t,r){t.registerTool("list-orgs",{description:"Every organization this login can reach, with the current one marked.",inputSchema:{}},async()=>await d(async()=>{let n=await r.getOnboarding();return{currentOrgId:n.currentOrgId,orgs:n.orgs}})),t.registerTool("create-org",{description:"Create an organization and switch this login to it. Later calls act in the new org.",inputSchema:{name:e().min(1)}},async({name:n})=>await d(async()=>await r.createOnboardingOrg(n))),t.registerTool("select-org",{description:"Switch this login to another organization, by an orgId from list-orgs.",inputSchema:{orgId:e().min(1)}},async({orgId:n})=>await d(async()=>await r.selectOnboardingOrg(n))),t.registerTool("list-projects",{description:"Every project in the current org, empty ones last. Project names are not unique, so take the id from here.",inputSchema:{}},async()=>await d(async()=>await r.listProjects())),t.registerTool("list-stages",{description:"Every stage of one project, by project name.",inputSchema:{project:e().min(1)}},async({project:n})=>await d(async()=>await r.listStages(n))),t.registerTool("create-stage",{description:"Create a stage in a project, optionally cloning another stage's architecture and env vars. A project name that does not exist yet is created with it, which is the only way to make a project without deploying a manifest.",inputSchema:{project:e().min(1),name:e().min(1),from:e().optional().describe("Stage to clone architecture and env vars from.")}},async({project:n,name:i,from:c})=>await d(async()=>await r.createStage(n,i,c)))}function O(t,r,n){if(r)t.registerTool("rotate-secret",{description:"Rotate the account secret. The current secret stops working immediately and the new one is shown once, so this breaks every deployment and CI job still holding the old one. Requires confirm:true.",inputSchema:{confirm:v}},async({confirm:i})=>await d(async()=>(w(i,"Everything holding the current secret breaks the moment this runs."),await r.rotateSecret())));if(n)t.registerTool("delete-project",{description:"Delete a project and everything under it: stages, agents, canvas, env vars, crons and workspace files. Takes a projectId from list-projects and requires confirm:true.",inputSchema:{projectId:e().min(1),confirm:v}},async({projectId:i,confirm:c})=>await d(async()=>(w(c,`Project '${i}' and everything under it goes away: name it, get the owner's agreement, then retry.`),await n.deleteProject(i))))}function q(t,r){t.registerTool("list-cron-runs",{description:"Run history for one cron, newest first. Check this before telling anyone a cron fired.",inputSchema:{cronId:e().min(1),limit:o().int().positive().max(100).optional()}},async({cronId:i,limit:c})=>await d(async()=>await r.listCronRuns(i,c===void 0?{}:{limit:c})));let n=[["suspend-sandbox","Suspend a persistent sandbox reservation.",(i,c)=>r.suspendSandbox(i,c)],["resume-sandbox","Resume a suspended sandbox reservation.",(i,c)=>r.resumeSandbox(i,c)],["terminate-sandbox","Terminate a sandbox reservation and drop its live-instance row. Terminate only a sandbox you created, and never one holding state you did not put there.",(i,c)=>r.terminateSandbox(i,c)],["open-sandbox-terminal","Mint a short-lived sealed ticket for an interactive PTY session on a persistent sandbox.",(i,c)=>r.openSandboxTerminal(i,c)]];for(let[i,c,p]of n)t.registerTool(i,{description:c,inputSchema:C},async({sandboxId:f,reservationKey:g})=>await d(async()=>await p(f,g)));t.registerTool("snapshot-sandbox",{description:"Snapshot a sandbox reservation into a reusable image (self-hosted provider).",inputSchema:{sandboxId:e().min(1),reservationKey:e().min(1),name:e().min(1)}},async({sandboxId:i,reservationKey:c,name:p})=>await d(async()=>await r.snapshotSandbox(i,c,p))),t.registerTool("upload-skill",{description:"Replace one skill's bundle wholesale (PUT, not a merge) by skillName. 'body' is the same source shape create-skill takes.",inputSchema:{id:e().min(1).describe("The skillName."),body:s(e(),l())}},async({id:i,body:c})=>await d(async()=>await r.uploadSkill(i,c))),t.registerTool("list-env-vars",{description:"List environment variable names. Values are write-only: the plane never returns them, so there is no read.",inputSchema:{}},async()=>await d(async()=>await r.listEnvVars())),t.registerTool("set-env-var",{description:"Create or replace one write-only environment variable. Reference it from a config as ${NAME} rather than inlining the value.",inputSchema:{name:e().min(1),value:e()}},async({name:i,value:c})=>await d(async()=>(await r.setEnvVar(i,c),{name:i,stored:!0}))),t.registerTool("delete-env-var",{description:"Delete one environment variable.",inputSchema:{name:e().min(1),confirm:v}},async({name:i,confirm:c})=>await d(async()=>(w(c,`Anything referencing \${${i}} breaks the moment this env var goes.`),{deleted:await r.deleteEnvVar(i),name:i}))),t.registerTool("assume-role",{description:"Exchange a role for a short-lived session token (default 1h, max 12h). Hand the returned token to whatever tool needs narrow access, as BROODS_SESSION_TOKEN. It is shown once and is not stored here.",inputSchema:{roleId:e().min(1),ttlSeconds:o().int().positive().max(43200).optional()}},async({roleId:i,ttlSeconds:c})=>await d(async()=>await r.assumeRole(i,c===void 0?{}:{ttlSeconds:c}))),t.registerTool("update-account",{description:"Rename this account or change its description. Everything else about an account is derived, not settable.",inputSchema:{username:e().optional(),description:e().nullable().optional()}},async({username:i,description:c})=>await d(async()=>await r.updateAccount({...i===void 0?{}:{username:i},...c===void 0?{}:{description:c}}))),t.registerTool("get-account",{description:"The account this server's credential resolves to. Run it first to confirm which tenant you are about to change.",inputSchema:{}},async()=>await d(async()=>await r.getAccount()))}function j(t,r,n,i){let c=e().min(1).describe(`The ${n.key}.`),p=n.scoped?` ${n.plural} live in one stage, so this also takes 'project' and 'stage'.`:"",{list:f,get:g,create:y,update:S,remove:_}=n;if(f){let u=`List every ${n.singular} on the account.${p}`;if(n.scoped)t.registerTool(`list-${n.plural}`,{description:u,inputSchema:R},async({project:h,stage:m})=>await d(async()=>await f(r,b(n,i,h,m))));else t.registerTool(`list-${n.plural}`,{description:u,inputSchema:{}},async()=>await d(async()=>await f(r)))}if(g)t.registerTool(`get-${n.singular}`,{description:`Read one ${n.singular} by ${n.key}.`,inputSchema:{id:c}},async({id:u})=>await d(async()=>await g(r,u)));if(y){let u=`Create one ${n.singular}. 'body' is the request body the config plane documents.`+(n.createHint?` ${n.createHint}`:"")+p+" Prefer changing the broods/ manifest and deploying for anything the project already declares.",h=s(e(),l());if(n.scoped)t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h,...R}},async({body:m,project:T,stage:I})=>await d(async()=>await y(r,m,b(n,i,T,I))));else t.registerTool(`create-${n.singular}`,{description:u,inputSchema:{body:h}},async({body:m})=>await d(async()=>await y(r,m)))}if(S)t.registerTool(`update-${n.singular}`,{description:`Deep-merge a patch into one ${n.singular} and return the updated record, so there is no need to read it back.`+(n.updateHint?` ${n.updateHint}`:""),inputSchema:{id:c,body:s(e(),l())}},async({id:u,body:h})=>await d(async()=>await S(r,u,h)));if(_)t.registerTool(`delete-${n.singular}`,{description:`Delete one ${n.singular}. Requires confirm:true, and takes one ${n.key} per call: never loop this over a list.`+(n.deleteHint?` ${n.deleteHint}`:""),inputSchema:{id:c,confirm:v}},async({id:u,confirm:h})=>await d(async()=>(w(h,`Deleting ${n.singular} '${u}' goes away for good: name it, get the owner's agreement, then retry.`),{deleted:await _(r,u),id:u})))}export{Pt as createBroodsMcpServer};
|