withruntime 0.8.3 → 0.9.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 (92) hide show
  1. package/COMPATIBILITY.md +145 -0
  2. package/E2B.md +23 -13
  3. package/README.md +8 -5
  4. package/README.src.md +8 -5
  5. package/compatibility-lock.json +281 -0
  6. package/dist/ai-harness/index.js +2 -2
  7. package/dist/api-defaults.d.ts +17 -0
  8. package/dist/api-defaults.js +22 -0
  9. package/dist/blaxel/preview.d.ts +1 -1
  10. package/dist/blaxel/preview.js +1 -1
  11. package/dist/blaxel/process.d.ts +1 -1
  12. package/dist/blaxel/process.js +11 -2
  13. package/dist/cli-words.d.ts +27 -0
  14. package/dist/cli-words.js +135 -0
  15. package/dist/cli.js +162 -31
  16. package/dist/client.d.ts +4 -1
  17. package/dist/client.js +8 -2
  18. package/dist/cloudflare/index.d.ts +294 -0
  19. package/dist/cloudflare/index.js +554 -0
  20. package/dist/cloudflare/worker.d.ts +415 -0
  21. package/dist/cloudflare/worker.js +297 -0
  22. package/dist/codesandbox/guest-service.d.ts +31 -0
  23. package/dist/codesandbox/guest-service.js +453 -0
  24. package/dist/codesandbox/index.d.ts +386 -0
  25. package/dist/codesandbox/index.js +1313 -0
  26. package/dist/compat/core.d.ts +39 -0
  27. package/dist/compat/core.js +199 -0
  28. package/dist/compat/files.d.ts +26 -0
  29. package/dist/compat/files.js +115 -0
  30. package/dist/compat/shell.d.ts +4 -0
  31. package/dist/compat/shell.js +165 -0
  32. package/dist/daytona/context.js +2 -1
  33. package/dist/daytona/process.d.ts +1 -1
  34. package/dist/daytona/process.js +27 -4
  35. package/dist/e2b/code-interpreter.d.ts +4 -5
  36. package/dist/e2b/code-interpreter.js +54 -56
  37. package/dist/e2b/commands.d.ts +5 -4
  38. package/dist/e2b/commands.js +37 -29
  39. package/dist/e2b/errors.js +1 -1
  40. package/dist/e2b/filesystem.d.ts +8 -6
  41. package/dist/e2b/filesystem.js +127 -28
  42. package/dist/e2b/sandbox.d.ts +4 -3
  43. package/dist/e2b/sandbox.js +10 -10
  44. package/dist/errors.d.ts +8 -0
  45. package/dist/errors.js +15 -2
  46. package/dist/freestyle/index.d.ts +301 -0
  47. package/dist/freestyle/index.js +310 -0
  48. package/dist/index.d.ts +1 -0
  49. package/dist/mcp.js +2 -2
  50. package/dist/modal/index.d.ts +205 -0
  51. package/dist/modal/index.js +485 -0
  52. package/dist/network-cli.js +1 -1
  53. package/dist/openai-agents/index.js +9 -26
  54. package/dist/products/audit.d.ts +3 -0
  55. package/dist/products/index.d.ts +2 -0
  56. package/dist/products/index.js +2 -0
  57. package/dist/products/interpreter.d.ts +11 -4
  58. package/dist/products/interpreter.js +33 -9
  59. package/dist/products/jobs.d.ts +1 -1
  60. package/dist/products/jobs.js +5 -4
  61. package/dist/products/limits.d.ts +10 -0
  62. package/dist/products/previews.d.ts +10 -2
  63. package/dist/products/previews.js +3 -2
  64. package/dist/products/tailscale.d.ts +57 -0
  65. package/dist/products/tailscale.js +17 -0
  66. package/dist/products/watch.d.ts +25 -4
  67. package/dist/products/watch.js +75 -14
  68. package/dist/runloop/index.d.ts +340 -0
  69. package/dist/runloop/index.js +438 -0
  70. package/dist/runloop/pagination.d.ts +46 -0
  71. package/dist/runloop/pagination.js +82 -0
  72. package/dist/runloop/snapshots.d.ts +52 -0
  73. package/dist/runloop/snapshots.js +244 -0
  74. package/dist/sandbox.d.ts +40 -9
  75. package/dist/sandbox.js +273 -76
  76. package/dist/snapshots.d.ts +11 -1
  77. package/dist/snapshots.js +11 -1
  78. package/dist/sprites/index.d.ts +251 -0
  79. package/dist/sprites/index.js +552 -0
  80. package/dist/tar.d.ts +8 -1
  81. package/dist/tar.js +185 -35
  82. package/dist/tools/index.js +2 -1
  83. package/dist/transport.d.ts +20 -2
  84. package/dist/transport.js +48 -11
  85. package/dist/types.d.ts +52 -3
  86. package/dist/vercel/command.js +12 -1
  87. package/dist/vercel/errors.d.ts +2 -2
  88. package/dist/vercel/errors.js +12 -1
  89. package/dist/vercel/filesystem.d.ts +21 -18
  90. package/dist/vercel/filesystem.js +95 -48
  91. package/dist/vercel/sandbox.js +5 -5
  92. package/package.json +45 -3
@@ -0,0 +1,310 @@
1
+ import { all, client, CompatibilityError, create, destroy, execOptions, lookup, only, ready, } from "../compat/core.js";
2
+ import { GuestFiles } from "../compat/files.js";
3
+ export { CompatibilityError };
4
+ const data = (s) => ({
5
+ id: s.id,
6
+ state: s.state,
7
+ slug: s.info.name,
8
+ displayName: s.info.labels["fs.displayName"] ?? null,
9
+ resources: { cpu: s.info.vcpu, memory: s.info.memoryMiB, storage: s.info.diskMiB },
10
+ metadata: Object.fromEntries(Object.entries(s.info.labels).filter(([k]) => !["compat.provider", "fs.displayName"].includes(k))),
11
+ idleTimeoutSeconds: s.info.idlePauseSeconds === 0 ? -1 : s.info.idlePauseSeconds,
12
+ vpcs: [],
13
+ networks: [],
14
+ createdAt: s.info.createdAt,
15
+ updatedAt: s.info.createdAt,
16
+ });
17
+ const snapshotData = (s) => ({
18
+ id: s.id,
19
+ sourceVmId: s.sourceSandboxId,
20
+ slug: s.name,
21
+ public: false,
22
+ createdAt: s.createdAt,
23
+ updatedAt: s.createdAt,
24
+ ttlSeconds: s.retentionDays * 86400,
25
+ });
26
+ export class Freestyle {
27
+ vms;
28
+ constructor(options = {}) {
29
+ this.vms = new VmsNamespace(client(options));
30
+ }
31
+ }
32
+ export class VmsNamespace {
33
+ runtime;
34
+ snapshots;
35
+ constructor(runtime) {
36
+ this.runtime = runtime;
37
+ this.snapshots = {
38
+ get: async (id) => snapshotData(await this.resolveSnapshot(id)),
39
+ delete: async (id) => runtime.snapshots.delete((await this.resolveSnapshot(id)).id),
40
+ list: async () => ({
41
+ snapshots: (await (await runtime.snapshots.list()).toArray()).map(snapshotData),
42
+ }),
43
+ };
44
+ }
45
+ async resolveSnapshot(id) {
46
+ if (/^[a-f0-9-]{36}$/i.test(id))
47
+ return this.runtime.snapshots.get(id);
48
+ const found = (await this.runtime.snapshots.list({ name: id })).data.find((s) => s.name === id);
49
+ if (!found)
50
+ throw new CompatibilityError("Freestyle", `snapshot ${id}; import the source environment into Runtime first`);
51
+ return found;
52
+ }
53
+ async create(options) {
54
+ only("Freestyle create", options, [
55
+ "snapshotId",
56
+ "slug",
57
+ "displayName",
58
+ "idleTimeoutSeconds",
59
+ "metadata",
60
+ "firewall",
61
+ ]);
62
+ if (!options.firewall || !Array.isArray(options.firewall.rules))
63
+ throw new TypeError("firewall.rules is required");
64
+ only("Freestyle firewall", options.firewall, ["rules"]);
65
+ for (const r of options.firewall.rules) {
66
+ only("Freestyle firewall rule", r, ["action", "source", "destination"]);
67
+ if (r.action !== "allow" ||
68
+ Object.keys(r.source).length ||
69
+ Object.keys(r.destination).length !== 1 ||
70
+ r.destination.public !== true)
71
+ throw new CompatibilityError("Freestyle", "firewall rules other than unrestricted outbound public access");
72
+ }
73
+ const snapshot = options.snapshotId
74
+ ? (await this.resolveSnapshot(options.snapshotId)).id
75
+ : undefined;
76
+ const s = await create(this.runtime, "freestyle", {
77
+ snapshot,
78
+ name: options.slug ?? undefined,
79
+ labels: { ...options.metadata, "fs.displayName": options.displayName ?? "" },
80
+ persistent: true,
81
+ idlePauseSeconds: options.idleTimeoutSeconds === -1 || options.idleTimeoutSeconds == null
82
+ ? 0
83
+ : options.idleTimeoutSeconds,
84
+ network: { internet: options.firewall.rules.length > 0 },
85
+ });
86
+ return {
87
+ vm: new Vm(this.runtime, s.id),
88
+ vmId: s.id,
89
+ data: data(s),
90
+ firewallRules: options.firewall.rules.map((rule) => ({
91
+ ...rule,
92
+ id: `runtime-network-${s.id}`,
93
+ source: { vmId: s.id },
94
+ })),
95
+ tlsRules: [],
96
+ };
97
+ }
98
+ ref(id) {
99
+ return new Vm(this.runtime, id);
100
+ }
101
+ async get(id) {
102
+ return data(await lookup(this.runtime, id));
103
+ }
104
+ async delete(id) {
105
+ await destroy(await lookup(this.runtime, id));
106
+ }
107
+ async list(options = {}) {
108
+ only("Freestyle list", options, ["state", "slug", "metadata", "limit", "offset"]);
109
+ const filters = options.metadata?.split(",").map((x) => {
110
+ const i = x.indexOf(":");
111
+ return [x.slice(0, i), x.slice(i + 1)];
112
+ }) ?? [];
113
+ const values = (await all(this.runtime, "freestyle")).filter((s) => (!options.state || s.state === options.state) &&
114
+ (!options.slug || s.info.name === options.slug) &&
115
+ filters.every(([k, v]) => s.info.labels[k] === v));
116
+ return {
117
+ vms: values
118
+ .slice(options.offset ?? 0, (options.offset ?? 0) + (options.limit ?? 100))
119
+ .map(data),
120
+ totalCount: values.length,
121
+ runningCount: values.filter((s) => s.state === "running").length,
122
+ startingCount: values.filter((s) => s.state === "starting").length,
123
+ pausingCount: values.filter((s) => s.state === "pausing").length,
124
+ pausedCount: values.filter((s) => s.state === "paused").length,
125
+ stoppedCount: values.filter((s) => s.state === "stopped").length,
126
+ };
127
+ }
128
+ }
129
+ export class VmFilesystem {
130
+ get;
131
+ files;
132
+ constructor(get) {
133
+ this.get = get;
134
+ this.files = new GuestFiles(get, "/");
135
+ }
136
+ async readFile(path, options = {}) {
137
+ return new Uint8Array(await new Response(await this.readFileStream(path, options)).arrayBuffer());
138
+ }
139
+ async readTextFile(path, options = {}) {
140
+ return new TextDecoder().decode(await this.readFile(path, options));
141
+ }
142
+ async readFileStream(path, options = {}) {
143
+ only("Freestyle file read", options, ["offset", "length", "signal"]);
144
+ for (const value of [options.offset, options.length])
145
+ if (value !== undefined && (!Number.isSafeInteger(value) || value < 0))
146
+ throw new TypeError("File range must contain nonnegative safe integers");
147
+ options.signal?.throwIfAborted();
148
+ const source = await (await this.get()).files.readStream(this.files.path(path), { signal: options.signal });
149
+ if (options.offset === undefined && options.length === undefined)
150
+ return source;
151
+ const reader = source.getReader();
152
+ let skip = options.offset ?? 0, remaining = options.length ?? Infinity;
153
+ return new ReadableStream({
154
+ async pull(controller) {
155
+ try {
156
+ options.signal?.throwIfAborted();
157
+ if (!remaining) {
158
+ await reader.cancel();
159
+ controller.close();
160
+ return;
161
+ }
162
+ for (;;) {
163
+ const next = await reader.read();
164
+ if (next.done) {
165
+ controller.close();
166
+ return;
167
+ }
168
+ const start = Math.min(skip, next.value.length);
169
+ skip -= start;
170
+ const chunk = next.value.subarray(start, start + remaining);
171
+ if (chunk.length) {
172
+ remaining -= chunk.length;
173
+ controller.enqueue(chunk);
174
+ return;
175
+ }
176
+ }
177
+ }
178
+ catch (error) {
179
+ await reader.cancel(error);
180
+ controller.error(error);
181
+ }
182
+ },
183
+ cancel(reason) {
184
+ return reader.cancel(reason);
185
+ },
186
+ });
187
+ }
188
+ async writeFile(path, content, options = {}) {
189
+ only("Freestyle file write", options, [
190
+ "mode",
191
+ "onProgress",
192
+ "signal",
193
+ "chunkSize",
194
+ "maxAttempts",
195
+ ]);
196
+ if (options.chunkSize !== undefined || options.maxAttempts !== undefined)
197
+ throw new CompatibilityError("Freestyle", "custom upload chunk sizing/retry budgets");
198
+ options.signal?.throwIfAborted();
199
+ const bytes = typeof content === "string"
200
+ ? new TextEncoder().encode(content)
201
+ : content instanceof Uint8Array
202
+ ? content
203
+ : new Uint8Array(await content.arrayBuffer());
204
+ let mode = options.mode;
205
+ if (mode === undefined)
206
+ mode = (await this.files.exists(path))
207
+ ? parseInt((await this.files.stat(path)).mode, 8)
208
+ : 0o600;
209
+ await this.files.writeFile(path, bytes, { mode, signal: options.signal });
210
+ options.onProgress?.({ completedBytes: bytes.length, totalBytes: bytes.length });
211
+ }
212
+ writeTextFile(path, content, options = {}) {
213
+ return this.writeFile(path, content, options);
214
+ }
215
+ mkdir(path) {
216
+ return this.files.mkdir(path, true);
217
+ }
218
+ remove(path) {
219
+ return this.files.remove(path, true);
220
+ }
221
+ exists(path) {
222
+ return this.files.exists(path);
223
+ }
224
+ async readDir(path) {
225
+ return (await this.files.readdir(path)).map((e) => ({ name: e.name, kind: e.type }));
226
+ }
227
+ async stat(path) {
228
+ const e = await this.files.stat(path);
229
+ const s = await this.get();
230
+ const r = await s.exec(["stat", "-c", "%U:%G", "--", this.files.path(path)], { check: true });
231
+ const [owner, group] = r.stdout.trim().split(":");
232
+ return {
233
+ size: e.size,
234
+ isFile: e.type === "file",
235
+ isDirectory: e.type === "directory",
236
+ isSymlink: e.type === "symlink",
237
+ permissions: e.mode,
238
+ owner: owner,
239
+ group: group,
240
+ modified: e.modifiedAt,
241
+ };
242
+ }
243
+ }
244
+ export class Vm {
245
+ runtime;
246
+ id;
247
+ fs;
248
+ constructor(runtime, id) {
249
+ this.runtime = runtime;
250
+ this.id = id;
251
+ this.fs = new VmFilesystem(() => lookup(runtime, id));
252
+ }
253
+ async data() {
254
+ return data(await lookup(this.runtime, this.id));
255
+ }
256
+ async start() {
257
+ return data(await ready(await lookup(this.runtime, this.id)));
258
+ }
259
+ async pause() {
260
+ const s = await lookup(this.runtime, this.id);
261
+ await s.pause();
262
+ return data(s);
263
+ }
264
+ async delete() {
265
+ await destroy(await lookup(this.runtime, this.id));
266
+ }
267
+ async update(options) {
268
+ only("Freestyle update", options, ["slug", "displayName", "idleTimeoutSeconds", "metadata"]);
269
+ const s = await lookup(this.runtime, this.id);
270
+ await s.update({
271
+ name: options.slug,
272
+ idlePauseSeconds: options.idleTimeoutSeconds === -1 ? 0 : options.idleTimeoutSeconds,
273
+ labels: {
274
+ ...s.info.labels,
275
+ ...options.metadata,
276
+ ...(options.displayName === undefined ? {} : { "fs.displayName": options.displayName }),
277
+ },
278
+ });
279
+ return data(s);
280
+ }
281
+ async exec(options) {
282
+ const o = typeof options === "string" ? { command: options } : options;
283
+ only("Freestyle exec", o, ["command", "linuxUser", "timeoutMs", "env", "stdin"]);
284
+ if (o.linuxUser)
285
+ throw new CompatibilityError("Freestyle", "exec as a different Linux user");
286
+ const s = await lookup(this.runtime, this.id);
287
+ const r = await s.exec(o.command, await execOptions(s, {
288
+ onStdout: () => undefined,
289
+ onStderr: () => undefined,
290
+ timeoutMs: o.timeoutMs,
291
+ env: o.env,
292
+ stdin: o.stdin === undefined
293
+ ? undefined
294
+ : Uint8Array.from(atob(o.stdin), (c) => c.charCodeAt(0)),
295
+ }));
296
+ return { stdout: r.stdout, stderr: r.stderr, statusCode: r.timedOut ? null : r.exitCode };
297
+ }
298
+ async snapshot(options = {}) {
299
+ only("Freestyle snapshot", options, ["slug", "displayName", "ttlSeconds"]);
300
+ if (options.ttlSeconds !== undefined &&
301
+ (options.ttlSeconds <= 0 || options.ttlSeconds % 86400 !== 0))
302
+ throw new CompatibilityError("Freestyle", "snapshot retention other than whole positive days");
303
+ const s = await (await lookup(this.runtime, this.id)).snapshot({
304
+ name: options.slug,
305
+ labels: options.displayName ? { "fs.displayName": options.displayName } : undefined,
306
+ retentionDays: options.ttlSeconds === undefined ? undefined : options.ttlSeconds / 86400,
307
+ });
308
+ return { snapshotId: s.id, sourceVmId: s.sourceSandboxId, snapshot: snapshotData(s) };
309
+ }
310
+ }
package/dist/index.d.ts CHANGED
@@ -20,6 +20,7 @@ export { SecretPartlyStoredError } from "./products/secrets.js";
20
20
  export type { McpCatalogEntry, McpGateway, McpServerRequest } from "./products/mcp.js";
21
21
  export type { FileEvent, FileEventType, WatchHandle, WatchNotice, WatchOptions, } from "./products/watch.js";
22
22
  export type { Mount, MountBucket } from "./products/mounts.js";
23
+ export type { TailscaleJoin, TailscaleJoined, TailscaleNode, TailscaleStatus, } from "./products/tailscale.js";
23
24
  export type { Volume, VolumeBackup, CreateVolume } from "./products/volumes.js";
24
25
  export type { CreateJob, Job, JobCompute, JobDefinition, JobLogs, JobRun, JobRunState, JobSchedule, } from "./products/jobs.js";
25
26
  export type { CheckedDomain, DnsRecord, Domain, EgressAddress, TcpPort, Tunnel as PrivateTunnel, TunnelPeer, TunnelPeerCreated, SetUpstreamProxy, UpstreamProxy, } from "./products/network-products.js";
package/dist/mcp.js CHANGED
@@ -3,7 +3,7 @@ import { resolveCredential } from "./credentials.js";
3
3
  import { RuntimeError } from "./errors.js";
4
4
  import { beginDeviceLogin } from "./login.js";
5
5
  import { envFetch } from "./proxy.js";
6
- import { apiOrigin, VERSION } from "./transport.js";
6
+ import { apiOrigin, defaultBaseUrl, VERSION } from "./transport.js";
7
7
  const CONNECT_INSTRUCTIONS = "Runtime is not connected on this machine yet. Call runtime_connect: it gives you a link and a code for the person you work for to approve in their browser (no key to copy). Once they have, call runtime_connect again; Runtime's tools then appear (sandboxes, commands, files and the rest).";
8
8
  const connectTool = {
9
9
  name: "runtime_connect",
@@ -32,7 +32,7 @@ export async function serveMcp(env = process.env, options = {}) {
32
32
  if (!(error instanceof RuntimeError && error.code === "missing_api_key"))
33
33
  throw error;
34
34
  }
35
- const origin = apiOrigin(env.RUNTIME_API_URL ?? "https://api.withruntime.com");
35
+ const origin = apiOrigin(defaultBaseUrl(env));
36
36
  const endpoint = new URL("/mcp", origin).href;
37
37
  let protocolVersion;
38
38
  let session;
@@ -0,0 +1,205 @@
1
+ import type { Runtime } from "../client.js";
2
+ import type { Process, Sandbox as NativeSandbox } from "../sandbox.js";
3
+ import { CompatibilityError, type ClientOptions } from "../compat/core.js";
4
+ export { CompatibilityError };
5
+ export declare class NotFoundError extends Error {
6
+ }
7
+ export declare class TimeoutError extends Error {
8
+ }
9
+ export declare class SandboxTimeoutError extends TimeoutError {
10
+ }
11
+ export declare class App {
12
+ readonly appId: string;
13
+ readonly name?: string | undefined;
14
+ readonly environmentName?: string | undefined;
15
+ constructor(appId: string, name?: string | undefined, environmentName?: string | undefined);
16
+ }
17
+ export type SandboxCreateParams = {
18
+ name?: string;
19
+ cpu?: number;
20
+ cpuLimit?: number;
21
+ memoryMiB?: number;
22
+ memoryLimitMiB?: number;
23
+ timeoutMs?: number;
24
+ workdir?: string;
25
+ command?: string[];
26
+ env?: Record<string, string>;
27
+ encryptedPorts?: number[];
28
+ blockNetwork?: boolean;
29
+ outboundDomainAllowlist?: string[];
30
+ outboundCidrAllowlist?: string[];
31
+ tags?: Record<string, string>;
32
+ regions?: string[];
33
+ gpu?: string;
34
+ pty?: boolean;
35
+ secrets?: Secret[];
36
+ experimentalEnableSnapshot?: boolean;
37
+ };
38
+ export type SandboxExecParams = {
39
+ mode?: "text" | "binary";
40
+ stdout?: "pipe" | "ignore";
41
+ stderr?: "pipe" | "ignore";
42
+ workdir?: string;
43
+ timeoutMs?: number;
44
+ env?: Record<string, string>;
45
+ pty?: boolean;
46
+ secrets?: Secret[];
47
+ };
48
+ export declare class Secret {
49
+ readonly values: Record<string, string>;
50
+ constructor(values: Record<string, string>);
51
+ }
52
+ export declare class ModalClient {
53
+ readonly runtime: Runtime;
54
+ readonly apps: {
55
+ fromName: (name: string, params?: {
56
+ createIfMissing?: boolean;
57
+ environment?: string;
58
+ }) => Promise<App>;
59
+ };
60
+ readonly images: {
61
+ fromRegistry: (tag: string, secret?: Secret) => Image;
62
+ fromId: (id: string) => Promise<Image>;
63
+ fromName: (name: string) => Promise<Image>;
64
+ delete: (id: string) => Promise<import("../products/images.js").Image>;
65
+ };
66
+ readonly sandboxes: SandboxService;
67
+ readonly secrets: {
68
+ fromObject: (values: Record<string, string>) => Secret;
69
+ };
70
+ constructor(options?: ClientOptions & {
71
+ tokenId?: string;
72
+ tokenSecret?: string;
73
+ environment?: string;
74
+ });
75
+ close(): void;
76
+ }
77
+ export declare class Image {
78
+ private readonly runtime;
79
+ private readonly tag?;
80
+ private readonly commands;
81
+ private readonly env;
82
+ private readonly cache;
83
+ private built?;
84
+ constructor(runtime: Runtime, tag?: string | undefined, id?: string, commands?: string[], env?: Record<string, string>, cache?: boolean);
85
+ get imageId(): string;
86
+ dockerfileCommands(commands: string[], params?: {
87
+ env?: Record<string, string>;
88
+ forceBuild?: boolean;
89
+ }): Image;
90
+ build(_app?: App): Promise<Image>;
91
+ }
92
+ export declare class SandboxService {
93
+ private readonly runtime;
94
+ constructor(runtime: Runtime);
95
+ create(app: App, image: Image, params?: SandboxCreateParams): Promise<Sandbox>;
96
+ fromId(id: string): Promise<Sandbox>;
97
+ fromName(appName: string, name: string): Promise<Sandbox>;
98
+ list(params?: {
99
+ appId?: string;
100
+ tags?: Record<string, string>;
101
+ }): AsyncGenerator<Sandbox, void, unknown>;
102
+ }
103
+ export declare class ModalReadStream<R extends string | Uint8Array = string> extends ReadableStream<R> {
104
+ constructor(process: Process, channel: "stdout" | "stderr", mode: "text" | "binary", ignore?: boolean);
105
+ readBytes(): Promise<Uint8Array<ArrayBuffer>>;
106
+ readText(): Promise<string>;
107
+ }
108
+ export declare class ModalWriteStream<R extends string | Uint8Array = string> extends WritableStream<R> {
109
+ private readonly process;
110
+ constructor(process: Process);
111
+ writeText(text: string): Promise<void>;
112
+ writeBytes(bytes: Uint8Array): Promise<void>;
113
+ }
114
+ export declare class ContainerProcess<R extends string | Uint8Array = string> {
115
+ readonly native: Process;
116
+ readonly stdin: ModalWriteStream<R>;
117
+ readonly stdout: ModalReadStream<R>;
118
+ readonly stderr: ModalReadStream<R>;
119
+ constructor(native: Process, mode: "text" | "binary", params?: SandboxExecParams);
120
+ wait(): Promise<number>;
121
+ closeStdin(): Promise<void>;
122
+ _poll(): Promise<number | null>;
123
+ }
124
+ export declare class Sandbox {
125
+ readonly native: NativeSandbox;
126
+ private readonly primary;
127
+ readonly filesystem: SandboxFilesystem;
128
+ readonly stdin: ModalWriteStream<string>;
129
+ readonly stdout: ModalReadStream<string>;
130
+ readonly stderr: ModalReadStream<string>;
131
+ private detached;
132
+ private lifecycle?;
133
+ monitorEntrypoint(): void;
134
+ constructor(native: NativeSandbox, primary: ContainerProcess);
135
+ get sandboxId(): string;
136
+ exec(command: string[], params?: SandboxExecParams & {
137
+ mode?: "text";
138
+ }): Promise<ContainerProcess<string>>;
139
+ exec(command: string[], params: SandboxExecParams & {
140
+ mode: "binary";
141
+ }): Promise<ContainerProcess<Uint8Array>>;
142
+ setTags(tags: Record<string, string>): Promise<void>;
143
+ getTags(): Promise<Record<string, string>>;
144
+ terminate(params?: {
145
+ wait?: boolean;
146
+ }): Promise<number | undefined>;
147
+ detach(): void;
148
+ wait(): Promise<number>;
149
+ poll(): Promise<number | null>;
150
+ tunnels(): Promise<{
151
+ [k: string]: {
152
+ host: string;
153
+ port: number;
154
+ url: string;
155
+ };
156
+ }>;
157
+ updateNetworkPolicy(params: {
158
+ outboundCidrAllowlist: string[];
159
+ outboundDomainAllowlist: string[];
160
+ }): Promise<void>;
161
+ experimentalSnapshot(): Promise<{
162
+ sandboxSnapshotId: string;
163
+ }>;
164
+ }
165
+ export declare class SandboxFilesystem {
166
+ private readonly native;
167
+ private readonly files;
168
+ constructor(native: NativeSandbox);
169
+ readBytes(path: string): Promise<Uint8Array<ArrayBufferLike>>;
170
+ readText(path: string): Promise<string>;
171
+ writeBytes(content: Uint8Array | ArrayBuffer, path: string): Promise<void>;
172
+ writeText(content: string, path: string): Promise<void>;
173
+ makeDirectory(path: string, options?: {
174
+ createParents?: boolean;
175
+ }): Promise<void>;
176
+ remove(path: string, options?: {
177
+ recursive?: boolean;
178
+ }): Promise<void>;
179
+ copyFromLocal(localPath: string, remotePath: string): Promise<void>;
180
+ copyToLocal(remotePath: string, localPath: string): Promise<void>;
181
+ listFiles(path: string): Promise<{
182
+ name: string;
183
+ path: string;
184
+ type: "file" | "directory" | "symlink" | "other";
185
+ size: number;
186
+ mode: number;
187
+ permissions: string;
188
+ owner: string;
189
+ group: string;
190
+ modifiedTime: number;
191
+ symlinkTarget: string | null;
192
+ }[]>;
193
+ stat(path: string): Promise<{
194
+ name: string;
195
+ path: string;
196
+ type: "file" | "directory" | "symlink" | "other";
197
+ size: number;
198
+ mode: number;
199
+ permissions: string;
200
+ owner: string;
201
+ group: string;
202
+ modifiedTime: number;
203
+ symlinkTarget: string | null;
204
+ }>;
205
+ }