@claxedo/sandbox-manager 0.6.0 → 0.7.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 +50 -1
- package/dist/checkpoint-manager.d.ts +47 -0
- package/dist/checkpoint-manager.mjs +116 -0
- package/dist/daytona-allow-list.d.ts +11 -0
- package/dist/daytona-allow-list.mjs +5 -1
- package/dist/driver-catalog.d.ts +9 -6
- package/dist/driver-catalog.mjs +150 -17
- package/dist/drivers/box.mjs +205 -10
- package/dist/drivers/cloudflare.d.ts +15 -1
- package/dist/drivers/cloudflare.mjs +301 -2
- package/dist/drivers/daytona.d.ts +33 -0
- package/dist/drivers/daytona.mjs +310 -2
- package/dist/drivers/docker.mjs +205 -10
- package/dist/drivers/exe.d.ts +26 -0
- package/dist/drivers/exe.mjs +469 -0
- package/dist/drivers/fetch-bridge.mjs +10 -1
- package/dist/drivers/modal.mjs +205 -10
- package/dist/drivers/vercel.d.ts +23 -4
- package/dist/drivers/vercel.mjs +225 -19
- package/dist/hosted-network-policy.d.ts +87 -0
- package/dist/hosted-network-policy.mjs +61 -0
- package/dist/image.d.ts +16 -1
- package/dist/image.mjs +14 -21
- package/dist/index.d.ts +220 -1
- package/dist/index.mjs +341 -20
- package/dist/lease-policy.d.ts +1 -2
- package/dist/lease-policy.mjs +203 -54
- package/dist/lease-types.d.ts +6 -1
- package/dist/runtime-version.mjs +1 -9
- package/dist/stores/memory.mjs +37 -2
- package/package.json +16 -2
package/dist/lease-policy.mjs
CHANGED
|
@@ -1,56 +1,220 @@
|
|
|
1
|
-
// src/
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
+
},
|
|
9
50
|
daytona: {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
+
}
|
|
15
73
|
},
|
|
16
74
|
modal: {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
+
}
|
|
22
100
|
},
|
|
23
101
|
vercel: {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
+
}
|
|
29
127
|
},
|
|
30
128
|
cloudflare: {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
+
}
|
|
36
157
|
},
|
|
37
158
|
box: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
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
|
+
}
|
|
43
178
|
},
|
|
44
179
|
docker: {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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
|
+
}
|
|
50
199
|
}
|
|
51
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
|
+
};
|
|
52
209
|
function sandboxDriverPlacement(driver) {
|
|
53
|
-
|
|
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
|
+
};
|
|
54
218
|
}
|
|
55
219
|
function decideSandboxStart(lease, placement, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
56
220
|
if (lease.status === "ready") {
|
|
@@ -83,20 +247,6 @@ function decideSandboxHealthFailure(lease, _placement, now, config = DEFAULT_WOR
|
|
|
83
247
|
const backoff = Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount - 1));
|
|
84
248
|
return { action: "wait", until: now + backoff, reason: `health failure #${retryCount}, backoff ${backoff}ms` };
|
|
85
249
|
}
|
|
86
|
-
function decideSandboxIdle(lease, activeHoldCount, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
87
|
-
if (lease.status !== "ready") {
|
|
88
|
-
return { action: "skip", reason: `status is ${lease.status}, not ready` };
|
|
89
|
-
}
|
|
90
|
-
if (activeHoldCount > 0) {
|
|
91
|
-
return { action: "skip", reason: `${activeHoldCount} active hold(s)` };
|
|
92
|
-
}
|
|
93
|
-
const lastActivity = lease.last_activity_at ?? lease.created_at;
|
|
94
|
-
const idleFor = now - lastActivity;
|
|
95
|
-
if (idleFor < config.idleMs) {
|
|
96
|
-
return { action: "wait", until: lastActivity + config.idleMs, reason: `idle for ${idleFor}ms, need ${config.idleMs}ms` };
|
|
97
|
-
}
|
|
98
|
-
return { action: "stop_idle", reason: `idle for ${idleFor}ms (threshold: ${config.idleMs}ms)` };
|
|
99
|
-
}
|
|
100
250
|
function nextSandboxRetryAt(retryCount, now, config = DEFAULT_WORKSPACE_HOST_DECISION_CONFIG) {
|
|
101
251
|
if (retryCount >= config.maxRetries) return null;
|
|
102
252
|
return now + Math.min(config.backoffMaxMs, 1e3 * 2 ** Math.max(0, retryCount));
|
|
@@ -124,7 +274,6 @@ function decideStartMethod(lease, placement) {
|
|
|
124
274
|
export {
|
|
125
275
|
DEFAULT_WORKSPACE_HOST_DECISION_CONFIG,
|
|
126
276
|
decideSandboxHealthFailure,
|
|
127
|
-
decideSandboxIdle,
|
|
128
277
|
decideSandboxStart,
|
|
129
278
|
nextSandboxRetryAt,
|
|
130
279
|
sandboxDriverPlacement
|
package/dist/lease-types.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { SandboxDriverID } from "./driver-catalog";
|
|
2
|
-
|
|
2
|
+
import type { SandboxCheckpointReference, SandboxPersistenceCapabilities, SandboxRestoreStatus } from "./index";
|
|
3
|
+
export type SandboxLeaseRowStatus = "pending" | "acquiring" | "starting" | "ready" | "unhealthy" | "backoff" | "stopping" | "stopped" | "destroyed" | "failed";
|
|
3
4
|
export type SandboxComputeClass = "small" | "medium" | "large" | "gpu";
|
|
4
5
|
export type SandboxLeaseRow = {
|
|
5
6
|
workspace_id: string;
|
|
@@ -22,6 +23,10 @@ export type SandboxLeaseRow = {
|
|
|
22
23
|
accel_base_image_id: string | null;
|
|
23
24
|
accel_prepared_image_id: string | null;
|
|
24
25
|
accel_snapshot_id: string | null;
|
|
26
|
+
labels?: Record<string, string> | null;
|
|
27
|
+
checkpoint: SandboxCheckpointReference | null;
|
|
28
|
+
persistence: SandboxPersistenceCapabilities | null;
|
|
29
|
+
restore: SandboxRestoreStatus | null;
|
|
25
30
|
created_at: number;
|
|
26
31
|
updated_at: number;
|
|
27
32
|
};
|
package/dist/runtime-version.mjs
CHANGED
|
@@ -1,15 +1,7 @@
|
|
|
1
1
|
// src/runtime-version.ts
|
|
2
2
|
var DEFAULT_WORKSPACE_RUNTIME_VERSION = "0.5.2";
|
|
3
|
-
var versionCache;
|
|
4
3
|
function workspaceRuntimeVersion() {
|
|
5
|
-
|
|
6
|
-
const envVersion = process.env.WORKSPACE_RUNTIME_VERSION;
|
|
7
|
-
if (envVersion) {
|
|
8
|
-
versionCache = envVersion;
|
|
9
|
-
return versionCache;
|
|
10
|
-
}
|
|
11
|
-
versionCache = DEFAULT_WORKSPACE_RUNTIME_VERSION;
|
|
12
|
-
return versionCache;
|
|
4
|
+
return process.env.WORKSPACE_RUNTIME_VERSION || DEFAULT_WORKSPACE_RUNTIME_VERSION;
|
|
13
5
|
}
|
|
14
6
|
export {
|
|
15
7
|
workspaceRuntimeVersion
|
package/dist/stores/memory.mjs
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
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
|
+
|
|
1
27
|
// src/index.ts
|
|
2
28
|
function applySandboxLeasePatch(current, patch, updatedAt) {
|
|
3
29
|
return {
|
|
@@ -13,6 +39,9 @@ function applySandboxLeasePatch(current, patch, updatedAt) {
|
|
|
13
39
|
...patch.labels === void 0 ? {} : { labels: patch.labels },
|
|
14
40
|
...patch.nextRetryAt === void 0 ? {} : { nextRetryAt: patch.nextRetryAt ?? void 0 },
|
|
15
41
|
...patch.lastError === void 0 ? {} : { lastError: patch.lastError ?? void 0 },
|
|
42
|
+
...patch.checkpoint === void 0 ? {} : { checkpoint: patch.checkpoint ?? void 0 },
|
|
43
|
+
...patch.persistence === void 0 ? {} : { persistence: patch.persistence ?? void 0 },
|
|
44
|
+
...patch.restore === void 0 ? {} : { restore: patch.restore ?? void 0 },
|
|
16
45
|
updatedAt
|
|
17
46
|
};
|
|
18
47
|
}
|
|
@@ -50,7 +79,10 @@ function createMemoryLeaseStore(seed = []) {
|
|
|
50
79
|
driverResourceId: resumable ? current.driverResourceId : void 0,
|
|
51
80
|
lastHeartbeatAt: resumable ? current.lastHeartbeatAt : void 0,
|
|
52
81
|
lastActivityAt: resumable ? current.lastActivityAt : void 0,
|
|
53
|
-
labels: resumable ? current.labels : void 0
|
|
82
|
+
labels: resumable ? current.labels : void 0,
|
|
83
|
+
checkpoint: current?.checkpoint,
|
|
84
|
+
persistence: current?.persistence,
|
|
85
|
+
restore: current?.restore
|
|
54
86
|
};
|
|
55
87
|
leases.set(workspaceId, next);
|
|
56
88
|
return { acquired: true, lease: next };
|
|
@@ -106,7 +138,10 @@ function sandboxLease(input) {
|
|
|
106
138
|
lastError: input.lastError,
|
|
107
139
|
lastHeartbeatAt: input.lastHeartbeatAt,
|
|
108
140
|
lastActivityAt: input.lastActivityAt,
|
|
109
|
-
labels: input.labels
|
|
141
|
+
labels: input.labels,
|
|
142
|
+
checkpoint: input.checkpoint,
|
|
143
|
+
persistence: input.persistence,
|
|
144
|
+
restore: input.restore
|
|
110
145
|
};
|
|
111
146
|
}
|
|
112
147
|
export {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claxedo/sandbox-manager",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Sandbox lifecycle manager with epoch-based leases and pluggable drivers for Daytona, Modal, Vercel Sandbox, Cloudflare, Box, and Docker",
|
|
6
6
|
"license": "MIT",
|
|
@@ -44,6 +44,13 @@
|
|
|
44
44
|
"import": "./dist/constants.mjs",
|
|
45
45
|
"default": "./dist/constants.mjs"
|
|
46
46
|
},
|
|
47
|
+
"./checkpoint-manager": {
|
|
48
|
+
"types": "./dist/checkpoint-manager.d.ts",
|
|
49
|
+
"bun": "./dist/checkpoint-manager.mjs",
|
|
50
|
+
"development": "./dist/checkpoint-manager.mjs",
|
|
51
|
+
"import": "./dist/checkpoint-manager.mjs",
|
|
52
|
+
"default": "./dist/checkpoint-manager.mjs"
|
|
53
|
+
},
|
|
47
54
|
"./defaults": {
|
|
48
55
|
"types": "./dist/defaults.d.ts",
|
|
49
56
|
"bun": "./dist/defaults.mjs",
|
|
@@ -65,6 +72,13 @@
|
|
|
65
72
|
"import": "./dist/drivers/box.mjs",
|
|
66
73
|
"default": "./dist/drivers/box.mjs"
|
|
67
74
|
},
|
|
75
|
+
"./drivers/exe": {
|
|
76
|
+
"types": "./dist/drivers/exe.d.ts",
|
|
77
|
+
"bun": "./dist/drivers/exe.mjs",
|
|
78
|
+
"development": "./dist/drivers/exe.mjs",
|
|
79
|
+
"import": "./dist/drivers/exe.mjs",
|
|
80
|
+
"default": "./dist/drivers/exe.mjs"
|
|
81
|
+
},
|
|
68
82
|
"./drivers/cloudflare": {
|
|
69
83
|
"types": "./dist/drivers/cloudflare.d.ts",
|
|
70
84
|
"bun": "./dist/drivers/cloudflare.mjs",
|
|
@@ -174,7 +188,7 @@
|
|
|
174
188
|
"build": "tsx scripts/build.ts",
|
|
175
189
|
"prepublishOnly": "npm run build",
|
|
176
190
|
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
177
|
-
"test": "bun test src"
|
|
191
|
+
"test": "mkdir -p .artifacts/unit && bun test src --reporter=junit --reporter-outfile=.artifacts/unit/junit.xml"
|
|
178
192
|
},
|
|
179
193
|
"devDependencies": {
|
|
180
194
|
"@tsconfig/node-lts": "22.0.4",
|