beachside 0.8.0 → 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.
package/README.md CHANGED
@@ -6,17 +6,25 @@ Install `beachside @beachside/daytona` (or `beachside @beachside/e2b`).
6
6
 
7
7
  ```ts
8
8
  import { Beachside } from "beachside";
9
- import { daytona } from "@beachside/daytona";
9
+ import { daytonaAdapter } from "@beachside/daytona";
10
10
 
11
- const beachside = await Beachside.connect(daytona({ apiKey: process.env.DAYTONA_API_KEY!, target: "us" }));
11
+ const beachside = await Beachside.connect({
12
+ adapter: daytonaAdapter,
13
+ credentials: { apiKey: process.env.DAYTONA_API_KEY! },
14
+ config: { target: "us" },
15
+ });
12
16
  await beachside.close();
13
17
  ```
14
18
 
15
19
  ```ts
16
20
  import { Beachside, Image } from "beachside";
17
- import { daytona } from "@beachside/daytona";
21
+ import { daytonaAdapter } from "@beachside/daytona";
18
22
 
19
- const beachside = await Beachside.connect(daytona({ apiKey: process.env.DAYTONA_API_KEY!, target: "us" }));
23
+ const beachside = await Beachside.connect({
24
+ adapter: daytonaAdapter,
25
+ credentials: { apiKey: process.env.DAYTONA_API_KEY! },
26
+ config: { target: "us" },
27
+ });
20
28
  try {
21
29
  const box = await beachside.sandboxes.create({ environment: Image.prepared("your-snapshot-id") });
22
30
  try {
@@ -22,7 +22,13 @@ export declare class FilesystemError extends BeachsideError {
22
22
  }
23
23
  export declare function filesystemError(error: unknown): Error;
24
24
  export declare function byteLimit(value: number | undefined, defaultValue?: number): number | undefined;
25
+ /**
26
+ * The effective limit of one buffered adapter read or write: the caller's optional `maxBytes`
27
+ * guard, bounded by the adapter's own buffered limit. Larger files use the adapter's streams.
28
+ */
25
29
  export declare function bufferedLimit(value: number | undefined, adapterLimit: number): number;
30
+ /** The error for a file larger than an adapter without file streams can move in one call. */
31
+ export declare function adapterFileLimit(adapterLimit: number, code: "CAPACITY" | "OUTPUT_CAPACITY"): BeachsideError;
26
32
  export declare function streamFile(read: (ctx: ReadContext) => Promise<ReadableStream<Uint8Array>>, closed: AbortSignal, options: FileStreamOptions, defaults: TransferPolicy): AsyncIterable<Uint8Array>;
27
33
  export declare function writeStream(write: (bytes: AsyncIterable<Uint8Array>, ctx: FileTransferContext) => Promise<{
28
34
  bytesWritten: number;
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export declare const Beachside: {
6
6
  connect: typeof connectDirect;
7
7
  };
8
8
  export { Image, outputText, BeachsideError, UnsupportedFeatureError, OutcomeUnknownError, WaitAbortedError, NonzeroExitError, NoExitCodeError, } from "./resource.js";
9
- export type { ImageInput, PreparedImage, ImageBuildResult, CreateInput, NetworkPolicy, ExecInput, ExecOutput, OutputPreview, DirectBeachsideClient, DirectSandboxHandle, SandboxHandle, SnapshotHandle, ImageHandle, VolumeHandle, ReadOptions, OperationHandle, RecoveryReference, BeachsideClient, } from "./resource.js";
9
+ export type { ImageInput, PreparedImage, ImageBuildResult, CreateInput, NetworkPolicy, ExecInput, ExecStdinStream, ExecOutput, OutputPreview, DirectBeachsideClient, DirectSandboxHandle, SandboxHandle, SnapshotHandle, ImageHandle, VolumeHandle, ReadOptions, OperationHandle, RecoveryReference, BeachsideClient, } from "./resource.js";
10
10
  export { ResourceReference, ResourceKind, validateResourceReference, assertResourceScope, assertResourceIdentity, SnapshotRequest, SnapshotRequirements, Preserve, } from "@beachside/adapter";
11
11
  export type { Support, Capabilities, DirectCapabilities, OperationOutcome, SnapshotPlan, SnapshotProfile, SandboxState, SandboxReference, SuspendResult, ResumeResult, RenewRequest, RenewResult, Preview, Fact, Deadline, ResourceMinimums, SandboxResources, CreatePlan, } from "@beachside/adapter";
12
12
  export { AdapterSnapshot, AdapterVolume, AdapterImage } from "./resources.js";
package/dist/index.js CHANGED
@@ -26,6 +26,97 @@ var Image = {
26
26
  return { kind: "oci", value };
27
27
  }
28
28
  };
29
+ function isStdinStream(value) {
30
+ return value instanceof ReadableStream || value !== null && typeof value === "object" && !(value instanceof Uint8Array) && Symbol.asyncIterator in value;
31
+ }
32
+ function stdinNeedsStream(stdin) {
33
+ if (stdin === undefined)
34
+ return false;
35
+ if (isStdinStream(stdin))
36
+ return true;
37
+ if (stdin instanceof Uint8Array)
38
+ return stdin.byteLength > MAX_EXEC_STDIN_BYTES;
39
+ return stdin.length * 3 > MAX_EXEC_STDIN_BYTES && utf8Bytes(stdin) > MAX_EXEC_STDIN_BYTES;
40
+ }
41
+ function utf8Bytes(text) {
42
+ return new TextEncoder().encode(text).byteLength;
43
+ }
44
+ function streamedStdin(stdin) {
45
+ if (stdin === undefined || !stdinNeedsStream(stdin))
46
+ return;
47
+ if (stdin instanceof ReadableStream)
48
+ return readableSource(stdin);
49
+ if (isStdinStream(stdin))
50
+ return iterableSource(stdin);
51
+ let bytes = stdin instanceof Uint8Array ? Uint8Array.from(stdin) : new TextEncoder().encode(stdin);
52
+ return {
53
+ async next() {
54
+ const chunk = bytes;
55
+ bytes = null;
56
+ return chunk;
57
+ },
58
+ cancel() {
59
+ bytes = null;
60
+ }
61
+ };
62
+ }
63
+ function stdinChunk(value) {
64
+ if (!(value instanceof Uint8Array))
65
+ throw new BeachsideError("INVALID_ARGUMENT", "Expected stdin stream byte chunks");
66
+ return value;
67
+ }
68
+ function readableSource(stream) {
69
+ let reader;
70
+ let cancelled = false;
71
+ return {
72
+ async next() {
73
+ if (cancelled)
74
+ return null;
75
+ reader ??= stream.getReader();
76
+ const part = await reader.read();
77
+ if (!part.done)
78
+ return stdinChunk(part.value);
79
+ cancelled = true;
80
+ reader.releaseLock();
81
+ return null;
82
+ },
83
+ cancel() {
84
+ if (cancelled)
85
+ return;
86
+ cancelled = true;
87
+ if (!reader) {
88
+ stream.cancel().catch(() => {
89
+ return;
90
+ });
91
+ return;
92
+ }
93
+ const owned = reader;
94
+ owned.cancel().catch(() => {
95
+ return;
96
+ }).finally(() => owned.releaseLock());
97
+ }
98
+ };
99
+ }
100
+ function iterableSource(iterable) {
101
+ const iterator = iterable[Symbol.asyncIterator]();
102
+ let cancelled = false;
103
+ return {
104
+ async next() {
105
+ if (cancelled)
106
+ return null;
107
+ const part = await iterator.next();
108
+ return part.done ? null : stdinChunk(part.value);
109
+ },
110
+ cancel() {
111
+ if (cancelled)
112
+ return;
113
+ cancelled = true;
114
+ Promise.resolve().then(() => iterator.return?.()).catch(() => {
115
+ return;
116
+ });
117
+ }
118
+ };
119
+ }
29
120
  var ExecStdinInput = z.union([
30
121
  z.string().max(MAX_EXEC_STDIN_BYTES).transform((value) => ({ kind: "text", value })),
31
122
  z.instanceof(Uint8Array).refine((value) => value.byteLength <= MAX_EXEC_STDIN_BYTES).transform((value) => ({ kind: "bytes", value }))
@@ -229,6 +320,8 @@ function validateExec(input, options = {}) {
229
320
  if (options.allowStdin === false && !isArgumentArray(input) && request?.stdin !== undefined)
230
321
  throw new BeachsideError("INVALID_ARGUMENT", "stdin is available only for finite exec input");
231
322
  let stdin;
323
+ if (request?.stdin !== undefined && isStdinStream(request.stdin))
324
+ throw new BeachsideError("INVALID_ARGUMENT", "Streamed stdin is available through exec(), not as finite input");
232
325
  if (request?.stdin !== undefined) {
233
326
  const parsedInput = ExecStdinInput.safeParse(request.stdin);
234
327
  if (!parsedInput.success)
@@ -418,10 +511,12 @@ class FilesystemError extends BeachsideError {
418
511
  }
419
512
  }
420
513
  function filesystemError(error) {
421
- if (error instanceof AdapterFilesystemError)
422
- return new FilesystemError(error.code, error.message, error.details);
423
- if (error instanceof AdapterError)
424
- return new BeachsideError(error.code, error.message);
514
+ if (error instanceof AdapterError) {
515
+ const mapped = error instanceof AdapterFilesystemError ? new FilesystemError(error.code, error.message, error.details) : new BeachsideError(error.code, error.message);
516
+ if (error.cause !== undefined)
517
+ mapped.cause = error.cause;
518
+ return mapped;
519
+ }
425
520
  return error instanceof Error ? error : new Error("Filesystem operation failed", { cause: error });
426
521
  }
427
522
  function byteLimit(value, defaultValue) {
@@ -431,10 +526,12 @@ function byteLimit(value, defaultValue) {
431
526
  return limit;
432
527
  }
433
528
  function bufferedLimit(value, adapterLimit) {
434
- const limit = byteLimit(value, 1048576);
435
- if (limit > 16777216)
436
- throw new BeachsideError("INVALID_ARGUMENT", "Buffered file limit exceeds 16 MiB; use streams");
437
- return Math.min(limit, byteLimit(adapterLimit));
529
+ const limit = byteLimit(value);
530
+ const adapter = byteLimit(adapterLimit);
531
+ return limit === undefined ? adapter : Math.min(limit, adapter);
532
+ }
533
+ function adapterFileLimit(adapterLimit, code) {
534
+ return new BeachsideError(code, `File exceeds this adapter's ${adapterLimit}-byte file limit; it has no file streams`, code === "OUTPUT_CAPACITY" ? "unknown" : "none");
438
535
  }
439
536
 
440
537
  class Transfer {
@@ -892,7 +989,7 @@ function certifiedRecoveryAvailable(reference) {
892
989
  // package.json
893
990
  var package_default = {
894
991
  name: "beachside",
895
- version: "0.8.0",
992
+ version: "0.9.0",
896
993
  private: false,
897
994
  type: "module",
898
995
  files: [
@@ -2597,9 +2694,15 @@ async function callbackExec(client, sandbox, controlActive, input, options) {
2597
2694
  const callback = options.onOutput;
2598
2695
  if (typeof callback !== "function")
2599
2696
  throw new BeachsideError("INVALID_ARGUMENT", "Expected execution output callback");
2600
- const request = validateExec(input);
2601
- if (!Array.isArray(input) && "deadlineSeconds" in input && input.deadlineSeconds !== undefined)
2697
+ const object = Array.isArray(input) || !("command" in input) ? undefined : input;
2698
+ const streamed = streamedStdin(object?.stdin);
2699
+ const request = validateExec(streamed && object ? { ...object, stdin: undefined } : input);
2700
+ const deadlineSeconds = object?.deadlineSeconds;
2701
+ const localDeadline = streamed ? deadlineSeconds ?? request.deadlineSeconds : undefined;
2702
+ if (!streamed && deadlineSeconds !== undefined)
2602
2703
  throw new BeachsideError("UNSUPPORTED", "Callback execution cannot map deadlineSeconds on the process transport; use signal to bound local observation");
2704
+ if (streamed && client.session.processes?.supports?.stdin !== "bytes")
2705
+ throw new BeachsideError("UNSUPPORTED", "Streamed stdin and stdin over 1 MiB need incremental process stdin, which this adapter lacks");
2603
2706
  const maxOutputBytes = client.session.supports.exec?.maxOutputBytes;
2604
2707
  if (maxOutputBytes !== undefined && request.maxOutputBytes > maxOutputBytes)
2605
2708
  throw new BeachsideError("UNSUPPORTED", "Requested execution output limit is unsupported");
@@ -2610,7 +2713,7 @@ async function callbackExec(client, sandbox, controlActive, input, options) {
2610
2713
  cwd: request.cwd,
2611
2714
  env: request.env,
2612
2715
  output: { mode: "stream" },
2613
- stdin: request.stdin === undefined ? "closed" : "pipe"
2716
+ stdin: request.stdin === undefined && !streamed ? "closed" : "pipe"
2614
2717
  }, options, controlActive, { maxBytes: request.maxOutputBytes });
2615
2718
  const observation = new AbortController;
2616
2719
  const signal = AbortSignal.any([
@@ -2654,20 +2757,58 @@ async function callbackExec(client, sandbox, controlActive, input, options) {
2654
2757
  await raceAbort(Promise.resolve().then(invoke), signal);
2655
2758
  }
2656
2759
  })().catch(stop);
2760
+ const source = streamed ?? (request.stdin === undefined ? undefined : (() => {
2761
+ let bytes = request.stdin;
2762
+ return {
2763
+ async next() {
2764
+ const chunk = bytes;
2765
+ bytes = null;
2766
+ return chunk;
2767
+ },
2768
+ cancel() {
2769
+ bytes = null;
2770
+ }
2771
+ };
2772
+ })());
2773
+ let delivered = false;
2657
2774
  const delivery = (async () => {
2658
- if (request.stdin !== undefined) {
2659
- for (let offset = 0;offset < request.stdin.length; offset += 65536) {
2775
+ if (source === undefined)
2776
+ return;
2777
+ for (let chunk = await source.next();chunk; chunk = await source.next())
2778
+ for (let offset = 0;offset < chunk.length; offset += 65536) {
2660
2779
  if (signal.aborted)
2661
2780
  throw signal.reason;
2662
- await process.write(request.stdin.subarray(offset, offset + 65536), { signal });
2781
+ if (streamed && exit)
2782
+ return;
2783
+ await process.write(chunk.subarray(offset, offset + 65536), { signal });
2663
2784
  }
2664
- if (signal.aborted)
2665
- throw signal.reason;
2666
- await process.closeStdin({ signal });
2667
- }
2668
- })().catch(stop);
2785
+ if (signal.aborted)
2786
+ throw signal.reason;
2787
+ delivered = true;
2788
+ await process.closeStdin({ signal });
2789
+ })().then(() => {
2790
+ return;
2791
+ }, (error) => {
2792
+ if (streamed && exit)
2793
+ return;
2794
+ stop(error);
2795
+ });
2796
+ const deadline = localDeadline === undefined ? undefined : setTimeout(() => {
2797
+ initiatingFailure ??= {
2798
+ error: new BeachsideError("TIMEOUT", `Execution exceeded deadlineSeconds (${localDeadline}); termination was requested`, "possible")
2799
+ };
2800
+ observation.abort();
2801
+ process.terminate({ signal: AbortSignal.timeout(30000) }).catch(() => {
2802
+ return;
2803
+ });
2804
+ }, localDeadline * 1000);
2669
2805
  try {
2670
- await Promise.all([delivery, output, waiting, raceAbort(capture, signal)]);
2806
+ await Promise.all([
2807
+ streamed ? Promise.race([delivery, waiting]) : delivery,
2808
+ output,
2809
+ waiting,
2810
+ raceAbort(capture, signal)
2811
+ ]);
2671
2812
  if (captured.exitCode !== exit.exitCode)
2672
2813
  throw new BeachsideError("INVALID_RESPONSE", "Execution capture conflicts with confirmed exit", "possible");
2673
2814
  return checkExec(captured);
@@ -2691,6 +2832,9 @@ async function callbackExec(client, sandbox, controlActive, input, options) {
2691
2832
  context2.output = captured;
2692
2833
  throw context2;
2693
2834
  } finally {
2835
+ clearTimeout(deadline);
2836
+ if (!delivered)
2837
+ source?.cancel();
2694
2838
  await process.detach();
2695
2839
  }
2696
2840
  }
@@ -3292,7 +3436,7 @@ function fileOptions(options) {
3292
3436
  function fileReadLimit(maxBytes) {
3293
3437
  if (!Number.isSafeInteger(maxBytes) || maxBytes < 0)
3294
3438
  throw new BeachsideError("INVALID_ARGUMENT", "Adapter file limit is invalid", "none");
3295
- return Math.min(maxBytes, 1048576);
3439
+ return maxBytes;
3296
3440
  }
3297
3441
  function abortWaiting(ref, reason, outcome) {
3298
3442
  throw new WaitAbortedError(ref, reason, outcome ?? acknowledgedLifecycleOutcome(ref));
@@ -3948,10 +4092,13 @@ class AdapterSandbox {
3948
4092
  });
3949
4093
  }
3950
4094
  async exec(input, options = {}) {
3951
- if (options.onOutput !== undefined) {
4095
+ const streamed = !Array.isArray(input) && "command" in input && stdinNeedsStream(input.stdin);
4096
+ if (options.onOutput !== undefined || streamed) {
3952
4097
  this.client.ensureOpen();
3953
4098
  const control = processControl(this.client, this.id);
3954
- return callbackExec(this.client, sandboxInput(this.id, this.reference), () => control.active, input, options);
4099
+ return callbackExec(this.client, sandboxInput(this.id, this.reference), () => control.active, input, options.onOutput ? options : { ...options, onOutput: () => {
4100
+ return;
4101
+ } });
3955
4102
  }
3956
4103
  return waitFor(this.client.telemetry, await internalMethod(this.submitExec)(input, options), options);
3957
4104
  }
@@ -4140,12 +4287,38 @@ class AdapterSandbox {
4140
4287
  }
4141
4288
  async readFile(path, options = {}) {
4142
4289
  this.client.ensureOpen();
4143
- if (!this.client.session.files?.read)
4290
+ const files = this.client.session.files;
4291
+ if (!files?.read)
4144
4292
  unsupported("readFile");
4145
4293
  validateFilePath(path);
4146
- const maxBytes = bufferedLimit(options.maxBytes, this.client.session.files.maxBytes);
4147
- const read = this.client.session.files.read.bind(this.client.session.files);
4148
- return readFileBytes((context2) => read({ sandbox: sandboxInput(this.id, this.reference), path, maxBytes }, context2), maxBytes, this.client.signal, options);
4294
+ const guard = byteLimit(options.maxBytes);
4295
+ const maxBytes = bufferedLimit(guard, files.maxBytes);
4296
+ const read = files.read.bind(files);
4297
+ try {
4298
+ return await readFileBytes((context2) => read({ sandbox: sandboxInput(this.id, this.reference), path, maxBytes }, context2), maxBytes, this.client.signal, options);
4299
+ } catch (error) {
4300
+ const adapterBound = guard === undefined || guard > files.maxBytes;
4301
+ if (!(error instanceof BeachsideError) || error.code !== "OUTPUT_CAPACITY" || !adapterBound)
4302
+ throw error;
4303
+ if (!files.readStream)
4304
+ throw adapterFileLimit(files.maxBytes, "OUTPUT_CAPACITY");
4305
+ }
4306
+ const chunks = [];
4307
+ let total = 0;
4308
+ for await (const chunk of this.readFileStream(path, {
4309
+ signal: options.signal,
4310
+ maxBytes: guard
4311
+ })) {
4312
+ chunks.push(chunk);
4313
+ total += chunk.byteLength;
4314
+ }
4315
+ const bytes = new Uint8Array(total);
4316
+ let offset = 0;
4317
+ for (const chunk of chunks) {
4318
+ bytes.set(chunk, offset);
4319
+ offset += chunk.byteLength;
4320
+ }
4321
+ return bytes;
4149
4322
  }
4150
4323
  async writeFile(path, bytes, options = {}) {
4151
4324
  if (!this.supports("writeFile"))
@@ -4153,10 +4326,13 @@ class AdapterSandbox {
4153
4326
  validateFilePath(path);
4154
4327
  if (!(bytes instanceof Uint8Array))
4155
4328
  throw new BeachsideError("INVALID_ARGUMENT", "Expected byte buffer");
4156
- const limit2 = bufferedLimit(options.maxBytes, this.client.session.files.maxBytes);
4157
- if (bytes.length > limit2)
4329
+ const files = this.client.session.files;
4330
+ const guard = byteLimit(options.maxBytes);
4331
+ if (guard !== undefined && bytes.length > guard)
4158
4332
  throw new BeachsideError("CAPACITY", "File exceeds byte limit");
4159
- if (bytes.length > 1048576 && this.client.session.files?.writeStream) {
4333
+ if (bytes.length > files.maxBytes && !files.writeStream)
4334
+ throw adapterFileLimit(files.maxBytes, "CAPACITY");
4335
+ if ((bytes.length > 1048576 || bytes.length > files.maxBytes) && files.writeStream) {
4160
4336
  const payload2 = Uint8Array.from(bytes);
4161
4337
  async function* chunks() {
4162
4338
  yield payload2;
@@ -5030,6 +5206,8 @@ class AdapterDirectClient {
5030
5206
  }
5031
5207
  }
5032
5208
  async function connectDirect(options, observability = {}) {
5209
+ if (options instanceof Function || "adapter" in options && options.adapter instanceof Function)
5210
+ throw new BeachsideError("INVALID_ARGUMENT", "Expected an adapter definition, got a function: pass the definition (`adapter: vercelAdapter`) or call the provider factory (`Beachside.connect(vercel({ ... }))`)", "none");
5033
5211
  const cleanup = z8.strictObject({ storage: z8.enum(["require-durable", "allow-unconfirmed"]).optional() }).optional().safeParse(("bound" in options ? observability : options).cleanup);
5034
5212
  if (!cleanup.success)
5035
5213
  throw new BeachsideError("INVALID_ARGUMENT", "Invalid cleanup configuration", "none");
@@ -58,12 +58,31 @@ export type ExecInput = {
58
58
  command: ExecCommand;
59
59
  cwd?: string;
60
60
  env?: Record<string, string>;
61
- /** Finite stdin bytes; strings encode as UTF-8 and supplied input ends with guest EOF. */
62
- stdin?: string | Uint8Array;
61
+ /**
62
+ * Command input, ending with guest EOF. Strings encode as UTF-8. A stream (`AsyncIterable` or
63
+ * `ReadableStream` of bytes) is sent as it arrives, with no size limit, while the command runs;
64
+ * streams and input over 1 MiB need an adapter with incremental process stdin.
65
+ */
66
+ stdin?: string | Uint8Array | ExecStdinStream;
63
67
  /** Provider-specific execution/observation limit (default 300), not a total wait budget. Use the call signal to bound local waiting. */
64
68
  deadlineSeconds?: number;
65
69
  maxOutputBytes?: number;
66
70
  };
71
+ /** Streamed command input: any async iterable or web stream of byte chunks. */
72
+ export type ExecStdinStream = AsyncIterable<Uint8Array> | ReadableStream<Uint8Array>;
73
+ export declare function isStdinStream(value: ExecInput["stdin"]): value is ExecStdinStream;
74
+ /** Whether stdin must travel incrementally: a stream, or bytes or text over the finite bound. */
75
+ export declare function stdinNeedsStream(stdin: ExecInput["stdin"]): boolean;
76
+ /**
77
+ * Input that must travel incrementally, read one chunk at a time. `cancel` stops the source when
78
+ * the command no longer needs it, releasing a web stream's reader even while a read is pending.
79
+ */
80
+ export type StdinSource = {
81
+ next(): Promise<Uint8Array | null>;
82
+ cancel(): void;
83
+ };
84
+ /** The streamed source for `stdin`, or undefined for finite input that fits the bound. */
85
+ export declare function streamedStdin(stdin: ExecInput["stdin"]): StdinSource | undefined;
67
86
  export type ValidatedExecInput = Required<Pick<ExecInput, "command" | "deadlineSeconds" | "maxOutputBytes">> & Omit<ExecInput, "stdin"> & {
68
87
  stdin?: Uint8Array;
69
88
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beachside",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "files": [
@@ -19,14 +19,14 @@
19
19
  "build": "rm -rf dist && bun build src/index.ts --target node --format esm --splitting --outdir dist --external @beachside/adapter --external zod --external @opentelemetry/api && tsc -p tsconfig.json --noEmit false --declaration --emitDeclarationOnly --outDir dist && bun ../../scripts/rewrite-declarations.mjs"
20
20
  },
21
21
  "dependencies": {
22
- "@beachside/adapter": "0.8.0",
22
+ "@beachside/adapter": "0.9.0",
23
23
  "zod": "4.6.5",
24
24
  "@opentelemetry/api": "1.9.1"
25
25
  },
26
26
  "devDependencies": {
27
27
  "@beachside-internal/provider-fake": "0.0.0",
28
- "@beachside/daytona": "0.8.0",
29
- "@beachside/e2b": "0.8.0"
28
+ "@beachside/daytona": "0.9.0",
29
+ "@beachside/e2b": "0.9.0"
30
30
  },
31
31
  "license": "Apache-2.0",
32
32
  "repository": {