@evelandhq/sandbox-bwrap 0.1.2 → 0.1.3

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
@@ -21,11 +21,12 @@ the sandbox module into the release directory at build time — `agent/sandbox.j
21
21
  agent, or `agent/sandbox/sandbox.js` when a sandbox folder exists, recursively for every
22
22
  subagent — and vendors this package's built output beside it, so agent projects never declare
23
23
  a deployment backend themselves. If a project shipped its own sandbox module, the build
24
- replaces that definition and reports it in the build log; authored `bootstrap()` and
25
- `onSession()` behavior is not used. The sibling `agent/sandbox/workspace/**` tree is preserved,
26
- so Eve still seeds those files into each Session's `/workspace`. Each Eveland Release supplies a
27
- distinct template revision, so Sessions created against a new Deployment see its updated seeds
28
- while existing durable Session workspaces remain untouched. The systemd runtime invokes
24
+ wraps that definition and reports it in the build log: Eveland overrides only `backend`, while
25
+ authored `bootstrap()`, `onSession()`, `description`, and `revalidationKey` remain active. The
26
+ sibling `agent/sandbox/workspace/**` tree is preserved, so Eve still seeds those files into each
27
+ Session's `/workspace`. Each Eveland Release supplies a distinct template revision, so Sessions
28
+ created against a new Deployment see its updated seeds while existing durable Session workspaces
29
+ remain untouched. The systemd runtime invokes
29
30
  bwrap as its unprivileged deployment user. The local Docker runtime installs bwrap inside the Agent
30
31
  image and grants the outer container only the capabilities nested bwrap requires; the
31
32
  Agent container still receives no Docker socket. Local `eve dev` is untouched — it never runs
@@ -85,11 +86,17 @@ next callback reopens it.
85
86
  | `templateRevision` | `null` | Optional immutable release identity included in the template cache key but not the session path. Change it when seed files change so new Sessions use a fresh template without overwriting durable workspaces. Eveland sets it from its internal `EVELAND_SANDBOX_TEMPLATE_REVISION`. |
86
87
  | `runTimeoutMs` | `600000` | Hard wall-clock limit for one `run()` command. Timeout aborts the command and kills its complete bwrap process group. Set `null` to disable it. The limit deliberately does not apply to `spawn()`, which is the API for long-running processes. |
87
88
 
89
+ Both lifecycle callbacks may call `use({ networkPolicy: "allow-all" | "deny-all" })`. The
90
+ policy is applied before `use()` returns the template or live Session, so subsequent commands in
91
+ that callback use the requested network boundary. Calling `use()` without options keeps the
92
+ backend's configured policy.
93
+
88
94
  ## How it works
89
95
 
90
- - **prewarm** (build time): runs the authored `bootstrap` inside bwrap against a
91
- staging directory, resolves Eve's `$HOME/.agents/skills/**` seed paths to
92
- `/workspace/.agents/skills/**`, writes seed files, then atomically renames it into
96
+ - **prewarm** (build time): resolves Eve's `$HOME/.agents/skills/**` seed paths to
97
+ `/workspace/.agents/skills/**`, writes every seed into a staging directory, then runs the
98
+ authored `bootstrap` inside bwrap so it can consume those canonical inputs, before atomically
99
+ renaming the result into
93
100
  `<cacheDir>/templates/<hash>` (`<cacheDir>` defaults to
94
101
  `<appRoot>/.eve/sandbox-cache/bwrap` when the `cacheDir` option is not set). Idempotent
95
102
  per template key + options hash; `templateRevision` participates in that hash.
package/dist/backend.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { SandboxBackend } from "eve/sandbox";
2
- import type { BwrapSandboxCreateOptions } from "./options.js";
2
+ import type { BwrapSandboxCreateOptions, BwrapSandboxUseOptions } from "./options.js";
3
3
  import type { ProcessRunner } from "./process.js";
4
4
  /**
5
5
  * Stable backend name. Participates in eve's template/session cache-key
@@ -11,4 +11,4 @@ export interface CreateBwrapSandboxBackendInput {
11
11
  /** Injectable process launcher so backend logic is testable without bwrap. */
12
12
  readonly runner?: ProcessRunner;
13
13
  }
14
- export declare function createBwrapSandboxBackend(input?: CreateBwrapSandboxBackendInput): SandboxBackend;
14
+ export declare function createBwrapSandboxBackend(input?: CreateBwrapSandboxBackendInput): SandboxBackend<BwrapSandboxUseOptions, BwrapSandboxUseOptions>;
package/dist/backend.js CHANGED
@@ -67,6 +67,12 @@ export function createBwrapSandboxBackend(input = {}) {
67
67
  }
68
68
  }
69
69
  }
70
+ async function useSession(session, useOptions) {
71
+ if (useOptions?.networkPolicy !== undefined) {
72
+ await session.setNetworkPolicy(useOptions.networkPolicy);
73
+ }
74
+ return session;
75
+ }
70
76
  return {
71
77
  name: BWRAP_BACKEND_NAME,
72
78
  async prewarm({ templateKey, bootstrap, seedFiles, log, runtimeContext }) {
@@ -79,9 +85,10 @@ export function createBwrapSandboxBackend(input = {}) {
79
85
  await mkdir(stagingPath, { recursive: true });
80
86
  try {
81
87
  const session = openSession(templateKey, stagingPath, runtimeContext.appRoot);
82
- if (bootstrap)
83
- await bootstrap({ use: async () => session });
84
88
  await writeSeedFiles(session, seedFiles);
89
+ if (bootstrap) {
90
+ await bootstrap({ use: async (useOptions) => await useSession(session, useOptions) });
91
+ }
85
92
  await rename(stagingPath, templatePath);
86
93
  }
87
94
  catch (error) {
@@ -114,7 +121,7 @@ export function createBwrapSandboxBackend(input = {}) {
114
121
  const session = openSession(sessionKey, sessionPath, runtimeContext.appRoot);
115
122
  return {
116
123
  session,
117
- useSessionFn: async () => session,
124
+ useSessionFn: async (useOptions) => await useSession(session, useOptions),
118
125
  async captureState() {
119
126
  return { backendName: BWRAP_BACKEND_NAME, metadata: {}, sessionKey };
120
127
  },
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import type { SandboxBackend } from "eve/sandbox";
2
- import type { BwrapSandboxCreateOptions } from "./options.js";
2
+ import type { BwrapSandboxCreateOptions, BwrapSandboxUseOptions } from "./options.js";
3
3
  export { BWRAP_BACKEND_NAME, createBwrapSandboxBackend, type CreateBwrapSandboxBackendInput, } from "./backend.js";
4
- export type { BwrapNetworkPolicy, BwrapSandboxCreateOptions } from "./options.js";
4
+ export type { BwrapNetworkPolicy, BwrapSandboxCreateOptions, BwrapSandboxUseOptions, } from "./options.js";
5
5
  export { DEFAULT_RUN_TIMEOUT_MS } from "./options.js";
6
6
  export { isBwrapAvailable } from "./process.js";
7
7
  export type { ProcessRunner, SpawnedProcess } from "./process.js";
@@ -18,4 +18,4 @@ export type { ProcessRunner, SpawnedProcess } from "./process.js";
18
18
  * });
19
19
  * ```
20
20
  */
21
- export declare function bwrap(options?: BwrapSandboxCreateOptions): SandboxBackend;
21
+ export declare function bwrap(options?: BwrapSandboxCreateOptions): SandboxBackend<BwrapSandboxUseOptions, BwrapSandboxUseOptions>;
package/dist/options.d.ts CHANGED
@@ -1,5 +1,10 @@
1
1
  /** Coarse egress control, matching what eve's Docker backend supports. */
2
2
  export type BwrapNetworkPolicy = "allow-all" | "deny-all";
3
+ /** Options lifecycle hooks can apply when they open a template or live Session. */
4
+ export interface BwrapSandboxUseOptions {
5
+ /** Network policy used by subsequent commands in this lifecycle callback. */
6
+ readonly networkPolicy?: BwrapNetworkPolicy;
7
+ }
3
8
  /** Commands executed through `run()` are bounded by default; use `spawn()` for daemons. */
4
9
  export declare const DEFAULT_RUN_TIMEOUT_MS = 600000;
5
10
  /** Options accepted by `bwrap(opts)`. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@evelandhq/sandbox-bwrap",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "bubblewrap SandboxBackend for eve agents — real exec sandboxing without Docker or KVM",
5
5
  "keywords": [
6
6
  "agent",