@cloudflare/sandbox 0.10.3 → 0.12.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.
@@ -1,81 +1,8 @@
1
- import { Container } from "@cloudflare/containers";
1
+ import { Container, ContainerProxy } from "@cloudflare/containers";
2
2
  import "capnweb";
3
3
 
4
- //#region ../shared/dist/desktop-types.d.ts
5
-
6
- interface DesktopStartResult {
7
- success: boolean;
8
- resolution: [number, number];
9
- dpi: number;
10
- }
11
- interface DesktopStopResult {
12
- success: boolean;
13
- }
14
- interface DesktopStatusResult {
15
- success: boolean;
16
- status: 'active' | 'partial' | 'inactive';
17
- processes: Record<string, DesktopProcessHealth>;
18
- resolution: [number, number] | null;
19
- dpi: number | null;
20
- }
21
- interface DesktopProcessHealth {
22
- running: boolean;
23
- pid?: number;
24
- uptime?: number;
25
- }
26
- type DesktopImageFormat = 'png' | 'jpeg' | 'webp';
27
- interface DesktopScreenshotOptions {
28
- /**
29
- * How the SDK returns the screenshot payload to the caller.
30
- * - `'base64'` (default): `data` is a base64-encoded string (also the wire format).
31
- * - `'bytes'`: client-side convenience that base64-decodes the wire payload
32
- * into a `Uint8Array` before returning. The wire/server contract is
33
- * always base64.
34
- */
35
- format?: 'base64' | 'bytes';
36
- imageFormat?: DesktopImageFormat;
37
- quality?: number;
38
- showCursor?: boolean;
39
- }
40
- interface DesktopScreenshotRegion {
41
- x: number;
42
- y: number;
43
- width: number;
44
- height: number;
45
- }
46
- /**
47
- * Screenshot payload returned to the SDK caller when `format` is `'base64'`
48
- * (the default). Matches the wire shape sent by the container.
49
- */
50
- interface DesktopScreenshotResult {
51
- success: boolean;
52
- data: string;
53
- imageFormat: DesktopImageFormat;
54
- width: number;
55
- height: number;
56
- }
57
- /**
58
- * Screenshot payload returned to the SDK caller when `format: 'bytes'` is
59
- * requested. The SDK client decodes the base64 wire payload into a
60
- * `Uint8Array`; the server/wire contract is unchanged.
61
- */
62
- interface DesktopScreenshotBytesResult extends Omit<DesktopScreenshotResult, 'data'> {
63
- data: Uint8Array;
64
- }
65
- type DesktopMouseButton = 'left' | 'right' | 'middle';
66
- type DesktopScrollDirection = 'up' | 'down' | 'left' | 'right';
67
- interface DesktopCursorPosition {
68
- success: boolean;
69
- x: number;
70
- y: number;
71
- }
72
- interface DesktopScreenSize {
73
- success: boolean;
74
- width: number;
75
- height: number;
76
- }
77
- //#endregion
78
4
  //#region ../shared/dist/logger/types.d.ts
5
+
79
6
  type LogComponent = 'container' | 'sandbox-do' | 'executor';
80
7
  /**
81
8
  * Context metadata included in every log entry
@@ -1200,26 +1127,6 @@ interface SessionDeleteResult {
1200
1127
  sessionId: string;
1201
1128
  timestamp: string;
1202
1129
  }
1203
- interface PortExposeResult {
1204
- success: boolean;
1205
- port: number;
1206
- url: string;
1207
- timestamp: string;
1208
- }
1209
- interface PortListResult {
1210
- success: boolean;
1211
- ports: Array<{
1212
- port: number;
1213
- url: string;
1214
- status: 'active' | 'inactive';
1215
- }>;
1216
- timestamp: string;
1217
- }
1218
- interface PortCloseResult {
1219
- success: boolean;
1220
- port: number;
1221
- timestamp: string;
1222
- }
1223
1130
  interface ExecutionSession {
1224
1131
  /** Unique session identifier */
1225
1132
  readonly id: string;
@@ -1411,6 +1318,15 @@ interface RemoteMountBucketOptions {
1411
1318
  * Must start with '/' (e.g., '/workspaces/project123' or '/data/uploads/')
1412
1319
  */
1413
1320
  prefix?: string;
1321
+ /**
1322
+ * Keep real credentials in the Durable Object; write dummy credentials into
1323
+ * the container-side s3fs password file. Outbound s3fs requests are
1324
+ * intercepted by the DO, signed with real credentials, and forwarded to the
1325
+ * configured endpoint.
1326
+ *
1327
+ * Default: false (real credentials are written into the container)
1328
+ */
1329
+ credentialProxy?: boolean;
1414
1330
  }
1415
1331
  /**
1416
1332
  * Options for mounting a local R2 binding via bidirectional sync (local dev)
@@ -1571,13 +1487,6 @@ interface StartProcessRequest {
1571
1487
  autoCleanup?: boolean;
1572
1488
  origin?: 'user' | 'internal';
1573
1489
  }
1574
- /**
1575
- * Request to expose a port
1576
- */
1577
- interface ExposePortRequest {
1578
- port: number;
1579
- name?: string;
1580
- }
1581
1490
  /**
1582
1491
  * Request to create a backup archive from a directory.
1583
1492
  * The container creates a squashfs archive at archivePath.
@@ -1715,9 +1624,6 @@ interface SandboxProcessesAPI {
1715
1624
  streamProcessLogs(id: string): Promise<ReadableStream<Uint8Array>>;
1716
1625
  }
1717
1626
  interface SandboxPortsAPI {
1718
- exposePort(port: number, sessionId: string, name?: string): Promise<PortExposeResult>;
1719
- getExposedPorts(sessionId: string): Promise<PortListResult>;
1720
- unexposePort(port: number, sessionId: string): Promise<PortCloseResult>;
1721
1627
  watchPort(request: PortWatchRequest): Promise<ReadableStream<Uint8Array>>;
1722
1628
  }
1723
1629
  interface SandboxGitAPI {
@@ -1782,81 +1688,66 @@ interface SandboxBackupAPI {
1782
1688
  sessionId?: string;
1783
1689
  }): Promise<UploadPartsResponse>;
1784
1690
  }
1785
- interface SandboxDesktopAPI {
1786
- start(options?: {
1787
- resolution?: [number, number];
1788
- dpi?: number;
1789
- }): Promise<DesktopStartResult>;
1790
- stop(): Promise<DesktopStopResult>;
1791
- status(): Promise<DesktopStatusResult>;
1792
- screenshot(options?: DesktopScreenshotOptions & {
1793
- format?: 'base64';
1794
- }): Promise<DesktopScreenshotResult>;
1795
- screenshot(options: DesktopScreenshotOptions & {
1796
- format: 'bytes';
1797
- }): Promise<DesktopScreenshotBytesResult>;
1798
- screenshot(options?: DesktopScreenshotOptions): Promise<DesktopScreenshotResult | DesktopScreenshotBytesResult>;
1799
- screenshotRegion(region: DesktopScreenshotRegion, options?: DesktopScreenshotOptions & {
1800
- format?: 'base64';
1801
- }): Promise<DesktopScreenshotResult>;
1802
- screenshotRegion(region: DesktopScreenshotRegion, options: DesktopScreenshotOptions & {
1803
- format: 'bytes';
1804
- }): Promise<DesktopScreenshotBytesResult>;
1805
- screenshotRegion(region: DesktopScreenshotRegion, options?: DesktopScreenshotOptions): Promise<DesktopScreenshotResult | DesktopScreenshotBytesResult>;
1806
- click(x: number, y: number, options?: {
1807
- button?: DesktopMouseButton;
1808
- clickCount?: number;
1809
- }): Promise<void>;
1810
- doubleClick(x: number, y: number): Promise<void>;
1811
- tripleClick(x: number, y: number): Promise<void>;
1812
- rightClick(x: number, y: number): Promise<void>;
1813
- middleClick(x: number, y: number): Promise<void>;
1814
- mouseDown(x?: number, y?: number, options?: {
1815
- button?: DesktopMouseButton;
1816
- }): Promise<void>;
1817
- mouseUp(x?: number, y?: number, options?: {
1818
- button?: DesktopMouseButton;
1819
- }): Promise<void>;
1820
- moveMouse(x: number, y: number): Promise<void>;
1821
- drag(startX: number, startY: number, endX: number, endY: number, options?: {
1822
- button?: DesktopMouseButton;
1823
- }): Promise<void>;
1824
- scroll(x: number, y: number, direction: DesktopScrollDirection, amount?: number): Promise<void>;
1825
- getCursorPosition(): Promise<DesktopCursorPosition>;
1826
- type(text: string, options?: {
1827
- delayMs?: number;
1828
- }): Promise<void>;
1829
- press(key: string): Promise<void>;
1830
- keyDown(key: string): Promise<void>;
1831
- keyUp(key: string): Promise<void>;
1832
- getScreenSize(): Promise<DesktopScreenSize>;
1833
- getProcessStatus(name: string): Promise<DesktopProcessHealth>;
1834
- }
1835
1691
  interface SandboxWatchAPI {
1836
1692
  watch(request: WatchRequest): Promise<ReadableStream<Uint8Array>>;
1837
1693
  checkChanges(request: CheckChangesRequest): Promise<CheckChangesResult>;
1838
1694
  }
1839
1695
  /**
1840
- * Public-facing tunnel record.
1841
- *
1842
- * Today only quick tunnels (`*.trycloudflare.com`) are supported. Future
1843
- * PRs will add named tunnels, which will carry a `name: string` field;
1844
- * `TunnelInfo` will then become a discriminated union keyed on the
1845
- * presence of `name`. The quick variant declares `name?: never` so the
1846
- * narrowing works without a breaking change here.
1696
+ * Public-facing tunnel record. Discriminated on the presence of `name`:
1697
+ * quick tunnels (`*.trycloudflare.com`) omit it, named tunnels carry the
1698
+ * label that was passed to `get(port, { name })`.
1847
1699
  */
1848
- interface TunnelInfo {
1700
+ type TunnelInfo = QuickTunnelInfo | NamedTunnelInfo;
1701
+ interface QuickTunnelInfo {
1849
1702
  id: string;
1850
1703
  port: number;
1704
+ /** `https://<random>.trycloudflare.com`. */
1851
1705
  url: string;
1706
+ /** Hostname portion of `url`. */
1852
1707
  hostname: string;
1853
1708
  createdAt: string;
1854
- /** Reserved for the named-tunnel variant in a future PR. */
1709
+ /** Absent on quick tunnels; narrows the union. */
1855
1710
  name?: never;
1856
1711
  }
1712
+ interface NamedTunnelInfo {
1713
+ /** Cloudflare tunnel UUID (8-4-4-4-12). */
1714
+ id: string;
1715
+ port: number;
1716
+ /** `https://<hostname>`. */
1717
+ url: string;
1718
+ /** Full hostname bound to the tunnel (without scheme). */
1719
+ hostname: string;
1720
+ createdAt: string;
1721
+ /** Label originally passed via `TunnelOptions.name`. */
1722
+ name: string;
1723
+ }
1724
+ /**
1725
+ * Options accepted by `sandbox.tunnels.get(port, options)`. Omitting
1726
+ * `name` (or omitting the options object) selects the zero-config quick
1727
+ * tunnel; setting `name` selects the named-tunnel flow.
1728
+ */
1729
+ interface TunnelOptions {
1730
+ /**
1731
+ * Single DNS label under the configured zone. The full hostname is
1732
+ * `<name>.<zone-name>`. See `validateTunnelName` for the format rules.
1733
+ */
1734
+ name?: string;
1735
+ }
1857
1736
  interface SandboxTunnelsAPI {
1858
1737
  /** Spawn `cloudflared tunnel --url`. No credentials required. */
1859
1738
  runQuickTunnel(id: string, port: number): Promise<TunnelInfo>;
1739
+ /**
1740
+ * Spawn `cloudflared tunnel run --token <token> --url http://localhost:<port>`.
1741
+ *
1742
+ * The SDK is the source of truth for the hostname this tunnel binds to;
1743
+ * the container only sees the opaque token and the local port. The
1744
+ * returned `TunnelInfo` carries empty `url`/`hostname` fields — the SDK
1745
+ * enriches them with the values from the Cloudflare API before handing
1746
+ * the record to user code.
1747
+ *
1748
+ * The token must never be logged, persisted, or echoed back to callers.
1749
+ */
1750
+ runNamedTunnel(id: string, token: string, port: number): Promise<TunnelInfo>;
1860
1751
  /** Stop the cloudflared process for the given tunnel id. */
1861
1752
  destroyTunnel(id: string): Promise<{
1862
1753
  success: true;
@@ -2135,217 +2026,6 @@ declare class CommandClient extends BaseHttpClient implements SandboxCommandsAPI
2135
2026
  }): Promise<ReadableStream<Uint8Array>>;
2136
2027
  }
2137
2028
  //#endregion
2138
- //#region src/clients/desktop-client.d.ts
2139
- interface DesktopStartOptions {
2140
- resolution?: [number, number];
2141
- dpi?: number;
2142
- }
2143
- interface ScreenshotOptions {
2144
- format?: 'base64' | 'bytes';
2145
- imageFormat?: 'png' | 'jpeg' | 'webp';
2146
- quality?: number;
2147
- showCursor?: boolean;
2148
- }
2149
- interface ScreenshotRegion {
2150
- x: number;
2151
- y: number;
2152
- width: number;
2153
- height: number;
2154
- }
2155
- interface ClickOptions {
2156
- button?: 'left' | 'right' | 'middle';
2157
- }
2158
- type ScrollDirection = 'up' | 'down' | 'left' | 'right';
2159
- type KeyInput = string;
2160
- interface TypeOptions {
2161
- delayMs?: number;
2162
- }
2163
- interface DesktopStartResponse extends BaseApiResponse {
2164
- resolution: [number, number];
2165
- dpi: number;
2166
- }
2167
- interface DesktopStopResponse extends BaseApiResponse {}
2168
- interface DesktopStatusResponse extends BaseApiResponse {
2169
- status: 'active' | 'partial' | 'inactive';
2170
- processes: Record<string, {
2171
- running: boolean;
2172
- pid?: number;
2173
- uptime?: number;
2174
- }>;
2175
- resolution: [number, number] | null;
2176
- dpi: number | null;
2177
- }
2178
- interface ScreenshotResponse extends BaseApiResponse {
2179
- data: string;
2180
- imageFormat: 'png' | 'jpeg' | 'webp';
2181
- width: number;
2182
- height: number;
2183
- }
2184
- interface ScreenshotBytesResponse extends BaseApiResponse {
2185
- data: Uint8Array;
2186
- imageFormat: 'png' | 'jpeg' | 'webp';
2187
- width: number;
2188
- height: number;
2189
- }
2190
- interface CursorPositionResponse extends BaseApiResponse {
2191
- x: number;
2192
- y: number;
2193
- }
2194
- interface ScreenSizeResponse extends BaseApiResponse {
2195
- width: number;
2196
- height: number;
2197
- }
2198
- /**
2199
- * Public interface for desktop operations.
2200
- * Returned by `sandbox.desktop` via an RpcTarget wrapper so that pipelined
2201
- * method calls work across the Durable Object RPC boundary.
2202
- */
2203
- interface Desktop {
2204
- start(options?: DesktopStartOptions): Promise<DesktopStartResponse>;
2205
- stop(): Promise<DesktopStopResponse>;
2206
- status(): Promise<DesktopStatusResponse>;
2207
- screenshot(options?: ScreenshotOptions & {
2208
- format?: 'base64';
2209
- }): Promise<ScreenshotResponse>;
2210
- screenshot(options: ScreenshotOptions & {
2211
- format: 'bytes';
2212
- }): Promise<ScreenshotBytesResponse>;
2213
- screenshot(options?: ScreenshotOptions): Promise<ScreenshotResponse | ScreenshotBytesResponse>;
2214
- screenshotRegion(region: ScreenshotRegion, options?: ScreenshotOptions & {
2215
- format?: 'base64';
2216
- }): Promise<ScreenshotResponse>;
2217
- screenshotRegion(region: ScreenshotRegion, options: ScreenshotOptions & {
2218
- format: 'bytes';
2219
- }): Promise<ScreenshotBytesResponse>;
2220
- screenshotRegion(region: ScreenshotRegion, options?: ScreenshotOptions): Promise<ScreenshotResponse | ScreenshotBytesResponse>;
2221
- click(x: number, y: number, options?: ClickOptions): Promise<void>;
2222
- doubleClick(x: number, y: number, options?: ClickOptions): Promise<void>;
2223
- tripleClick(x: number, y: number, options?: ClickOptions): Promise<void>;
2224
- rightClick(x: number, y: number): Promise<void>;
2225
- middleClick(x: number, y: number): Promise<void>;
2226
- mouseDown(x?: number, y?: number, options?: ClickOptions): Promise<void>;
2227
- mouseUp(x?: number, y?: number, options?: ClickOptions): Promise<void>;
2228
- moveMouse(x: number, y: number): Promise<void>;
2229
- drag(startX: number, startY: number, endX: number, endY: number, options?: ClickOptions): Promise<void>;
2230
- scroll(x: number, y: number, direction: ScrollDirection, amount?: number): Promise<void>;
2231
- getCursorPosition(): Promise<CursorPositionResponse>;
2232
- type(text: string, options?: TypeOptions): Promise<void>;
2233
- press(key: KeyInput): Promise<void>;
2234
- keyDown(key: KeyInput): Promise<void>;
2235
- keyUp(key: KeyInput): Promise<void>;
2236
- getScreenSize(): Promise<ScreenSizeResponse>;
2237
- getProcessStatus(name: string): Promise<DesktopProcessHealth>;
2238
- }
2239
- /**
2240
- * Client for desktop environment lifecycle, input, and screen operations
2241
- */
2242
- declare class DesktopClient extends BaseHttpClient implements SandboxDesktopAPI {
2243
- /**
2244
- * Start the desktop environment with optional resolution and DPI.
2245
- */
2246
- start(options?: DesktopStartOptions): Promise<DesktopStartResponse>;
2247
- /**
2248
- * Stop the desktop environment and all related processes.
2249
- */
2250
- stop(): Promise<DesktopStopResponse>;
2251
- /**
2252
- * Get desktop lifecycle and process health status.
2253
- */
2254
- status(): Promise<DesktopStatusResponse>;
2255
- /**
2256
- * Capture a full-screen screenshot as base64 (default).
2257
- */
2258
- screenshot(options?: ScreenshotOptions & {
2259
- format?: 'base64';
2260
- }): Promise<ScreenshotResponse>;
2261
- /**
2262
- * Capture a full-screen screenshot as bytes.
2263
- */
2264
- screenshot(options: ScreenshotOptions & {
2265
- format: 'bytes';
2266
- }): Promise<ScreenshotBytesResponse>;
2267
- /**
2268
- * Capture a region screenshot as base64 (default).
2269
- */
2270
- screenshotRegion(region: ScreenshotRegion, options?: ScreenshotOptions & {
2271
- format?: 'base64';
2272
- }): Promise<ScreenshotResponse>;
2273
- /**
2274
- * Capture a region screenshot as bytes.
2275
- */
2276
- screenshotRegion(region: ScreenshotRegion, options: ScreenshotOptions & {
2277
- format: 'bytes';
2278
- }): Promise<ScreenshotBytesResponse>;
2279
- /**
2280
- * Single-click at the given coordinates.
2281
- */
2282
- click(x: number, y: number, options?: ClickOptions): Promise<void>;
2283
- /**
2284
- * Double-click at the given coordinates.
2285
- */
2286
- doubleClick(x: number, y: number, options?: ClickOptions): Promise<void>;
2287
- /**
2288
- * Triple-click at the given coordinates.
2289
- */
2290
- tripleClick(x: number, y: number, options?: ClickOptions): Promise<void>;
2291
- /**
2292
- * Right-click at the given coordinates.
2293
- */
2294
- rightClick(x: number, y: number): Promise<void>;
2295
- /**
2296
- * Middle-click at the given coordinates.
2297
- */
2298
- middleClick(x: number, y: number): Promise<void>;
2299
- /**
2300
- * Press and hold a mouse button.
2301
- */
2302
- mouseDown(x?: number, y?: number, options?: ClickOptions): Promise<void>;
2303
- /**
2304
- * Release a held mouse button.
2305
- */
2306
- mouseUp(x?: number, y?: number, options?: ClickOptions): Promise<void>;
2307
- /**
2308
- * Move the mouse cursor to coordinates.
2309
- */
2310
- moveMouse(x: number, y: number): Promise<void>;
2311
- /**
2312
- * Drag from start coordinates to end coordinates.
2313
- */
2314
- drag(startX: number, startY: number, endX: number, endY: number, options?: ClickOptions): Promise<void>;
2315
- /**
2316
- * Scroll at coordinates in the specified direction.
2317
- */
2318
- scroll(x: number, y: number, direction: ScrollDirection, amount?: number): Promise<void>;
2319
- /**
2320
- * Get the current cursor coordinates.
2321
- */
2322
- getCursorPosition(): Promise<CursorPositionResponse>;
2323
- /**
2324
- * Type text into the focused element.
2325
- */
2326
- type(text: string, options?: TypeOptions): Promise<void>;
2327
- /**
2328
- * Press and release a key or key combination.
2329
- */
2330
- press(key: KeyInput): Promise<void>;
2331
- /**
2332
- * Press and hold a key.
2333
- */
2334
- keyDown(key: KeyInput): Promise<void>;
2335
- /**
2336
- * Release a held key.
2337
- */
2338
- keyUp(key: KeyInput): Promise<void>;
2339
- /**
2340
- * Get the active desktop screen size.
2341
- */
2342
- getScreenSize(): Promise<ScreenSizeResponse>;
2343
- /**
2344
- * Get health status for a specific desktop process.
2345
- */
2346
- getProcessStatus(name: string): Promise<DesktopProcessHealth>;
2347
- }
2348
- //#endregion
2349
2029
  //#region src/clients/file-client.d.ts
2350
2030
  /**
2351
2031
  * Request interface for creating directories
@@ -2534,33 +2214,9 @@ declare class InterpreterClient extends BaseHttpClient implements SandboxInterpr
2534
2214
  //#endregion
2535
2215
  //#region src/clients/port-client.d.ts
2536
2216
  /**
2537
- * Request interface for unexposing ports
2538
- */
2539
- interface UnexposePortRequest {
2540
- port: number;
2541
- }
2542
- /**
2543
- * Client for port management and preview URL operations
2217
+ * Client for port readiness operations.
2544
2218
  */
2545
- declare class PortClient extends BaseHttpClient implements SandboxPortsAPI {
2546
- /**
2547
- * Expose a port and get a preview URL
2548
- * @param port - Port number to expose
2549
- * @param sessionId - The session ID for this operation
2550
- * @param name - Optional name for the port
2551
- */
2552
- exposePort(port: number, sessionId: string, name?: string): Promise<PortExposeResult>;
2553
- /**
2554
- * Unexpose a port and remove its preview URL
2555
- * @param port - Port number to unexpose
2556
- * @param sessionId - The session ID for this operation
2557
- */
2558
- unexposePort(port: number, sessionId: string): Promise<PortCloseResult>;
2559
- /**
2560
- * Get all currently exposed ports
2561
- * @param sessionId - The session ID for this operation
2562
- */
2563
- getExposedPorts(sessionId: string): Promise<PortListResult>;
2219
+ declare class PortClient extends BaseHttpClient {
2564
2220
  /**
2565
2221
  * Watch a port for readiness via SSE stream
2566
2222
  * @param request - Port watch configuration
@@ -2749,7 +2405,6 @@ declare class SandboxClient {
2749
2405
  readonly git: GitClient;
2750
2406
  readonly interpreter: InterpreterClient;
2751
2407
  readonly utils: UtilityClient;
2752
- readonly desktop: DesktopClient;
2753
2408
  readonly watch: WatchClient;
2754
2409
  /**
2755
2410
  * Tunnels are RPC-only — the route-based transport does not implement them.
@@ -2915,7 +2570,6 @@ declare class ContainerControlClient {
2915
2570
  get git(): SandboxGitAPI;
2916
2571
  get utils(): SandboxUtilsAPI;
2917
2572
  get backup(): SandboxBackupAPI;
2918
- get desktop(): SandboxDesktopAPI;
2919
2573
  get watch(): SandboxWatchAPI;
2920
2574
  get tunnels(): SandboxTunnelsAPI;
2921
2575
  get interpreter(): SandboxInterpreterAPI;
@@ -2933,7 +2587,7 @@ declare class ContainerControlClient {
2933
2587
  //#endregion
2934
2588
  //#region src/tunnels/tunnels-handler.d.ts
2935
2589
  interface TunnelsHandler {
2936
- get(port: number): Promise<TunnelInfo>;
2590
+ get(port: number, options?: TunnelOptions): Promise<TunnelInfo>;
2937
2591
  list(): Promise<TunnelInfo[]>;
2938
2592
  destroy(portOrInfo: number | TunnelInfo): Promise<void>;
2939
2593
  }
@@ -2949,6 +2603,18 @@ type SandboxConfiguration = {
2949
2603
  containerTimeouts?: NonNullable<SandboxOptions['containerTimeouts']>;
2950
2604
  transport?: SandboxTransport;
2951
2605
  };
2606
+ /**
2607
+ * SDK-level ContainerProxy that directly dispatches SDK-internal mount hosts
2608
+ * (r2.internal, s3-credential-proxy.internal) without relying on
2609
+ * outboundHandlersRegistry lookups, which are NOT shared between the Durable
2610
+ * Object's execution context and the ContainerProxy WorkerEntrypoint context.
2611
+ *
2612
+ * Users must export this class from their Worker entrypoint so the Sandbox DO
2613
+ * can create outbound-interception fetchers that reference it.
2614
+ */
2615
+ declare class ContainerProxy$1 extends ContainerProxy {
2616
+ fetch(request: Request): Promise<Response>;
2617
+ }
2952
2618
  declare function getSandbox<T extends Sandbox<any>>(ns: DurableObjectNamespace<T>, id: string, options?: SandboxOptions): T;
2953
2619
  declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox {
2954
2620
  defaultPort: number;
@@ -2958,6 +2624,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
2958
2624
  private sandboxName;
2959
2625
  private tunnelsHandler;
2960
2626
  private tunnelExitHandler;
2627
+ private destroyAllTunnels;
2961
2628
  private readonly controlCallback;
2962
2629
  private normalizeId;
2963
2630
  private defaultSession;
@@ -2967,6 +2634,8 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
2967
2634
  private logger;
2968
2635
  private keepAliveEnabled;
2969
2636
  private activeMounts;
2637
+ private mountOperationQueue;
2638
+ private currentRuntime;
2970
2639
  private transport;
2971
2640
  /**
2972
2641
  * True once transport has been written to storage at least once (either
@@ -2992,7 +2661,22 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
2992
2661
  private r2SecretAccessKey;
2993
2662
  private r2AccountId;
2994
2663
  private backupBucketName;
2664
+ private backupBucketEndpoint;
2995
2665
  private r2Client;
2666
+ /**
2667
+ * Lazily-resolved Cloudflare account id for named-tunnel provisioning.
2668
+ * Resolved on first access via `tunnels/credentials.ts` and cached for
2669
+ * the lifetime of this DO instance. See the credentials helper for
2670
+ * the precedence chain.
2671
+ */
2672
+ private tunnelAccountIdPromise;
2673
+ /**
2674
+ * Lazily-resolved Cloudflare zone id for named-tunnel provisioning.
2675
+ * Falls back to the single zone the token can see under the resolved
2676
+ * account id when `CLOUDFLARE_ZONE_ID` is not set. Cached for the
2677
+ * lifetime of this DO instance.
2678
+ */
2679
+ private tunnelZoneIdPromise;
2996
2680
  /**
2997
2681
  * Default container startup timeouts (conservative for production)
2998
2682
  * Based on Cloudflare docs: "Containers take several minutes to provision"
@@ -3012,25 +2696,6 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3012
2696
  * env/SDK defaults".
3013
2697
  */
3014
2698
  private hasStoredContainerTimeouts;
3015
- /**
3016
- * Desktop environment operations.
3017
- * Within the DO, this getter provides direct access to DesktopClient.
3018
- * Over RPC, the getSandbox() proxy intercepts this property and routes
3019
- * calls through callDesktop() instead.
3020
- */
3021
- get desktop(): Desktop;
3022
- /**
3023
- * Allowed desktop methods — derived from the Desktop interface.
3024
- * Restricts callDesktop() to a known set of operations.
3025
- */
3026
- private static readonly DESKTOP_METHODS;
3027
- /**
3028
- * Dispatch method for desktop operations.
3029
- * Called by the client-side proxy created in getSandbox() to provide
3030
- * the `sandbox.desktop.status()` API without relying on RPC pipelining
3031
- * through property getters which is broken when using vite-plugin.
3032
- */
3033
- callDesktop(method: string, args: unknown[]): Promise<unknown>;
3034
2699
  /**
3035
2700
  * Dispatch method for tunnel operations.
3036
2701
  * Called by the client-side proxy created in getSandbox() to provide
@@ -3083,12 +2748,16 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3083
2748
  * @throws InvalidMountConfigError if bucket name, mount path, or endpoint is invalid
3084
2749
  */
3085
2750
  mountBucket(bucket: string, mountPath: string, options: MountBucketOptions): Promise<void>;
2751
+ private runMountOperation;
2752
+ private mountBucketUnlocked;
3086
2753
  /**
3087
2754
  * Local dev mount: bidirectional sync via R2 binding + file/watch APIs
3088
2755
  */
3089
2756
  private mountBucketLocal;
3090
2757
  private getR2EgressParams;
3091
- private validateR2EgressS3fsOptions;
2758
+ private validateProtectedS3fsOptions;
2759
+ private getS3CredentialProxyParams;
2760
+ private resolveCredentialProxyAuthStrategy;
3092
2761
  /**
3093
2762
  * Credential-less R2 mount: egress interception routes s3fs requests to the
3094
2763
  * R2 binding. No S3 credentials are needed in the container or Worker env.
@@ -3105,6 +2774,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3105
2774
  * @throws InvalidMountConfigError if mount path doesn't exist or isn't mounted
3106
2775
  */
3107
2776
  unmountBucket(mountPath: string): Promise<void>;
2777
+ private unmountBucketUnlocked;
3108
2778
  /**
3109
2779
  * Shared validation for mount path (absolute, not already in use).
3110
2780
  */
@@ -3117,6 +2787,15 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3117
2787
  * Generate unique password file path for s3fs credentials
3118
2788
  */
3119
2789
  private generatePasswordFilePath;
2790
+ /**
2791
+ * Generate unique ahbe_conf file path for s3fs additional header config
2792
+ */
2793
+ private generateS3FSAdditionalHeaderFilePath;
2794
+ /**
2795
+ * Create s3fs ahbe_conf file that suppresses the Expect: 100-continue header.
2796
+ * Restricted to 0600 so s3fs will accept it (same requirement as passwd files).
2797
+ */
2798
+ private createDisableExpectHeaderFile;
3120
2799
  /**
3121
2800
  * Create password file with s3fs credentials
3122
2801
  * Format: bucket:accessKeyId:secretAccessKey
@@ -3126,6 +2805,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3126
2805
  * Delete password file
3127
2806
  */
3128
2807
  private deletePasswordFile;
2808
+ private deleteAdditionalHeaderFile;
3129
2809
  /**
3130
2810
  * Execute S3FS mount command
3131
2811
  */
@@ -3157,18 +2837,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3157
2837
  destroy(): Promise<void>;
3158
2838
  private doDestroy;
3159
2839
  onStart(): Promise<void>;
3160
- /**
3161
- * Re-expose ports on the container runtime using tokens persisted in DO
3162
- * storage. Called from onStart() after a container (re)start.
3163
- *
3164
- * The DO storage holds the source of truth for which ports should be
3165
- * exposed, which tokens authorize them, and the friendly name (if any)
3166
- * that the caller set when first exposing the port. If a port is already
3167
- * exposed on the container this is a no-op for that port. Individual port
3168
- * failures are logged but do not abort the overall restore — a transient
3169
- * failure for one port must not prevent the others from being restored.
3170
- */
3171
- private restoreExposedPorts;
2840
+ stop(signal?: Parameters<Container<Env>['stop']>[0]): Promise<void>;
3172
2841
  /**
3173
2842
  * Read the `portTokens` map from DO storage, normalizing the legacy
3174
2843
  * string-valued format (just a token) to the current object format
@@ -3176,6 +2845,10 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3176
2845
  * can appear on any DO whose storage was written before that change.
3177
2846
  */
3178
2847
  private readPortTokens;
2848
+ private readActivePreviewPorts;
2849
+ private writeActivePreviewPorts;
2850
+ private readPreviewState;
2851
+ private clearActivePreviewPorts;
3179
2852
  /**
3180
2853
  * Check if the container version matches the SDK version
3181
2854
  * Logs a warning if there's a mismatch
@@ -3230,6 +2903,14 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3230
2903
  * When keepAlive is disabled, calls parent implementation which stops the container
3231
2904
  */
3232
2905
  onActivityExpired(): Promise<void>;
2906
+ private isPreviewProxyRequest;
2907
+ private invalidPreviewTokenResponse;
2908
+ private stalePreviewURLResponse;
2909
+ private getPreviewForwardingContainer;
2910
+ private beginPreviewForward;
2911
+ private fetchPreviewIfRunning;
2912
+ private buildPreviewProxyRequest;
2913
+ private proxyPreviewRequest;
3233
2914
  fetch(request: Request): Promise<Response>;
3234
2915
  wsConnect(request: Request, port: number): Promise<Response>;
3235
2916
  private determinePort;
@@ -3403,23 +3084,6 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3403
3084
  }): Promise<ReadableStream<Uint8Array>>;
3404
3085
  listFiles(path: string, options?: ListFilesOptions): Promise<ListFilesResult>;
3405
3086
  exists(path: string, sessionId?: string): Promise<FileExistsResult>;
3406
- /**
3407
- * Get the noVNC preview URL for browser-based desktop viewing.
3408
- * Confirms desktop is active, then uses exposePort() to generate
3409
- * a token-authenticated preview URL for the noVNC port (6080).
3410
- *
3411
- * @param hostname - The custom domain hostname for preview URLs
3412
- * (e.g., 'preview.example.com'). Required because preview URLs
3413
- * use subdomain patterns that .workers.dev doesn't support.
3414
- * @param options - Optional settings
3415
- * @param options.token - Reuse an existing token instead of generating a new one
3416
- * @returns The authenticated noVNC preview URL
3417
- */
3418
- getDesktopStreamUrl(hostname: string, options?: {
3419
- token?: string;
3420
- }): Promise<{
3421
- url: string;
3422
- }>;
3423
3087
  /**
3424
3088
  * Watch a directory for file system changes using native inotify.
3425
3089
  *
@@ -3448,11 +3112,10 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3448
3112
  /**
3449
3113
  * Expose a port and get a preview URL for accessing services running in the sandbox
3450
3114
  *
3451
- * Preview URLs survive transient container restarts: the token and any
3452
- * friendly name are persisted in Durable Object storage, and the port is
3453
- * automatically re-exposed on the container when it comes back up. Tokens
3454
- * are cleared only on explicit `unexposePort()` or full sandbox
3455
- * `destroy()`.
3115
+ * Preview URL authorization survives transient container restarts, but
3116
+ * forwarding is active only for the runtime where `exposePort()` was last
3117
+ * called. Call `exposePort()` again after a restart to reactivate an
3118
+ * existing URL for the current runtime.
3456
3119
  *
3457
3120
  * @param port - Port number to expose (1024-65535)
3458
3121
  * @param options - Configuration options
@@ -3484,11 +3147,22 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3484
3147
  port: number;
3485
3148
  name: string | undefined;
3486
3149
  }>;
3150
+ /**
3151
+ * Revoke preview URL authorization and current-runtime activation for a port.
3152
+ *
3153
+ * Revocation is idempotent: calling this for a port with no preview state is
3154
+ * still successful. The operation clears Durable Object-owned preview state
3155
+ * only and does not contact, probe, wake, or clean up the container runtime.
3156
+ */
3487
3157
  unexposePort(port: number): Promise<void>;
3158
+ /**
3159
+ * Returns preview URLs that are currently forwardable in the active runtime.
3160
+ * Durable authorization without current-runtime activation is omitted.
3161
+ */
3488
3162
  getExposedPorts(hostname: string): Promise<{
3489
3163
  url: string;
3490
3164
  port: number;
3491
- status: "active" | "inactive";
3165
+ status: "active";
3492
3166
  }[]>;
3493
3167
  /**
3494
3168
  * Namespaced tunnel API. Quick tunnels are zero-config preview URLs
@@ -3517,8 +3191,45 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3517
3191
  * fields.
3518
3192
  */
3519
3193
  private ensureTunnelsBuilt;
3194
+ /**
3195
+ * Resolve the Cloudflare account id used for named-tunnel provisioning.
3196
+ *
3197
+ * Memoised for the lifetime of this DO instance. The first call may hit
3198
+ * `GET /user/tokens/verify` to derive the account id from the configured
3199
+ * `CLOUDFLARE_API_TOKEN`; subsequent calls return the cached promise.
3200
+ *
3201
+ * Only successful resolutions are cached: a rejected lookup clears the
3202
+ * slot so the next caller retries. Otherwise a transient failure on
3203
+ * first use would permanently poison every later named-tunnel `get()`
3204
+ * on this DO instance.
3205
+ */
3206
+ private getTunnelAccountId;
3207
+ /**
3208
+ * Resolve the Cloudflare zone id used for named-tunnel provisioning.
3209
+ *
3210
+ * Memoised for the lifetime of this DO instance. Falls back to the
3211
+ * single zone the token can see under `accountId` via `GET /zones`
3212
+ * when `CLOUDFLARE_ZONE_ID` is not set. Failed lookups clear the cache
3213
+ * so the next caller retries — see `getTunnelAccountId` for the
3214
+ * rationale.
3215
+ */
3216
+ private getTunnelZoneId;
3217
+ /**
3218
+ * Returns whether a port is currently preview-forwardable.
3219
+ * This checks Durable Object-owned auth and runtime activation without
3220
+ * contacting or waking the container.
3221
+ */
3520
3222
  isPortExposed(port: number): Promise<boolean>;
3223
+ /**
3224
+ * Checks durable preview URL authorization for a port/token pair.
3225
+ *
3226
+ * This does not check whether the port is activated for the current runtime
3227
+ * and is not sufficient to decide whether preview traffic may forward.
3228
+ */
3521
3229
  validatePortToken(port: number, token: string): Promise<boolean>;
3230
+ private validatePreviewURLForRuntime;
3231
+ private getCurrentPreviewPorts;
3232
+ private previewTokensMatch;
3522
3233
  private validateCustomToken;
3523
3234
  private generatePortToken;
3524
3235
  private constructPreviewUrl;
@@ -3598,17 +3309,19 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3598
3309
  * Returns validated presigned URL configuration or throws if not configured.
3599
3310
  * All credential fields plus the R2 binding are required for backup to work.
3600
3311
  */
3601
- private requirePresignedUrlSupport;
3312
+ private requirePresignedURLSupport;
3313
+ private getBackupBucketEndpoint;
3314
+ private getBackupObjectURL;
3602
3315
  /**
3603
3316
  * Generate a presigned GET URL for downloading an object from R2.
3604
3317
  * The container can curl this URL directly without credentials.
3605
3318
  */
3606
- private generatePresignedGetUrl;
3319
+ private generatePresignedGetURL;
3607
3320
  /**
3608
3321
  * Generate a presigned PUT URL for uploading an object to R2.
3609
3322
  * The container can curl PUT to this URL directly without credentials.
3610
3323
  */
3611
- private generatePresignedPutUrl;
3324
+ private generatePresignedPutURL;
3612
3325
  /**
3613
3326
  * Upload a backup archive via presigned PUT URL.
3614
3327
  * The container curls the archive directly to R2, bypassing the DO.
@@ -3618,7 +3331,7 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3618
3331
  /**
3619
3332
  * Generate a presigned PUT URL for a single part in a multipart upload.
3620
3333
  */
3621
- private generatePresignedPartUrl;
3334
+ private generatePresignedPartURL;
3622
3335
  /**
3623
3336
  * Upload a backup archive to R2 using parallel multipart upload.
3624
3337
  * Uses the S3-compatible API exclusively for create/complete/abort so that
@@ -3710,7 +3423,8 @@ declare class Sandbox<Env = unknown> extends Container<Env> implements ISandbox
3710
3423
  */
3711
3424
  private doRestoreBackupLocal;
3712
3425
  private configureR2EgressOutbound;
3426
+ private configureS3CredentialProxyOutbound;
3713
3427
  }
3714
3428
  //#endregion
3715
- export { StartProcessRequest as $, DesktopStopResponse as A, ProcessOptions as At, ExecuteResponse as B, WaitForPortOptions as Bt, ClickOptions as C, PortListResult as Ct, DesktopStartOptions as D, ProcessKillResult as Dt, DesktopClient as E, ProcessInfoResult as Et, ScreenshotRegion as F, SandboxOptions as Ft, HttpClientOptions as G, PtyOptions as Gt, BaseApiResponse as H, isExecResult as Ht, ScreenshotResponse as I, SandboxTransport as It, SessionRequest as J, Execution as Jt, RequestConfig as K, CodeContext as Kt, ScrollDirection as L, SessionOptions as Lt, ScreenSizeResponse as M, ProcessStatus as Mt, ScreenshotBytesResponse as N, RemoteMountBucketOptions as Nt, DesktopStartResponse as O, ProcessListResult as Ot, ScreenshotOptions as P, RestoreBackupResult as Pt, ExposePortRequest as Q, TypeOptions as R, StreamOptions as Rt, WriteFileRequest as S, PortExposeResult as St, Desktop as T, ProcessCleanupResult as Tt, ContainerStub as U, isProcess as Ut, BackupClient as V, WatchOptions as Vt, ErrorResponse as W, isProcessStatus as Wt, TunnelInfo as X, RunCodeOptions as Xt, SandboxInterpreterAPI as Y, ExecutionResult as Yt, ExecuteRequest as Z, GitClient as _, ListFilesOptions as _t, CreateSessionRequest as a, CheckChangesResult as at, MkdirRequest as b, MountBucketOptions as bt, DeleteSessionResponse as c, ExecOptions as ct, ProcessClient as d, FileChunk as dt, BackupOptions as et, PortClient as f, FileMetadata as ft, GitCheckoutRequest as g, ISandbox as gt, InterpreterClient as h, GitCheckoutResult as ht, CommandsResponse as i, CheckChangesOptions as it, KeyInput as j, ProcessStartResult as jt, DesktopStatusResponse as k, ProcessLogsResult as kt, PingResponse as l, ExecResult as lt, ExecutionCallbacks as m, FileWatchSSEEvent as mt, getSandbox as n, BucketCredentials as nt, CreateSessionResponse as o, DirectoryBackup as ot, UnexposePortRequest as p, FileStreamEvent as pt, ResponseHandler as q, CreateContextOptions as qt, SandboxClient as r, BucketProvider as rt, DeleteSessionRequest as s, ExecEvent as st, Sandbox as t, BaseExecOptions as tt, UtilityClient as u, ExecutionSession as ut, FileClient as v, LocalMountBucketOptions as vt, CursorPositionResponse as w, Process as wt, ReadFileRequest as x, PortCloseResult as xt, FileOperationRequest as y, LogEvent as yt, CommandClient as z, WaitForLogResult as zt };
3716
- //# sourceMappingURL=sandbox-CwcSm_60.d.ts.map
3429
+ export { FileStreamEvent as $, RequestConfig as A, CreateContextOptions as At, BackupOptions as B, CommandClient as C, WaitForPortOptions as Ct, ContainerStub as D, isProcessStatus as Dt, BaseApiResponse as E, isProcess as Et, SandboxInterpreterAPI as F, CheckChangesResult as G, BucketCredentials as H, TunnelInfo as I, ExecOptions as J, DirectoryBackup as K, TunnelOptions as L, SessionRequest as M, ExecutionResult as Mt, NamedTunnelInfo as N, RunCodeOptions as Nt, ErrorResponse as O, PtyOptions as Ot, QuickTunnelInfo as P, FileMetadata as Q, ExecuteRequest as R, WriteFileRequest as S, WaitForLogResult as St, BackupClient as T, isExecResult as Tt, BucketProvider as U, BaseExecOptions as V, CheckChangesOptions as W, ExecutionSession as X, ExecResult as Y, FileChunk as Z, GitClient as _, RestoreBackupResult as _t, CommandsResponse as a, LogEvent as at, MkdirRequest as b, SessionOptions as bt, DeleteSessionRequest as c, ProcessCleanupResult as ct, UtilityClient as d, ProcessListResult as dt, FileWatchSSEEvent as et, ProcessClient as f, ProcessLogsResult as ft, GitCheckoutRequest as g, RemoteMountBucketOptions as gt, InterpreterClient as h, ProcessStatus as ht, SandboxClient as i, LocalMountBucketOptions as it, ResponseHandler as j, Execution as jt, HttpClientOptions as k, CodeContext as kt, DeleteSessionResponse as l, ProcessInfoResult as lt, ExecutionCallbacks as m, ProcessStartResult as mt, Sandbox as n, ISandbox as nt, CreateSessionRequest as o, MountBucketOptions as ot, PortClient as p, ProcessOptions as pt, ExecEvent as q, getSandbox as r, ListFilesOptions as rt, CreateSessionResponse as s, Process as st, ContainerProxy$1 as t, GitCheckoutResult as tt, PingResponse as u, ProcessKillResult as ut, FileClient as v, SandboxOptions as vt, ExecuteResponse as w, WatchOptions as wt, ReadFileRequest as x, StreamOptions as xt, FileOperationRequest as y, SandboxTransport as yt, StartProcessRequest as z };
3430
+ //# sourceMappingURL=sandbox-D3N9M5EI.d.ts.map