@claxedo/sandbox-manager 0.7.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
@@ -11,7 +11,7 @@ The package owns the generic pieces:
11
11
  - `SandboxDriver`
12
12
  - provider drivers for Cloudflare, Daytona, Docker, fetch bridge, Modal, and Vercel
13
13
 
14
- It deliberately does not own Claxedo product auth, billing, Convex schema, SQLite app storage, routes, or relay tokens. Applications provide those through adapters and call `createSandboxManager`.
14
+ It deliberately does not own Claxedo product auth, billing, app storage schema, routes, or relay tokens. Applications provide those through adapters and call `createSandboxManager`.
15
15
 
16
16
  ## Install
17
17
 
@@ -59,8 +59,8 @@ Swap `createDockerSandboxDriver` for `createDaytonaSandboxDriver`,
59
59
  `@claxedo/sandbox-manager/drivers/*`) to place on a hosted provider instead —
60
60
  see [`docs/architecture.md`](docs/architecture.md) for the full driver
61
61
  comparison and each provider's required options. Swap `createMemoryLeaseStore`
62
- for a persisted `SandboxLeaseStore` implementation (e.g. backed by SQLite or
63
- Convex) to survive process restarts.
62
+ for a persisted `SandboxLeaseStore` implementation (e.g. backed by SQLite) to
63
+ survive process restarts.
64
64
 
65
65
  ## Credentials & secrets
66
66
 
@@ -100,25 +100,21 @@ Per-provider mechanism (from each provider's official docs):
100
100
  | --- | --- | --- |
101
101
  | Daytona | `native` | `daytona.secret.create({name, value, hosts})`; the sandbox env holds an opaque `dtn_secret_…` placeholder and an egress proxy substitutes the real value only for allowlisted hosts ([docs](https://www.daytona.io/docs/en/secrets/)). |
102
102
  | Vercel | `native` | Firewall header-transform (`updateNetworkPolicy`): the value is spliced onto egress to the allowlisted hosts as `header`, so the sandbox makes an unauthenticated request ([docs](https://vercel.com/docs/sandbox/concepts/firewall)). `updateNetworkPolicy` replaces the whole policy, so the driver sends the **union** of the create-time allow-list and the brokered hosts — attaching a credential must not revoke egress the caller was already granted (a mid-run `npm install` would start failing), nor widen it to a brokered host the create-time policy never approved. |
103
- | Cloudflare | `proxy` | Implemented via the official [Worker-proxy pattern](https://developers.cloudflare.com/sandbox/guides/proxy-requests/): the driver sends the value to the sandbox Worker (API-token-gated, never into the container); the Worker stores it in KV, mints a short-lived per-sandbox JWT, and sets `CLAXEDO_EGRESS_PROXY_URL`/`CLAXEDO_EGRESS_TOKEN`/`CLAXEDO_EGRESS_HOSTS` in the container. The sandbox routes brokered-host egress through the Worker, which validates the JWT and injects the credential as `header` — the raw value never enters the sandbox. The reusable core is `@claxedo/sandbox-manager/drivers/cloudflare-egress` (mint/verify + `handleEgressRequest`). |
103
+ | Cloudflare | `native` | The driver sends named registrations to the API-token-gated Worker. KV holds the values outside the container; native HTTPS outbound handlers replace named placeholders in registered headers. Each request reads KV, so there is no expiring container JWT. KV propagation delay still applies to rotation and withdrawal. |
104
104
  | Modal | `none` | Modal [Secrets](https://modal.com/docs/guide/secrets) are an encrypted by-reference store, but exposed as **readable env vars** inside the sandbox — they cannot satisfy the never-readable contract. |
105
105
  | Docker, fetch | `none` | Plaintext env only. |
106
106
 
107
107
  **Fail-closed contract.** A brokered secret is never silently downgraded to
108
- readable env. `native` (transparent egress) and `proxy` (Cloudflare Worker
109
- egress proxy) both keep the value out of the sandbox and provision normally;
110
- only a `none` driver makes the manager refuse to provision (`status:
108
+ readable env. Only `native` keeps the value out of the sandbox and provisions
109
+ normally; a `none` driver makes the manager refuse to provision (`status:
111
110
  "unavailable", error: "secret_brokering_unsupported"`) rather than expose or
112
111
  drop the credential. Brokered secret values are also never written to labels,
113
112
  never logged, and never captured in a driver snapshot.
114
113
 
115
- > Consumption note: `native` brokering is transparent (existing code reaches
116
- > the real host and the platform injects). Cloudflare `proxy` is NOT
117
- > transparent — the sandbox must route brokered-host requests through
118
- > `CLAXEDO_EGRESS_PROXY_URL` (with the `CLAXEDO_EGRESS_TOKEN` bearer and the
119
- > `x-claxedo-egress-target` header). Modal stays `none`; its secret store
120
- > improves storage hygiene for *readable* credentials but does not hide them
121
- > from the sandbox.
114
+ > Native brokering keeps the original upstream URL. Cloudflare accepts its
115
+ > named placeholder as the complete credential header, or with a Bearer prefix
116
+ > for Authorization API-key clients. Modal remains `none`: its encrypted store
117
+ > exposes credentials as readable environment variables inside the sandbox.
122
118
 
123
119
  ## Egress containment
124
120
 
@@ -1,42 +1,11 @@
1
1
  import { validateSandboxPersistenceCapabilities, type SandboxDriverMetadata } from "./index";
2
- export declare const sandboxDriverIds: readonly ["exe", "daytona", "modal", "vercel", "cloudflare", "box", "docker"];
3
- export type SandboxDriverID = (typeof sandboxDriverIds)[number];
4
- export type SandboxDriverAuth = {
5
- exe?: {
6
- api_token?: string;
7
- };
8
- daytona?: {
9
- api_key?: string;
10
- };
11
- modal?: {
12
- token_id?: string;
13
- token_secret?: string;
14
- };
15
- vercel?: {
16
- access_token?: string;
17
- team_id?: string;
18
- project_id?: string;
19
- };
20
- cloudflare?: {
21
- api_token?: string;
22
- worker_url?: string;
23
- };
24
- box?: {
25
- api_key?: string;
26
- };
27
- docker?: {
28
- image?: string;
29
- };
30
- };
31
- export type SandboxDriverConfig = {
32
- default_driver?: SandboxDriverID;
33
- auth?: SandboxDriverAuth;
34
- };
2
+ import { defaultSandboxDriverID, listSandboxDrivers, sandboxDriverId, type SandboxDriverAuth, type SandboxDriverConfig, type SandboxDriverEnv, type SandboxDriverID } from "@claxedo/sandbox-contract";
3
+ export { defaultSandboxDriverID, listSandboxDrivers, sandboxDriverId };
35
4
  export type SandboxDriverCatalogEntry = {
36
5
  id: SandboxDriverID;
37
6
  label: string;
38
7
  metadata: SandboxDriverMetadata;
39
- credentialFields: Array<{
8
+ credentialFields: ReadonlyArray<{
40
9
  key: string;
41
10
  label: string;
42
11
  secret?: boolean;
@@ -44,25 +13,6 @@ export type SandboxDriverCatalogEntry = {
44
13
  };
45
14
  export { validateSandboxPersistenceCapabilities };
46
15
  export declare const sandboxDriverCatalog: Record<SandboxDriverID, SandboxDriverCatalogEntry>;
47
- export declare function isSandboxDriverID(input: string | undefined): input is SandboxDriverID;
48
- export declare function sandboxDriverId(input: string | undefined, cfg?: SandboxDriverConfig, env?: SandboxDriverEnv): "box" | "cloudflare" | "daytona" | "docker" | "exe" | "modal" | "vercel" | undefined;
49
- export declare function defaultSandboxDriverID(cfg?: SandboxDriverConfig, env?: SandboxDriverEnv): SandboxDriverID;
50
16
  export declare function sandboxDriverAuth<T extends SandboxDriverID>(cfg: SandboxDriverConfig | undefined, id: T, env?: SandboxDriverEnv): SandboxDriverAuth[T] | undefined;
51
17
  export declare function hasSandboxDriverAuth(cfg: SandboxDriverConfig | undefined, id: SandboxDriverID, env?: SandboxDriverEnv): boolean;
52
18
  export declare function dockerSandboxDriverEnabled(env?: SandboxDriverEnv): boolean;
53
- export declare function listSandboxDrivers(cfg?: SandboxDriverConfig, env?: SandboxDriverEnv, managedDriverIds?: ReadonlySet<string>): {
54
- default_driver: "box" | "cloudflare" | "daytona" | "docker" | "exe" | "modal" | "vercel";
55
- drivers: {
56
- id: "box" | "cloudflare" | "daytona" | "docker" | "exe" | "modal" | "vercel";
57
- label: string;
58
- fields: {
59
- key: string;
60
- label: string;
61
- secret?: boolean;
62
- }[];
63
- configured: boolean;
64
- source: "config" | "managed" | "none";
65
- default: boolean;
66
- }[];
67
- };
68
- type SandboxDriverEnv = Record<string, string | undefined>;
@@ -68,13 +68,120 @@ function defaultSandboxImage(version = workspaceRuntimeVersion(), buildId, env =
68
68
  return `${sandboxImageRepository(env)}:workspace-runtime-${snapshotVersion(version)}${buildIdSuffix(buildId, env)}-v${SNAPSHOT_SCHEMA_VERSION}`;
69
69
  }
70
70
 
71
- // src/driver-catalog.ts
71
+ // ../sandbox-contract/dist/index.mjs
72
+ function isString(value) {
73
+ return typeof value === "string";
74
+ }
75
+ function trimToUndefined(value) {
76
+ if (!isString(value))
77
+ return;
78
+ const trimmed = value.trim();
79
+ return trimmed.length > 0 ? trimmed : void 0;
80
+ }
72
81
  var sandboxDriverIds = ["exe", "daytona", "modal", "vercel", "cloudflare", "box", "docker"];
82
+ var sandboxDriverCredentialFields = {
83
+ exe: [{ key: "api_token", label: "API Token", secret: true }],
84
+ daytona: [{ key: "api_key", label: "API Key", secret: true }],
85
+ modal: [
86
+ { key: "token_id", label: "Token ID", secret: true },
87
+ { key: "token_secret", label: "Token Secret", secret: true }
88
+ ],
89
+ vercel: [
90
+ { key: "access_token", label: "Access Token", secret: true },
91
+ { key: "team_id", label: "Team ID" },
92
+ { key: "project_id", label: "Project ID" }
93
+ ],
94
+ cloudflare: [
95
+ { key: "api_token", label: "API Token", secret: true },
96
+ { key: "worker_url", label: "Worker URL" }
97
+ ],
98
+ box: [{ key: "api_key", label: "API Key", secret: true }],
99
+ docker: [{ key: "image", label: "Image" }]
100
+ };
101
+ var sandboxDriverLabels = {
102
+ exe: "exe.dev",
103
+ daytona: "Daytona",
104
+ modal: "Modal",
105
+ vercel: "Vercel",
106
+ cloudflare: "Cloudflare",
107
+ box: "Box",
108
+ docker: "Docker"
109
+ };
110
+ function isSandboxDriverID(input) {
111
+ return !!input && sandboxDriverIds.includes(input);
112
+ }
113
+ function enabled(input) {
114
+ return ["1", "true", "yes", "on"].includes(input?.trim().toLowerCase() ?? "");
115
+ }
116
+ function dockerSandboxDriverEnabled(env = process.env) {
117
+ return enabled(env.CLAXEDO_ENABLE_DOCKER_SANDBOX) || enabled(env.CLAXEDO_DEV_DOCKER_SANDBOX);
118
+ }
119
+ function sandboxDriverAuthValues(cfg, id, env = process.env) {
120
+ if (id === "daytona") {
121
+ const api_key = trimToUndefined(cfg?.auth?.daytona?.api_key);
122
+ return api_key ? { api_key } : void 0;
123
+ }
124
+ if (id === "exe") {
125
+ const api_token = trimToUndefined(cfg?.auth?.exe?.api_token) ?? trimToUndefined(env.EXE_DEV_API_TOKEN);
126
+ return api_token ? { api_token } : void 0;
127
+ }
128
+ if (id === "modal") {
129
+ const token_id = trimToUndefined(cfg?.auth?.modal?.token_id) ?? trimToUndefined(env.MODAL_TOKEN_ID);
130
+ const token_secret = trimToUndefined(cfg?.auth?.modal?.token_secret) ?? trimToUndefined(env.MODAL_TOKEN_SECRET);
131
+ return token_id && token_secret ? { token_id, token_secret } : void 0;
132
+ }
133
+ if (id === "vercel") {
134
+ const access_token = trimToUndefined(cfg?.auth?.vercel?.access_token) ?? trimToUndefined(env.VERCEL_TOKEN);
135
+ const team_id = trimToUndefined(cfg?.auth?.vercel?.team_id) ?? trimToUndefined(env.VERCEL_TEAM_ID);
136
+ const project_id = trimToUndefined(cfg?.auth?.vercel?.project_id) ?? trimToUndefined(env.VERCEL_PROJECT_ID);
137
+ return access_token && team_id && project_id ? { access_token, team_id, project_id } : void 0;
138
+ }
139
+ if (id === "cloudflare") {
140
+ const api_token = trimToUndefined(cfg?.auth?.cloudflare?.api_token) ?? trimToUndefined(env.CLOUDFLARE_API_TOKEN);
141
+ const worker_url = trimToUndefined(cfg?.auth?.cloudflare?.worker_url) ?? trimToUndefined(env.CLOUDFLARE_SANDBOX_WORKER_URL);
142
+ return api_token && worker_url ? { api_token, worker_url } : void 0;
143
+ }
144
+ if (id === "box") {
145
+ const api_key = trimToUndefined(cfg?.auth?.box?.api_key) ?? trimToUndefined(env.BOX_API_KEY);
146
+ return api_key ? { api_key } : void 0;
147
+ }
148
+ if (!dockerSandboxDriverEnabled(env)) return void 0;
149
+ const image = trimToUndefined(cfg?.auth?.docker?.image) ?? trimToUndefined(env.CLAXEDO_DOCKER_SANDBOX_IMAGE) ?? trimToUndefined(env.CLAXEDO_SANDBOX_IMAGE);
150
+ return image ? { image } : {};
151
+ }
152
+ function sandboxDriverId(input, cfg, env = process.env) {
153
+ if (!isSandboxDriverID(input)) return void 0;
154
+ if (input === "docker" && !sandboxDriverAuthValues(cfg, input, env)) return void 0;
155
+ return input;
156
+ }
157
+ function defaultSandboxDriverID(cfg, env = process.env) {
158
+ return sandboxDriverId(cfg?.default_driver, cfg, env) ?? (enabled(env.CLAXEDO_DOCKER_SANDBOX_DEFAULT) && sandboxDriverAuthValues(cfg, "docker", env) ? "docker" : "daytona");
159
+ }
160
+ function listSandboxDrivers(cfg, env = process.env, managedDriverIds = /* @__PURE__ */ new Set()) {
161
+ const defaultDriver = defaultSandboxDriverID(cfg, env);
162
+ return {
163
+ default_driver: defaultDriver,
164
+ drivers: sandboxDriverIds.filter((id) => id !== "docker" || !!sandboxDriverAuthValues(cfg, "docker", env)).map((id) => {
165
+ const configuredFromConfigOrEnv = !!sandboxDriverAuthValues(cfg, id, env);
166
+ const configured = id === "docker" ? configuredFromConfigOrEnv : configuredFromConfigOrEnv || managedDriverIds.has(id);
167
+ return {
168
+ id,
169
+ label: sandboxDriverLabels[id],
170
+ fields: sandboxDriverCredentialFields[id],
171
+ configured,
172
+ source: configuredFromConfigOrEnv ? "config" : configured ? "managed" : "none",
173
+ default: id === defaultDriver
174
+ };
175
+ })
176
+ };
177
+ }
178
+
179
+ // src/driver-catalog.ts
73
180
  var sandboxDriverCatalog = {
74
181
  exe: {
75
182
  id: "exe",
76
- label: "exe.dev",
77
- credentialFields: [{ key: "api_token", label: "API Token", secret: true }],
183
+ label: sandboxDriverLabels.exe,
184
+ credentialFields: sandboxDriverCredentialFields.exe,
78
185
  metadata: {
79
186
  driverRunsIn: ["worker", "node"],
80
187
  hostStopBehavior: "not-supported",
@@ -94,17 +201,15 @@ var sandboxDriverCatalog = {
94
201
  },
95
202
  daytona: {
96
203
  id: "daytona",
97
- label: "Daytona",
98
- credentialFields: [{ key: "api_key", label: "API Key", secret: true }],
204
+ label: sandboxDriverLabels.daytona,
205
+ credentialFields: sandboxDriverCredentialFields.daytona,
99
206
  metadata: {
100
207
  driverRunsIn: ["worker", "node"],
101
208
  hostStopBehavior: "suspends-host",
102
209
  hostResumeBehavior: "same-host",
103
210
  targetAccess: "relay",
104
211
  secretBrokering: "native",
105
- // Daytona is the only driver that can filter egress by NAME as well as
106
- // by address: `domainAllowList` (names) alongside `networkAllowList`
107
- // (CIDRs), with `networkBlockAll` as the deny-all floor.
212
+ // The driver translates names to domainAllowList, or addresses to networkAllowList.
108
213
  egressControl: "hosts-and-cidrs",
109
214
  persistence: {
110
215
  resume: "same-sandbox",
@@ -118,20 +223,15 @@ var sandboxDriverCatalog = {
118
223
  },
119
224
  modal: {
120
225
  id: "modal",
121
- label: "Modal",
122
- credentialFields: [
123
- { key: "token_id", label: "Token ID", secret: true },
124
- { key: "token_secret", label: "Token Secret", secret: true }
125
- ],
226
+ label: sandboxDriverLabels.modal,
227
+ credentialFields: sandboxDriverCredentialFields.modal,
126
228
  metadata: {
127
229
  driverRunsIn: ["node"],
128
230
  hostStopBehavior: "terminates-host",
129
231
  hostResumeBehavior: "replacement-host",
130
232
  targetAccess: "relay",
131
233
  secretBrokering: "none",
132
- // Modal can cut the network entirely (`blockNetwork`) but cannot express
133
- // an allowlist, and its driver throws on a host policy. A blackout is
134
- // not containment for a workspace that has to clone and reach a model.
234
+ // The driver does not install Modal's domain allowlist or alpha sidecar.
135
235
  egressControl: "none",
136
236
  persistence: {
137
237
  resume: "replacement-restore",
@@ -145,20 +245,15 @@ var sandboxDriverCatalog = {
145
245
  },
146
246
  vercel: {
147
247
  id: "vercel",
148
- label: "Vercel",
149
- credentialFields: [
150
- { key: "access_token", label: "Access Token", secret: true },
151
- { key: "team_id", label: "Team ID" },
152
- { key: "project_id", label: "Project ID" }
153
- ],
248
+ label: sandboxDriverLabels.vercel,
249
+ credentialFields: sandboxDriverCredentialFields.vercel,
154
250
  metadata: {
155
251
  driverRunsIn: ["node"],
156
252
  hostStopBehavior: "terminates-host",
157
253
  hostResumeBehavior: "replacement-host",
158
254
  targetAccess: "relay",
159
255
  secretBrokering: "native",
160
- // Vercel's sandbox firewall takes a hostname allow list (or "deny-all"),
161
- // never CIDRs.
256
+ // The driver translates hosts only; the SDK's subnet rules are not wired to net.cidrs.
162
257
  egressControl: "hosts",
163
258
  persistence: {
164
259
  resume: "replacement-restore",
@@ -172,23 +267,15 @@ var sandboxDriverCatalog = {
172
267
  },
173
268
  cloudflare: {
174
269
  id: "cloudflare",
175
- label: "Cloudflare",
176
- credentialFields: [
177
- { key: "api_token", label: "API Token", secret: true },
178
- { key: "worker_url", label: "Worker URL" }
179
- ],
270
+ label: sandboxDriverLabels.cloudflare,
271
+ credentialFields: sandboxDriverCredentialFields.cloudflare,
180
272
  metadata: {
181
273
  driverRunsIn: ["worker"],
182
274
  hostStopBehavior: "not-supported",
183
275
  hostResumeBehavior: "same-host",
184
276
  targetAccess: "relay",
185
- secretBrokering: "proxy",
186
- // The Cloudflare Sandbox Worker exposes no egress filter: its broker
187
- // (drivers/cloudflare-egress.ts) is an OPT-IN proxy the sandbox chooses
188
- // to route brokered-credential requests through, not a boundary. The
189
- // driver therefore drops `net` entirely — which is exactly why this
190
- // must be declared, so the manager refuses instead of provisioning a
191
- // sandbox the caller believes is contained.
277
+ secretBrokering: "native",
278
+ // Credential handlers do not restrict unrelated destinations.
192
279
  egressControl: "none",
193
280
  persistence: {
194
281
  resume: "replacement-restore",
@@ -202,8 +289,8 @@ var sandboxDriverCatalog = {
202
289
  },
203
290
  box: {
204
291
  id: "box",
205
- label: "Box",
206
- credentialFields: [{ key: "api_key", label: "API Key", secret: true }],
292
+ label: sandboxDriverLabels.box,
293
+ credentialFields: sandboxDriverCredentialFields.box,
207
294
  metadata: {
208
295
  driverRunsIn: ["node"],
209
296
  hostStopBehavior: "suspends-host",
@@ -223,8 +310,8 @@ var sandboxDriverCatalog = {
223
310
  },
224
311
  docker: {
225
312
  id: "docker",
226
- label: "Docker",
227
- credentialFields: [{ key: "image", label: "Image" }],
313
+ label: sandboxDriverLabels.docker,
314
+ credentialFields: sandboxDriverCredentialFields.docker,
228
315
  metadata: {
229
316
  driverRunsIn: ["local"],
230
317
  hostStopBehavior: "terminates-host",
@@ -243,106 +330,28 @@ var sandboxDriverCatalog = {
243
330
  }
244
331
  }
245
332
  };
246
- function isSandboxDriverID(input) {
247
- return !!input && sandboxDriverIds.includes(input);
248
- }
249
- function sandboxDriverId(input, cfg, env = process.env) {
250
- if (!isSandboxDriverID(input)) return;
251
- if (input === "docker" && !sandboxDriverAuth(cfg, input, env)) return;
252
- return input;
253
- }
254
- function defaultSandboxDriverID(cfg, env = process.env) {
255
- return sandboxDriverId(cfg?.default_driver, cfg, env) ?? (dockerSandboxDefault(env) && sandboxDriverAuth(cfg, "docker", env) ? "docker" : "daytona");
256
- }
257
333
  function sandboxDriverAuth(cfg, id, env = process.env) {
258
- if (id === "daytona") return authDaytona(cfg);
259
- if (id === "exe") return authExe(cfg, env);
260
- if (id === "modal") return authModal(cfg, env);
261
- if (id === "vercel") return authVercel(cfg, env);
262
- if (id === "cloudflare") return authCloudflare(cfg, env);
263
- if (id === "box") return authBox(cfg, env);
264
- return authDocker(cfg, env);
334
+ if (id === "docker") {
335
+ const configured = sandboxDriverAuthValues(cfg, "docker", env);
336
+ if (!configured) return void 0;
337
+ const image = configured.image ?? defaultSandboxImage(workspaceRuntimeVersion(), void 0, env);
338
+ return { image };
339
+ }
340
+ return sandboxDriverAuthValues(cfg, id, env);
265
341
  }
266
342
  function hasSandboxDriverAuth(cfg, id, env = process.env) {
267
343
  return !!sandboxDriverAuth(cfg, id, env);
268
344
  }
269
- function dockerSandboxDriverEnabled(env = process.env) {
270
- return dockerSandboxEnabled(env);
271
- }
272
- function listSandboxDrivers(cfg, env = process.env, managedDriverIds = /* @__PURE__ */ new Set()) {
273
- const def = defaultSandboxDriverID(cfg, env);
274
- return {
275
- default_driver: def,
276
- drivers: sandboxDriverIds.filter((id) => id !== "docker" || !!sandboxDriverAuth(cfg, "docker", env)).map((id) => {
277
- const configuredFromConfigOrEnv = !!sandboxDriverAuth(cfg, id, env);
278
- const configured = id === "docker" ? configuredFromConfigOrEnv : configuredFromConfigOrEnv || managedDriverIds.has(id);
279
- return {
280
- id,
281
- label: sandboxDriverCatalog[id].label,
282
- fields: sandboxDriverCatalog[id].credentialFields,
283
- configured,
284
- source: configuredFromConfigOrEnv ? "config" : configured ? "managed" : "none",
285
- default: id === def
286
- };
287
- })
288
- };
289
- }
290
- function clean(input) {
291
- const txt = input?.trim();
292
- return txt ? txt : void 0;
293
- }
294
- function enabled(input) {
295
- return ["1", "true", "yes", "on"].includes(input?.trim().toLowerCase() ?? "");
296
- }
297
- function dockerSandboxEnabled(env) {
298
- return enabled(env.CLAXEDO_ENABLE_DOCKER_SANDBOX) || enabled(env.CLAXEDO_DEV_DOCKER_SANDBOX);
299
- }
300
- function dockerSandboxDefault(env) {
301
- return enabled(env.CLAXEDO_DOCKER_SANDBOX_DEFAULT);
302
- }
303
- function authDaytona(cfg) {
304
- const api_key = clean(cfg?.auth?.daytona?.api_key);
305
- return api_key ? { api_key } : void 0;
306
- }
307
- function authExe(cfg, env) {
308
- const api_token = clean(cfg?.auth?.exe?.api_token) ?? clean(env.EXE_DEV_API_TOKEN);
309
- return api_token ? { api_token } : void 0;
310
- }
311
- function authModal(cfg, env) {
312
- const token_id = clean(cfg?.auth?.modal?.token_id) ?? clean(env.MODAL_TOKEN_ID);
313
- const token_secret = clean(cfg?.auth?.modal?.token_secret) ?? clean(env.MODAL_TOKEN_SECRET);
314
- return token_id && token_secret ? { token_id, token_secret } : void 0;
315
- }
316
- function authVercel(cfg, env) {
317
- const access_token = clean(cfg?.auth?.vercel?.access_token) ?? clean(env.VERCEL_TOKEN);
318
- const team_id = clean(cfg?.auth?.vercel?.team_id) ?? clean(env.VERCEL_TEAM_ID);
319
- const project_id = clean(cfg?.auth?.vercel?.project_id) ?? clean(env.VERCEL_PROJECT_ID);
320
- return access_token && team_id && project_id ? { access_token, team_id, project_id } : void 0;
321
- }
322
- function authCloudflare(cfg, env) {
323
- const api_token = clean(cfg?.auth?.cloudflare?.api_token) ?? clean(env.CLOUDFLARE_API_TOKEN);
324
- const worker_url = clean(cfg?.auth?.cloudflare?.worker_url) ?? clean(env.CLOUDFLARE_SANDBOX_WORKER_URL);
325
- return api_token && worker_url ? { api_token, worker_url } : void 0;
326
- }
327
- function authBox(cfg, env) {
328
- const api_key = clean(cfg?.auth?.box?.api_key) ?? clean(env.BOX_API_KEY);
329
- return api_key ? { api_key } : void 0;
330
- }
331
- function authDocker(cfg, env) {
332
- if (!dockerSandboxEnabled(env)) return;
333
- return {
334
- image: clean(cfg?.auth?.docker?.image) ?? clean(env.CLAXEDO_DOCKER_SANDBOX_IMAGE) ?? clean(env.CLAXEDO_SANDBOX_IMAGE) ?? defaultSandboxImage(workspaceRuntimeVersion(), void 0, env)
335
- };
345
+ function dockerSandboxDriverEnabled2(env = process.env) {
346
+ return dockerSandboxDriverEnabled(env);
336
347
  }
337
348
  export {
338
349
  defaultSandboxDriverID,
339
- dockerSandboxDriverEnabled,
350
+ dockerSandboxDriverEnabled2 as dockerSandboxDriverEnabled,
340
351
  hasSandboxDriverAuth,
341
- isSandboxDriverID,
342
352
  listSandboxDrivers,
343
353
  sandboxDriverAuth,
344
354
  sandboxDriverCatalog,
345
355
  sandboxDriverId,
346
- sandboxDriverIds,
347
356
  validateSandboxPersistenceCapabilities
348
357
  };