@claxedo/sandbox-manager 0.9.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.
Files changed (67) hide show
  1. package/README.md +233 -26
  2. package/dist/checkpoint-manager.d.ts +29 -4
  3. package/dist/checkpoint-manager.mjs +133 -24
  4. package/dist/command.d.ts +9 -2
  5. package/dist/command.mjs +8 -8
  6. package/dist/contract.d.ts +687 -0
  7. package/dist/driver-billing.d.ts +29 -0
  8. package/dist/driver-catalog.d.ts +42 -7
  9. package/dist/driver-catalog.mjs +115 -161
  10. package/dist/drivers/boat-client.d.ts +95 -0
  11. package/dist/drivers/boat-named-snapshots.d.ts +31 -0
  12. package/dist/drivers/boat-template.d.ts +49 -0
  13. package/dist/drivers/boat-template.mjs +1196 -0
  14. package/dist/drivers/boat.d.ts +64 -0
  15. package/dist/drivers/boat.mjs +990 -0
  16. package/dist/drivers/cloudflare.d.ts +3 -3
  17. package/dist/drivers/cloudflare.mjs +208 -147
  18. package/dist/drivers/docker.d.ts +4 -3
  19. package/dist/drivers/docker.mjs +154 -126
  20. package/dist/drivers/local-brokering.d.ts +14 -0
  21. package/dist/drivers/local-brokering.mjs +1029 -0
  22. package/dist/drivers/modal.d.ts +2 -2
  23. package/dist/drivers/modal.mjs +121 -111
  24. package/dist/drivers/transient-error.d.ts +2 -0
  25. package/dist/drivers/vercel.d.ts +3 -2
  26. package/dist/drivers/vercel.mjs +151 -115
  27. package/dist/egress-policy.d.ts +134 -0
  28. package/dist/egress-warnings.d.ts +22 -0
  29. package/dist/garbage-collect.d.ts +14 -0
  30. package/dist/hosted-network-policy.d.ts +9 -2
  31. package/dist/hosted-network-policy.mjs +218 -1
  32. package/dist/image-name.d.ts +12 -2
  33. package/dist/image-name.mjs +14 -5
  34. package/dist/image.d.ts +1 -20
  35. package/dist/image.mjs +11 -88
  36. package/dist/index.d.ts +8 -578
  37. package/dist/index.mjs +1379 -320
  38. package/dist/lease-failure.d.ts +173 -0
  39. package/dist/lease-lifecycle.d.ts +65 -0
  40. package/dist/lease-retry-wait.d.ts +8 -0
  41. package/dist/lease-start.d.ts +21 -0
  42. package/dist/lease-types.d.ts +4 -3
  43. package/dist/manager.d.ts +2 -0
  44. package/dist/runtime-env.d.ts +4 -2
  45. package/dist/runtime-env.mjs +37 -2
  46. package/dist/runtime-snapshot.d.ts +49 -0
  47. package/dist/runtime-version.d.ts +9 -0
  48. package/dist/runtime-version.mjs +2 -0
  49. package/dist/service-url-exposure.d.ts +0 -1
  50. package/dist/service-url-exposure.mjs +0 -9
  51. package/dist/start-fresh.d.ts +17 -0
  52. package/dist/start-telemetry.d.ts +37 -0
  53. package/dist/stores/memory.d.ts +1 -1
  54. package/dist/stores/memory.mjs +63 -52
  55. package/package.json +26 -42
  56. package/dist/daytona-allow-list.d.ts +0 -16
  57. package/dist/daytona-allow-list.mjs +0 -11
  58. package/dist/drivers/box.d.ts +0 -52
  59. package/dist/drivers/box.mjs +0 -574
  60. package/dist/drivers/daytona.d.ts +0 -163
  61. package/dist/drivers/daytona.mjs +0 -683
  62. package/dist/drivers/exe.d.ts +0 -26
  63. package/dist/drivers/exe.mjs +0 -492
  64. package/dist/drivers/fetch-bridge.d.ts +0 -10
  65. package/dist/drivers/fetch-bridge.mjs +0 -126
  66. package/dist/lease-policy.d.ts +0 -52
  67. package/dist/lease-policy.mjs +0 -290
@@ -1,52 +0,0 @@
1
- import type { SandboxLeaseRow } from "./lease-types";
2
- import type { SandboxDriverID } from "@claxedo/sandbox-contract";
3
- export type SandboxDecision = {
4
- action: "skip";
5
- reason: string;
6
- } | {
7
- action: "wait";
8
- until: number;
9
- reason: string;
10
- } | {
11
- action: "resume";
12
- reason: string;
13
- } | {
14
- action: "restore_snapshot";
15
- snapshot_id: string;
16
- reason: string;
17
- } | {
18
- action: "start_prepared";
19
- image_id: string;
20
- reason: string;
21
- } | {
22
- action: "start_fresh";
23
- reason: string;
24
- } | {
25
- action: "stop_idle";
26
- reason: string;
27
- } | {
28
- action: "mark_failed";
29
- reason: string;
30
- };
31
- export type SandboxDecisionConfig = {
32
- maxRetries: number;
33
- idleMs: number;
34
- backoffMaxMs: number;
35
- healthTimeoutMs: number;
36
- };
37
- export type SandboxDriverPlacement = {
38
- canPauseAndRestartSameResource: boolean;
39
- canCreateFilesystemSnapshot: boolean;
40
- canStartFromPreparedImage: boolean;
41
- canStopExplicitly: boolean;
42
- hasHealthProbe: boolean;
43
- };
44
- export declare const DEFAULT_WORKSPACE_HOST_DECISION_CONFIG: SandboxDecisionConfig;
45
- export declare function sandboxDriverPlacement(driver: SandboxDriverID): SandboxDriverPlacement;
46
- export declare function decideSandboxStart(lease: SandboxLeaseRow, placement: SandboxDriverPlacement, now: number, config?: SandboxDecisionConfig): SandboxDecision;
47
- /**
48
- * Health-failure policy is placement-independent: retry budget and backoff are
49
- * the same question for every driver, so this deliberately takes no placement.
50
- */
51
- export declare function decideSandboxHealthFailure(lease: SandboxLeaseRow, now: number, config?: SandboxDecisionConfig): SandboxDecision;
52
- export declare function nextSandboxRetryAt(retryCount: number, now: number, config?: SandboxDecisionConfig): number | null;
@@ -1,290 +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
- // ../sandbox-contract/dist/index.mjs
28
- var sandboxDriverCredentialFields = {
29
- exe: [{ key: "api_token", label: "API Token", secret: true }],
30
- daytona: [{ key: "api_key", label: "API Key", secret: true }],
31
- modal: [
32
- { key: "token_id", label: "Token ID", secret: true },
33
- { key: "token_secret", label: "Token Secret", secret: true }
34
- ],
35
- vercel: [
36
- { key: "access_token", label: "Access Token", secret: true },
37
- { key: "team_id", label: "Team ID" },
38
- { key: "project_id", label: "Project ID" }
39
- ],
40
- cloudflare: [
41
- { key: "api_token", label: "API Token", secret: true },
42
- { key: "worker_url", label: "Worker URL" }
43
- ],
44
- box: [{ key: "api_key", label: "API Key", secret: true }],
45
- docker: [{ key: "image", label: "Image" }]
46
- };
47
- var sandboxDriverLabels = {
48
- exe: "exe.dev",
49
- daytona: "Daytona",
50
- modal: "Modal",
51
- vercel: "Vercel",
52
- cloudflare: "Cloudflare",
53
- box: "Box",
54
- docker: "Docker"
55
- };
56
-
57
- // src/driver-catalog.ts
58
- var sandboxDriverCatalog = {
59
- exe: {
60
- id: "exe",
61
- label: sandboxDriverLabels.exe,
62
- credentialFields: sandboxDriverCredentialFields.exe,
63
- metadata: {
64
- driverRunsIn: ["worker", "node"],
65
- hostStopBehavior: "not-supported",
66
- hostResumeBehavior: "same-host",
67
- targetAccess: "relay",
68
- secretBrokering: "none",
69
- egressControl: "none",
70
- persistence: {
71
- resume: "same-sandbox",
72
- capture: "none",
73
- clone: true,
74
- captureSource: "not-applicable",
75
- retention: "provider-managed",
76
- restoreMount: "same-resource"
77
- }
78
- }
79
- },
80
- daytona: {
81
- id: "daytona",
82
- label: sandboxDriverLabels.daytona,
83
- credentialFields: sandboxDriverCredentialFields.daytona,
84
- metadata: {
85
- driverRunsIn: ["worker", "node"],
86
- hostStopBehavior: "suspends-host",
87
- hostResumeBehavior: "same-host",
88
- targetAccess: "relay",
89
- secretBrokering: "native",
90
- // The driver translates names to domainAllowList, or addresses to networkAllowList.
91
- egressControl: "hosts-and-cidrs",
92
- persistence: {
93
- resume: "same-sandbox",
94
- capture: "filesystem",
95
- clone: false,
96
- captureSource: "preserved",
97
- retention: "provider-managed",
98
- restoreMount: "new-resource"
99
- }
100
- }
101
- },
102
- modal: {
103
- id: "modal",
104
- label: sandboxDriverLabels.modal,
105
- credentialFields: sandboxDriverCredentialFields.modal,
106
- metadata: {
107
- driverRunsIn: ["node"],
108
- hostStopBehavior: "terminates-host",
109
- hostResumeBehavior: "replacement-host",
110
- targetAccess: "relay",
111
- secretBrokering: "none",
112
- // The driver does not install Modal's domain allowlist or alpha sidecar.
113
- egressControl: "none",
114
- persistence: {
115
- resume: "replacement-restore",
116
- capture: "filesystem",
117
- clone: false,
118
- captureSource: "preserved",
119
- retention: "provider-managed",
120
- restoreMount: "new-resource"
121
- }
122
- }
123
- },
124
- vercel: {
125
- id: "vercel",
126
- label: sandboxDriverLabels.vercel,
127
- credentialFields: sandboxDriverCredentialFields.vercel,
128
- metadata: {
129
- driverRunsIn: ["node"],
130
- hostStopBehavior: "terminates-host",
131
- hostResumeBehavior: "replacement-host",
132
- targetAccess: "relay",
133
- secretBrokering: "native",
134
- // The driver translates hosts only; the SDK's subnet rules are not wired to net.cidrs.
135
- egressControl: "hosts",
136
- persistence: {
137
- resume: "replacement-restore",
138
- capture: "filesystem",
139
- clone: false,
140
- captureSource: "stopped",
141
- retention: "explicit",
142
- restoreMount: "new-resource"
143
- }
144
- }
145
- },
146
- cloudflare: {
147
- id: "cloudflare",
148
- label: sandboxDriverLabels.cloudflare,
149
- credentialFields: sandboxDriverCredentialFields.cloudflare,
150
- metadata: {
151
- driverRunsIn: ["worker"],
152
- hostStopBehavior: "not-supported",
153
- hostResumeBehavior: "same-host",
154
- targetAccess: "relay",
155
- secretBrokering: "native",
156
- // Credential handlers do not restrict unrelated destinations.
157
- egressControl: "none",
158
- persistence: {
159
- resume: "replacement-restore",
160
- capture: "directories",
161
- clone: false,
162
- captureSource: "preserved",
163
- retention: "provider-managed",
164
- restoreMount: "copy-on-write"
165
- }
166
- }
167
- },
168
- box: {
169
- id: "box",
170
- label: sandboxDriverLabels.box,
171
- credentialFields: sandboxDriverCredentialFields.box,
172
- metadata: {
173
- driverRunsIn: ["node"],
174
- hostStopBehavior: "suspends-host",
175
- hostResumeBehavior: "same-host",
176
- targetAccess: "relay",
177
- secretBrokering: "none",
178
- egressControl: "none",
179
- persistence: {
180
- resume: "same-sandbox",
181
- capture: "none",
182
- clone: false,
183
- captureSource: "not-applicable",
184
- retention: "provider-managed",
185
- restoreMount: "same-resource"
186
- }
187
- }
188
- },
189
- docker: {
190
- id: "docker",
191
- label: sandboxDriverLabels.docker,
192
- credentialFields: sandboxDriverCredentialFields.docker,
193
- metadata: {
194
- driverRunsIn: ["local"],
195
- hostStopBehavior: "terminates-host",
196
- hostResumeBehavior: "same-host",
197
- targetAccess: "loopback",
198
- secretBrokering: "none",
199
- egressControl: "none",
200
- persistence: {
201
- resume: "replacement-restore",
202
- capture: "same-resource",
203
- clone: false,
204
- captureSource: "preserved",
205
- retention: "provider-managed",
206
- restoreMount: "same-resource"
207
- }
208
- }
209
- }
210
- };
211
-
212
- // src/lease-policy.ts
213
- var DEFAULT_WORKSPACE_HOST_DECISION_CONFIG = {
214
- maxRetries: 8,
215
- idleMs: 10 * 60 * 1e3,
216
- backoffMaxMs: 3e4,
217
- healthTimeoutMs: 6e4
218
- };
219
- function sandboxDriverPlacement(driver) {
220
- const metadata = sandboxDriverCatalog[driver].metadata;
221
- return {
222
- canPauseAndRestartSameResource: metadata.persistence.resume === "same-sandbox",
223
- canCreateFilesystemSnapshot: metadata.persistence.capture === "filesystem" || metadata.persistence.capture === "directories",
224
- canStartFromPreparedImage: driver === "exe" || driver === "daytona" || driver === "modal" || driver === "box" || driver === "docker",
225
- canStopExplicitly: metadata.hostStopBehavior !== "not-supported",
226
- hasHealthProbe: true
227
- };
228
- }
229
- function decideSandboxStart(lease, placement, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
230
- if (lease.status === "ready") {
231
- return { action: "skip", reason: "already ready" };
232
- }
233
- if (lease.status === "failed") {
234
- return { action: "mark_failed", reason: `terminal failure: ${lease.last_error ?? "unknown"}` };
235
- }
236
- if (lease.status === "backoff") {
237
- if (lease.retry_count >= config.maxRetries) {
238
- return { action: "mark_failed", reason: `exceeded max retries (${config.maxRetries})` };
239
- }
240
- if (lease.next_retry_at && now < lease.next_retry_at) {
241
- return { action: "wait", until: lease.next_retry_at, reason: "backoff timer not elapsed" };
242
- }
243
- }
244
- if (lease.status === "acquiring" || lease.status === "starting") {
245
- return { action: "skip", reason: `already ${lease.status}` };
246
- }
247
- return decideStartMethod(lease, placement);
248
- }
249
- function decideSandboxHealthFailure(lease, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
250
- if (lease.status !== "ready" && lease.status !== "unhealthy") {
251
- return { action: "skip", reason: `status is ${lease.status}, health check not applicable` };
252
- }
253
- const retryCount = lease.retry_count + 1;
254
- if (retryCount > config.maxRetries) {
255
- return { action: "mark_failed", reason: `health failures exceeded max retries (${config.maxRetries})` };
256
- }
257
- const backoff = Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount - 1));
258
- return { action: "wait", until: now + backoff, reason: `health failure #${retryCount}, backoff ${backoff}ms` };
259
- }
260
- function nextSandboxRetryAt(retryCount, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
261
- if (retryCount >= config.maxRetries) return null;
262
- return now + Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount));
263
- }
264
- function decideStartMethod(lease, placement) {
265
- if (lease.sandbox_id && placement.canPauseAndRestartSameResource) {
266
- return { action: "resume", reason: `resume sandbox ${lease.sandbox_id}` };
267
- }
268
- if (lease.accel_snapshot_id && placement.canCreateFilesystemSnapshot) {
269
- return {
270
- action: "restore_snapshot",
271
- snapshot_id: lease.accel_snapshot_id,
272
- reason: `restore snapshot ${lease.accel_snapshot_id}`
273
- };
274
- }
275
- if (lease.accel_prepared_image_id && placement.canStartFromPreparedImage) {
276
- return {
277
- action: "start_prepared",
278
- image_id: lease.accel_prepared_image_id,
279
- reason: `start from prepared image ${lease.accel_prepared_image_id}`
280
- };
281
- }
282
- return { action: "start_fresh", reason: "no acceleration available, cold start" };
283
- }
284
- export {
285
- DEFAULT_WORKSPACE_HOST_DECISION_CONFIG,
286
- decideSandboxHealthFailure,
287
- decideSandboxStart,
288
- nextSandboxRetryAt,
289
- sandboxDriverPlacement
290
- };