@evelandhq/sandbox-bwrap 0.4.1 → 0.5.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 +11 -4
- package/dist/index.d.ts +1 -1
- package/dist/provider-definition.d.ts +14 -1
- package/dist/provider-definition.js +37 -18
- package/dist/provider.d.ts +1 -1
- package/dist/runtime.d.ts +6 -0
- package/dist/runtime.js +5 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -120,8 +120,11 @@ directory — it is durable state. Cleanup closes that compute generation to new
|
|
|
120
120
|
the next backend `create()` opens a fresh generation over the same workspace. Repeated
|
|
121
121
|
`create()` calls through one backend instance share the live generation, so one handle
|
|
122
122
|
cannot race a new spawn past another handle's cleanup barrier. The provider's
|
|
123
|
-
`
|
|
124
|
-
generation the same way.
|
|
123
|
+
`onSandboxStop()` and `onRuntimeShutdown()` do the same, and its `resume()` shares the live
|
|
124
|
+
generation the same way. eve 0.75 renamed the handle hooks from `onSessionStop()` and
|
|
125
|
+
`onSessionDelete()` to `onSandboxStop()` and `onSandboxDelete()` and calls only the new names,
|
|
126
|
+
while eve 0.64 through 0.74 call only the old ones; the handle carries both pairs, each pair
|
|
127
|
+
the same function, so one installed copy serves every eve in the peer range.
|
|
125
128
|
|
|
126
129
|
### Options
|
|
127
130
|
|
|
@@ -163,8 +166,12 @@ The provider (eve 0.64 and later):
|
|
|
163
166
|
- **resume** (every later access, and after restarts): reopens the recorded workspace and
|
|
164
167
|
applies the recorded network policy to a new compute generation. It fails instead of
|
|
165
168
|
recreating a workspace that is gone.
|
|
166
|
-
- **onSessionDelete
|
|
167
|
-
metadata; the template survives.
|
|
169
|
+
- **onSandboxDelete** (`onSessionDelete` before eve 0.75): kills the session's processes
|
|
170
|
+
and removes its workspace and metadata; the template survives.
|
|
171
|
+
- **onSessionEnd** (eve 0.75 and later, once a durable session has completed, expired or
|
|
172
|
+
failed): releases the session's workspace and metadata from the persisted state alone,
|
|
173
|
+
stopping the live generation if this process holds one, without resuming the sandbox. It
|
|
174
|
+
is idempotent, so eve may retry it, and a workspace that is already gone stays gone.
|
|
168
175
|
|
|
169
176
|
The backend (eve 0.62 and 0.63):
|
|
170
177
|
|
package/dist/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { BwrapSandboxCreateOptions } from "./options.js";
|
|
|
3
3
|
export { BWRAP_BACKEND_NAME, createBwrapSandboxBackend, type CreateBwrapSandboxBackendInput, } from "./backend.js";
|
|
4
4
|
export type { BwrapBackendBootstrapContext, BwrapBackendCreateInput, BwrapBackendHandle, BwrapBackendPrewarmInput, BwrapBackendRuntimeContext, BwrapBackendSessionState, BwrapSandboxBackend, BwrapSeedFile, } from "./backend-contract.js";
|
|
5
5
|
export { BwrapTemplateNotProvisionedError } from "./errors.js";
|
|
6
|
-
export { BWRAP_PROVIDER_STATE_PROTOCOL_VERSION, createBwrapSandboxProviderDefinition, type BwrapPreparedArtifact, type BwrapSandboxEnvironmentOptions, type BwrapSandboxOpenOptions, type BwrapSandboxProviderDefinition, type BwrapSessionState, type CreateBwrapSandboxProviderDefinitionInput, type MutableNetworkSandboxSession, } from "./provider-definition.js";
|
|
6
|
+
export { BWRAP_PROVIDER_STATE_PROTOCOL_VERSION, createBwrapSandboxProviderDefinition, type BwrapPreparedArtifact, type BwrapSandboxEnvironmentOptions, type BwrapSandboxOpenOptions, type BwrapSandboxProviderDefinition, type BwrapSessionState, type CreateBwrapSandboxProviderDefinitionInput, type BwrapProviderHandle, type BwrapSandboxDeleteOptions, type MutableNetworkSandboxSession, } from "./provider-definition.js";
|
|
7
7
|
export type { BwrapSession } from "./session.js";
|
|
8
8
|
export type { BwrapNetworkPolicy, BwrapSandboxCreateOptions, BwrapSandboxUseOptions, } from "./options.js";
|
|
9
9
|
export type { BwrapCommandFinishReason, BwrapSandboxEvent, BwrapSandboxEventSink, } from "./events.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SandboxNetworkPolicy, SandboxSession } from "eve/sandbox";
|
|
2
|
-
import type { SandboxProviderDefinition } from "eve/sandbox/provider";
|
|
2
|
+
import type { SandboxProviderDefinition, SandboxProviderHandle } from "eve/sandbox/provider";
|
|
3
3
|
import { type BwrapDirectoryCopier } from "./cache.js";
|
|
4
4
|
import type { BwrapNetworkPolicy, BwrapSandboxCreateOptions } from "./options.js";
|
|
5
5
|
import type { ProcessRunner } from "./process.js";
|
|
@@ -18,6 +18,19 @@ export declare const BWRAP_PROVIDER_STATE_PROTOCOL_VERSION = 1;
|
|
|
18
18
|
export type MutableNetworkSandboxSession = SandboxSession & {
|
|
19
19
|
setNetworkPolicy(policy: SandboxNetworkPolicy): Promise<void>;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* The handle this provider hands eve. eve 0.75 renamed the handle's lifecycle
|
|
23
|
+
* hooks from `onSessionStop`/`onSessionDelete` to `onSandboxStop`/`onSandboxDelete`
|
|
24
|
+
* and calls only the new names, while 0.64 through 0.74 call only the old ones.
|
|
25
|
+
* One installed copy of this package serves every eve in the peer range, so the
|
|
26
|
+
* handle answers to both names, each pair being the same function.
|
|
27
|
+
*/
|
|
28
|
+
export type BwrapProviderHandle = SandboxProviderHandle<MutableNetworkSandboxSession> & {
|
|
29
|
+
onSessionStop(): Promise<void>;
|
|
30
|
+
onSessionDelete(options?: BwrapSandboxDeleteOptions): Promise<void>;
|
|
31
|
+
};
|
|
32
|
+
/** What eve passes when it deletes a sandbox: at most an abort signal. */
|
|
33
|
+
export type BwrapSandboxDeleteOptions = Parameters<SandboxProviderHandle<MutableNetworkSandboxSession>["onSandboxDelete"]>[0];
|
|
21
34
|
/** Options for `BwrapSandbox.environment(...)`. */
|
|
22
35
|
export type BwrapSandboxEnvironmentOptions = Omit<BwrapSandboxCreateOptions, "templateRevision"> & {
|
|
23
36
|
/**
|
|
@@ -52,31 +52,38 @@ export function createBwrapSandboxProviderDefinition(input = {}) {
|
|
|
52
52
|
leaseRoot: roots.sessionRoot,
|
|
53
53
|
});
|
|
54
54
|
await applyNetworkPolicy(session, created);
|
|
55
|
+
// The processes are the compute and the workspace directory is the
|
|
56
|
+
// durable session: stopping kills the processes and keeps the files.
|
|
57
|
+
const stop = async () => {
|
|
58
|
+
await session.killAll();
|
|
59
|
+
};
|
|
60
|
+
// The session's own workspace is disposable; the template it was
|
|
61
|
+
// cloned from is shared by every other session and must survive.
|
|
62
|
+
const remove = async (deleteOptions) => {
|
|
63
|
+
deleteOptions?.abortSignal?.throwIfAborted();
|
|
64
|
+
await session.killAll();
|
|
65
|
+
runtime.forgetRuntimeSession(sessionPath);
|
|
66
|
+
await removeSessionWorkspace(roots.sessionRoot, sessionPath);
|
|
67
|
+
};
|
|
55
68
|
return {
|
|
56
69
|
sandbox: session,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
async onSessionStop() {
|
|
60
|
-
await session.killAll();
|
|
61
|
-
},
|
|
70
|
+
onSandboxStop: stop,
|
|
71
|
+
onSessionStop: stop,
|
|
62
72
|
async onRuntimeShutdown() {
|
|
63
73
|
await session.killAll();
|
|
64
74
|
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
async onSessionDelete(deleteOptions) {
|
|
68
|
-
deleteOptions?.abortSignal?.throwIfAborted();
|
|
69
|
-
await session.killAll();
|
|
70
|
-
runtime.forgetRuntimeSession(sessionPath);
|
|
71
|
-
await rm(sessionPath, { force: true, recursive: true });
|
|
72
|
-
await removeCacheMetadata({
|
|
73
|
-
cacheRoot: roots.sessionRoot,
|
|
74
|
-
kind: "session",
|
|
75
|
-
id: basename(sessionPath),
|
|
76
|
-
});
|
|
77
|
-
},
|
|
75
|
+
onSandboxDelete: remove,
|
|
76
|
+
onSessionDelete: remove,
|
|
78
77
|
};
|
|
79
78
|
}
|
|
79
|
+
async function removeSessionWorkspace(sessionRoot, sessionPath) {
|
|
80
|
+
await rm(sessionPath, { force: true, recursive: true });
|
|
81
|
+
await removeCacheMetadata({
|
|
82
|
+
cacheRoot: sessionRoot,
|
|
83
|
+
kind: "session",
|
|
84
|
+
id: basename(sessionPath),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
80
87
|
return {
|
|
81
88
|
async prepare(ctx) {
|
|
82
89
|
const templateKey = JSON.stringify({
|
|
@@ -176,6 +183,18 @@ export function createBwrapSandboxProviderDefinition(input = {}) {
|
|
|
176
183
|
await session.setNetworkPolicy(state.networkPolicy);
|
|
177
184
|
});
|
|
178
185
|
},
|
|
186
|
+
// eve 0.75 releases a durable session's sandbox once the session has
|
|
187
|
+
// completed, expired or failed, from persisted state alone. Only the
|
|
188
|
+
// workspace is touched, never the template, and nothing is resumed to
|
|
189
|
+
// do it: a live generation in this process is stopped, a workspace that
|
|
190
|
+
// is already gone is left gone, so the step may retry.
|
|
191
|
+
async onSessionEnd(ctx, _preparedArtifact, sessionState) {
|
|
192
|
+
const state = requireSessionState(sessionState);
|
|
193
|
+
const roots = cacheRoots(ctx.storagePath);
|
|
194
|
+
const sessionPath = sessionPathIn(roots.sessionRoot, state.sessionKey);
|
|
195
|
+
await runtime.closeRuntimeSession(sessionPath);
|
|
196
|
+
await removeSessionWorkspace(roots.sessionRoot, sessionPath);
|
|
197
|
+
},
|
|
179
198
|
};
|
|
180
199
|
},
|
|
181
200
|
};
|
package/dist/provider.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BWRAP_PROVIDER_STATE_PROTOCOL_VERSION, createBwrapSandboxProviderDefinition, type BwrapPreparedArtifact, type BwrapSandboxEnvironmentOptions, type BwrapSandboxOpenOptions, type BwrapSandboxProviderDefinition, type BwrapSessionState, type CreateBwrapSandboxProviderDefinitionInput, type MutableNetworkSandboxSession, } from "./provider-definition.js";
|
|
1
|
+
export { BWRAP_PROVIDER_STATE_PROTOCOL_VERSION, createBwrapSandboxProviderDefinition, type BwrapPreparedArtifact, type BwrapSandboxEnvironmentOptions, type BwrapSandboxOpenOptions, type BwrapSandboxProviderDefinition, type BwrapSessionState, type CreateBwrapSandboxProviderDefinitionInput, type BwrapProviderHandle, type BwrapSandboxDeleteOptions, type MutableNetworkSandboxSession, } from "./provider-definition.js";
|
|
2
2
|
export { isBwrapAvailable } from "./process.js";
|
|
3
3
|
/**
|
|
4
4
|
* The bubblewrap sandbox provider for eve 0.64 and later.
|
package/dist/runtime.d.ts
CHANGED
|
@@ -35,6 +35,12 @@ export interface BwrapRuntime {
|
|
|
35
35
|
}>;
|
|
36
36
|
/** Drops a deleted workspace's generation so the next open starts fresh. */
|
|
37
37
|
forgetRuntimeSession(workspaceDir: string): void;
|
|
38
|
+
/**
|
|
39
|
+
* Stops the live generation over this workspace, if there is one, and drops
|
|
40
|
+
* it. Nothing is started for a workspace that has no generation, so this is
|
|
41
|
+
* safe to call for a session whose sandbox was never resumed in this process.
|
|
42
|
+
*/
|
|
43
|
+
closeRuntimeSession(workspaceDir: string): Promise<void>;
|
|
38
44
|
}
|
|
39
45
|
export declare function createBwrapRuntime(input: {
|
|
40
46
|
readonly options: ResolvedBwrapSandboxOptions;
|
package/dist/runtime.js
CHANGED
|
@@ -68,6 +68,11 @@ export function createBwrapRuntime(input) {
|
|
|
68
68
|
forgetRuntimeSession(workspaceDir) {
|
|
69
69
|
generations.delete(workspaceDir);
|
|
70
70
|
},
|
|
71
|
+
async closeRuntimeSession(workspaceDir) {
|
|
72
|
+
const current = generations.get(workspaceDir);
|
|
73
|
+
generations.delete(workspaceDir);
|
|
74
|
+
await current?.killAll();
|
|
75
|
+
},
|
|
71
76
|
};
|
|
72
77
|
}
|
|
73
78
|
function resolveSeedPath(seedPath) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@evelandhq/sandbox-bwrap",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "bubblewrap sandbox for eve agents — real exec sandboxing without Docker or KVM",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^26.0.1",
|
|
47
47
|
"ai": "^7.0.44",
|
|
48
|
-
"eve": "0.
|
|
48
|
+
"eve": "0.75.1",
|
|
49
49
|
"eve-floor": "npm:eve@0.62.0",
|
|
50
50
|
"oxfmt": "0.58.0",
|
|
51
51
|
"oxlint": "1.73.0",
|