@claxedo/sandbox-manager 0.7.0 → 0.10.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 +245 -42
- package/dist/checkpoint-manager.d.ts +29 -4
- package/dist/checkpoint-manager.mjs +133 -24
- package/dist/command.d.ts +9 -2
- package/dist/command.mjs +8 -8
- package/dist/contract.d.ts +687 -0
- package/dist/driver-billing.d.ts +29 -0
- package/dist/driver-catalog.d.ts +43 -58
- package/dist/driver-catalog.mjs +192 -229
- package/dist/drivers/boat-client.d.ts +95 -0
- package/dist/drivers/boat-named-snapshots.d.ts +31 -0
- package/dist/drivers/boat-template.d.ts +49 -0
- package/dist/drivers/boat-template.mjs +1196 -0
- package/dist/drivers/boat.d.ts +64 -0
- package/dist/drivers/boat.mjs +990 -0
- package/dist/drivers/cloudflare.d.ts +5 -8
- package/dist/drivers/cloudflare.mjs +364 -213
- package/dist/drivers/docker.d.ts +4 -3
- package/dist/drivers/docker.mjs +244 -165
- package/dist/drivers/local-brokering.d.ts +14 -0
- package/dist/drivers/local-brokering.mjs +1029 -0
- package/dist/drivers/modal.d.ts +4 -7
- package/dist/drivers/modal.mjs +220 -155
- package/dist/drivers/transient-error.d.ts +13 -0
- package/dist/drivers/vercel.d.ts +21 -23
- package/dist/drivers/vercel.mjs +279 -169
- package/dist/egress-policy.d.ts +134 -0
- package/dist/egress-warnings.d.ts +22 -0
- package/dist/garbage-collect.d.ts +14 -0
- package/dist/hosted-network-policy.d.ts +11 -4
- package/dist/hosted-network-policy.mjs +221 -4
- package/dist/image-name.d.ts +12 -2
- package/dist/image-name.mjs +43 -0
- package/dist/image.d.ts +1 -20
- package/dist/image.mjs +11 -66
- package/dist/index.d.ts +8 -533
- package/dist/index.mjs +1420 -315
- package/dist/json.d.ts +13 -0
- package/dist/lease-failure.d.ts +173 -0
- package/dist/lease-lifecycle.d.ts +65 -0
- package/dist/lease-retry-wait.d.ts +8 -0
- package/dist/lease-start.d.ts +21 -0
- package/dist/lease-types.d.ts +15 -5
- package/dist/manager.d.ts +2 -0
- package/dist/runtime-env.d.ts +15 -2
- package/dist/runtime-env.mjs +50 -1
- package/dist/runtime-snapshot.d.ts +49 -0
- package/dist/runtime-version.d.ts +9 -0
- package/dist/runtime-version.mjs +2 -0
- package/dist/service-url-exposure.d.ts +1 -3
- package/dist/service-url-exposure.mjs +1 -26
- package/dist/start-fresh.d.ts +17 -0
- package/dist/start-telemetry.d.ts +37 -0
- package/dist/stores/memory.d.ts +1 -1
- package/dist/stores/memory.mjs +65 -54
- package/package.json +67 -81
- package/dist/daytona-allow-list.d.ts +0 -16
- package/dist/daytona-allow-list.mjs +0 -11
- package/dist/drivers/box.d.ts +0 -52
- package/dist/drivers/box.mjs +0 -499
- package/dist/drivers/cloudflare-egress.d.ts +0 -40
- package/dist/drivers/cloudflare-egress.mjs +0 -113
- package/dist/drivers/daytona.d.ts +0 -127
- package/dist/drivers/daytona.mjs +0 -541
- package/dist/drivers/exe.d.ts +0 -26
- package/dist/drivers/exe.mjs +0 -469
- package/dist/drivers/fetch-bridge.d.ts +0 -10
- package/dist/drivers/fetch-bridge.mjs +0 -111
- package/dist/lease-policy.d.ts +0 -48
- package/dist/lease-policy.mjs +0 -280
package/dist/lease-policy.mjs
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
// src/hosted-network-policy.ts
|
|
2
|
-
var SANDBOX_MODEL_PROVIDER_HOSTS = [
|
|
3
|
-
"api.anthropic.com",
|
|
4
|
-
"api.openai.com",
|
|
5
|
-
"generativelanguage.googleapis.com",
|
|
6
|
-
"openrouter.ai",
|
|
7
|
-
// Model catalog + engine config, fetched on runner startup.
|
|
8
|
-
"models.dev",
|
|
9
|
-
"opencode.ai"
|
|
10
|
-
];
|
|
11
|
-
var SANDBOX_PACKAGE_REGISTRY_HOSTS = [
|
|
12
|
-
"registry.npmjs.org",
|
|
13
|
-
"nodejs.org",
|
|
14
|
-
"pypi.org",
|
|
15
|
-
"files.pythonhosted.org",
|
|
16
|
-
"crates.io",
|
|
17
|
-
"static.crates.io",
|
|
18
|
-
"index.crates.io",
|
|
19
|
-
"proxy.golang.org",
|
|
20
|
-
"sum.golang.org"
|
|
21
|
-
];
|
|
22
|
-
var SANDBOX_BASELINE_EGRESS_HOSTS = [
|
|
23
|
-
...SANDBOX_MODEL_PROVIDER_HOSTS,
|
|
24
|
-
...SANDBOX_PACKAGE_REGISTRY_HOSTS
|
|
25
|
-
];
|
|
26
|
-
|
|
27
|
-
// src/driver-catalog.ts
|
|
28
|
-
var sandboxDriverCatalog = {
|
|
29
|
-
exe: {
|
|
30
|
-
id: "exe",
|
|
31
|
-
label: "exe.dev",
|
|
32
|
-
credentialFields: [{ key: "api_token", label: "API Token", secret: true }],
|
|
33
|
-
metadata: {
|
|
34
|
-
driverRunsIn: ["worker", "node"],
|
|
35
|
-
hostStopBehavior: "not-supported",
|
|
36
|
-
hostResumeBehavior: "same-host",
|
|
37
|
-
targetAccess: "relay",
|
|
38
|
-
secretBrokering: "none",
|
|
39
|
-
egressControl: "none",
|
|
40
|
-
persistence: {
|
|
41
|
-
resume: "same-sandbox",
|
|
42
|
-
capture: "none",
|
|
43
|
-
clone: true,
|
|
44
|
-
captureSource: "not-applicable",
|
|
45
|
-
retention: "provider-managed",
|
|
46
|
-
restoreMount: "same-resource"
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
daytona: {
|
|
51
|
-
id: "daytona",
|
|
52
|
-
label: "Daytona",
|
|
53
|
-
credentialFields: [{ key: "api_key", label: "API Key", secret: true }],
|
|
54
|
-
metadata: {
|
|
55
|
-
driverRunsIn: ["worker", "node"],
|
|
56
|
-
hostStopBehavior: "suspends-host",
|
|
57
|
-
hostResumeBehavior: "same-host",
|
|
58
|
-
targetAccess: "relay",
|
|
59
|
-
secretBrokering: "native",
|
|
60
|
-
// Daytona is the only driver that can filter egress by NAME as well as
|
|
61
|
-
// by address: `domainAllowList` (names) alongside `networkAllowList`
|
|
62
|
-
// (CIDRs), with `networkBlockAll` as the deny-all floor.
|
|
63
|
-
egressControl: "hosts-and-cidrs",
|
|
64
|
-
persistence: {
|
|
65
|
-
resume: "same-sandbox",
|
|
66
|
-
capture: "filesystem",
|
|
67
|
-
clone: false,
|
|
68
|
-
captureSource: "preserved",
|
|
69
|
-
retention: "provider-managed",
|
|
70
|
-
restoreMount: "new-resource"
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
modal: {
|
|
75
|
-
id: "modal",
|
|
76
|
-
label: "Modal",
|
|
77
|
-
credentialFields: [
|
|
78
|
-
{ key: "token_id", label: "Token ID", secret: true },
|
|
79
|
-
{ key: "token_secret", label: "Token Secret", secret: true }
|
|
80
|
-
],
|
|
81
|
-
metadata: {
|
|
82
|
-
driverRunsIn: ["node"],
|
|
83
|
-
hostStopBehavior: "terminates-host",
|
|
84
|
-
hostResumeBehavior: "replacement-host",
|
|
85
|
-
targetAccess: "relay",
|
|
86
|
-
secretBrokering: "none",
|
|
87
|
-
// Modal can cut the network entirely (`blockNetwork`) but cannot express
|
|
88
|
-
// an allowlist, and its driver throws on a host policy. A blackout is
|
|
89
|
-
// not containment for a workspace that has to clone and reach a model.
|
|
90
|
-
egressControl: "none",
|
|
91
|
-
persistence: {
|
|
92
|
-
resume: "replacement-restore",
|
|
93
|
-
capture: "filesystem",
|
|
94
|
-
clone: false,
|
|
95
|
-
captureSource: "preserved",
|
|
96
|
-
retention: "provider-managed",
|
|
97
|
-
restoreMount: "new-resource"
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
vercel: {
|
|
102
|
-
id: "vercel",
|
|
103
|
-
label: "Vercel",
|
|
104
|
-
credentialFields: [
|
|
105
|
-
{ key: "access_token", label: "Access Token", secret: true },
|
|
106
|
-
{ key: "team_id", label: "Team ID" },
|
|
107
|
-
{ key: "project_id", label: "Project ID" }
|
|
108
|
-
],
|
|
109
|
-
metadata: {
|
|
110
|
-
driverRunsIn: ["node"],
|
|
111
|
-
hostStopBehavior: "terminates-host",
|
|
112
|
-
hostResumeBehavior: "replacement-host",
|
|
113
|
-
targetAccess: "relay",
|
|
114
|
-
secretBrokering: "native",
|
|
115
|
-
// Vercel's sandbox firewall takes a hostname allow list (or "deny-all"),
|
|
116
|
-
// never CIDRs.
|
|
117
|
-
egressControl: "hosts",
|
|
118
|
-
persistence: {
|
|
119
|
-
resume: "replacement-restore",
|
|
120
|
-
capture: "filesystem",
|
|
121
|
-
clone: false,
|
|
122
|
-
captureSource: "stopped",
|
|
123
|
-
retention: "explicit",
|
|
124
|
-
restoreMount: "new-resource"
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
cloudflare: {
|
|
129
|
-
id: "cloudflare",
|
|
130
|
-
label: "Cloudflare",
|
|
131
|
-
credentialFields: [
|
|
132
|
-
{ key: "api_token", label: "API Token", secret: true },
|
|
133
|
-
{ key: "worker_url", label: "Worker URL" }
|
|
134
|
-
],
|
|
135
|
-
metadata: {
|
|
136
|
-
driverRunsIn: ["worker"],
|
|
137
|
-
hostStopBehavior: "not-supported",
|
|
138
|
-
hostResumeBehavior: "same-host",
|
|
139
|
-
targetAccess: "relay",
|
|
140
|
-
secretBrokering: "proxy",
|
|
141
|
-
// The Cloudflare Sandbox Worker exposes no egress filter: its broker
|
|
142
|
-
// (drivers/cloudflare-egress.ts) is an OPT-IN proxy the sandbox chooses
|
|
143
|
-
// to route brokered-credential requests through, not a boundary. The
|
|
144
|
-
// driver therefore drops `net` entirely — which is exactly why this
|
|
145
|
-
// must be declared, so the manager refuses instead of provisioning a
|
|
146
|
-
// sandbox the caller believes is contained.
|
|
147
|
-
egressControl: "none",
|
|
148
|
-
persistence: {
|
|
149
|
-
resume: "replacement-restore",
|
|
150
|
-
capture: "directories",
|
|
151
|
-
clone: false,
|
|
152
|
-
captureSource: "preserved",
|
|
153
|
-
retention: "provider-managed",
|
|
154
|
-
restoreMount: "copy-on-write"
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
},
|
|
158
|
-
box: {
|
|
159
|
-
id: "box",
|
|
160
|
-
label: "Box",
|
|
161
|
-
credentialFields: [{ key: "api_key", label: "API Key", secret: true }],
|
|
162
|
-
metadata: {
|
|
163
|
-
driverRunsIn: ["node"],
|
|
164
|
-
hostStopBehavior: "suspends-host",
|
|
165
|
-
hostResumeBehavior: "same-host",
|
|
166
|
-
targetAccess: "relay",
|
|
167
|
-
secretBrokering: "none",
|
|
168
|
-
egressControl: "none",
|
|
169
|
-
persistence: {
|
|
170
|
-
resume: "same-sandbox",
|
|
171
|
-
capture: "none",
|
|
172
|
-
clone: false,
|
|
173
|
-
captureSource: "not-applicable",
|
|
174
|
-
retention: "provider-managed",
|
|
175
|
-
restoreMount: "same-resource"
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
docker: {
|
|
180
|
-
id: "docker",
|
|
181
|
-
label: "Docker",
|
|
182
|
-
credentialFields: [{ key: "image", label: "Image" }],
|
|
183
|
-
metadata: {
|
|
184
|
-
driverRunsIn: ["local"],
|
|
185
|
-
hostStopBehavior: "terminates-host",
|
|
186
|
-
hostResumeBehavior: "same-host",
|
|
187
|
-
targetAccess: "loopback",
|
|
188
|
-
secretBrokering: "none",
|
|
189
|
-
egressControl: "none",
|
|
190
|
-
persistence: {
|
|
191
|
-
resume: "replacement-restore",
|
|
192
|
-
capture: "same-resource",
|
|
193
|
-
clone: false,
|
|
194
|
-
captureSource: "preserved",
|
|
195
|
-
retention: "provider-managed",
|
|
196
|
-
restoreMount: "same-resource"
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
// src/lease-policy.ts
|
|
203
|
-
var DEFAULT_WORKSPACE_HOST_DECISION_CONFIG = {
|
|
204
|
-
maxRetries: 8,
|
|
205
|
-
idleMs: 10 * 60 * 1e3,
|
|
206
|
-
backoffMaxMs: 3e4,
|
|
207
|
-
healthTimeoutMs: 6e4
|
|
208
|
-
};
|
|
209
|
-
function sandboxDriverPlacement(driver) {
|
|
210
|
-
const metadata = sandboxDriverCatalog[driver].metadata;
|
|
211
|
-
return {
|
|
212
|
-
canPauseAndRestartSameResource: metadata.persistence.resume === "same-sandbox",
|
|
213
|
-
canCreateFilesystemSnapshot: metadata.persistence.capture === "filesystem" || metadata.persistence.capture === "directories",
|
|
214
|
-
canStartFromPreparedImage: driver === "exe" || driver === "daytona" || driver === "modal" || driver === "box" || driver === "docker",
|
|
215
|
-
canStopExplicitly: metadata.hostStopBehavior !== "not-supported",
|
|
216
|
-
hasHealthProbe: true
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
function decideSandboxStart(lease, placement, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
220
|
-
if (lease.status === "ready") {
|
|
221
|
-
return { action: "skip", reason: "already ready" };
|
|
222
|
-
}
|
|
223
|
-
if (lease.status === "failed") {
|
|
224
|
-
return { action: "mark_failed", reason: `terminal failure: ${lease.last_error ?? "unknown"}` };
|
|
225
|
-
}
|
|
226
|
-
if (lease.status === "backoff") {
|
|
227
|
-
if (lease.retry_count >= config.maxRetries) {
|
|
228
|
-
return { action: "mark_failed", reason: `exceeded max retries (${config.maxRetries})` };
|
|
229
|
-
}
|
|
230
|
-
if (lease.next_retry_at && now < lease.next_retry_at) {
|
|
231
|
-
return { action: "wait", until: lease.next_retry_at, reason: "backoff timer not elapsed" };
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
if (lease.status === "acquiring" || lease.status === "starting") {
|
|
235
|
-
return { action: "skip", reason: `already ${lease.status}` };
|
|
236
|
-
}
|
|
237
|
-
return decideStartMethod(lease, placement);
|
|
238
|
-
}
|
|
239
|
-
function decideSandboxHealthFailure(lease, _placement, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
240
|
-
if (lease.status !== "ready" && lease.status !== "unhealthy") {
|
|
241
|
-
return { action: "skip", reason: `status is ${lease.status}, health check not applicable` };
|
|
242
|
-
}
|
|
243
|
-
const retryCount = lease.retry_count + 1;
|
|
244
|
-
if (retryCount > config.maxRetries) {
|
|
245
|
-
return { action: "mark_failed", reason: `health failures exceeded max retries (${config.maxRetries})` };
|
|
246
|
-
}
|
|
247
|
-
const backoff = Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount - 1));
|
|
248
|
-
return { action: "wait", until: now + backoff, reason: `health failure #${retryCount}, backoff ${backoff}ms` };
|
|
249
|
-
}
|
|
250
|
-
function nextSandboxRetryAt(retryCount, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
251
|
-
if (retryCount >= config.maxRetries) return null;
|
|
252
|
-
return now + Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount));
|
|
253
|
-
}
|
|
254
|
-
function decideStartMethod(lease, placement) {
|
|
255
|
-
if (lease.sandbox_id && placement.canPauseAndRestartSameResource) {
|
|
256
|
-
return { action: "resume", reason: `resume sandbox ${lease.sandbox_id}` };
|
|
257
|
-
}
|
|
258
|
-
if (lease.accel_snapshot_id && placement.canCreateFilesystemSnapshot) {
|
|
259
|
-
return {
|
|
260
|
-
action: "restore_snapshot",
|
|
261
|
-
snapshot_id: lease.accel_snapshot_id,
|
|
262
|
-
reason: `restore snapshot ${lease.accel_snapshot_id}`
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
if (lease.accel_prepared_image_id && placement.canStartFromPreparedImage) {
|
|
266
|
-
return {
|
|
267
|
-
action: "start_prepared",
|
|
268
|
-
image_id: lease.accel_prepared_image_id,
|
|
269
|
-
reason: `start from prepared image ${lease.accel_prepared_image_id}`
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
return { action: "start_fresh", reason: "no acceleration available, cold start" };
|
|
273
|
-
}
|
|
274
|
-
export {
|
|
275
|
-
DEFAULT_WORKSPACE_HOST_DECISION_CONFIG,
|
|
276
|
-
decideSandboxHealthFailure,
|
|
277
|
-
decideSandboxStart,
|
|
278
|
-
nextSandboxRetryAt,
|
|
279
|
-
sandboxDriverPlacement
|
|
280
|
-
};
|