withruntime 0.33.2 → 0.34.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.
Files changed (43) hide show
  1. package/E2B.md +7 -0
  2. package/dist/agents-cli.d.ts +1 -1
  3. package/dist/agents-cli.js +171 -7
  4. package/dist/agents-deploy.d.ts +13 -3
  5. package/dist/agents-deploy.js +68 -9
  6. package/dist/apps-cli.d.ts +1 -1
  7. package/dist/apps-cli.js +41 -9
  8. package/dist/browsers/index.d.ts +9 -0
  9. package/dist/browsers/index.js +10 -0
  10. package/dist/browsers-cli.d.ts +13 -0
  11. package/dist/browsers-cli.js +160 -0
  12. package/dist/ci-cli.d.ts +1 -1
  13. package/dist/ci-cli.js +66 -13
  14. package/dist/cli.d.ts +4 -0
  15. package/dist/cli.js +94 -10
  16. package/dist/desktops/index.d.ts +9 -0
  17. package/dist/desktops/index.js +10 -0
  18. package/dist/e2b/code-interpreter.d.ts +3 -12
  19. package/dist/e2b/code-interpreter.js +3 -6
  20. package/dist/e2b/index.d.ts +7 -1
  21. package/dist/e2b/index.js +9 -2
  22. package/dist/index.d.ts +6 -4
  23. package/dist/products/agents.d.ts +162 -8
  24. package/dist/products/agents.js +108 -3
  25. package/dist/products/apps.d.ts +46 -5
  26. package/dist/products/browsers.d.ts +26 -0
  27. package/dist/products/browsers.js +11 -0
  28. package/dist/products/ci.d.ts +49 -7
  29. package/dist/products/ci.js +15 -1
  30. package/dist/products/desktops.d.ts +71 -0
  31. package/dist/products/desktops.js +27 -0
  32. package/dist/products/index.d.ts +4 -0
  33. package/dist/products/index.js +5 -0
  34. package/dist/products/network.d.ts +4 -2
  35. package/dist/products/secrets.d.ts +10 -2
  36. package/dist/products/secrets.js +27 -7
  37. package/dist/products/uptime.d.ts +97 -0
  38. package/dist/products/uptime.js +42 -0
  39. package/dist/products/volumes.d.ts +41 -9
  40. package/dist/products/volumes.js +5 -2
  41. package/dist/transport.d.ts +4 -1
  42. package/dist/transport.js +2 -2
  43. package/package.json +13 -2
package/dist/cli.js CHANGED
@@ -69,7 +69,9 @@ Account
69
69
  (job create --secret NAME); with --host, both
70
70
  secrets scope <NAME> --only-label k=v... | --only-sandbox <id>... | --only-app <id>... | --all-sandboxes
71
71
  Change which sandboxes get it; no value needed
72
- secrets ls | get <NAME> Names, hosts, placeholders and jobs versions, never values
72
+ secrets ls [--limit N] [--after NAME] | get <NAME>
73
+ Names, hosts, placeholders and jobs versions, never values;
74
+ by name, a page of N after NAME
73
75
  secrets rotate <NAME> A new version of the jobs copy, from standard input
74
76
  secrets reveal <NAME> [--version N] Print the jobs copy's value. The sandboxes' copy is
75
77
  never readable, by anyone
@@ -136,6 +138,8 @@ Products
136
138
  builds A connected repository's commits built into what an App deploys (beta)
137
139
  ci CI/CD: each push and pull request of a repository checked in sandboxes (beta)
138
140
  containers One OCI image's process on its own microVM, at the sandbox rates (beta)
141
+ browsers Chromium on its own sandbox: a CDP address and screenshots (beta)
142
+ desktops A Linux desktop on its own sandbox: live view, computer use (beta)
139
143
  agents Claude Code, Codex, Gemini CLI or your own agent in a sandbox per session (beta)
140
144
  domains Your own hostname for a sandbox's port, with HTTPS
141
145
  ports A public TCP port to a sandbox: databases, game servers
@@ -476,6 +480,8 @@ const COMMANDS = [
476
480
  "builds",
477
481
  "ci",
478
482
  "containers",
483
+ "browsers",
484
+ "desktops",
479
485
  "agents",
480
486
  "domains",
481
487
  "ports",
@@ -500,6 +506,8 @@ const OWN_HELP = [
500
506
  "builds",
501
507
  "ci",
502
508
  "containers",
509
+ "browsers",
510
+ "desktops",
503
511
  "agents",
504
512
  "keys",
505
513
  "reservations",
@@ -872,6 +880,8 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
872
880
  const rt = await client(env);
873
881
  const cursors = new Set();
874
882
  let cursor;
883
+ // The export is final only as far as its earliest page's finalThrough.
884
+ let finalThrough;
875
885
  for (;;) {
876
886
  const page = await rt.usageExport({
877
887
  since,
@@ -891,8 +901,19 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
891
901
  else if (page.csv)
892
902
  out.write(page.csv);
893
903
  await out.drain?.();
894
- if (page.nextCursor === null)
904
+ const at = page.finalThrough;
905
+ finalThrough =
906
+ finalThrough === undefined
907
+ ? at
908
+ : finalThrough === null || at === null
909
+ ? null
910
+ : at < finalThrough
911
+ ? at
912
+ : finalThrough;
913
+ if (page.nextCursor === null) {
914
+ out.error(finalLine({ until: page.until, finalThrough: finalThrough ?? null }));
895
915
  return 0;
916
+ }
896
917
  cursors.add(page.nextCursor);
897
918
  cursor = page.nextCursor;
898
919
  }
@@ -1351,6 +1372,10 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
1351
1372
  product = "containers";
1352
1373
  return (await import("./apps-cli.js")).containersCommand(rest, env, out, () => client(env), kit);
1353
1374
  }
1375
+ if (["browser", "browsers", "desktop", "desktops"].includes(command)) {
1376
+ product = command.endsWith("s") ? command : `${command}s`;
1377
+ return (await import("./browsers-cli.js")).machineProductCommand(product, rest, out, () => client(env), kit);
1378
+ }
1354
1379
  if (command === "agent" || command === "agents") {
1355
1380
  product = "agents";
1356
1381
  return (await import("./agents-cli.js")).agentsCommand(rest, env, out, () => client(env), kit);
@@ -1365,6 +1390,15 @@ export async function run(argv, env = process.env, out = defaultOut(argv)) {
1365
1390
  }
1366
1391
  throw unknown("command", command, COMMANDS);
1367
1392
  }
1393
+ /** `usage export`'s last word, on stderr beside the CSV: how much of the
1394
+ * range can still change. */
1395
+ export function finalLine(page) {
1396
+ if (page.finalThrough === null)
1397
+ return "Charges in this range may still settle; export it again later for a final copy.";
1398
+ if (Date.parse(page.finalThrough) >= Date.parse(page.until))
1399
+ return "Final: no more charges will settle in this range.";
1400
+ return `Final up to ${page.finalThrough}; charges after that may still settle. Export again later for the rest.`;
1401
+ }
1368
1402
  /** `runtime usage` for a person: the balance, the free usage and what each kind
1369
1403
  * of resource was charged, in dollars. --json keeps every figure, and each
1370
1404
  * resource with its rates and CPU time. */
@@ -2689,6 +2723,8 @@ read = readSecret) {
2689
2723
  "only-app",
2690
2724
  "agent",
2691
2725
  "env",
2726
+ "limit",
2727
+ "after",
2692
2728
  ]);
2693
2729
  const print = (human, value) => out.write(out.json ? JSON.stringify(value) : human);
2694
2730
  const rows = (list) => list.length
@@ -2706,11 +2742,19 @@ read = readSecret) {
2706
2742
  ])
2707
2743
  : "No secrets.";
2708
2744
  if (verb === "ls" || verb === "list" || verb === undefined) {
2745
+ const limit = integer(args, "limit");
2746
+ if (limit !== undefined && (limit < 1 || limit > 100))
2747
+ throw usage("--limit takes 1 to 100 secrets a page.");
2748
+ const after = flag(args, "after");
2709
2749
  const runtime = await client(env);
2710
- const all = await runtime.secrets.all();
2750
+ // A page of both copies by name, as the API pages each: an organization
2751
+ // keeps at most 50 secrets for sandboxes, so both are read whole.
2752
+ const every = (await runtime.secrets.all()).filter((s) => after === undefined || s.name > after);
2753
+ const all = limit === undefined ? every : every.slice(0, limit);
2754
+ const more = all.length < every.length ? all.at(-1).name : undefined;
2711
2755
  // --json keeps the sandboxes' list it always printed; the jobs copies
2712
2756
  // are in `runtime secrets get <NAME> --json`.
2713
- print(rows(all), all.flatMap((s) => (s.sandboxes ? [s.sandboxes] : [])));
2757
+ print(more ? `${rows(all)}\nMore: ${me} secrets ls --limit ${limit} --after ${more}` : rows(all), all.flatMap((s) => (s.sandboxes ? [s.sandboxes] : [])));
2714
2758
  return 0;
2715
2759
  }
2716
2760
  const jobsOnly = "Only a secret's copy for jobs has versions and can be read back";
@@ -4377,10 +4421,39 @@ const VOLUME_HELP = `runtime volumes <command>
4377
4421
  backup-rm <backupId> Delete a backup
4378
4422
  backup-policy <id> [--daily on|off] [--retention-days N]
4379
4423
  Daily backups on or off, and how long each is kept
4424
+ backup-policy <id> --every <minutes> | --cron "<m h dom mon dow>" [--keep hourly=24,daily=7,...]
4425
+ Back up on a schedule of its own (UTC), keeping
4426
+ last, hourly, daily, weekly, monthly, yearly counts
4427
+ backup-policy <id> --no-schedule Back to daily backups
4380
4428
  Attach one: runtime sandboxes create --volume <id>:/data
4381
- Volumes are backed up off their host daily unless you turn it off.
4429
+ Volumes are backed up off their host daily, or on their own schedule, unless you turn it off.
4382
4430
  Shared commands work where shared disks are enabled.
4383
4431
  `;
4432
+ const KEEP_TIERS = ["last", "hourly", "daily", "weekly", "monthly", "yearly"];
4433
+ /** `hourly=24,daily=7` as keep counts; the server checks the numbers. */
4434
+ function keepCounts(text) {
4435
+ const counts = {};
4436
+ for (const part of text.split(",")) {
4437
+ const [name, value, extra] = part.trim().split("=");
4438
+ const tier = KEEP_TIERS.find((t) => t === name);
4439
+ if (!tier || value === undefined || extra !== undefined || !/^\d+$/.test(value))
4440
+ throw usage(`--keep takes name=count pairs such as hourly=24,daily=7; names: ${KEEP_TIERS.join(", ")}.`);
4441
+ counts[tier] = Number(value);
4442
+ }
4443
+ return counts;
4444
+ }
4445
+ /** "daily backups on, kept 7 days", or the schedule, its keep counts and next run. */
4446
+ function backupPolicyWords(b) {
4447
+ if (!b.schedule)
4448
+ return `daily backups ${b.daily ? "on" : "off"}, kept ${b.retentionDays} days`;
4449
+ const when = "everyMinutes" in b.schedule
4450
+ ? `every ${b.schedule.everyMinutes} minutes`
4451
+ : `on cron "${b.schedule.cron.trim()}" (UTC)`;
4452
+ const kept = KEEP_TIERS.filter((t) => (b.keep?.[t] ?? 0) > 0)
4453
+ .map((t) => `${t} ${b.keep[t]}`)
4454
+ .join(", ");
4455
+ return `backups ${when}${b.daily ? "" : " (off)"}, keeping ${kept}${b.daily && b.nextAt ? `; next ${b.nextAt}` : ""}`;
4456
+ }
4384
4457
  async function volume(argv, env, out) {
4385
4458
  const [verb, ...rest] = argv;
4386
4459
  const print = (human, value) => out.write(out.json ? JSON.stringify(value) : human);
@@ -4489,7 +4562,7 @@ async function volume(argv, env, out) {
4489
4562
  String(b.sizeMiB),
4490
4563
  b.storedBytes === null ? "-" : `${Math.ceil(b.storedBytes / 1048576)} MiB`,
4491
4564
  b.createdAt,
4492
- b.expiresAt,
4565
+ b.expiresAt ?? "by keep counts",
4493
4566
  ]),
4494
4567
  ])
4495
4568
  : "No backups yet.", all);
@@ -4510,19 +4583,30 @@ async function volume(argv, env, out) {
4510
4583
  return 0;
4511
4584
  }
4512
4585
  case "backup-policy": {
4513
- const args = parse(rest, [], ["daily", "retention-days"]);
4586
+ const args = parse(rest, ["no-schedule"], ["daily", "retention-days", "every", "cron", "keep"]);
4514
4587
  const id = need(args.positional[0], "a volume id");
4515
4588
  const daily = flag(args, "daily");
4516
4589
  if (daily !== undefined && !["on", "off", "true", "false"].includes(daily))
4517
4590
  throw usage("--daily takes on or off.");
4518
4591
  const days = integer(args, "retention-days");
4519
- if (daily === undefined && days === undefined)
4520
- throw usage("Give --daily on|off, --retention-days N or both.");
4592
+ const every = integer(args, "every");
4593
+ const cron = flag(args, "cron");
4594
+ const off = has(args, "no-schedule");
4595
+ if ([every !== undefined, cron !== undefined, off].filter(Boolean).length > 1)
4596
+ throw usage("Give one of --every, --cron and --no-schedule.");
4597
+ const keepText = flag(args, "keep");
4598
+ const keep = keepText === undefined ? undefined : keepCounts(keepText);
4599
+ if ([daily, days, every, cron, keep].every((x) => x === undefined) && !off)
4600
+ throw usage("Give --daily on|off, --retention-days N, --every, --cron, --keep or --no-schedule.");
4521
4601
  const updated = await api.setBackupPolicy(id, {
4522
4602
  ...(daily === undefined ? {} : { daily: daily === "on" || daily === "true" }),
4523
4603
  ...(days === undefined ? {} : { retentionDays: days }),
4604
+ ...(every === undefined ? {} : { schedule: { everyMinutes: every } }),
4605
+ ...(cron === undefined ? {} : { schedule: { cron } }),
4606
+ ...(off ? { schedule: null } : {}),
4607
+ ...(keep === undefined ? {} : { keep }),
4524
4608
  });
4525
- print(`${updated.id} daily backups ${updated.backups.daily ? "on" : "off"}, kept ${updated.backups.retentionDays} days`, updated);
4609
+ print(`${updated.id} ${backupPolicyWords(updated.backups)}`, updated);
4526
4610
  return 0;
4527
4611
  }
4528
4612
  }
@@ -0,0 +1,9 @@
1
+ /** `withruntime/desktops`: Desktops alone. A Linux desktop on its own sandbox, with a live view and computer use, at the sandbox rates. In a private beta.
2
+ *
3
+ * import { desktops } from "withruntime/desktops";
4
+ * const client = desktops(); // RUNTIME_API_KEY, or this machine's saved connection
5
+ */
6
+ import { Runtime, type RuntimeOptions } from "../client.js";
7
+ export type * from "../products/desktops.js";
8
+ /** `runtime.desktops` of a client made with `options`. */
9
+ export declare function desktops(options?: RuntimeOptions): Runtime["desktops"];
@@ -0,0 +1,10 @@
1
+ /** `withruntime/desktops`: Desktops alone. A Linux desktop on its own sandbox, with a live view and computer use, at the sandbox rates. In a private beta.
2
+ *
3
+ * import { desktops } from "withruntime/desktops";
4
+ * const client = desktops(); // RUNTIME_API_KEY, or this machine's saved connection
5
+ */
6
+ import { Runtime } from "../client.js";
7
+ /** `runtime.desktops` of a client made with `options`. */
8
+ export function desktops(options) {
9
+ return new Runtime(options).desktops;
10
+ }
@@ -1,11 +1,4 @@
1
- /** `@e2b/code-interpreter`, on Runtime. Change the import:
2
- *
3
- * import { Sandbox } from "withruntime/e2b/code-interpreter";
4
- *
5
- * runCode runs in Runtime's interpreter (sandbox.runtime.interpreter):
6
- * stateful contexts in every E2B interpreter language. */
7
- import type { Runtime } from "../client.js";
8
- import type { ConnectionOpts } from "./client.js";
1
+ import { E2B as BaseE2B } from "./index.js";
9
2
  import { Sandbox as BaseSandbox } from "./sandbox.js";
10
3
  export * from "./index.js";
11
4
  export type RunCodeLanguage = "python" | "javascript" | "typescript" | "r" | "java" | "bash" | (string & {});
@@ -135,9 +128,7 @@ export declare class Sandbox extends BaseSandbox {
135
128
  }
136
129
  export default Sandbox;
137
130
  /** E2B's client with bound options, for the code interpreter. */
138
- export declare class E2B {
131
+ export declare class E2B extends BaseE2B {
132
+ protected static readonly sandboxClass: typeof BaseSandbox;
139
133
  readonly Sandbox: typeof Sandbox;
140
- constructor(opts?: Omit<ConnectionOpts, "signal"> & {
141
- client?: Runtime;
142
- });
143
134
  }
@@ -1,5 +1,5 @@
1
1
  import { guard, NotSupportedError, SandboxError, TimeoutError } from "./errors.js";
2
- import { bind } from "./index.js";
2
+ import { E2B as BaseE2B } from "./index.js";
3
3
  import { Sandbox as BaseSandbox } from "./sandbox.js";
4
4
  export * from "./index.js";
5
5
  /** A line of output, as E2B's callbacks receive it. */
@@ -234,9 +234,6 @@ export class Sandbox extends BaseSandbox {
234
234
  }
235
235
  export default Sandbox;
236
236
  /** E2B's client with bound options, for the code interpreter. */
237
- export class E2B {
238
- Sandbox;
239
- constructor(opts = {}) {
240
- this.Sandbox = bind(Sandbox, opts);
241
- }
237
+ export class E2B extends BaseE2B {
238
+ static sandboxClass = Sandbox;
242
239
  }
@@ -15,9 +15,15 @@ export type { ConnectionOpts, HttpVersion, RuntimeOpts } from "./client.js";
15
15
  export { Pty, type PtyCreateOpts, type PtyConnectOpts } from "./pty.js";
16
16
  export { Template, TemplateBase, Volume, Secret, waitForPort, waitForURL, waitForProcess, waitForFile, waitForTimeout, SecretPaginator, Git, ReadyCmd, LogEntry, LogEntryStart, LogEntryEnd, defaultBuildLogger, ConnectionConfig, ApiClient, getSignature, ALL_TRAFFIC, VolumeFileType, } from "./unsupported.js";
17
17
  export default Sandbox;
18
- /** E2B's client with bound options: `new E2B({ apiKey }).Sandbox.create()`. */
18
+ /** E2B's client with bound options: `new E2B({ apiKey }).Sandbox.create()`.
19
+ * Its Secret, Template and Volume refuse, naming Runtime's alternative, as
20
+ * the top-level exports do. */
19
21
  export declare class E2B {
22
+ protected static readonly sandboxClass: typeof Sandbox;
20
23
  readonly Sandbox: typeof Sandbox;
24
+ readonly Secret: import("./unsupported.js").Unsupported;
25
+ readonly Template: import("./unsupported.js").Unsupported;
26
+ readonly Volume: import("./unsupported.js").Unsupported;
21
27
  constructor(opts?: Omit<ConnectionOpts, "signal"> & {
22
28
  client?: Runtime;
23
29
  });
package/dist/e2b/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { clientFor } from "./client.js";
2
2
  import { Sandbox } from "./sandbox.js";
3
+ import { Secret, Template, Volume } from "./unsupported.js";
3
4
  export { Sandbox, SandboxPaginator, DEFAULT_SHAPE, DEFAULT_TIMEOUT_MS, } from "./sandbox.js";
4
5
  export { Commands, CommandHandle, pidOf, } from "./commands.js";
5
6
  export { Filesystem, FileType, FilesystemEventType, } from "./filesystem.js";
@@ -7,11 +8,17 @@ export { SandboxError, TimeoutError, InvalidArgumentError, NotEnoughSpaceError,
7
8
  export { Pty } from "./pty.js";
8
9
  export { Template, TemplateBase, Volume, Secret, waitForPort, waitForURL, waitForProcess, waitForFile, waitForTimeout, SecretPaginator, Git, ReadyCmd, LogEntry, LogEntryStart, LogEntryEnd, defaultBuildLogger, ConnectionConfig, ApiClient, getSignature, ALL_TRAFFIC, VolumeFileType, } from "./unsupported.js";
9
10
  export default Sandbox;
10
- /** E2B's client with bound options: `new E2B({ apiKey }).Sandbox.create()`. */
11
+ /** E2B's client with bound options: `new E2B({ apiKey }).Sandbox.create()`.
12
+ * Its Secret, Template and Volume refuse, naming Runtime's alternative, as
13
+ * the top-level exports do. */
11
14
  export class E2B {
15
+ static sandboxClass = Sandbox;
12
16
  Sandbox;
17
+ Secret = Secret;
18
+ Template = Template;
19
+ Volume = Volume;
13
20
  constructor(opts = {}) {
14
- this.Sandbox = bind(Sandbox, opts);
21
+ this.Sandbox = bind(new.target.sandboxClass, opts);
15
22
  }
16
23
  }
17
24
  /** A subclass whose static calls use `opts`'s key or client unless a call
package/dist/index.d.ts CHANGED
@@ -18,13 +18,13 @@ export type { BookRoom, RoomBooking, RoomBookingPage } from "./products/reservat
18
18
  export type { AuditEvent, AuditPage } from "./products/audit.js";
19
19
  export type { Plan, PlanAddOn, PlanChange, PlanIncluded, PlanLimit, PlanNow, Plans, } from "./products/plans.js";
20
20
  export type { UsageExportQuery, UsageExportRow, UsageExportPage, } from "./products/observability.js";
21
- export type { JobSecret, Secret, SecretApiPolicy, SecretGit, SecretGithubApp, SecretRule, SecretScope, SecretUse, SetSecret, } from "./products/secrets.js";
21
+ export type { JobSecret, Secret, SecretApiPolicy, SecretGit, SecretGithubApp, SecretRule, SecretScope, SecretUse, ListSecrets, SetSecret, } from "./products/secrets.js";
22
22
  export { SecretPartlyStoredError } from "./products/secrets.js";
23
23
  export type { McpCatalogEntry, McpGateway, McpServerRequest } from "./products/mcp.js";
24
24
  export type { FileEvent, FileEventType, WatchHandle, WatchNotice, WatchOptions, } from "./products/watch.js";
25
25
  export type { Mount, MountBucket } from "./products/mounts.js";
26
26
  export type { TailscaleJoin, TailscaleJoined, TailscaleNode, TailscaleStatus, } from "./products/tailscale.js";
27
- export type { Volume, VolumeBackup, CreateVolume, VolumeAttachment } from "./products/volumes.js";
27
+ export type { Volume, VolumeBackup, VolumeBackupKeep, VolumeBackupSchedule, CreateVolume, VolumeAttachment, } from "./products/volumes.js";
28
28
  export type { CreateJob, Job, JobAlert, JobAlertDelivery, JobCompute, JobDefinition, JobLogs, JobRun, JobRunState, JobSchedule, UpdateJob, } from "./products/jobs.js";
29
29
  export type { CheckedDomain, DnsRecord, Domain, EgressAddress, TcpPort, Tunnel as PrivateTunnel, TunnelPeer, TunnelPeerCreated, SetUpstreamProxy, UpstreamProxy, } from "./products/network-products.js";
30
30
  export type { PrivateNetwork } from "./products/private-network.js";
@@ -78,8 +78,10 @@ export { openWalletAccount, claimWalletAccount, rekeyWalletAccount, type OpenedW
78
78
  export type { Topup } from "./products/billing.js";
79
79
  export type { NewKey, LimitedKey, LimitedKeyAction, MadeKey, ListedKey, KeyUsage, } from "./products/api-keys.js";
80
80
  export type { SsoConnection, SsoStatus } from "./products/sso.js";
81
- export type { Agent, AgentDefinition, AgentEvent, AgentMemoryEntry, AgentMemoryFile, AgentMemoryHit, AgentMemoryPage, AgentMemoryUsage, AgentMemoryWritten, AgentSession, AgentSessionHandle, AgentSessionState, AgentTemplate, AgentTemplateKey, AgentTrigger, AgentTriggerKind, AgentUse, CreateAgent, CreateAgentTrigger, StartAgentSession, } from "./products/agents.js";
81
+ export type { Agent, AgentAsk, AgentAskState, AgentDefinition, AgentEvent, AgentHeldCall, AgentMemoryEntry, AgentMemoryFile, AgentMemoryHit, AgentMemoryPage, AgentMemoryUsage, AgentMemoryWritten, AgentSession, AgentSessionHandle, AgentSessionState, AgentTemplate, AgentTemplateKey, AgentTrigger, AgentTriggerCall, AgentTriggerCallOutcome, AgentTriggerKind, AgentTriggerRules, AgentUse, AnswerAgentAsk, CreateAgent, CreateAgentTrigger, ListAgentAsks, StartAgentSession, } from "./products/agents.js";
82
82
  export { AGENT_TEMPLATES, AGENT_USES } from "./products/agents.js";
83
83
  export type { AgentsDeployChange, AgentsDeployOptions, AgentsDeployResult, AgentsFile, AgentsFileAgent, AgentsFileTrigger, AgentsSource, } from "./agents-deploy.js";
84
84
  export type { Container, ContainerState, CreateContainer, UpdateContainer, } from "./products/containers.js";
85
- export type { CiFlake, CiFlakeDetail, CiRepository, CiTestResult, ConnectCiRepository, ListCiFlakes, ListCiRepositories, UpdateCiFlake, } from "./products/ci.js";
85
+ export type { Browser, BrowserConnectOptions, BrowserInfo, BrowserScreenshot, BrowserScreenshotResult, CreateBrowser, UpdateBrowser, } from "./products/browsers.js";
86
+ export type { CreateDesktop, Desktop, DesktopAct, DesktopState, UpdateDesktop, } from "./products/desktops.js";
87
+ export type { CiFlake, CiFlakeDetail, CiReleaseStep, CiRepository, CiTestResult, ConnectCiRepository, ListCiFlakes, ListCiReleaseSteps, ListCiRepositories, UpdateCiFlake, } from "./products/ci.js";
@@ -51,6 +51,11 @@ export type AgentDefinition = {
51
51
  * GEMINI_API_KEY, OPENROUTER_API_KEY, or an OpenAI-compatible endpoint's
52
52
  * key with env.OPENAI_BASE_URL). */
53
53
  secrets?: string[];
54
+ /** Claude accounts, 1 to 16 egress secrets' names: subscription tokens,
55
+ * or API keys for a name holding API_KEY. Each session takes the one with
56
+ * the most usage left; the review template moves to the next when one is
57
+ * out of usage, and waits for the soonest reset when all are. */
58
+ pool?: string[];
54
59
  /** MCP servers the harness may reach. */
55
60
  mcp?: {
56
61
  name: string;
@@ -130,12 +135,90 @@ export type AgentEvent = {
130
135
  } & Record<string, unknown>;
131
136
  createdAt: string;
132
137
  };
138
+ export type AgentAskState = "open" | "answered" | "expired" | "withdrawn" | "closed";
139
+ /** One row of the account's inbox: a question a session's harness needs
140
+ * answered to go on. Asks of one agent's sessions sharing a memory, with the same `step` are
141
+ * one row while it is open, and one answer reaches every session asking. */
142
+ export type AgentAsk = {
143
+ id: string;
144
+ /** The agent of the session that asked first. */
145
+ agentId: string;
146
+ /** What it waits on, in the asker's words. */
147
+ step: string | null;
148
+ question: string;
149
+ /** Why it matters. */
150
+ why: string | null;
151
+ options: {
152
+ label: string;
153
+ detail?: string;
154
+ }[];
155
+ /** The recommended option's label; taken as the answer when it expires. */
156
+ pick: string | null;
157
+ /** Who sees it: its agent's labels with the ask's own over them. */
158
+ labels: Record<string, string>;
159
+ state: AgentAskState;
160
+ /** An option's label and/or words; `expired` when the pick was taken at
161
+ * expiry. */
162
+ answer: {
163
+ option?: string;
164
+ text?: string;
165
+ expired?: boolean;
166
+ } | null;
167
+ /** A key's principal id, or `runtime` for a pick taken at expiry. */
168
+ answeredBy: string | null;
169
+ /** The sessions asking it, each with its ask event's seq and the answer
170
+ * event that woke it. */
171
+ sessions: {
172
+ sessionId: string;
173
+ state: "asking" | "answered" | "expired" | "withdrawn" | "ended";
174
+ seq: number;
175
+ answerSeq: number | null;
176
+ }[];
177
+ expiresAt: string | null;
178
+ createdAt: string;
179
+ updatedAt: string;
180
+ closedAt: string | null;
181
+ };
182
+ export type ListAgentAsks = {
183
+ /** Open by default. */
184
+ state?: AgentAskState[];
185
+ agent?: string;
186
+ /** Asks carrying every one of these labels: who sees an ask. */
187
+ labels?: Record<string, string>;
188
+ cursor?: string;
189
+ limit?: number;
190
+ };
191
+ /** An option's label, words, or both. */
192
+ export type AnswerAgentAsk = {
193
+ option?: string;
194
+ text?: string;
195
+ };
133
196
  export type AgentTriggerKind = "slack" | "github" | "schedule" | "webhook";
197
+ /** A trigger's rules, each optional. */
198
+ export type AgentTriggerRules = {
199
+ /** Queue order of its sessions when the agent's maxConcurrent is full:
200
+ * -100 to 100, higher first, then oldest. Default 0. */
201
+ priority?: number;
202
+ /** Sessions it may start in an hour; a call past it is held for you.
203
+ * Joining an open session is never capped. Default none. */
204
+ maxStartsPerHour?: number;
205
+ /** A call whose key's last session has ended: "start" a new one (the
206
+ * default), "note" it in the ended session's log and run nothing, or
207
+ * "ask" you (the call is held until you start it). */
208
+ onEnded?: "start" | "note" | "ask";
209
+ /** Where a held call is told: "email" to who added the trigger (the
210
+ * default), or "webhook", the account's webhooks' agent.call.held alone. */
211
+ notify?: "email" | "webhook";
212
+ /** A webhook's only: the key of a call that sends none, from its JSON's
213
+ * fields: "{cause}", "{alert.host}:{check}". */
214
+ key?: string;
215
+ };
134
216
  export type AgentTrigger = {
135
217
  id: string;
136
218
  agentId: string;
137
219
  kind: AgentTriggerKind;
138
220
  config: Record<string, unknown>;
221
+ rules: AgentTriggerRules;
139
222
  pausedAt: string | null;
140
223
  pausedWhy: string | null;
141
224
  createdAt: string;
@@ -157,7 +240,7 @@ export type StartAgentSession = {
157
240
  key?: string;
158
241
  labels?: Record<string, string>;
159
242
  };
160
- export type CreateAgentTrigger = {
243
+ export type CreateAgentTrigger = ({
161
244
  kind: "slack";
162
245
  config: {
163
246
  team: string;
@@ -180,9 +263,48 @@ export type CreateAgentTrigger = {
180
263
  } | {
181
264
  kind: "webhook";
182
265
  config: Record<string, never>;
266
+ }) & {
267
+ rules?: AgentTriggerRules;
268
+ };
269
+ /** One call to a webhook trigger: its words, and the key and labels of the
270
+ * session it starts or joins. */
271
+ export type AgentTriggerCall = {
272
+ text: string;
273
+ key?: string;
274
+ labels?: Record<string, string>;
275
+ };
276
+ /** What a call did: started a session, joined its key's open one, was
277
+ * noted in its key's ended one, or was held for you (`why`). */
278
+ export type AgentTriggerCallOutcome = {
279
+ outcome: "started" | "joined" | "noted" | "held";
280
+ sessionId: string | null;
281
+ seq: number | null;
282
+ callId: string | null;
283
+ why: AgentHeldCall["why"] | null;
284
+ replayed: boolean;
285
+ };
286
+ /** A call a trigger held for you because no session could take it. None is
287
+ * ever dropped. */
288
+ export type AgentHeldCall = {
289
+ id: string;
290
+ triggerId: string;
291
+ agentId: string;
292
+ key: string | null;
293
+ text: string;
294
+ labels: Record<string, string>;
295
+ /** The trigger was paused; it had started maxStartsPerHour sessions this
296
+ * hour; its key's session had ended and onEnded is "ask"; the agent's day
297
+ * budget was spent; the account's sessions were at their limit; Agents
298
+ * was closed to the account. */
299
+ why: "paused" | "rate" | "ended" | "budget" | "quota" | "closed";
300
+ state: "held" | "started" | "dismissed";
301
+ sessionId: string | null;
302
+ notify: "email" | "webhook";
303
+ createdAt: string;
304
+ resolvedAt: string | null;
183
305
  };
184
- /** The five harnesses' names, so `templates["claude-code"]` is known to be there. */
185
- export type AgentTemplateKey = "claude-code" | "codex" | "gemini-cli" | "claude-agent-sdk" | "openai-agents-sdk";
306
+ /** The harnesses' names, so `templates["claude-code"]` is known to be there. */
307
+ export type AgentTemplateKey = "claude-code" | "codex" | "gemini-cli" | "claude-agent-sdk" | "openai-agents-sdk" | "review" | "judge";
186
308
  /** A file of an agent's memory (`memory.list`). `scope` is whose: empty for
187
309
  * the shared memory, which every session reads (one keeping memory per key
188
310
  * reads what you wrote there, and never changes it), or a session key
@@ -240,9 +362,8 @@ export type AgentTemplate = {
240
362
  /** How your own subscription logs it in, for your own team's agents, or
241
363
  * null when it takes an API key alone. */
242
364
  subscription: string | null;
243
- definition: {
365
+ definition: Pick<AgentDefinition, "secrets" | "pool" | "vcpu" | "memoryMiB" | "maxSessionSeconds"> & {
244
366
  command: string;
245
- secrets: string[];
246
367
  };
247
368
  };
248
369
  /** A use: what an agent is for, merged into a template's definition. */
@@ -257,7 +378,7 @@ export type AgentUse = {
257
378
  template: "support" | "team";
258
379
  };
259
380
  };
260
- /** The five harnesses (agents-contract.md); tests/agents.test.ts holds them
381
+ /** The harnesses (agents-contract.md); tests/agents.test.ts holds them
261
382
  * to packages/cloud-guide/agent-templates.json. */
262
383
  export declare const AGENT_TEMPLATES: Readonly<Record<AgentTemplateKey, AgentTemplate>>;
263
384
  /** A harness by a key read from a file or a flag, or undefined. */
@@ -321,13 +442,45 @@ export declare function agents(t: Transport): {
321
442
  * (`session_open`): stop it first. */
322
443
  delete: (id: string, options?: RequestOptions) => Promise<void>;
323
444
  };
445
+ /** The account's inbox: the questions its agents' sessions need answered
446
+ * to go on, one row per step however many sessions ask it. */
447
+ asks: {
448
+ /** Newest first; open ones unless `state` says otherwise. */
449
+ list: (query?: ListAgentAsks, options?: RequestOptions) => Promise<Page<AgentAsk>>;
450
+ get: (id: string, options?: RequestOptions) => Promise<AgentAsk>;
451
+ /** Every session asking it reads the answer next, and wakes. An ask no
452
+ * longer open is refused with `ask_closed`. */
453
+ answer: (id: string, answer: AnswerAgentAsk, options?: RequestOptions) => Promise<AgentAsk>;
454
+ };
324
455
  triggers: {
325
456
  create: (agent: string, input: CreateAgentTrigger, options?: RequestOptions) => Promise<AgentTrigger>;
326
457
  list: (agent: string, options?: RequestOptions) => Promise<AgentTrigger[]>;
327
- /** Its events are refused, saying `why`; nothing else is held. */
458
+ /** Held: a webhook's calls are kept for you (see `held`), saying
459
+ * `why`; nothing else is held. */
328
460
  pause: (id: string, why: string, options?: RequestOptions) => Promise<AgentTrigger>;
329
461
  resume: (id: string, options?: RequestOptions) => Promise<AgentTrigger>;
330
462
  delete: (id: string, options?: RequestOptions) => Promise<void>;
463
+ /** Its rules, whole, in place: its secret stays. `{}` is every default. */
464
+ setRules: (id: string, rules: AgentTriggerRules, options?: RequestOptions) => Promise<AgentTrigger>;
465
+ /** A webhook trigger's call, as its sender makes it: by the trigger's
466
+ * secret, never your key. A call with the key of an open session joins
467
+ * it. Pass `idempotencyKey` to make a retry the same call. */
468
+ call: (id: string, secret: string, call: AgentTriggerCall, options?: RequestOptions) => Promise<AgentTriggerCallOutcome>;
469
+ /** Calls it held for you, newest first. */
470
+ held: (trigger: string, query?: {
471
+ state?: AgentHeldCall["state"][];
472
+ cursor?: string;
473
+ limit?: number;
474
+ }, options?: RequestOptions) => Promise<Page<AgentHeldCall>>;
475
+ /** Start a held call: one session with it and every call held for its
476
+ * key since, oldest first. */
477
+ startHeld: (id: string, call: string, options?: RequestOptions) => Promise<{
478
+ session: AgentSession;
479
+ joined: boolean;
480
+ calls: number;
481
+ }>;
482
+ /** Dismiss a held call: nothing runs. */
483
+ dismissHeld: (id: string, call: string, options?: RequestOptions) => Promise<AgentHeldCall>;
331
484
  };
332
485
  /** Its built-in memory: text files kept across sessions, which the
333
486
  * agent reads, writes and searches from inside its sessions. A scope is
@@ -363,7 +516,8 @@ export declare function agents(t: Transport): {
363
516
  }, options?: RequestOptions) => Promise<boolean>;
364
517
  };
365
518
  /** The harnesses, as data: claude-code, codex, gemini-cli,
366
- * claude-agent-sdk, openai-agents-sdk. */
519
+ * claude-agent-sdk, openai-agents-sdk, review (a CI/CD agent step's
520
+ * reviewer) and judge (an agent step held to your instructions alone). */
367
521
  templates: Readonly<Record<AgentTemplateKey, AgentTemplate>>;
368
522
  /** The uses, as data: support (your customers) and team (your team). */
369
523
  uses: Readonly<Record<"team" | "support", AgentUse>>;