agentic-pi 0.1.2 → 0.2.1

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
@@ -169,16 +169,32 @@ Linux + KVM should be in the same ballpark. Numbers are reproducible
169
169
  from `test/fixtures/phase3-smoke-sandbox-gondolin.jsonl`.
170
170
 
171
171
  **Event stream.** A `sandbox_status` JSONL line is emitted right after
172
- the session header:
172
+ the session header. It carries an `envKeys` list (just the keys, never
173
+ the values) so consumers can verify which env vars were handed to the VM:
173
174
 
174
175
  ```jsonl
175
- {"type":"sandbox_status","backend":"gondolin","status":{"backend":"gondolin","cwd":"/path/to/workspace","guestPath":"/workspace","createMs":47},"sessionId":"…","timestamp":"…"}
176
+ {"type":"sandbox_status","backend":"gondolin","status":{"backend":"gondolin","cwd":"/path/to/workspace","guestPath":"/workspace","createMs":47,"envKeys":["GH_TOKEN","GITHUB_TOKEN"]},"sessionId":"…","timestamp":"…"}
176
177
  ```
177
178
 
178
179
  If `--sandbox none` (the default), the same line is still emitted with
179
180
  `backend: "none"` so downstream consumers always know which mode the run
180
181
  used.
181
182
 
183
+ **Passing env into the VM.** Use `--sandbox-env KEY=VAL` on the CLI
184
+ (repeatable), or `sandboxEnv: { KEY: "VAL" }` on the programmatic API.
185
+ The agent's `bash` calls see these as ordinary environment variables.
186
+
187
+ When `--profile <github>` is also active and the GitHub extension is
188
+ configured, agentic-pi automatically mints a short-lived installation
189
+ token via the configured auth backend (App JWT exchange, or static
190
+ `GITHUB_TOKEN` passthrough) and injects it as **both** `GITHUB_TOKEN`
191
+ and `GH_TOKEN`. Inside the VM, `git push`, `git fetch`, and `gh`
192
+ commands work without further setup.
193
+
194
+ The **App PEM is never copied into the VM** — only the resulting token,
195
+ which is short-lived. User-supplied `--sandbox-env GITHUB_TOKEN=…`
196
+ overrides the auto-injected value if you need to scope down further.
197
+
182
198
  ## When to use this
183
199
 
184
200
  - You have an orchestrator that calls a coding agent once per workflow
@@ -237,6 +253,7 @@ GITHUB_TOKEN=ghp_…
237
253
  | `--no-builtin-tools` | Disable Pi's `read,write,edit,bash,grep,find,ls`. |
238
254
  | `--tools <a,b,c>` | Explicit tool allowlist (combined with profile if set). |
239
255
  | `--sandbox <none\|gondolin>` | Route `read`/`write`/`edit`/`bash` through a sandbox backend. Default `none`. `gondolin` boots a QEMU micro-VM mounting cwd at `/workspace`. Requires QEMU on the host; native-only (not Docker-in-Docker). See section 8. |
256
+ | `--sandbox-env KEY=VAL` | Inject env var into the sandbox VM (repeatable). Ignored when `--sandbox=none`. Auto-injects a minted `GITHUB_TOKEN`/`GH_TOKEN` when `--profile` is also active. |
240
257
  | `--dangerously-skip-permissions` | Accepted for caller-side compatibility. No-op. |
241
258
 
242
259
  Reads the prompt from stdin. Emits JSONL on stdout. Exits 0 on `agent_end`,
@@ -283,6 +300,14 @@ const result = await run({
283
300
  noSession: true,
284
301
  cwd: "/path/to/workspace",
285
302
 
303
+ // Per-run env handed to the sandbox VM. Ignored when sandbox="none".
304
+ // When sandbox="gondolin" + profile is set, GITHUB_TOKEN/GH_TOKEN are
305
+ // auto-injected from a minted installation token — explicit values
306
+ // here win.
307
+ sandboxEnv: {
308
+ CI_BUILD_REF: process.env.GITHUB_SHA ?? "",
309
+ },
310
+
286
311
  // Optional observability hooks. Both are pure callbacks — no I/O happens
287
312
  // unless you do something with the values.
288
313
  onEvent: (record) => myShim.writeJsonl(record),
@@ -382,19 +407,22 @@ agentic-pi publishes to npm via a GitHub Actions workflow using **npm
382
407
  trusted publishing** (OIDC) — no `NPM_TOKEN` secret is needed in the
383
408
  repo.
384
409
 
385
- To cut a release (recommended path):
386
-
387
- 1. Bump `version` in `package.json` — `npm version patch` does this, plus
388
- commit and tag, in one step.
389
- 2. Push the commit and tag: `git push --follow-tags`.
390
- 3. Create a GitHub Release on the new tag, e.g.
391
- `gh release create v0.2.0 --generate-notes` or via the GitHub web UI.
392
- 4. The `publish.yml` workflow runs on the `release: published` event.
393
-
394
- The workflow also triggers on bare `v*.*.*` tag pushes and on manual
395
- `workflow_dispatch`. The `release` event is the preferred path because
396
- tag-push events get suppressed when a tag is pushed in the same `git
397
- push` invocation as branch commits — a real GitHub Actions quirk.
410
+ To cut a release:
411
+
412
+ 1. Bump `version` in `package.json` — `npm version patch` (or `minor` /
413
+ `major`) does the version bump, the commit, and the tag in one step.
414
+ 2. Push the commit and tag: `git push --follow-tags`. CI runs against
415
+ the version-bump commit on `main`.
416
+ 3. Create a GitHub Release on the new tag once CI is green:
417
+ `gh release create v0.2.0 --generate-notes` or via the web UI.
418
+ 4. The `publish.yml` workflow runs on the `release: published` event —
419
+ this is the only auto-trigger. (CI does not re-run; `publish.yml`
420
+ re-validates type-check, build, and unit tests itself so nothing is
421
+ skipped.)
422
+
423
+ `publish.yml` also accepts a manual `workflow_dispatch` with an explicit
424
+ tag/ref — useful if a release-triggered run failed (network, OIDC config
425
+ not yet set up) and you want to retry without re-cutting the release.
398
426
 
399
427
  The publish step fails if the tag (or the dispatch `ref` input) doesn't
400
428
  match `package.json` version — there is no path that publishes a version
package/dist/args.d.ts CHANGED
@@ -26,6 +26,40 @@ export interface RunConfig {
26
26
  dangerouslySkipPermissions: boolean;
27
27
  /** Sandbox backend for read/write/edit/bash. */
28
28
  sandbox: "none" | "gondolin";
29
+ /**
30
+ * Image to boot when `sandbox === "gondolin"`. Resolved by the image
31
+ * loader:
32
+ * - `"default"` → bundled `agentic-pi-dev` manifest (auto-downloaded).
33
+ * - `"gondolin-builtin"` → gondolin's built-in `alpine-base:latest`.
34
+ * - absolute path → a local `gondolin build` output directory.
35
+ * Ignored when `sandbox === "none"`. Default: `"default"`.
36
+ */
37
+ sandboxImage?: string;
38
+ /**
39
+ * Environment variables to inject into the sandbox VM. Ignored when
40
+ * sandbox === "none" (Pi's host tools already inherit process.env).
41
+ * Use this to hand `GITHUB_TOKEN`, secrets, or workflow context to the
42
+ * agent's `bash` calls inside the VM.
43
+ *
44
+ * Set via `--sandbox-env KEY=VAL` (repeatable). When `--profile` is
45
+ * active and the GitHub extension is configured, a short-lived
46
+ * installation token is auto-injected as both `GITHUB_TOKEN` and
47
+ * `GH_TOKEN`. User-provided values override the auto-injected ones.
48
+ */
49
+ sandboxEnv?: Record<string, string>;
50
+ /**
51
+ * HTTP egress allowlist for the sandbox VM. Without this, gondolin
52
+ * returns 502 to every outbound request from inside the VM —
53
+ * `git clone`, `git push`, `gh api`, `npm install`, `pip install` all
54
+ * fail. Default: a built-in GitHub-only list (github.com,
55
+ * api.github.com, codeload.github.com, objects.githubusercontent.com,
56
+ * raw.githubusercontent.com).
57
+ *
58
+ * Set explicit hosts via `--allow-host <host>` (repeatable) to extend
59
+ * or replace the default. Pass `--no-network` to disable HTTP egress
60
+ * entirely. Ignored when `sandbox === "none"`.
61
+ */
62
+ allowedHttpHosts?: string[] | null;
29
63
  }
30
64
  export declare function printHelp(): void;
31
65
  export declare function parseArgs(argv: string[]): RunConfig;
package/dist/args.js CHANGED
@@ -24,6 +24,22 @@ Flags:
24
24
  Default: none. 'gondolin' boots a per-run QEMU micro-VM
25
25
  mounting the cwd at /workspace. Requires QEMU on host;
26
26
  native only (Docker-in-Docker not viable; see SPIKE-gondolin.md).
27
+ --sandbox-env KEY=VAL Inject env var into the sandbox VM. Repeatable.
28
+ Ignored when --sandbox=none. When --profile is active,
29
+ GITHUB_TOKEN and GH_TOKEN are auto-injected from a minted
30
+ installation token (App PEM never enters the VM).
31
+ --allow-host <host> Add a host to the sandbox HTTP egress allowlist.
32
+ Repeatable. First explicit use replaces the default
33
+ GitHub-only allowlist; subsequent uses extend it.
34
+ Ignored when --sandbox=none.
35
+ --no-network Disable HTTP egress from the sandbox entirely.
36
+ Ignored when --sandbox=none.
37
+ --sandbox-image <name> Image to boot when --sandbox=gondolin. Values:
38
+ 'default' (recommended) — bundled agentic-pi-dev image
39
+ with git/gh/node/python/rust baked in (auto-downloaded).
40
+ 'gondolin-builtin' — stock alpine-base:latest, no extras.
41
+ <absolute path> — directory produced by 'gondolin build'.
42
+ Default: 'default'.
27
43
  --dangerously-skip-permissions Accepted for compat; Pi has no permission prompts anyway
28
44
 
29
45
  Reads the prompt from stdin. Emits Pi-native JSONL events on stdout, terminating
@@ -90,6 +106,47 @@ export function parseArgs(argv) {
90
106
  config.sandbox = v;
91
107
  break;
92
108
  }
109
+ case "--sandbox-image": {
110
+ const v = next();
111
+ if (v.length === 0) {
112
+ throw new Error(`--sandbox-image requires a non-empty value`);
113
+ }
114
+ config.sandboxImage = v;
115
+ break;
116
+ }
117
+ case "--sandbox-env": {
118
+ const v = next();
119
+ const eq = v.indexOf("=");
120
+ if (eq < 1) {
121
+ throw new Error(`--sandbox-env must be KEY=VAL (got '${v}')`);
122
+ }
123
+ const key = v.slice(0, eq);
124
+ const val = v.slice(eq + 1);
125
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {
126
+ throw new Error(`--sandbox-env KEY must match POSIX identifier rules (got '${key}')`);
127
+ }
128
+ config.sandboxEnv = { ...(config.sandboxEnv ?? {}), [key]: val };
129
+ break;
130
+ }
131
+ case "--allow-host": {
132
+ const v = next().trim();
133
+ if (!v)
134
+ throw new Error("--allow-host requires a non-empty host");
135
+ if (!/^[A-Za-z0-9.\-*]+$/.test(v)) {
136
+ throw new Error(`--allow-host must be a host pattern (got '${v}')`);
137
+ }
138
+ // First explicit --allow-host replaces the default GitHub list;
139
+ // subsequent ones extend. Pass --no-network first to start from
140
+ // an empty allowlist with HTTP enabled? No — --no-network sets
141
+ // null (HTTP disabled). To start from empty allow-list, pass an
142
+ // explicit `--allow-host` for whatever you want and nothing else.
143
+ const cur = Array.isArray(config.allowedHttpHosts) ? config.allowedHttpHosts : [];
144
+ config.allowedHttpHosts = [...cur, v];
145
+ break;
146
+ }
147
+ case "--no-network":
148
+ config.allowedHttpHosts = null;
149
+ break;
93
150
  case "-h":
94
151
  case "--help":
95
152
  printHelp();
package/dist/args.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../src/args.ts"],"names":[],"mappings":"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"}
@@ -10,7 +10,7 @@
10
10
  * decide whether to surface a warning.
11
11
  */
12
12
  import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
13
- import { type AuthFailureReason } from "./auth.js";
13
+ import { type AuthFailureReason, type GitHubAuth } from "./auth.js";
14
14
  import { type GitAccessProfile } from "./profiles.js";
15
15
  export { isGitAccessProfile, type GitAccessProfile } from "./profiles.js";
16
16
  /** Why the extension didn't load tools. */
@@ -28,6 +28,13 @@ export interface GitHubExtensionResult {
28
28
  message?: string;
29
29
  /** Always echoed back so the consumer knows what they asked for. */
30
30
  profile?: GitAccessProfile;
31
+ /**
32
+ * The auth backend that was constructed (App or static-token). Exposed
33
+ * so the runner can mint a short-lived installation token to inject
34
+ * into the sandbox VM as `GITHUB_TOKEN`. Only present when
35
+ * `status === "configured"`.
36
+ */
37
+ auth?: GitHubAuth;
31
38
  }
32
39
  /**
33
40
  * Build the GitHub extension for a given profile.
@@ -53,6 +53,7 @@ export function loadGitHubExtension(profileName) {
53
53
  toolNames: profileTools.map((t) => t.name),
54
54
  status: "configured",
55
55
  profile: profileName,
56
+ auth,
56
57
  };
57
58
  }
58
59
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/github/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,gBAAgB,EAA0B,MAAM,WAAW,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,kBAAkB,GAEnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,kBAAkB,EAAyB,MAAM,eAAe,CAAC;AAuB1E;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAoB;IACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,WAAW,EAAE,EAAE;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,YAAY;SACrB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,2BAA2B,WAAW,uBAAuB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrG,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACrD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,WAAW,EAAE,EAAE;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,SAAS;YACjB,MAAM;YACN,OAAO;YACP,OAAO,EAAE,WAAW;SACrB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,WAAW;KACrB,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA6B;IAClE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,MAAM,CAAC,MAAM,KAAK,gBAAgB,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,CAAC;AAClF,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/extensions/github/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,gBAAgB,EAA2C,MAAM,WAAW,CAAC;AACtF,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EACL,aAAa,EACb,kBAAkB,GAEnB,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,kBAAkB,EAAyB,MAAM,eAAe,CAAC;AA8B1E;;;;;;;;GAQG;AACH,MAAM,UAAU,mBAAmB,CAAC,WAAoB;IACtD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,WAAW,EAAE,EAAE;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,SAAS;YACjB,MAAM,EAAE,YAAY;SACrB,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CACb,2BAA2B,WAAW,uBAAuB,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACrG,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,EAAE,CAAC;IACrD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,WAAW,EAAE,EAAE;YACf,SAAS,EAAE,EAAE;YACb,MAAM,EAAE,SAAS;YACjB,MAAM;YACN,OAAO;YACP,OAAO,EAAE,WAAW;SACrB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,SAAS,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1C,MAAM,EAAE,YAAY;QACpB,OAAO,EAAE,WAAW;QACpB,IAAI;KACL,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAA6B;IAClE,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC9C,OAAO,MAAM,CAAC,MAAM,KAAK,gBAAgB,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,CAAC;AAClF,CAAC"}
package/dist/run.d.ts CHANGED
@@ -31,6 +31,15 @@ export interface RunOptions {
31
31
  profile?: string;
32
32
  /** Sandbox backend. Default: "none". */
33
33
  sandbox?: "none" | "gondolin";
34
+ /**
35
+ * Image to boot when `sandbox: "gondolin"`. Values:
36
+ * - `"default"` (recommended) — bundled `agentic-pi-dev` image
37
+ * (auto-downloaded into `~/.cache/agentic-pi/images/`).
38
+ * - `"gondolin-builtin"` — stock `alpine-base:latest`, no toolchain.
39
+ * - absolute path — local `gondolin build` output directory.
40
+ * Default: `"default"`.
41
+ */
42
+ sandboxImage?: string;
34
43
  /** Working directory. Default: process.cwd(). */
35
44
  cwd?: string;
36
45
  /** Skip session persistence. Default: false. */
@@ -41,6 +50,27 @@ export interface RunOptions {
41
50
  noBuiltinTools?: boolean;
42
51
  /** Explicit tool allowlist. */
43
52
  tools?: string[];
53
+ /**
54
+ * Environment variables to inject into the sandbox VM (ignored when
55
+ * `sandbox: "none"`). When `sandbox: "gondolin"` with a `profile`
56
+ * configured, a short-lived GitHub installation token is auto-injected
57
+ * as `GITHUB_TOKEN` + `GH_TOKEN` — values here override the auto ones.
58
+ */
59
+ sandboxEnv?: Record<string, string>;
60
+ /**
61
+ * HTTP egress allowlist for the sandbox VM. Without this, gondolin's
62
+ * HTTP interceptor returns 502 to every outbound request.
63
+ *
64
+ * - `undefined` (default): allow the standard GitHub hosts + common
65
+ * public package registries (npm, pypi, crates, go, rubygems,
66
+ * alpine/debian apt). See `DEFAULT_GUEST_ALLOWED_HOSTS` in
67
+ * `sandbox/gondolin.ts` for the exact list.
68
+ * - explicit `string[]`: caller-supplied allowlist (replaces default).
69
+ * - `null`: disable HTTP hooks entirely; gondolin blocks egress.
70
+ *
71
+ * Ignored when `sandbox: "none"`.
72
+ */
73
+ allowedHttpHosts?: string[] | null;
44
74
  /**
45
75
  * Called for every emitted JSONL record in order. Same shape that the
46
76
  * CLI writes to stdout, with `sessionId` and `timestamp` already injected.
package/dist/run.js CHANGED
@@ -43,6 +43,9 @@ export async function run(options) {
43
43
  tools: options.tools,
44
44
  dangerouslySkipPermissions: false,
45
45
  sandbox: options.sandbox ?? "none",
46
+ sandboxEnv: options.sandboxEnv,
47
+ sandboxImage: options.sandboxImage,
48
+ allowedHttpHosts: options.allowedHttpHosts,
46
49
  };
47
50
  const collector = new CollectorSink(options.onEvent);
48
51
  const sink = options.extraSink
package/dist/run.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
package/dist/runner.js CHANGED
@@ -15,23 +15,17 @@ import { Emitter } from "./emitter.js";
15
15
  import { loadGitHubExtension, isMisconfigurationSkip } from "./extensions/github/index.js";
16
16
  import { resolveModel } from "./models.js";
17
17
  import { buildSandbox } from "./sandbox/index.js";
18
+ import { ensureImage, ImageLoaderError } from "./sandbox/images/loader.js";
18
19
  export async function runOnce(config, prompt, deps) {
19
20
  const warn = deps.onWarn ?? (() => undefined);
20
21
  const authStorage = AuthStorage.create();
21
22
  const modelRegistry = ModelRegistry.create(authStorage);
22
23
  const model = resolveModel(config.model, modelRegistry);
23
24
  const sessionManager = buildSessionManager(config);
24
- // Build the sandbox backend (boots Gondolin VM if --sandbox gondolin).
25
- // Done eagerly so VM-boot / preflight failures surface before any tokens
26
- // are spent on a prompt.
27
- const sandboxOutcome = await buildSandbox({ backend: config.sandbox, cwd: config.cwd });
28
- if (!sandboxOutcome.ok) {
29
- warn(`--sandbox=${sandboxOutcome.backend} failed (${sandboxOutcome.reason}): ${sandboxOutcome.hint}`);
30
- return 2;
31
- }
32
- const sandbox = sandboxOutcome.sandbox;
33
- // Build the GitHub extension up-front so we can surface auth issues before
34
- // creating the session (rather than at first tool call).
25
+ // GitHub extension built FIRST so the runner can mint an installation
26
+ // token before the sandbox boots the token is one of the env values
27
+ // we hand to the VM. Building the extension is cheap (no LLM, no IO
28
+ // except reading the PEM); failures surface as a warning, not an exit.
35
29
  const github = loadGitHubExtension(config.profile);
36
30
  // Loud about misconfigurations (partial App creds, unreadable PEM) — the
37
31
  // user almost certainly meant for GitHub to work. Silent about benign
@@ -44,6 +38,79 @@ export async function runOnce(config, prompt, deps) {
44
38
  config.profile) {
45
39
  warn(`--profile=${config.profile} set but no GITHUB_APP_* or GITHUB_TOKEN env vars found; GitHub tools disabled`);
46
40
  }
41
+ // Compose the env for the sandbox VM. Order (later wins):
42
+ // 1. Auto-injected GITHUB_TOKEN/GH_TOKEN from a minted installation
43
+ // token (when sandbox=gondolin AND github extension is configured).
44
+ // 2. User-provided --sandbox-env entries.
45
+ // App PEM is never copied into the VM — only the short-lived token.
46
+ const sandboxEnv = {};
47
+ if (config.sandbox === "gondolin" && github.status === "configured" && github.auth) {
48
+ try {
49
+ const token = await github.auth.getToken();
50
+ sandboxEnv.GITHUB_TOKEN = token;
51
+ sandboxEnv.GH_TOKEN = token;
52
+ }
53
+ catch (err) {
54
+ warn(`Could not mint a GitHub installation token for sandbox env: ${err.message}`);
55
+ }
56
+ }
57
+ if (config.sandboxEnv) {
58
+ Object.assign(sandboxEnv, config.sandboxEnv);
59
+ }
60
+ // Resolve --sandbox-image to an absolute path + descriptor. Default
61
+ // when --sandbox=gondolin is "default" (auto-downloaded
62
+ // agentic-pi-dev image). Explicit "gondolin-builtin" opts out.
63
+ let imagePath;
64
+ let imageDescriptor;
65
+ if (config.sandbox === "gondolin") {
66
+ const selector = config.sandboxImage ?? "default";
67
+ try {
68
+ const resolved = await ensureImage(selector);
69
+ if (resolved.kind === "builtin") {
70
+ imageDescriptor = { name: "gondolin-builtin", source: "builtin" };
71
+ }
72
+ else {
73
+ imagePath = resolved.imagePath;
74
+ imageDescriptor = resolved.descriptor;
75
+ }
76
+ }
77
+ catch (err) {
78
+ if (err instanceof ImageLoaderError) {
79
+ // When the user didn't explicitly ask for the default image
80
+ // (i.e. they didn't pass --sandbox-image), fall back to the
81
+ // gondolin builtin with a warning so they still get a working
82
+ // sandbox. If they passed --sandbox-image=default explicitly,
83
+ // a failure there is fatal — they asked for this image.
84
+ if (config.sandboxImage === undefined) {
85
+ warn(`default image unavailable (${err.message}); falling back to gondolin-builtin. Hint: ${err.hint}`);
86
+ imageDescriptor = { name: "gondolin-builtin", source: "builtin" };
87
+ }
88
+ else {
89
+ warn(`--sandbox-image=${selector} failed: ${err.message}. Hint: ${err.hint}`);
90
+ return 2;
91
+ }
92
+ }
93
+ else {
94
+ throw err;
95
+ }
96
+ }
97
+ }
98
+ // Build the sandbox backend (boots Gondolin VM if --sandbox gondolin).
99
+ // Done eagerly so VM-boot / preflight failures surface before any tokens
100
+ // are spent on a prompt.
101
+ const sandboxOutcome = await buildSandbox({
102
+ backend: config.sandbox,
103
+ cwd: config.cwd,
104
+ env: Object.keys(sandboxEnv).length > 0 ? sandboxEnv : undefined,
105
+ imagePath,
106
+ image: imageDescriptor,
107
+ allowedHttpHosts: config.allowedHttpHosts,
108
+ });
109
+ if (!sandboxOutcome.ok) {
110
+ warn(`--sandbox=${sandboxOutcome.backend} failed (${sandboxOutcome.reason}): ${sandboxOutcome.hint}`);
111
+ return 2;
112
+ }
113
+ const sandbox = sandboxOutcome.sandbox;
47
114
  // When a sandbox is active it supplies its own read/write/edit/bash that
48
115
  // route through the VM; Pi's host built-ins of the same names must be
49
116
  // suppressed so they don't shadow ours.
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,WAAW,EACX,aAAa,EACb,cAAc,EACd,kBAAkB,GACnB,MAAM,iCAAiC,CAAC;AAIzC,OAAO,EAAE,OAAO,EAAoB,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3F,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,YAAY,EAA4C,MAAM,oBAAoB,CAAC;AAC5F,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAW3E,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,MAAiB,EACjB,MAAc,EACd,IAAiB;IAEjB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAE9C,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;IACzC,MAAM,aAAa,GAAG,aAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;IAExD,MAAM,cAAc,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAEnD,sEAAsE;IACtE,sEAAsE;IACtE,oEAAoE;IACpE,uEAAuE;IACvE,MAAM,MAAM,GAAG,mBAAmB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnD,yEAAyE;IACzE,sEAAsE;IACtE,yCAAyC;IACzC,IAAI,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,8BAA8B,MAAM,CAAC,MAAM,MAAM,MAAM,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC,CAAC;IAChF,CAAC;SAAM,IACL,MAAM,CAAC,MAAM,KAAK,SAAS;QAC3B,MAAM,CAAC,MAAM,KAAK,gBAAgB;QAClC,MAAM,CAAC,OAAO,EACd,CAAC;QACD,IAAI,CAAC,aAAa,MAAM,CAAC,OAAO,gFAAgF,CAAC,CAAC;IACpH,CAAC;IAED,0DAA0D;IAC1D,sEAAsE;IACtE,yEAAyE;IACzE,4CAA4C;IAC5C,oEAAoE;IACpE,MAAM,UAAU,GAA2B,EAAE,CAAC;IAC9C,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU,IAAI,MAAM,CAAC,MAAM,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QACnF,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC3C,UAAU,CAAC,YAAY,GAAG,KAAK,CAAC;YAChC,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC9B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,+DAAgE,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAChG,CAAC;IACH,CAAC;IACD,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QACtB,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;IAC/C,CAAC;IAED,oEAAoE;IACpE,wDAAwD;IACxD,+DAA+D;IAC/D,IAAI,SAA6B,CAAC;IAClC,IAAI,eAA4C,CAAC;IACjD,IAAI,MAAM,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,IAAI,SAAS,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;YAC7C,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAChC,eAAe,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YACpE,CAAC;iBAAM,CAAC;gBACN,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;gBAC/B,eAAe,GAAG,QAAQ,CAAC,UAAU,CAAC;YACxC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,gBAAgB,EAAE,CAAC;gBACpC,4DAA4D;gBAC5D,4DAA4D;gBAC5D,8DAA8D;gBAC9D,8DAA8D;gBAC9D,wDAAwD;gBACxD,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;oBACtC,IAAI,CAAC,8BAA8B,GAAG,CAAC,OAAO,8CAA8C,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;oBACxG,eAAe,GAAG,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBACpE,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,mBAAmB,QAAQ,YAAY,GAAG,CAAC,OAAO,WAAW,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;oBAC9E,OAAO,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,yEAAyE;IACzE,yBAAyB;IACzB,MAAM,cAAc,GAAG,MAAM,YAAY,CAAC;QACxC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QAChE,SAAS;QACT,KAAK,EAAE,eAAe;QACtB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC,CAAC;IACH,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;QACvB,IAAI,CAAC,aAAa,cAAc,CAAC,OAAO,YAAY,cAAc,CAAC,MAAM,MAAM,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC;QACtG,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,OAAO,GAAkB,cAAc,CAAC,OAAO,CAAC;IAEtD,yEAAyE;IACzE,sEAAsE;IACtE,wCAAwC;IACxC,MAAM,WAAW,GACf,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACnC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACtC,SAAS,CAAC;IAEZ,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,kBAAkB,CAAC;QAC3C,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,KAAK;QACL,aAAa,EAAE,MAAM,CAAC,QAAQ;QAC9B,cAAc;QACd,WAAW;QACX,aAAa;QACb,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,OAAO,EAAE,WAAW;QACpB,WAAW,EAAE,CAAC,GAAG,OAAO,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC;KAC7D,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,IAAI,OAAO,CACzB;QACE,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,EACD,IAAI,CAAC,IAAI,CACV,CAAC;IAEF,OAAO,CAAC,aAAa,EAAE,CAAC;IACxB,OAAO,CAAC,KAAK,CAAC;QACZ,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,CAAC;QACZ,IAAI,EAAE,kBAAkB;QACxB,SAAS,EAAE,QAAQ;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM;KACnC,CAAC,CAAC;IAEH,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,KAAwB,EAAE,EAAE;QACjE,OAAO,CAAC,KAAK,CAAC,KAA8D,CAAC,CAAC;QAE9E,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YACzD,QAAQ,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC/B,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,qBAAqB,EAAE,KAAK,EAAE,CAAC,CAAC;IACjE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC;YACZ,IAAI,EAAE,aAAa;YACnB,KAAK,EAAE,EAAE,IAAI,EAAG,GAAa,CAAC,IAAI,EAAE,OAAO,EAAG,GAAa,CAAC,OAAO,EAAE;SACtE,CAAC,CAAC;QACH,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,wEAAwE;IACxE,4EAA4E;IAC5E,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC;YACZ,IAAI,EAAE,gBAAgB;YACtB,KAAK,EAAE;gBACL,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,iBAAiB,EAAE,KAAK,CAAC,iBAAiB;gBAC1C,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,IAAI,EAAE,KAAK,CAAC,IAAI;aACjB;SACF,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC;YACZ,IAAI,EAAE,sBAAsB;YAC5B,KAAK,EAAE,EAAE,OAAO,EAAG,GAAa,CAAC,OAAO,EAAE;SAC3C,CAAC,CAAC;IACL,CAAC;IAED,WAAW,EAAE,CAAC;IACd,OAAO,CAAC,OAAO,EAAE,CAAC;IAClB,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IAEtB,IAAI,QAAQ,IAAI,CAAC,YAAY;QAAE,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAS,mBAAmB,CAAC,MAAiB;IAC5C,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACrB,OAAO,cAAc,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;AAC9D,CAAC"}
@@ -16,6 +16,60 @@
16
16
  * upstream example. If full FS isolation is needed later, route those too.
17
17
  */
18
18
  import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
19
+ import type { ImageDescriptor } from "./index.js";
20
+ export interface GondolinSandboxOptions {
21
+ /**
22
+ * Environment variables to set inside the guest VM. Available to every
23
+ * `bash` invocation the agent makes. Use this to hand credentials,
24
+ * workflow context, or feature flags to the sandboxed process.
25
+ *
26
+ * Note: gondolin docs explicitly warn against baking secrets into
27
+ * pre-built images; runtime env is the supported channel for
28
+ * credentials, which is what this option exists for.
29
+ */
30
+ env?: Record<string, string>;
31
+ /**
32
+ * Absolute path to a gondolin build output directory. When set, the VM
33
+ * boots from these assets instead of gondolin's built-in
34
+ * `alpine-base:latest`. The caller (typically `runner.ts`) is
35
+ * responsible for resolving the user-facing `--sandbox-image` value
36
+ * (default / gondolin-builtin / path) to this absolute path.
37
+ */
38
+ imagePath?: string;
39
+ /** Descriptor surfaced verbatim in `status.image`. */
40
+ image?: ImageDescriptor;
41
+ /**
42
+ * Hosts the sandboxed guest is allowed to make HTTP(S) egress to.
43
+ * Without an HTTP hook configured, gondolin's HTTP interceptor returns
44
+ * 502 to every outbound request — `git clone`, `git push`, `gh ...`,
45
+ * `npm install`, `pip install` all fail. When this option is set
46
+ * (or left at its default), `createHttpHooks({ allowedHosts })` wires
47
+ * up the egress proxy.
48
+ *
49
+ * Pass `null` to disable HTTP hooks entirely (gondolin will then block
50
+ * all HTTP egress at the QEMU layer). Pass an explicit array to scope
51
+ * down or extend the default. Omit to use the GitHub-only default,
52
+ * which matches agentic-pi's built-in github extension surface.
53
+ */
54
+ allowedHttpHosts?: string[] | null;
55
+ }
56
+ /**
57
+ * Hosts the sandboxed guest can reach by default. The set covers the
58
+ * everyday needs of a coding-agent `bash` session: git over HTTPS, gh,
59
+ * and the common public package registries so `npm install`, `pip
60
+ * install`, `cargo build`, `go mod download`, `bundle install`, and
61
+ * `apk add` work without extra configuration.
62
+ *
63
+ * Model-provider hosts (`api.anthropic.com`, `api.openai.com`, etc.)
64
+ * are deliberately omitted — agentic-pi calls the LLM from the host
65
+ * process, not from inside the sandbox, so the VM never needs to reach
66
+ * them.
67
+ *
68
+ * The list is intentionally limited to **public** registries. Anything
69
+ * private (internal artifact repos, npm enterprise, etc.) must be added
70
+ * explicitly via `--allow-host` / `allowedHttpHosts: [...]`.
71
+ */
72
+ export declare const DEFAULT_GUEST_ALLOWED_HOSTS: readonly string[];
19
73
  export interface GondolinSandbox {
20
74
  /** Tools to pass into `createAgentSession({ customTools })`. */
21
75
  customTools: ToolDefinition<any>[];
@@ -27,6 +81,16 @@ export interface GondolinSandbox {
27
81
  cwd: string;
28
82
  guestPath: string;
29
83
  createMs: number;
84
+ /** Sorted list of env var KEY names injected (values omitted for safety). */
85
+ envKeys: string[];
86
+ /** Image descriptor (omitted when caller didn't supply one). */
87
+ image?: ImageDescriptor;
88
+ /**
89
+ * Resolved HTTP egress allowlist. `null` when HTTP hooks were disabled
90
+ * (caller passed `allowedHttpHosts: null`). Omitted when the backend
91
+ * doesn't have a meaningful HTTP policy.
92
+ */
93
+ allowedHttpHosts?: string[] | null;
30
94
  };
31
95
  }
32
96
  /**
@@ -36,4 +100,4 @@ export interface GondolinSandbox {
36
100
  * Throws if VM.create rejects. The preflight check is the caller's
37
101
  * responsibility — call `preflightGondolin()` first.
38
102
  */
39
- export declare function buildGondolinSandbox(cwd: string): Promise<GondolinSandbox>;
103
+ export declare function buildGondolinSandbox(cwd: string, options?: GondolinSandboxOptions): Promise<GondolinSandbox>;
@@ -17,7 +17,7 @@
17
17
  */
18
18
  import path from "node:path";
19
19
  import { createBashTool, createEditTool, createReadTool, createWriteTool, } from "@earendil-works/pi-coding-agent";
20
- import { RealFSProvider, VM } from "@earendil-works/gondolin";
20
+ import { RealFSProvider, VM, createHttpHooks } from "@earendil-works/gondolin";
21
21
  const GUEST_WORKSPACE = "/workspace";
22
22
  function shQuote(value) {
23
23
  // POSIX shell quoting: wrap in single quotes; escape any internal quote.
@@ -148,6 +148,49 @@ function createGondolinBashOps(vm, localCwd) {
148
148
  },
149
149
  };
150
150
  }
151
+ /**
152
+ * Hosts the sandboxed guest can reach by default. The set covers the
153
+ * everyday needs of a coding-agent `bash` session: git over HTTPS, gh,
154
+ * and the common public package registries so `npm install`, `pip
155
+ * install`, `cargo build`, `go mod download`, `bundle install`, and
156
+ * `apk add` work without extra configuration.
157
+ *
158
+ * Model-provider hosts (`api.anthropic.com`, `api.openai.com`, etc.)
159
+ * are deliberately omitted — agentic-pi calls the LLM from the host
160
+ * process, not from inside the sandbox, so the VM never needs to reach
161
+ * them.
162
+ *
163
+ * The list is intentionally limited to **public** registries. Anything
164
+ * private (internal artifact repos, npm enterprise, etc.) must be added
165
+ * explicitly via `--allow-host` / `allowedHttpHosts: [...]`.
166
+ */
167
+ export const DEFAULT_GUEST_ALLOWED_HOSTS = [
168
+ // GitHub — git over HTTPS + gh CLI
169
+ "github.com",
170
+ "api.github.com",
171
+ "codeload.github.com",
172
+ "objects.githubusercontent.com",
173
+ "raw.githubusercontent.com",
174
+ // npm / yarn / pnpm
175
+ "registry.npmjs.org",
176
+ "registry.yarnpkg.com",
177
+ // Python — pypi + wheels CDN
178
+ "pypi.org",
179
+ "files.pythonhosted.org",
180
+ // Rust
181
+ "crates.io",
182
+ "static.crates.io",
183
+ "index.crates.io",
184
+ // Go modules
185
+ "proxy.golang.org",
186
+ "sum.golang.org",
187
+ // Ruby
188
+ "rubygems.org",
189
+ // Alpine apk + Debian apt mirrors (the apk on `apk add` etc.)
190
+ "dl-cdn.alpinelinux.org",
191
+ "deb.debian.org",
192
+ "security.debian.org",
193
+ ];
151
194
  /**
152
195
  * Boot a Gondolin VM mounting `cwd` at /workspace, and build the four
153
196
  * Pi tool overrides (read, write, edit, bash) that route through it.
@@ -155,7 +198,18 @@ function createGondolinBashOps(vm, localCwd) {
155
198
  * Throws if VM.create rejects. The preflight check is the caller's
156
199
  * responsibility — call `preflightGondolin()` first.
157
200
  */
158
- export async function buildGondolinSandbox(cwd) {
201
+ export async function buildGondolinSandbox(cwd, options = {}) {
202
+ const env = options.env;
203
+ const imagePath = options.imagePath;
204
+ // HTTP egress policy. `undefined` (default) → GitHub-only allowlist via
205
+ // createHttpHooks; explicit array → caller-provided allowlist; `null` →
206
+ // skip hooks entirely (gondolin then blocks all HTTP at the QEMU layer).
207
+ const allowedHosts = options.allowedHttpHosts === undefined
208
+ ? [...DEFAULT_GUEST_ALLOWED_HOSTS]
209
+ : options.allowedHttpHosts;
210
+ const httpConfig = allowedHosts === null
211
+ ? undefined
212
+ : createHttpHooks({ allowedHosts });
159
213
  const t0 = Date.now();
160
214
  const vm = await VM.create({
161
215
  vfs: {
@@ -163,6 +217,9 @@ export async function buildGondolinSandbox(cwd) {
163
217
  [GUEST_WORKSPACE]: new RealFSProvider(cwd),
164
218
  },
165
219
  },
220
+ ...(imagePath ? { sandbox: { imagePath } } : {}),
221
+ ...(env && Object.keys(env).length > 0 ? { env } : {}),
222
+ ...(httpConfig ? { httpHooks: httpConfig.httpHooks } : {}),
166
223
  });
167
224
  const createMs = Date.now() - t0;
168
225
  // Confirm the VM is actually executable before returning. Without this
@@ -198,6 +255,9 @@ export async function buildGondolinSandbox(cwd) {
198
255
  cwd,
199
256
  guestPath: GUEST_WORKSPACE,
200
257
  createMs,
258
+ envKeys: env ? Object.keys(env).sort() : [],
259
+ ...(options.image ? { image: options.image } : {}),
260
+ allowedHttpHosts: allowedHosts === null ? null : [...allowedHosts],
201
261
  },
202
262
  close: async () => {
203
263
  if (closed)
@@ -1 +1 @@
1
- {"version":3,"file":"gondolin.js","sourceRoot":"","sources":["../../src/sandbox/gondolin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gondolin.js","sourceRoot":"","sources":["../../src/sandbox/gondolin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Image loader for `--sandbox-image`.
3
+ *
4
+ * Three resolution modes:
5
+ * - `"gondolin-builtin"` → `{ kind: "builtin" }` (let gondolin pick).
6
+ * - absolute path → `{ kind: "local", imagePath }`.
7
+ * - `"default"` → resolves the bundled DEFAULT_IMAGE_MANIFEST,
8
+ * verifies the per-arch tarball against the
9
+ * baked sha256, extracts into
10
+ * `~/.cache/agentic-pi/images/<sha>/`,
11
+ * returns that path. Atomic: extract to
12
+ * `<sha>.tmp/` then rename.
13
+ *
14
+ * The cache layout is `<cacheRoot>/images/<sha256>/` — one directory
15
+ * per sha, so different image versions coexist and verification on
16
+ * disk is just `existsSync(dir)`. No eviction (Phase B4 open question).
17
+ *
18
+ * Network errors throw a typed `ImageLoaderError` with `hint` so the
19
+ * runner can surface `--sandbox-image gondolin-builtin` as the escape
20
+ * hatch without parsing the message.
21
+ */
22
+ import { type ImageManifest } from "./manifest.js";
23
+ export type LoaderArch = "aarch64" | "x86_64";
24
+ export type ImageResolution = {
25
+ kind: "builtin";
26
+ } | {
27
+ kind: "local";
28
+ imagePath: string;
29
+ descriptor: {
30
+ name: string;
31
+ source: "local-path";
32
+ };
33
+ } | {
34
+ kind: "downloaded";
35
+ imagePath: string;
36
+ descriptor: {
37
+ name: string;
38
+ version: string;
39
+ source: "cached" | "downloaded";
40
+ downloadMs?: number;
41
+ };
42
+ };
43
+ export declare class ImageLoaderError extends Error {
44
+ readonly hint: string;
45
+ constructor(message: string, hint: string);
46
+ }
47
+ export interface EnsureImageOptions {
48
+ /** Override the manifest (used by tests). Defaults to DEFAULT_IMAGE_MANIFEST. */
49
+ manifest?: ImageManifest;
50
+ /** Override the cache root. Defaults to `<XDG_CACHE_HOME or ~/.cache>/agentic-pi`. */
51
+ cacheRoot?: string;
52
+ /** Override the detected host arch. */
53
+ arch?: LoaderArch;
54
+ /** Fetch function (DI for tests). Defaults to global `fetch`. */
55
+ fetch?: typeof fetch;
56
+ }
57
+ export declare function detectArch(): LoaderArch;
58
+ export declare function defaultCacheRoot(): string;
59
+ /**
60
+ * Resolve a `--sandbox-image` selector to a concrete path or builtin
61
+ * directive. Pure async; no side effects beyond the cache directory.
62
+ */
63
+ export declare function ensureImage(name: string, options?: EnsureImageOptions): Promise<ImageResolution>;
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Image loader for `--sandbox-image`.
3
+ *
4
+ * Three resolution modes:
5
+ * - `"gondolin-builtin"` → `{ kind: "builtin" }` (let gondolin pick).
6
+ * - absolute path → `{ kind: "local", imagePath }`.
7
+ * - `"default"` → resolves the bundled DEFAULT_IMAGE_MANIFEST,
8
+ * verifies the per-arch tarball against the
9
+ * baked sha256, extracts into
10
+ * `~/.cache/agentic-pi/images/<sha>/`,
11
+ * returns that path. Atomic: extract to
12
+ * `<sha>.tmp/` then rename.
13
+ *
14
+ * The cache layout is `<cacheRoot>/images/<sha256>/` — one directory
15
+ * per sha, so different image versions coexist and verification on
16
+ * disk is just `existsSync(dir)`. No eviction (Phase B4 open question).
17
+ *
18
+ * Network errors throw a typed `ImageLoaderError` with `hint` so the
19
+ * runner can surface `--sandbox-image gondolin-builtin` as the escape
20
+ * hatch without parsing the message.
21
+ */
22
+ import { spawn } from "node:child_process";
23
+ import { createHash } from "node:crypto";
24
+ import { createWriteStream } from "node:fs";
25
+ import { mkdir, rename, rm, stat } from "node:fs/promises";
26
+ import { tmpdir, homedir, arch as osArch } from "node:os";
27
+ import path from "node:path";
28
+ import { pipeline } from "node:stream/promises";
29
+ import { DEFAULT_IMAGE_MANIFEST, isManifestPublished, } from "./manifest.js";
30
+ export class ImageLoaderError extends Error {
31
+ hint;
32
+ constructor(message, hint) {
33
+ super(message);
34
+ this.name = "ImageLoaderError";
35
+ this.hint = hint;
36
+ }
37
+ }
38
+ export function detectArch() {
39
+ const a = osArch();
40
+ if (a === "arm64")
41
+ return "aarch64";
42
+ if (a === "x64")
43
+ return "x86_64";
44
+ throw new ImageLoaderError(`unsupported host arch '${a}' for default image`, "use --sandbox-image gondolin-builtin or build a local image for your arch");
45
+ }
46
+ export function defaultCacheRoot() {
47
+ const xdg = process.env.XDG_CACHE_HOME;
48
+ const base = xdg && xdg.length > 0 ? xdg : path.join(homedir(), ".cache");
49
+ return path.join(base, "agentic-pi");
50
+ }
51
+ /**
52
+ * Resolve a `--sandbox-image` selector to a concrete path or builtin
53
+ * directive. Pure async; no side effects beyond the cache directory.
54
+ */
55
+ export async function ensureImage(name, options = {}) {
56
+ if (name === "gondolin-builtin") {
57
+ return { kind: "builtin" };
58
+ }
59
+ if (path.isAbsolute(name)) {
60
+ return {
61
+ kind: "local",
62
+ imagePath: name,
63
+ descriptor: { name: path.basename(name), source: "local-path" },
64
+ };
65
+ }
66
+ if (name !== "default") {
67
+ // Anything else (relative path, unknown name) is a usage error.
68
+ throw new ImageLoaderError(`unrecognized --sandbox-image value '${name}'`, "expected 'default', 'gondolin-builtin', or an absolute path");
69
+ }
70
+ const manifest = options.manifest ?? DEFAULT_IMAGE_MANIFEST;
71
+ if (!isManifestPublished(manifest)) {
72
+ throw new ImageLoaderError(`default image manifest not yet populated (this build of agentic-pi predates the first image release)`, "use --sandbox-image gondolin-builtin until the npm package is rebuilt against a published image");
73
+ }
74
+ const arch = options.arch ?? detectArch();
75
+ const archive = manifest.archives[arch];
76
+ if (!archive || !archive.url || archive.sha256.length !== 64) {
77
+ throw new ImageLoaderError(`default image has no entry for arch '${arch}'`, "use --sandbox-image gondolin-builtin or build a local image");
78
+ }
79
+ const cacheRoot = options.cacheRoot ?? defaultCacheRoot();
80
+ const imageDir = path.join(cacheRoot, "images", archive.sha256);
81
+ // Fast path: a complete extraction is on disk.
82
+ if (await isExtractedImage(imageDir)) {
83
+ return {
84
+ kind: "downloaded",
85
+ imagePath: imageDir,
86
+ descriptor: {
87
+ name: manifest.name,
88
+ version: manifest.version,
89
+ source: "cached",
90
+ },
91
+ };
92
+ }
93
+ const fetchImpl = options.fetch ?? fetch;
94
+ const t0 = Date.now();
95
+ await downloadAndExtract(archive, imageDir, fetchImpl);
96
+ const downloadMs = Date.now() - t0;
97
+ return {
98
+ kind: "downloaded",
99
+ imagePath: imageDir,
100
+ descriptor: {
101
+ name: manifest.name,
102
+ version: manifest.version,
103
+ source: "downloaded",
104
+ downloadMs,
105
+ },
106
+ };
107
+ }
108
+ /**
109
+ * A complete extraction has a `manifest.json` (gondolin's asset
110
+ * manifest, written by `gondolin build`). Checking for the directory
111
+ * alone is insufficient — a previous run could have crashed mid-extract.
112
+ */
113
+ async function isExtractedImage(dir) {
114
+ try {
115
+ const s = await stat(path.join(dir, "manifest.json"));
116
+ return s.isFile();
117
+ }
118
+ catch {
119
+ return false;
120
+ }
121
+ }
122
+ async function downloadAndExtract(archive, imageDir, fetchImpl) {
123
+ const tmpRoot = path.join(tmpdir(), `agentic-pi-image-${process.pid}-${Date.now()}`);
124
+ const tmpExtract = path.join(tmpRoot, "extract");
125
+ const tmpArchive = path.join(tmpRoot, "archive.tar.gz");
126
+ await mkdir(tmpExtract, { recursive: true });
127
+ let response;
128
+ try {
129
+ response = await fetchImpl(archive.url);
130
+ }
131
+ catch (err) {
132
+ await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
133
+ throw new ImageLoaderError(`failed to download image from ${archive.url}: ${err.message}`, "set --sandbox-image gondolin-builtin to skip the auto-downloaded image");
134
+ }
135
+ if (!response.ok || !response.body) {
136
+ await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
137
+ throw new ImageLoaderError(`image download failed: HTTP ${response.status} from ${archive.url}`, "set --sandbox-image gondolin-builtin to skip the auto-downloaded image");
138
+ }
139
+ // Stream to disk + hash in one pass — the tarball is ~hundreds of MB,
140
+ // so don't buffer in memory.
141
+ const hash = createHash("sha256");
142
+ const fileSink = createWriteStream(tmpArchive);
143
+ await pipeline(response.body, async function* (source) {
144
+ for await (const chunk of source) {
145
+ const buf = chunk;
146
+ hash.update(buf);
147
+ yield buf;
148
+ }
149
+ }, fileSink);
150
+ const actualSha = hash.digest("hex");
151
+ if (actualSha !== archive.sha256) {
152
+ await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
153
+ throw new ImageLoaderError(`image sha256 mismatch: expected ${archive.sha256}, got ${actualSha}`, "the manifest baked into this build of agentic-pi is out of sync with the release artifact");
154
+ }
155
+ // Extract using system tar. Both macOS bsdtar and GNU tar accept
156
+ // `-x -z -f <file> -C <dir>`; that's a hard prerequisite for using
157
+ // gondolin in the first place (the build pipeline needs it too) so
158
+ // we don't preflight separately here.
159
+ await extractTarGz(tmpArchive, tmpExtract);
160
+ // Atomic publish: rename tmp dir to the final sha-keyed dir.
161
+ await mkdir(path.dirname(imageDir), { recursive: true });
162
+ try {
163
+ await rename(tmpExtract, imageDir);
164
+ }
165
+ catch (err) {
166
+ // Either a concurrent run won the race, or rename failed across FS.
167
+ // If the target now exists and is valid, treat as success.
168
+ if (await isExtractedImage(imageDir)) {
169
+ await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
170
+ return;
171
+ }
172
+ await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
173
+ throw new ImageLoaderError(`failed to install image at ${imageDir}: ${err.message}`, "check disk space and ~/.cache/agentic-pi permissions");
174
+ }
175
+ await rm(tmpRoot, { recursive: true, force: true }).catch(() => undefined);
176
+ }
177
+ function extractTarGz(archivePath, destDir) {
178
+ return new Promise((resolve, reject) => {
179
+ const proc = spawn("tar", ["-xzf", archivePath, "-C", destDir], {
180
+ stdio: ["ignore", "ignore", "pipe"],
181
+ });
182
+ let stderr = "";
183
+ proc.stderr.on("data", (c) => {
184
+ stderr += c.toString();
185
+ });
186
+ proc.on("error", reject);
187
+ proc.on("exit", (code) => {
188
+ if (code === 0)
189
+ resolve();
190
+ else
191
+ reject(new ImageLoaderError(`tar extraction failed (exit ${code}): ${stderr.trim() || "no stderr"}`, "ensure 'tar' is on PATH and the archive isn't corrupt"));
192
+ });
193
+ });
194
+ }
195
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/sandbox/images/loader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Baked-in manifest for the `default` agentic-pi-dev image.
3
+ *
4
+ * The image is built and released by `.github/workflows/image.yml`,
5
+ * which tags releases on `image-v*` (independent from the npm `v*`
6
+ * stream). After cutting an `image-v<x.y.z>` release, copy the
7
+ * per-arch URLs and sha256s from the release's `manifest.json` into
8
+ * the placeholders below and ship a new npm version.
9
+ *
10
+ * The sha256 is the authoritative signature — the loader verifies it
11
+ * before extracting. Reproducibility across rebuilds is best-effort
12
+ * (depends on Alpine mirror state), not guaranteed.
13
+ */
14
+ export interface ImageArchive {
15
+ url: string;
16
+ sha256: string;
17
+ /** Size hint used for download progress / sanity check. Optional. */
18
+ uncompressedBytes: number;
19
+ }
20
+ export interface ImageManifest {
21
+ name: string;
22
+ version: string;
23
+ archives: {
24
+ aarch64: ImageArchive;
25
+ x86_64: ImageArchive;
26
+ };
27
+ }
28
+ export declare const DEFAULT_IMAGE_MANIFEST: ImageManifest;
29
+ export declare function isManifestPublished(m?: ImageManifest): boolean;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Baked-in manifest for the `default` agentic-pi-dev image.
3
+ *
4
+ * The image is built and released by `.github/workflows/image.yml`,
5
+ * which tags releases on `image-v*` (independent from the npm `v*`
6
+ * stream). After cutting an `image-v<x.y.z>` release, copy the
7
+ * per-arch URLs and sha256s from the release's `manifest.json` into
8
+ * the placeholders below and ship a new npm version.
9
+ *
10
+ * The sha256 is the authoritative signature — the loader verifies it
11
+ * before extracting. Reproducibility across rebuilds is best-effort
12
+ * (depends on Alpine mirror state), not guaranteed.
13
+ */
14
+ // Pinned to image-v0.1.0 (first published release). Bump in lockstep
15
+ // with new image-v* releases — copy the published manifest.json
16
+ // verbatim. `uncompressedBytes` is informational only; the sha256 is
17
+ // the load-bearing check.
18
+ export const DEFAULT_IMAGE_MANIFEST = {
19
+ name: "agentic-pi-dev",
20
+ version: "0.1.0",
21
+ archives: {
22
+ aarch64: {
23
+ url: "https://github.com/cliftonc/agentic-pi/releases/download/image-v0.1.0/agentic-pi-dev-aarch64.tar.gz",
24
+ sha256: "2b5d303cbcdb8753d0b9eb1a15345b0b32140bc517ee07e3e946c6484093481c",
25
+ uncompressedBytes: 352753267,
26
+ },
27
+ x86_64: {
28
+ url: "https://github.com/cliftonc/agentic-pi/releases/download/image-v0.1.0/agentic-pi-dev-x86_64.tar.gz",
29
+ sha256: "08676e200b8ecd91e3727e67c295408756426447f9390a0f92c2d27d389e72f9",
30
+ uncompressedBytes: 378160995,
31
+ },
32
+ },
33
+ };
34
+ export function isManifestPublished(m = DEFAULT_IMAGE_MANIFEST) {
35
+ return m.archives.aarch64.sha256.length === 64 && m.archives.x86_64.sha256.length === 64;
36
+ }
37
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../src/sandbox/images/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAkBH,qEAAqE;AACrE,gEAAgE;AAChE,qEAAqE;AACrE,0BAA0B;AAC1B,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,IAAI,EAAE,gBAAgB;IACtB,OAAO,EAAE,OAAO;IAChB,QAAQ,EAAE;QACR,OAAO,EAAE;YACP,GAAG,EAAE,qGAAqG;YAC1G,MAAM,EAAE,kEAAkE;YAC1E,iBAAiB,EAAE,SAAS;SAC7B;QACD,MAAM,EAAE;YACN,GAAG,EAAE,oGAAoG;YACzG,MAAM,EAAE,kEAAkE;YAC1E,iBAAiB,EAAE,SAAS;SAC7B;KACF;CACF,CAAC;AAEF,MAAM,UAAU,mBAAmB,CAAC,IAAmB,sBAAsB;IAC3E,OAAO,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC;AAC3F,CAAC"}
@@ -24,6 +24,38 @@ export type SandboxResult = SandboxNone | (Omit<GondolinSandbox, "status"> & {
24
24
  export interface BuildSandboxOptions {
25
25
  backend: SandboxBackend;
26
26
  cwd: string;
27
+ /** Env vars to inject into the sandbox (ignored when backend === "none"). */
28
+ env?: Record<string, string>;
29
+ /**
30
+ * Absolute path to a gondolin build output directory to mount as the
31
+ * guest. When `undefined`, gondolin uses its built-in `alpine-base`.
32
+ * Ignored when `backend === "none"`. The runner is responsible for
33
+ * resolving `--sandbox-image` (default / gondolin-builtin / path) to
34
+ * this path before calling buildSandbox.
35
+ */
36
+ imagePath?: string;
37
+ /**
38
+ * Optional descriptor of which image is being used, surfaced verbatim
39
+ * in `sandbox_status.image`. The sandbox layer does not interpret it —
40
+ * the runner builds it from the loader result.
41
+ */
42
+ image?: ImageDescriptor;
43
+ /**
44
+ * Allowed HTTP egress hosts for the sandboxed guest. See
45
+ * `GondolinSandboxOptions.allowedHttpHosts` for the semantics:
46
+ * - `undefined` (default): GitHub-only allowlist
47
+ * - explicit `string[]`: caller-supplied allowlist
48
+ * - `null`: skip HTTP hooks entirely (gondolin blocks everything)
49
+ *
50
+ * Ignored when `backend === "none"`.
51
+ */
52
+ allowedHttpHosts?: string[] | null;
53
+ }
54
+ export interface ImageDescriptor {
55
+ name: string;
56
+ version?: string;
57
+ source: "builtin" | "local-path" | "cached" | "downloaded";
58
+ downloadMs?: number;
27
59
  }
28
60
  export type BuildSandboxOutcome = {
29
61
  ok: true;
@@ -31,7 +31,12 @@ export async function buildSandbox(opts) {
31
31
  };
32
32
  }
33
33
  try {
34
- const sandbox = await buildGondolinSandbox(opts.cwd);
34
+ const sandbox = await buildGondolinSandbox(opts.cwd, {
35
+ env: opts.env,
36
+ imagePath: opts.imagePath,
37
+ image: opts.image,
38
+ allowedHttpHosts: opts.allowedHttpHosts,
39
+ });
35
40
  return {
36
41
  ok: true,
37
42
  sandbox: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,oBAAoB,EAAwB,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAwB,MAAM,gBAAgB,CAAC;AAkCzE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE;gBACP,OAAO,EAAE,MAAM;gBACf,WAAW,EAAE,EAAE;gBACf,gBAAgB,EAAE,KAAK;gBACvB,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;gBAC5B,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;aAC5B;SACF,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,MAAM,SAAS,GAAoB,iBAAiB,EAAE,CAAC;IACvD,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,IAAI,EAAE,SAAS,CAAC,IAAI;SACrB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACrD,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE;gBACP,OAAO,EAAE,UAAU;gBACnB,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,gBAAgB,EAAE,IAAI;gBACtB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,kBAAkB;YAC1B,IAAI,EAAG,GAAa,CAAC,OAAO;SAC7B,CAAC;IACJ,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sandbox/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,oBAAoB,EAAwB,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,iBAAiB,EAAwB,MAAM,gBAAgB,CAAC;AAmEzE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAyB;IAC1D,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE;gBACP,OAAO,EAAE,MAAM;gBACf,WAAW,EAAE,EAAE;gBACf,gBAAgB,EAAE,KAAK;gBACvB,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;gBAC5B,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;aAC5B;SACF,CAAC;IACJ,CAAC;IAED,yBAAyB;IACzB,MAAM,SAAS,GAAoB,iBAAiB,EAAE,CAAC;IACvD,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;QAClB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,SAAS,CAAC,MAAM;YACxB,IAAI,EAAE,SAAS,CAAC,IAAI;SACrB,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,GAAG,EAAE;YACnD,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;SACxC,CAAC,CAAC;QACH,OAAO;YACL,EAAE,EAAE,IAAI;YACR,OAAO,EAAE;gBACP,OAAO,EAAE,UAAU;gBACnB,WAAW,EAAE,OAAO,CAAC,WAAW;gBAChC,gBAAgB,EAAE,IAAI;gBACtB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;aACvB;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO,EAAE,UAAU;YACnB,MAAM,EAAE,kBAAkB;YAC1B,IAAI,EAAG,GAAa,CAAC,OAAO;SAC7B,CAAC;IACJ,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-pi",
3
- "version": "0.1.2",
3
+ "version": "0.2.1",
4
4
  "description": "A drop-in coding-agent harness built on earendil-works/pi, designed to replace opencode in workflow-driven systems like lastlight.",
5
5
  "license": "MIT",
6
6
  "repository": {