@stixxert/pi-docker-sandbox 0.1.0 → 1.1.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 CHANGED
@@ -4,6 +4,15 @@ A [pi](https://pi.dev) extension that gives an AI coding agent a **private
4
4
  docker sandbox** to deploy into — powered by
5
5
  [Docker Sandboxes](https://docs.docker.com/ai/sandboxes/) (`sbx`).
6
6
 
7
+ **How this sandboxes pi.** There are many ways to sandbox pi: wrap the whole
8
+ agent in a container or dedicated VM, confine it in a locked-down workspace,
9
+ or — as this project does — give pi a sandbox *to deploy into*. This is a
10
+ **pi extension, not a wrapper**: pi itself is never contained. It keeps
11
+ running in its normal host environment with its usual tools, workspace, and
12
+ agent micro-VM; the extension only adds a separate private microVM — with its
13
+ own docker daemon — as the agent's deploy target. What gets sandboxed here is
14
+ the docker work, not the pi process.
15
+
7
16
  Each pi session gets its own **sandbox microVM with its own docker daemon**,
8
17
  running in parallel to the agent. The agent can pull images, build, run
9
18
  containers, and `docker compose up` — while the **host's docker is never
@@ -23,6 +32,42 @@ daemon are a liability. With this extension:
23
32
  redirect it.
24
33
  - `docker_verify` runs a live isolation audit (PASS/FAIL per check).
25
34
 
35
+ ## Two modes
36
+
37
+ **1. Deploy target (default).** `pi install` this package and the agent gets
38
+ the `docker_*` tools: a private sbx microVM, with its own daemon, to deploy
39
+ into. pi's own tools keep running wherever pi runs.
40
+
41
+ **2. Execution backend.** Load `sandbox/` instead and pi runs *against* the
42
+ sandbox: `bash`, `read`, `write`, `edit`, `grep`, `find`, `ls` and your `!`
43
+ commands all execute inside the sbx microVM, while pi itself stays on the
44
+ host with its own auth, config, sessions and model keys.
45
+
46
+ ```bash
47
+ cd /path/to/project
48
+ pi -e /path/to/pi-docker-sandbox/sandbox
49
+ ```
50
+
51
+ This is pi's "route tool execution into an isolated environment" pattern —
52
+ the same shape as pi's [Gondolin
53
+ example](https://github.com/earendil-works/pi-mono), with an sbx microVM as
54
+ the target rather than a local QEMU VM. See [sandbox/README.md](sandbox/README.md).
55
+
56
+ It is also the **lighter alternative to running pi inside a sandbox**: no
57
+ template with pi baked in, no bootstrap seeding state into the sandbox, no
58
+ per-project auth/sessions/credential handling, no sandbox rebuild to pick up
59
+ a new pi version. The tools are *overridden*, not added — so the model's
60
+ tool list is byte-for-byte the built-in one and not one prompt token is
61
+ spent on the sandbox.
62
+
63
+ The sandbox it creates can itself be slim: [template/](template/) builds a
64
+ **648 MB** baseline automatically (vs ~2.2 GB for the pi-bearing template),
65
+ because pi no longer has to live inside it. See
66
+ [template/README.md](template/README.md).
67
+
68
+ Both modes can be active at once; the `docker_*` tools keep working when the
69
+ backend is loaded.
70
+
26
71
  ## Requirements
27
72
 
28
73
  - [pi](https://pi.dev) (the extension runs in the host pi process)
@@ -105,7 +150,7 @@ workspace mounted). No manual steps required.
105
150
  | `docker_init` | Scaffold a Dockerfile (+ compose) with language detection |
106
151
  | `docker_compose` | Deploy/manage compose projects (`up -d --build`) |
107
152
  | `docker_stop` / `docker_start` / `docker_rm` | Container lifecycle |
108
- | `docker_curl` | Probe a published port from the host process (GET/POST/PUT) |
153
+ | `docker_curl` | Probe a published port from the host process (GET/POST/PUT; only ports this sandbox published) |
109
154
  | `docker_sandbox_rm` | Remove this session's sandbox (microVM + everything inside) |
110
155
  | `docker_gc` | Sweep stale `pi-sbx-*` sandboxes left by crashed sessions |
111
156
 
@@ -164,7 +209,8 @@ persistent name (e.g. a shared sandbox reused across restarts), pin
164
209
  mappings; after a host reboot let the session-start GC handle it, or run
165
210
  `sbx rm --force $(sbx ls -q | grep pi-sbx)` from a host pane.
166
211
  - Agent-side verification: `docker_curl` (host-side fetch, GET/POST/PUT with
167
- optional body); human-side: `http://localhost:<hostport>/`.
212
+ optional body, confined to ports this sandbox published); human-side:
213
+ `http://localhost:<hostport>/`.
168
214
 
169
215
  See [boundary.md](boundary.md) for the full agent ↔ sbx boundary
170
216
  model and usage guide (agent + human). The extension is not dependent on
@@ -204,6 +250,11 @@ The agent's VM mounts the workspace at `/workspace`; the extension maps
204
250
  sandbox (the workspace is direct-mounted there). So `docker_build` contexts
205
251
  and `docker_run` volume binds "just work".
206
252
 
253
+ The mapping is **confined to the workspace**: `/workspace/..` traversal,
254
+ absolute host paths, and symlinks that point outside the workspace are all
255
+ rejected, so the agent cannot reach host paths outside the mounted workspace
256
+ via build contexts, volume binds, or `docker_init`.
257
+
207
258
  ## Example deploy flow
208
259
 
209
260
  ```
@@ -266,6 +317,35 @@ directly by pi (copy it to `~/.pi/agent/extensions/docker-sandbox.ts`, or
266
317
  pi package manifest (`pi.extensions`) and declares typecheck-only dev deps;
267
318
  `tsconfig.json` keeps `tsc --strict` honest against the pi SDK types.
268
319
 
320
+ ## Releases (CI/CD)
321
+
322
+ Releases are fully automated with [semantic-release](https://semantic-release.gitbook.io/)
323
+ via GitHub Actions (`.github/workflows/release.yml`). The **commit messages
324
+ themselves signal the release**: push to `main` and CI analyzes commits since
325
+ the last release tag, then bumps the version, tags, creates a GitHub Release,
326
+ and publishes to npm — only when there is something releasable.
327
+
328
+ | Commit message | Version bump |
329
+ |---|---|
330
+ | `fix: ...` | patch (`1.0.0` → `1.0.1`) |
331
+ | `feat: ...` | minor (`1.0.0` → `1.1.0`) |
332
+ | `BREAKING CHANGE: ...` (in body or footer) | major (`1.0.0` → `2.0.0`) |
333
+ | anything else (`docs:`, `chore:`, `refactor:`, …) | no release |
334
+
335
+ One-time setup: configure **trusted publishing** on npm so the workflow can
336
+ publish via OIDC — no npm token stored anywhere. On npmjs.com → package
337
+ `@stixxert/pi-docker-sandbox` → Settings → **Trusted Publisher**, add:
338
+
339
+ - Organization or user: `stixxert`
340
+ - Repository: `pi-docker-sandbox`
341
+ - Workflow filename: `release.yml`
342
+ - Environment name: *(leave empty)*
343
+ - Allowed actions: `npm publish`
344
+
345
+ `GITHUB_TOKEN` needs no setup. The first push to `main` containing a
346
+ `fix:`/`feat:` commit publishes the initial version. Provenance attestations
347
+ are generated automatically with trusted publishing.
348
+
269
349
  ## License
270
350
 
271
351
  Apache-2.0 — see [LICENSE](LICENSE).
package/boundary.md CHANGED
@@ -14,6 +14,16 @@ for the **agent** and for the **human operator**.
14
14
  > Gondolin is used throughout this document simply as the concrete reference
15
15
  > deployment.
16
16
 
17
+ > **Two modes.** This document describes the default **deploy target** mode,
18
+ > where the sandbox exists for `docker_*` and the agent keeps using its own
19
+ > tools. The repo also ships an **execution backend** (`sandbox/`) that routes
20
+ > pi's built-in tools into the same sandbox, for which the agent's own VM drops
21
+ > out of the picture and workspace paths are used as-is (the workspace is
22
+ > direct-mounted at its host absolute path inside the sandbox, so no
23
+ > `/workspace` hop is involved). See
24
+ > [sandbox/README.md](sandbox/README.md) and
25
+ > [security.md](security.md#execution-backend-built-in-tools-routed-into-the-sandbox).
26
+
17
27
  ## Topology
18
28
 
19
29
  ```
@@ -65,7 +75,7 @@ host macOS (trusted operator)
65
75
  | Host env confidentiality | `DOCKER_*`/`COMPOSE_*` always stripped; secure by default (only a minimal safe set is forwarded); `DOCKER_SANDBOX_ENV_ALLOWLIST` opts in to specific vars, `_PASSTHROUGH` opts out entirely; `docker_verify` audits the active mode |
66
76
  | Host files untouched | Only the session workspace is mounted into the sandbox; host `~/.docker`, `~/.ssh` etc. are not visible (audited by `docker_verify`) |
67
77
  | Project writes (optional) | `DOCKER_SANDBOX_WORKSPACE_RO=1` → project mounted read-only; all project writes must go through the agent's own tools |
68
- | Ports | Published on host `127.0.0.1` only (`sbx ports`); the agent probes them with `docker_curl` (host-side fetch); the agent's VM cannot reach host loopback |
78
+ | Ports | Published on host `127.0.0.1` only (`sbx ports`); the agent probes them with `docker_curl` (host-side fetch, confined to ports this sandbox published); the agent's VM cannot reach host loopback |
69
79
 
70
80
  ## Ports & networking (verified rules)
71
81
 
@@ -98,7 +108,8 @@ host macOS (trusted operator)
98
108
  pokes the sandbox every ~60s while the pi session is alive).
99
109
  6. **Verification paths**:
100
110
  - Agent → `docker_curl http://127.0.0.1:<hostport>/` (host-side fetch;
101
- GET/POST/PUT with optional body).
111
+ GET/POST/PUT with optional body; only ports this sandbox published are
112
+ reachable).
102
113
  - Sandbox-internal → `docker_exec` against `127.0.0.1:<port>` (same docker
103
114
  network).
104
115
  - Human → open `http://localhost:<hostport>/` on the host.