@agent-compose/sdk 0.7.0 → 0.8.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 (116) hide show
  1. package/README.md +66 -39
  2. package/dist/agent/__tests__/runtime-json-schema.test.d.ts +10 -0
  3. package/dist/agent/agent-context.d.ts +21 -1
  4. package/dist/agent/agent-loop.d.ts +24 -1
  5. package/dist/client.d.ts +338 -534
  6. package/dist/directives.d.ts +112 -0
  7. package/dist/display.d.ts +242 -0
  8. package/dist/errors.d.ts +24 -1
  9. package/dist/index.d.ts +24 -12
  10. package/dist/index.js +3545 -1667
  11. package/dist/pause/wrappers.d.ts +31 -9
  12. package/dist/runtimes/_acp-client.d.ts +46 -1
  13. package/dist/runtimes/_cli-agent.d.ts +49 -4
  14. package/dist/runtimes/_jsonl-guard.d.ts +103 -0
  15. package/dist/runtimes/amp.d.ts +2 -2
  16. package/dist/runtimes/claude-code.d.ts +59 -0
  17. package/dist/runtimes/claude-code.test.d.ts +14 -0
  18. package/dist/runtimes/claude.d.ts +16 -0
  19. package/dist/runtimes/claude.test.d.ts +8 -0
  20. package/dist/runtimes/codex.d.ts +9 -3
  21. package/dist/runtimes/cursor.d.ts +2 -2
  22. package/dist/runtimes/droid.d.ts +2 -2
  23. package/dist/runtimes/jsonl-guard.test.d.ts +19 -0
  24. package/dist/runtimes/openai-desktop.js +2691 -864
  25. package/dist/runtimes/opencode.d.ts +2 -2
  26. package/dist/runtimes/vercel.js +12 -1
  27. package/dist/sandbox/devbox.d.ts +42 -0
  28. package/dist/sandbox/exec-stream.d.ts +14 -0
  29. package/dist/sandbox/network-policy.d.ts +100 -0
  30. package/dist/sandbox/provider-def.d.ts +79 -0
  31. package/dist/sandbox/providers/desktop.d.ts +10 -0
  32. package/dist/sandbox/providers/e2b.d.ts +17 -0
  33. package/dist/sandbox/providers/local.d.ts +11 -0
  34. package/dist/sandbox/providers/vercel.d.ts +18 -0
  35. package/dist/sandbox/registry.d.ts +45 -0
  36. package/dist/sandbox/sizes.d.ts +68 -0
  37. package/dist/sandbox.d.ts +24 -299
  38. package/dist/step-invocation/__tests__/foreground-recovery.test.d.ts +1 -0
  39. package/dist/step-invocation/invoker.d.ts +10 -0
  40. package/dist/step-invocation/protocol.d.ts +5 -0
  41. package/dist/types/api-compliance.d.ts +71 -0
  42. package/dist/types/api-conversations.d.ts +492 -0
  43. package/dist/types/api-factory.d.ts +309 -0
  44. package/dist/types/api-projects.d.ts +131 -0
  45. package/dist/types/api-runs.d.ts +377 -0
  46. package/dist/types/api-scopes.d.ts +102 -0
  47. package/dist/types/conversation-stream.d.ts +191 -0
  48. package/dist/types/execution-context.d.ts +12 -2
  49. package/dist/types/protocol.d.ts +30 -1
  50. package/dist/types/sandbox-environment.d.ts +8 -5
  51. package/dist/types/sandbox.d.ts +74 -4
  52. package/dist/types/workflow-metadata.d.ts +33 -8
  53. package/dist/types/workflow-plan.d.ts +10 -0
  54. package/dist/types/workflow.d.ts +18 -205
  55. package/dist/utils/bundler.d.ts +12 -1
  56. package/dist/workflow-steps/index.d.ts +1 -1
  57. package/dist/workflow-steps/observability.d.ts +8 -1
  58. package/dist/workflow-steps/runner.d.ts +3 -3
  59. package/dist/workflow-steps/step.d.ts +15 -1
  60. package/dist/workflow-steps/types.d.ts +19 -5
  61. package/dist/workflow-steps/workflow.d.ts +22 -1
  62. package/dist/workflows/engine.d.ts +3 -2
  63. package/dist/workflows/invoke-child.d.ts +2 -2
  64. package/package.json +1 -1
  65. package/src/agent/agent-context.ts +186 -3
  66. package/src/agent/agent-loop.ts +31 -2
  67. package/src/client.ts +909 -621
  68. package/src/directives.ts +184 -0
  69. package/src/display.ts +788 -0
  70. package/src/errors.ts +39 -0
  71. package/src/index.ts +104 -10
  72. package/src/pause/wrappers.ts +44 -9
  73. package/src/runtimes/_acp-client.ts +72 -3
  74. package/src/runtimes/_cli-agent.ts +159 -36
  75. package/src/runtimes/_jsonl-guard.ts +219 -0
  76. package/src/runtimes/claude-code.ts +246 -0
  77. package/src/runtimes/claude.ts +32 -2
  78. package/src/runtimes/codex.ts +55 -3
  79. package/src/runtimes/openai-desktop.ts +59 -14
  80. package/src/sandbox/devbox.ts +48 -0
  81. package/src/sandbox/exec-stream.ts +48 -0
  82. package/src/sandbox/network-policy.ts +181 -0
  83. package/src/sandbox/provider-def.ts +94 -0
  84. package/src/sandbox/providers/desktop.ts +57 -0
  85. package/src/sandbox/providers/e2b.ts +354 -0
  86. package/src/sandbox/providers/local.ts +106 -0
  87. package/src/sandbox/providers/vercel.ts +331 -0
  88. package/src/sandbox/registry.ts +198 -0
  89. package/src/sandbox/sizes.ts +95 -0
  90. package/src/sandbox.ts +59 -1275
  91. package/src/step-invocation/invoker.ts +151 -28
  92. package/src/step-invocation/protocol.ts +8 -0
  93. package/src/types/api-compliance.ts +79 -0
  94. package/src/types/api-conversations.ts +522 -0
  95. package/src/types/api-factory.ts +336 -0
  96. package/src/types/api-projects.ts +140 -0
  97. package/src/types/api-runs.ts +412 -0
  98. package/src/types/api-scopes.ts +102 -0
  99. package/src/types/conversation-stream.ts +231 -0
  100. package/src/types/execution-context.ts +10 -2
  101. package/src/types/protocol.ts +33 -0
  102. package/src/types/sandbox-environment.ts +28 -9
  103. package/src/types/sandbox.ts +73 -4
  104. package/src/types/workflow-metadata.ts +35 -8
  105. package/src/types/workflow-plan.ts +11 -0
  106. package/src/types/workflow.ts +25 -292
  107. package/src/utils/bundler.ts +32 -5
  108. package/src/utils/errors.ts +16 -1
  109. package/src/workflow-steps/index.ts +1 -0
  110. package/src/workflow-steps/observability.ts +19 -8
  111. package/src/workflow-steps/runner.ts +4 -4
  112. package/src/workflow-steps/step.ts +49 -1
  113. package/src/workflow-steps/types.ts +20 -5
  114. package/src/workflow-steps/workflow.ts +22 -1
  115. package/src/workflows/engine.ts +3 -2
  116. package/src/workflows/invoke-child.ts +2 -2
package/dist/sandbox.d.ts CHANGED
@@ -1,303 +1,28 @@
1
1
  /**
2
- * Sandbox provider registry — creates and manages isolated execution environments.
2
+ * Sandbox module — public surface.
3
3
  *
4
- * Providers: "vercel" (Vercel Sandbox), "e2b" (E2B), "e2b-desktop" (E2B Desktop).
5
- * Each provider validates its required env vars at creation time.
4
+ * Implementation lives in `sandbox/`:
5
+ * - `sandbox/network-policy.ts` — egress policy shape + per-provider translators
6
+ * - `sandbox/sizes.ts` — machine sizes + E2B template aliases
7
+ * - `sandbox/devbox.ts` — the ADR-0038 per-member desktop machine alias
8
+ * - `sandbox/provider-def.ts` — provider contract, create opts, fleet tag
9
+ * - `sandbox/exec-stream.ts` — SSE exec-stream parser (broker clients)
10
+ * - `sandbox/providers/*` — vercel / e2b / e2b-desktop / local providers
11
+ * - `sandbox/registry.ts` — provider registry + fleet management
6
12
  */
7
- import { Sandbox } from "e2b";
8
- import type { SandboxNetworkOpts as E2bNetworkOpts } from "e2b";
9
- import { Sandbox as Desktop } from "@e2b/desktop";
10
- import type { SandboxProvider, DesktopSandboxProvider, SandboxCommandResult } from "./types/sandbox.js";
11
- import type { ConnectorRequestRules } from "./types/workflow-metadata.js";
12
- import type { NetworkPolicy as VercelNetworkPolicy } from "@vercel/sandbox";
13
13
  export type { SandboxProvider, DesktopSandboxProvider, SandboxCommandRunOptions, SandboxCommandResult, SandboxDuplexProcess, SandboxSpawnDuplexOptions } from "./types/sandbox.js";
14
- export type SandboxProviderName = "vercel" | "e2b" | "e2b-desktop";
15
- export declare const AGENT_COMPOSE_TAG: string;
16
- /**
17
- * Network policy for outbound HTTPS requests — ONE shape for every provider;
18
- * only the enforcement point differs. When a sandbox makes a request matching
19
- * a domain in `allow`, the egress layer injects the specified headers before
20
- * forwarding — credentials never exist inside the VM. Both providers enforce
21
- * this natively at the platform edge from the resolved policy passed at
22
- * create: Vercel via its firewall (`requestRules` translate to native `match`
23
- * rules), E2B via its native network firewall (`toE2bNetwork` →
24
- * `allowOut`/`denyOut`/`rules`). See `toVercelNetworkPolicy` / `toE2bNetwork`.
25
- */
26
- export interface SandboxNetworkHeaderTransform {
27
- headers?: Record<string, string>;
28
- }
29
- export interface SandboxNetworkAllowRule {
30
- transform?: SandboxNetworkHeaderTransform[];
31
- /** Tier-2 request gate (method/path) — the transform only applies when the
32
- * request matches. Honoured on Vercel (translated to native `match` rules).
33
- * NOT honoured on E2B: its native rules carry only a `transform`, no
34
- * method/path matcher, so a brokered credential rides ALL requests to an
35
- * allowed host there (see `toE2bNetwork`). Present on connector-auth rules;
36
- * see `ConnectorRequestRules`. */
37
- requestRules?: ConnectorRequestRules;
38
- }
39
- export interface SandboxNetworkSubnetPolicy {
40
- allow?: string[];
41
- deny?: string[];
42
- }
43
- export type SandboxNetworkPolicy = "allow-all" | "deny-all" | {
44
- allow?: string[] | Record<string, SandboxNetworkAllowRule[]>;
45
- subnets?: SandboxNetworkSubnetPolicy;
46
- };
47
- /** Sandbox machine size. A coarse small/medium/large knob that maps to
48
- * provider machine specs at create time. Vercel honours it natively via
49
- * `resources.vcpus` (2048 MB RAM per vCPU). E2B sizing is baked into the
50
- * template, so E2B ignores this field. Default: "small". */
51
- /** Sandbox hardware SKU. Named for the actual machine spec (vCPU + RAM) rather
52
- * than abstract t-shirt sizes. Memory is always 2048 MB per vCPU:
53
- * 2vcpu-4gb = 2 vCPU / 4 GiB (Vercel's own default machine)
54
- * 4vcpu-8gb = 4 vCPU / 8 GiB
55
- * 8vcpu-16gb = 8 vCPU / 16 GiB (per-sandbox ceiling on STANDARD accounts —
56
- * probed live: 16 & 32 vCPU 400 on dev)
57
- * 32vcpu-64gb = 32 vCPU / 64 GiB (ENTERPRISE ONLY — standard accounts reject >8 vCPU) */
58
- export type SandboxSize = "2vcpu-4gb" | "4vcpu-8gb" | "8vcpu-16gb" | "32vcpu-64gb";
59
- /** SKU → Vercel vCPU count (RAM follows at 2048 MB/vCPU). */
60
- export declare const SANDBOX_VCPUS: Record<SandboxSize, number>;
61
- /** SDK fallback size when neither the caller nor the deployment specifies one.
62
- * Deliberately conservative — the OPERATIONAL default is the server's
63
- * `SANDBOX_DEFAULT_SIZE` env var (now also `2vcpu-4gb`). Keeping the default
64
- * small matters because Vercel rate-limits creation by vCPUs-per-window
65
- * (`api-sandboxes-vcpus-creation`); a large default 429s bursty/simultaneous
66
- * creates. Workloads that need more RAM/CPU declare `resources.size` on the
67
- * workflow rather than inflating the default for everyone. */
68
- export declare const DEFAULT_SANDBOX_SIZE: SandboxSize;
69
- /** The E2B sizes we pre-build a template for. E2B sizing is template-baked
70
- * (no per-create cpu/mem knob), so honouring `resources.size` on E2B means
71
- * ONE pre-built template per size. `32vcpu-64gb` is absent (E2B has no
72
- * >8-vCPU equivalent). `8vcpu-16gb` is also absent: it needs 16 GiB RAM, but
73
- * the E2B account caps memory at 8 GiB (`Template.build` 400s with
74
- * "Memory can't be higher than 8192 MiB"). Add it back here (and rebuild the
75
- * templates) only once the account's memory limit is raised. The register/
76
- * invoke guards reject an unsupported E2B size before it can reach here. */
77
- export declare const E2B_TEMPLATE_SIZES: readonly SandboxSize[];
78
- /** Is `size` one E2B can be built/booted at? `32vcpu-64gb` (no >8-vCPU E2B
79
- * equivalent) and `8vcpu-16gb` (exceeds the account's 8 GiB memory cap) are
80
- * not — the guards lean on this so the "no E2B equivalent" decision lives in
81
- * exactly one place. */
82
- export declare function isE2bSupportedSize(size: SandboxSize): boolean;
83
- /** Machine spec for a SandboxSize, in the shape `Template.build` wants. RAM is
84
- * always 2048 MB/vCPU, matching the size name + Vercel parity
85
- * (`SANDBOX_VCPUS` × 2048). Used by `infra/e2b-template/build.ts` to stamp the
86
- * per-size base + agent-env templates. */
87
- export declare function e2bMachineSpec(size: SandboxSize): {
88
- cpuCount: number;
89
- memoryMB: number;
90
- };
91
- /** Stable E2B template ALIAS for the platform base at a given size
92
- * (`agent-compose-base-<size>`). Aliases — not snapshot ids — so the refs are
93
- * multi-account-clean: the same string resolves in any E2B account that built
94
- * the templates. Built by `infra/e2b-template/build.ts`; the E2B provider
95
- * boots this when a run on E2B declares no explicit `bootFrom`/template. */
96
- export declare function e2bBaseTemplate(size: SandboxSize): string;
97
- /** Stable E2B template ALIAS for the agent runtime (base + claude binary) at a
98
- * given size (`agent-env-<size>`). The agent default templates boot from this
99
- * via `bootFrom: { snapshotId: e2bAgentEnvTemplate(size) }`. Multi-account-clean
100
- * for the same reason as `e2bBaseTemplate`. */
101
- export declare function e2bAgentEnvTemplate(size: SandboxSize): string;
102
- /** Is `id` one of the platform-managed E2B template aliases — a
103
- * `agent-compose-base-<size>` or `agent-env-<size>` for a supported size?
104
- *
105
- * These are stable, platform-built, multi-account-clean strings (NOT tenant
106
- * captures), so any workflow may boot from them: the same alias resolves to
107
- * the same platform base in every account, and there is no tenant data behind
108
- * it to leak. The dispatch snapshot gate uses this to vouch a platform E2B
109
- * boot alias without it having to be a team-owned capture or a published
110
- * template's bootFrom. */
111
- export declare function isPlatformE2bTemplateAlias(id: string): boolean;
112
- export interface SandboxCreateOpts {
113
- envs: Record<string, string>;
114
- metadata: Record<string, string>;
115
- timeoutMs: number;
116
- /** Provider-specific template/snapshot identifier. E2B: template id or
117
- * snapshot id (omit → E2B's default base). Vercel: snapshot id (omit → node24). */
118
- template?: string;
119
- /** Machine size. Vercel maps it to `resources.vcpus`; E2B ignores it
120
- * (size is template-defined). Omit → `DEFAULT_SANDBOX_SIZE`. */
121
- size?: SandboxSize;
122
- /** Outbound request policy with header transforms — ONE shape for every
123
- * provider; only the enforcement point differs. Both providers enforce +
124
- * inject natively at create from this value: Vercel via its firewall
125
- * (`toVercelNetworkPolicy`), E2B via its native network firewall
126
- * (`toE2bNetwork` → `network: { allowOut, denyOut, rules }`). */
127
- networkPolicy?: SandboxNetworkPolicy;
128
- }
129
- /**
130
- * What the provider reports as "currently alive" — the single input to orphan
131
- * reconciliation. `metadata` is best-effort: E2B populates it from sandbox
132
- * labels, Vercel from sandbox tags (max 5, stamped at create). Callers
133
- * that need runId correlation cross-reference `sandboxId` against their own
134
- * state (server: `workflow_runs.sandbox_id` + `run_agent_sandboxes.provider_sandbox_id`).
135
- */
136
- export interface OwnedSandbox {
137
- sandboxId: string;
138
- createdAt: Date;
139
- metadata: Record<string, string>;
140
- }
141
- interface SandboxProviderDef {
142
- requiredEnv: Record<string, string>;
143
- create: (opts: SandboxCreateOpts, env: Record<string, string>) => Promise<SandboxProvider>;
144
- reconnect?: (sandboxId: string) => Promise<SandboxProvider>;
145
- killAll?: (env: Record<string, string>) => Promise<void>;
146
- /**
147
- * Returns the number of sandboxes currently running against this provider.
148
- * Used for quota observability — account-wide, not per-instance.
149
- *
150
- * Both providers scope by our AGENT_COMPOSE_TAG (E2B metadata labels,
151
- * Vercel tags) so each fleet only reports its own sandboxes; DD aggregates
152
- * across instances with `sum by {provider}`.
153
- */
154
- getActiveCount?: (env: Record<string, string>) => Promise<number>;
155
- /**
156
- * Provider's view of what's currently alive for our account/fleet.
157
- * The reconciliation SoT — a sandbox missing from this list IS dead,
158
- * regardless of what our DB says. Implemented by listing the provider's
159
- * running sandboxes; E2B filters by metadata tag, Vercel by the `executor`
160
- * sandbox tag.
161
- */
162
- listOwned?: (env: Record<string, string>) => Promise<OwnedSandbox[]>;
163
- /**
164
- * Delete a snapshot by id. Called from the customer-initiated
165
- * `DELETE /workflows/:runId/snapshot` route. Best-effort — the DB is
166
- * source of truth; an orphan on the provider side is benign and cleaned
167
- * up eventually by the provider's own retention.
168
- */
169
- deleteSnapshot?: (snapshotId: string, env: Record<string, string>) => Promise<void>;
170
- /**
171
- * Does this snapshot id resolve on the provider for this account? A cheap
172
- * metadata lookup — NEVER provisions a sandbox. Used at server boot to
173
- * validate that the platform base snapshots the default templates boot from
174
- * actually exist for this deployment (catching e.g. a dev-account snapshot
175
- * baked into prod). Returns true if it resolves, false if the provider
176
- * reports it does not exist. Transport/credential errors PROPAGATE — an
177
- * indeterminate result must not be reported as "missing".
178
- */
179
- snapshotExists?: (snapshotId: string, env: Record<string, string>) => Promise<boolean>;
180
- }
181
- export declare function makeSandboxProvider(sb: Sandbox | Desktop): SandboxProvider;
182
- export declare function makeDesktopSandboxProvider(sb: Desktop): DesktopSandboxProvider;
183
- export interface ParseSseExecStreamOptions {
184
- onStdout?: (data: string) => void;
185
- onStderr?: (data: string) => void;
186
- }
187
- /**
188
- * Parse an SSE exec stream from a ReadableStream.
189
- * Used by the agent sandbox broker in runner.ts.
190
- */
191
- export declare function parseSseExecStream(body: ReadableStream<Uint8Array>, opts?: ParseSseExecStreamOptions): Promise<SandboxCommandResult>;
192
- /** Matches a path containing a dot-dot segment — literal (`/../`) or
193
- * percent-encoded (`%2e%2e`, `%2f` boundaries). `DOT_SEGMENT_PATH_RE2` is
194
- * the RE2 form handed to Vercel's matcher: wrapped in `.*` so it behaves
195
- * identically under search and full-match semantics (RE2 has no lookaround,
196
- * so the guard is a positive match on the traversal pattern, used as a
197
- * credential-stripping first rule). `DOT_SEGMENT_RE` is the local JS twin
198
- * used to validate DECLARED prefixes. */
199
- export declare const DOT_SEGMENT_PATH_RE2 = ".*(?:^|/|%2[fF])(?:\\.|%2[eE]){2}(?:/|%2[fF]|$).*";
200
- /**
201
- * Translate our policy shape into Vercel's native `NetworkPolicy`.
202
- *
203
- * The shapes are identical except for Tier-2: our `requestRules`
204
- * (`{ methods, pathPrefixes }`) become Vercel `match` rules
205
- * (`{ method, path: { startsWith } }`) — one rule per path prefix, since a
206
- * Vercel matcher carries a single path.
207
- *
208
- * Dot-segment defense: prefix matching is raw — `/repos/acme/../../user`
209
- * starts with `/repos/acme/` but the origin normalizes it to `/user`, riding
210
- * the credential outside its declared scope. We don't get to assume the
211
- * enforcer RFC-3986-normalizes before matching, so every domain with a path
212
- * gate gets a transform-free FIRST rule matching dot-segment paths
213
- * (first-match-wins ⇒ such requests go out credential-free), and declared
214
- * prefixes themselves are validated (must start with "/", no dot-segments).
215
- *
216
- * Accepted divergence from iron-proxy (E2B): off-gate requests to an allowed
217
- * domain pass WITHOUT the transform (Vercel terminates TLS only for
218
- * transform-bearing domains and applies first-match-wins) — iron-proxy
219
- * REFUSES them instead. Reachability differs; the property that matters is
220
- * preserved on both substrates: the brokered credential rides only declared
221
- * method/path combinations. Pinned by vercel-network-policy.test.ts.
222
- */
223
- export declare function toVercelNetworkPolicy(policy: SandboxNetworkPolicy): VercelNetworkPolicy;
224
- /**
225
- * Translate our policy shape into E2B's native `network` config
226
- * (`SandboxNetworkOpts`) — the E2B analogue of `toVercelNetworkPolicy`.
227
- *
228
- * - `allowOut`: the set of allowed egress targets — every host named in
229
- * `allow` PLUS every CIDR in `subnets.allow`. The Archil raw-TCP
230
- * data-plane CIDRs ride here as FIRST-CLASS allow entries (E2B has no
231
- * root-exemption to lean on, unlike the old in-VM iptables model).
232
- * - `denyOut`: the all-traffic sentinel (`0.0.0.0/0`) so the policy is
233
- * DEFAULT-DENY — only `allowOut` targets pass. E2B applies allow before
234
- * deny, so a host in both lists is allowed.
235
- * - `rules`: per-host header injection. For each host carrying transform(s),
236
- * emit one rule per transform with `{ transform: { headers } }`. A host
237
- * with a rule MUST also be in `allowOut` (registering a rule does not
238
- * grant egress on its own — E2B's API requires the host in `allowOut`).
239
- *
240
- * BEHAVIOURAL DIVERGENCE FROM iron-proxy / Vercel — path/method gating is NOT
241
- * available on E2B native rules. An `SandboxNetworkRule` carries only a
242
- * `transform` (header injection); there is no method/path matcher. So our
243
- * Tier-2 `requestRules` (`{ methods, pathPrefixes }`) cannot be enforced here:
244
- * a brokered credential rides EVERY request to an allowed host on E2B, whereas
245
- * Vercel (native `match`) and the old iron-proxy gated it to the declared
246
- * method+path. The host allowlist still confines WHICH hosts the credential
247
- * can reach; it just can't narrow to a method/path within an allowed host.
248
- *
249
- * String policies map straight through: "allow-all" → no restriction (omit
250
- * `allowOut`/`denyOut`), "deny-all" → block all egress.
251
- */
252
- export declare function toE2bNetwork(policy: SandboxNetworkPolicy): E2bNetworkOpts;
253
- /** Vercel caps sandbox tags at 5. Build the tag set with the fleet `executor`
254
- * tag always present and always winning over caller metadata — `listOwned` /
255
- * orphan reconciliation scope on it, so a clobbered or dropped executor tag
256
- * makes the sandbox invisible to cleanup. When metadata overflows the cap,
257
- * keep executor + the lexicographically-first 4 metadata keys, so what gets
258
- * dropped is deterministic rather than dependent on object insertion order. */
259
- export declare const VERCEL_MAX_TAGS = 5;
260
- export declare function buildVercelTags(metadata: Record<string, string>): Record<string, string>;
261
- /** Minimal SandboxProvider that targets the current process's host VM.
262
- * `commands.run` → `child_process.spawn`; `files.write` → `fs.writeFile`;
263
- * `kill` is a no-op because the caller IS the VM. Used by
264
- * `defineSandboxEnvironment` so setup recipes read like imperative
265
- * provisioning scripts. Uses `node:child_process` — works under both Node
266
- * (the runner executes `node /tmp/runner.bundle.js`) and Bun. */
267
- export declare function makeLocalSandboxProvider(): SandboxProvider;
268
- declare const SANDBOX_PROVIDERS: Record<string, SandboxProviderDef>;
269
- /** Provision a sandbox for the named provider. */
270
- export declare function createSandbox(provider: SandboxProviderName, opts: SandboxCreateOpts): Promise<SandboxProvider>;
271
- /** Reconnect to an existing sandbox by provider + provider-native sandbox ID. */
272
- export declare function reconnectSandbox(provider: SandboxProviderName, sandboxId: string): Promise<SandboxProvider>;
273
- /** Delete a snapshot by id on the named provider. No live sandbox needed. */
274
- export declare function deleteSandboxSnapshot(provider: SandboxProviderName, snapshotId: string): Promise<void>;
275
- /**
276
- * Does `snapshotId` resolve on the named provider for this account? A cheap
277
- * metadata lookup — never provisions a sandbox. `true` = resolves, `false` =
278
- * provider says it does not exist. Transport/credential errors propagate (an
279
- * indeterminate result is not "missing"). Used at server boot to validate the
280
- * platform base snapshots the default templates boot from.
281
- */
282
- export declare function snapshotResolves(provider: SandboxProviderName, snapshotId: string): Promise<boolean>;
283
- /**
284
- * Current active-sandbox count per configured provider, for quota gauges.
285
- * Skips providers whose required env isn't set or which don't implement
286
- * `getActiveCount`. Errors are surfaced per-provider so one flaky provider
287
- * doesn't silence the rest.
288
- */
289
- export type SandboxQuotaResult = Partial<Record<SandboxProviderName, number | Error>>;
290
- export declare function getSandboxQuotas(): Promise<SandboxQuotaResult>;
291
- /**
292
- * List every alive sandbox owned by this fleet, across all configured
293
- * providers — the orphan-reconciler SoT. Providers without `listOwned`
294
- * or missing env are skipped. Errors propagate per-provider so one flaky
295
- * provider doesn't silence the rest.
296
- */
297
- export type OwnedSandboxResult = Partial<Record<SandboxProviderName, OwnedSandbox[] | Error>>;
298
- export declare function listOwnedSandboxes(): Promise<OwnedSandboxResult>;
299
- /** Kill a sandbox by provider + native ID. Used by the orphan reconciler. */
300
- export declare function killSandboxById(provider: SandboxProviderName, sandboxId: string): Promise<void>;
301
- /** Kill all sandboxes across all registered providers. Call at startup to clean up after crashes. */
302
- export declare function killAllSandboxes(onError?: (provider: SandboxProviderName, err: unknown) => void): Promise<void>;
303
- export { SANDBOX_PROVIDERS };
14
+ export type { SandboxNetworkHeaderTransform, SandboxNetworkAllowRule, SandboxNetworkSubnetPolicy, SandboxNetworkPolicy, } from "./sandbox/network-policy.js";
15
+ export { DOT_SEGMENT_PATH_RE2, toVercelNetworkPolicy, toE2bNetwork } from "./sandbox/network-policy.js";
16
+ export type { SandboxSize } from "./sandbox/sizes.js";
17
+ export { SANDBOX_VCPUS, DEFAULT_SANDBOX_SIZE, E2B_TEMPLATE_SIZES, isE2bSupportedSize, e2bMachineSpec, e2bBaseTemplate, e2bAgentEnvTemplate, isPlatformE2bTemplateAlias, } from "./sandbox/sizes.js";
18
+ export { E2B_DEVBOX_TEMPLATE, E2B_DEVBOX_SPEC, E2B_DEVBOX_RECIPE_VERSION, e2bDevboxTemplateRef, } from "./sandbox/devbox.js";
19
+ export { AGENT_COMPOSE_TAG } from "./sandbox/provider-def.js";
20
+ export type { SandboxCreateOpts, OwnedSandbox } from "./sandbox/provider-def.js";
21
+ export { parseSseExecStream } from "./sandbox/exec-stream.js";
22
+ export type { ParseSseExecStreamOptions } from "./sandbox/exec-stream.js";
23
+ export { makeSandboxProvider } from "./sandbox/providers/e2b.js";
24
+ export { makeDesktopSandboxProvider } from "./sandbox/providers/desktop.js";
25
+ export { VERCEL_MAX_TAGS, buildVercelTags } from "./sandbox/providers/vercel.js";
26
+ export { makeLocalSandboxProvider } from "./sandbox/providers/local.js";
27
+ export { SANDBOX_PROVIDERS, createSandbox, reconnectSandbox, deleteSandboxSnapshot, snapshotResolves, getSandboxQuotas, listOwnedSandboxes, killSandboxById, killAllSandboxes, } from "./sandbox/registry.js";
28
+ export type { SandboxProviderName, SandboxQuotaResult, OwnedSandboxResult } from "./sandbox/registry.js";
@@ -75,6 +75,11 @@ export interface InvokeStepOptions {
75
75
  runnerPid: number;
76
76
  resultToken: string;
77
77
  }) => void;
78
+ /** Ceiling on the durable-result recovery poll after a live-stream fault
79
+ * (default 45m — the wedged-runner backstop). The activity passes its step
80
+ * ceiling so a stream fault on a step with hours of legitimate work left
81
+ * recovers instead of timing out; startToClose is the real wall. */
82
+ recoveryDeadlineMs?: number;
78
83
  }
79
84
  /** A step running as a background command (ADR-0028). The activity races its
80
85
  * `wait()` against a server pause request; on a pause it freezes the VM
@@ -114,4 +119,9 @@ export declare function reconnectStep<TOutput = unknown>(sandbox: SandboxProvide
114
119
  stepIndex: number;
115
120
  }, opts?: Pick<InvokeStepOptions, "onStdout" | "onStderr"> & {
116
121
  signal?: AbortSignal;
122
+ /** Ceiling on the durable-result poll (default 45m — the wedged-runner
123
+ * backstop). A worker-death recovery reconnecting MID-step passes the
124
+ * step ceiling instead: hours of legitimate work may remain, and the
125
+ * activity's per-attempt startToClose already bounds it server-side. */
126
+ pollDeadlineMs?: number;
117
127
  }): Promise<RunningStep<TOutput>>;
@@ -60,6 +60,11 @@ export declare function requestContextPath(stepIndex: number): string;
60
60
  * drop the tail of a heavy stdout stream — the invoker falls back to
61
61
  * reading this file when no sentinel is found on stdout. */
62
62
  export declare function stepResultFilePath(token: string): string;
63
+ /** Sandbox-side pidfile the FOREGROUND launch writes (`echo $$ > …`) before
64
+ * spawning the runner pipeline — the wrapping shell's pid. The recovery path
65
+ * reads it back to probe `/proc/<pid>` liveness when the live stream/wait
66
+ * call dies mid-step (providers with no background-process pid — Vercel). */
67
+ export declare function stepPidFilePath(token: string): string;
63
68
  /** Sandbox-side path where the runner's stdout is tee'd as a durable LOG file,
64
69
  * keyed by the per-invocation token. The live output rides E2B's connect-web
65
70
  * command stream, which THROWS on a compressed large frame (gRPC-web cannot
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Break-glass compliance session wire types (ADR-0051).
3
+ *
4
+ * A team admin has no default access to a scoped (Private/Shared) document.
5
+ * To view one they don't hold a grant on, they open a READ-ONLY,
6
+ * owner-approved, time-boxed compliance session over a scope (one factory, or
7
+ * the whole team). These are the shapes the server's `/api/v1/compliance/*`
8
+ * routes emit — `client.ts` is a thin typed wrapper over them.
9
+ */
10
+ export type ComplianceScopeKind = "factory" | "team";
11
+ export type ComplianceStatus = "pending" | "active" | "expired" | "revoked";
12
+ /** One break-glass compliance session. `expiresAt` is null while pending —
13
+ * the TTL clock starts at approval, not request. */
14
+ export interface ComplianceSession {
15
+ id: string;
16
+ teamId: string;
17
+ requestedByUserId: string | null;
18
+ requestedByLabel: string | null;
19
+ approvedByUserId: string | null;
20
+ approvedByLabel: string | null;
21
+ reason: string;
22
+ scopeKind: ComplianceScopeKind;
23
+ /** The factory this session covers (factory scope); null for team scope. */
24
+ scopeRef: string | null;
25
+ status: ComplianceStatus;
26
+ ttlSeconds: number;
27
+ expiresAt: string | null;
28
+ revokedByUserId: string | null;
29
+ revokedByLabel: string | null;
30
+ createdAt: string;
31
+ approvedAt: string | null;
32
+ revokedAt: string | null;
33
+ }
34
+ /** One per-document access recorded under an active session — the individual
35
+ * audit trail the session's reasoned entry authorizes. */
36
+ export interface ComplianceAccess {
37
+ id: string;
38
+ sessionId: string;
39
+ /** Nulled when the accessed file is later deleted (ON DELETE SET NULL);
40
+ * `filePath` is the durable snapshot that survives. */
41
+ fileId: string | null;
42
+ filePath: string;
43
+ accessedByUserId: string | null;
44
+ accessedByLabel: string | null;
45
+ accessedAt: string;
46
+ }
47
+ export interface RequestComplianceSessionInput {
48
+ scopeKind: ComplianceScopeKind;
49
+ /** Required for factory scope; must be omitted for team scope. */
50
+ scopeRef?: string | null;
51
+ reason: string;
52
+ /** Session lifetime once approved — 15 min floor, 7 day ceiling. */
53
+ ttlSeconds: number;
54
+ }
55
+ export interface ListComplianceSessionsOptions {
56
+ status?: ComplianceStatus;
57
+ limit?: number;
58
+ cursor?: string;
59
+ }
60
+ export interface ComplianceSessionsPage {
61
+ sessions: ComplianceSession[];
62
+ nextCursor: string | null;
63
+ }
64
+ export interface ListComplianceAccessesOptions {
65
+ limit?: number;
66
+ cursor?: string;
67
+ }
68
+ export interface ComplianceAccessesPage {
69
+ accesses: ComplianceAccess[];
70
+ nextCursor: string | null;
71
+ }