pi-microsandbox 0.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/LICENSE +21 -0
- package/README.md +120 -0
- package/SECURITY.md +58 -0
- package/docs/commands.md +38 -0
- package/docs/configuration.md +80 -0
- package/docs/development.md +119 -0
- package/docs/getting-started.md +66 -0
- package/docs/images.md +190 -0
- package/docs/safety.md +39 -0
- package/docs/storage.md +57 -0
- package/docs/troubleshooting.md +20 -0
- package/extensions/pi-msb/command.ts +532 -0
- package/extensions/pi-msb/config.ts +771 -0
- package/extensions/pi-msb/control.ts +803 -0
- package/extensions/pi-msb/footer.ts +191 -0
- package/extensions/pi-msb/git.ts +256 -0
- package/extensions/pi-msb/index.ts +156 -0
- package/extensions/pi-msb/labels.ts +321 -0
- package/extensions/pi-msb/locks.ts +292 -0
- package/extensions/pi-msb/operations-exec.ts +434 -0
- package/extensions/pi-msb/operations.ts +321 -0
- package/extensions/pi-msb/prune.ts +232 -0
- package/extensions/pi-msb/sandbox-manager.ts +702 -0
- package/extensions/pi-msb/skill-access.ts +164 -0
- package/extensions/pi-msb/storage.ts +332 -0
- package/extensions/pi-msb/tools.ts +417 -0
- package/extensions/pi-msb/transport.ts +518 -0
- package/extensions/pi-msb/types.ts +436 -0
- package/package.json +74 -0
package/docs/images.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Images
|
|
2
|
+
|
|
3
|
+
[Back to README](../README.md)
|
|
4
|
+
|
|
5
|
+
pi-microsandbox publishes six Ubuntu 26.04 image variants at
|
|
6
|
+
`ghcr.io/hcohe/pi-microsandbox`. Every tag is a Linux multi-platform image for
|
|
7
|
+
AMD64 and ARM64.
|
|
8
|
+
|
|
9
|
+
## Published variants
|
|
10
|
+
|
|
11
|
+
`VERSION` below is the independent image version, such as `1.0.0`. Release
|
|
12
|
+
tags are write-once. Latest tags are mutable development tags built from `main`.
|
|
13
|
+
Push an exact `image-vVERSION` Git tag to publish a release cohort. Package
|
|
14
|
+
`vX.Y.Z` tags do not invoke image builds, and manual workflow runs validate only.
|
|
15
|
+
|
|
16
|
+
| Variant | Contents | Release tag | Latest tag |
|
|
17
|
+
| --- | --- | --- | --- |
|
|
18
|
+
| `base` | Required guest commands and CA certificates, without a language toolchain | `base-VERSION` | `base-latest` |
|
|
19
|
+
| `node` | Base plus Node.js 24.21.0, npm, pnpm 12.3.4, Yarn 1.22.22, and native addon build support | `node-VERSION` | `node-latest` |
|
|
20
|
+
| `python` | Base plus Ubuntu Python 3, pip, uv/uvx 0.12.12, and native extension build support | `python-VERSION` | `python-latest` |
|
|
21
|
+
| `rust` | Base plus Rust 1.98.0, Cargo, rustup, and native dependency build support | `rust-VERSION` | `rust-latest` |
|
|
22
|
+
| `go` | Base plus Go 1.26.8 and cgo build support | `go-VERSION` | `go-latest` |
|
|
23
|
+
| `default` | Base plus the Node.js, Python, Rust, and Go modules above | `VERSION` | `latest` |
|
|
24
|
+
|
|
25
|
+
The base contract includes `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
|
|
26
|
+
`rm`, and the other core commands used by the image verification scripts. CA
|
|
27
|
+
certificates support HTTPS Git operations.
|
|
28
|
+
|
|
29
|
+
Select a variant in trusted project configuration:
|
|
30
|
+
|
|
31
|
+
```toml
|
|
32
|
+
# .pi-msb.toml
|
|
33
|
+
image = "ghcr.io/hcohe/pi-microsandbox:python-1.0.0"
|
|
34
|
+
pull_policy = "if-missing"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
If `image` is omitted, pi-microsandbox uses the configured `default` variant
|
|
38
|
+
release, qualified by both its `VERSION` tag and immutable index digest. Image
|
|
39
|
+
versions are independent of the installed package version. If `pull_policy` is
|
|
40
|
+
omitted, `"if-missing"` is used: Microsandbox pulls the image only when that
|
|
41
|
+
exact reference is absent from its cache. Use `"always"` to check a registry for
|
|
42
|
+
an updated mutable tag, or `"never"` to require a cached local image.
|
|
43
|
+
|
|
44
|
+
## How the images are assembled
|
|
45
|
+
|
|
46
|
+
[`default-image/variants.json`](../default-image/variants.json) is the single
|
|
47
|
+
source of variant composition and tag names. The workflow passes each entry's
|
|
48
|
+
toolchain list to one generic
|
|
49
|
+
[`default-image/Dockerfile`](../default-image/Dockerfile). Modular
|
|
50
|
+
`default-image/install/<language>.sh` and
|
|
51
|
+
`default-image/verify/<language>.sh` scripts install and exercise each selected
|
|
52
|
+
language.
|
|
53
|
+
|
|
54
|
+
The `default` variant runs the same Node.js, Python, Rust, and Go modules as the
|
|
55
|
+
individual variants. It does not have a duplicate package list. This keeps an
|
|
56
|
+
installer, its functional checks, and every image that uses it aligned.
|
|
57
|
+
|
|
58
|
+
Release builds pin the Ubuntu multi-platform image digest and a dated Ubuntu apt
|
|
59
|
+
snapshot shared by every variant. The snapshot pin applies only while the image
|
|
60
|
+
is assembled. Published images restore Ubuntu's normal apt sources so projects
|
|
61
|
+
can install current packages at runtime.
|
|
62
|
+
|
|
63
|
+
## Build a custom image
|
|
64
|
+
|
|
65
|
+
A custom image must provide `bash`, `sh`, `git`, `rg`, `file`, `cat`, `mkdir`,
|
|
66
|
+
and `rm`. Install CA certificates if the guest will use Git over HTTPS. With
|
|
67
|
+
`bootstrap_tools = "auto"`, pi-microsandbox can install missing required
|
|
68
|
+
commands through `apt-get` when the network policy permits it. A prepared image
|
|
69
|
+
is required when bootstrap is disabled or package repositories are unavailable.
|
|
70
|
+
|
|
71
|
+
Microsandbox supports registry images and images loaded into its own local
|
|
72
|
+
cache. Images in the Docker daemon are not automatically visible to
|
|
73
|
+
Microsandbox.
|
|
74
|
+
|
|
75
|
+
### Publish to an OCI registry
|
|
76
|
+
|
|
77
|
+
Start from a versioned base tag so the guest contract does not change when
|
|
78
|
+
`main` is rebuilt:
|
|
79
|
+
|
|
80
|
+
```dockerfile
|
|
81
|
+
FROM ghcr.io/hcohe/pi-microsandbox:base-1.0.0
|
|
82
|
+
|
|
83
|
+
RUN apt-get update \
|
|
84
|
+
&& apt-get install -y --no-install-recommends jq \
|
|
85
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Build and push for the current host architecture with Docker:
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
docker build -t registry.example.com/team/pi-image:1.0.0 .
|
|
92
|
+
docker push registry.example.com/team/pi-image:1.0.0
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Or publish both supported architectures with Buildx:
|
|
96
|
+
|
|
97
|
+
```sh
|
|
98
|
+
docker buildx build \
|
|
99
|
+
--platform linux/amd64,linux/arm64 \
|
|
100
|
+
--tag registry.example.com/team/pi-image:1.0.0 \
|
|
101
|
+
--push .
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Then select it in `.pi-msb.toml`:
|
|
105
|
+
|
|
106
|
+
```toml
|
|
107
|
+
image = "registry.example.com/team/pi-image:1.0.0"
|
|
108
|
+
pull_policy = "if-missing"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For a private registry, configure authentication on the host with Microsandbox,
|
|
112
|
+
for example with `msb registry login`, or in
|
|
113
|
+
`~/.microsandbox/config.json`. Registry pull credentials belong in
|
|
114
|
+
Microsandbox configuration, not in pi-microsandbox guest `secrets`. See the
|
|
115
|
+
Microsandbox [image guide](https://docs.microsandbox.dev/images/overview) and
|
|
116
|
+
[configuration reference](https://docs.microsandbox.dev/configuration).
|
|
117
|
+
|
|
118
|
+
### Load a local Docker image
|
|
119
|
+
|
|
120
|
+
Build the image, then transfer a Docker archive into the Microsandbox cache and
|
|
121
|
+
assign a local tag:
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
docker build -t pi-image:dev .
|
|
125
|
+
docker save pi-image:dev | msb load --tag pi-image:local
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The file form is useful when a pipeline cannot be used:
|
|
129
|
+
|
|
130
|
+
```sh
|
|
131
|
+
docker save -o pi-image.tar pi-image:dev
|
|
132
|
+
msb load --input pi-image.tar --tag pi-image:local
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Use the local reference without contacting a registry:
|
|
136
|
+
|
|
137
|
+
```toml
|
|
138
|
+
image = "pi-image:local"
|
|
139
|
+
pull_policy = "never"
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`pull_policy = "if-missing"` also uses the loaded image while it remains in the
|
|
143
|
+
cache, but may try a registry if it is removed. The Microsandbox
|
|
144
|
+
[local image guide](https://docs.microsandbox.dev/examples/docker/local-images)
|
|
145
|
+
documents the same transfer requirement and `msb load` forms.
|
|
146
|
+
|
|
147
|
+
## Add a language variant
|
|
148
|
+
|
|
149
|
+
A new language needs all three of these changes:
|
|
150
|
+
|
|
151
|
+
1. Add an executable `default-image/install/<language>.sh`.
|
|
152
|
+
2. Add an executable `default-image/verify/<language>.sh`.
|
|
153
|
+
3. Add the variant and its toolchain composition to
|
|
154
|
+
`default-image/variants.json`.
|
|
155
|
+
|
|
156
|
+
Names become filenames and image tags. Use at most 48 characters: start with a
|
|
157
|
+
lowercase letter, then use only lowercase letters, digits, and hyphens. Do not
|
|
158
|
+
use path syntax, underscores, or the reserved names `base`, `default`,
|
|
159
|
+
`dispatch`, or a name beginning with `_`.
|
|
160
|
+
|
|
161
|
+
Pin downloaded tool versions. Record and verify SHA-256 checksums for both AMD64
|
|
162
|
+
and ARM64 artifacts, using the helpers in `install/_common.sh`. Do not pipe
|
|
163
|
+
network downloads into a shell. The verifier must test native functionality,
|
|
164
|
+
not only version output. For example, compile and run a native extension or a
|
|
165
|
+
small program. Add the language to the `default` variant's `toolchains` only if
|
|
166
|
+
it should become part of the complete image; do not copy its packages into a
|
|
167
|
+
second default-only installer.
|
|
168
|
+
|
|
169
|
+
Validate metadata and shell scripts locally:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
node scripts/image-variants.mjs matrix
|
|
173
|
+
shellcheck -e SC1091 default-image/install/*.sh default-image/verify/*.sh
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Build a representative variant with the same context and build arguments as CI.
|
|
177
|
+
The Dockerfile runs its functional verifier during the build:
|
|
178
|
+
|
|
179
|
+
```sh
|
|
180
|
+
docker buildx build \
|
|
181
|
+
--platform linux/amd64,linux/arm64 \
|
|
182
|
+
--build-arg IMAGE_VARIANT=node \
|
|
183
|
+
--build-arg "TOOLCHAINS=node" \
|
|
184
|
+
--build-arg IMAGE_VERSION=dev \
|
|
185
|
+
--file default-image/Dockerfile \
|
|
186
|
+
default-image
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Repeat with the new variant and its exact space-separated toolchain composition.
|
|
190
|
+
Build the `default` variant too if its composition changed.
|
package/docs/safety.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Safety model
|
|
2
|
+
|
|
3
|
+
[Back to README](../README.md)
|
|
4
|
+
|
|
5
|
+
The default is fail-closed:
|
|
6
|
+
|
|
7
|
+
- A valid, trusted project configuration is resolved before a sandbox is
|
|
8
|
+
started. A boot or image/tool failure blocks the seven routed tools (`read`,
|
|
9
|
+
`write`, `edit`, `ls`, `find`, `grep`, and `bash`).
|
|
10
|
+
- `mode = "auto"` is retained as an alias for `"direct"`; both use a
|
|
11
|
+
same-absolute-path read/write bind. `mode = "git"`, `"direct"`, and
|
|
12
|
+
`"none"` select those behaviors explicitly.
|
|
13
|
+
- `execution_target = "host"` is an opt-in escape for routed tool calls. While
|
|
14
|
+
a sandbox is active it requires an interactive approval for the exact tool,
|
|
15
|
+
working directory, and recursively sorted arguments. It is not available in
|
|
16
|
+
headless operation and is never silently selected.
|
|
17
|
+
- `/msb off` is an explicit host-mode handoff and does not prompt. This is
|
|
18
|
+
different from `fallback_mode = "host"`, which automatically uses host tools
|
|
19
|
+
after a sandbox failure and is shown as `MSB host fallback`.
|
|
20
|
+
- A project cannot replace another process's sandbox: ownership is a
|
|
21
|
+
non-blocking kernel `flock` acquired before any sandbox or volume mutation.
|
|
22
|
+
Stale sandbox pruning never removes volumes.
|
|
23
|
+
|
|
24
|
+
The extension entry point does not import the native SDK. Unsupported hosts can
|
|
25
|
+
still load Pi and remain blocked or explicitly off. pi-microsandbox currently supports
|
|
26
|
+
macOS Apple Silicon and Linux with KVM; Windows is not supported.
|
|
27
|
+
|
|
28
|
+
## Host-read exceptions
|
|
29
|
+
|
|
30
|
+
Pi-discovered `SKILL.md` reads are a narrow host-read exception. A standalone
|
|
31
|
+
skill grants only its exact file; a directory skill grants regular files
|
|
32
|
+
canonically below its directory. Symlink escapes, devices, sockets, and
|
|
33
|
+
unrelated host paths are denied. A successful sandbox Bash/grep result may
|
|
34
|
+
record one exact generated `details.fullOutputPath`; neighboring files do not
|
|
35
|
+
become readable.
|
|
36
|
+
|
|
37
|
+
## Reporting vulnerabilities
|
|
38
|
+
|
|
39
|
+
Report suspected vulnerabilities privately. See the [security policy](../SECURITY.md); do not open a public issue.
|
package/docs/storage.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Storage modes and retained work
|
|
2
|
+
|
|
3
|
+
[Back to README](../README.md)
|
|
4
|
+
|
|
5
|
+
## Storage modes
|
|
6
|
+
|
|
7
|
+
| Mode | Guest view | Host effect of routed writes |
|
|
8
|
+
| --- | --- | --- |
|
|
9
|
+
| `git` | A named volume at the repository root, with the same absolute path | Volume only |
|
|
10
|
+
| `direct` | The current directory bind-mounted at the same absolute path | Host directory |
|
|
11
|
+
| `none` | An empty tmpfs at the same absolute path | No host files; changes disappear with the sandbox |
|
|
12
|
+
| `auto` | Same as `direct` | Host directory |
|
|
13
|
+
|
|
14
|
+
`direct` is intentionally a warning-level escape from the Git isolation model:
|
|
15
|
+
routed edits modify the live host directory. `none` is useful for testing path
|
|
16
|
+
behavior and starts empty; it is not a retained workspace.
|
|
17
|
+
|
|
18
|
+
## Git and retained volumes
|
|
19
|
+
|
|
20
|
+
Git mode never bind-mounts the host checkout. On boot, pi-microsandbox captures the
|
|
21
|
+
committed `HEAD` (and selected branch) into a temporary verified Git bundle,
|
|
22
|
+
copies it into the guest, and seeds a named volume mounted at the repository's
|
|
23
|
+
absolute root. Untracked files, including `.env`, and working-tree edits are
|
|
24
|
+
not in that bundle. The temporary host and guest bundle files are removed after
|
|
25
|
+
seeding, including failure paths.
|
|
26
|
+
|
|
27
|
+
Edits and commits made in Git mode land in the retained volume. The host
|
|
28
|
+
checkout is not changed by ordinary routed tools. A normal Pi session shutdown
|
|
29
|
+
removes the sandbox but keeps the managed volume; the next boot reuses it only
|
|
30
|
+
when the complete session/schema/mode/cwd identity matches. A copied or forked
|
|
31
|
+
session state is rejected by the full session ID and gets a different resource
|
|
32
|
+
identity.
|
|
33
|
+
|
|
34
|
+
The SDK's `VolumeHandle` returned by `Volume.get()` does not expose a host
|
|
35
|
+
path. pi-microsandbox therefore refuses to fabricate one: a newly created volume
|
|
36
|
+
may show its path, while a later retained-volume lookup may not support
|
|
37
|
+
`/msb volumes ls` or volume enrichment. The volume remains mountable by name
|
|
38
|
+
and is never automatically deleted. Use the path recorded at creation time or
|
|
39
|
+
the microsandbox volume tooling when host-side inspection is required.
|
|
40
|
+
|
|
41
|
+
To manually synchronize a retained checkout, use a host-side fetch deliberately
|
|
42
|
+
(the command is not performed automatically by pi-microsandbox):
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
REPO=/absolute/path/to/checkout
|
|
46
|
+
VOLUME_PATH=/path/returned-for-the-managed-volume
|
|
47
|
+
BRANCH=$(git -C "$REPO" branch --show-current)
|
|
48
|
+
|
|
49
|
+
git -C "$VOLUME_PATH" remote remove host 2>/dev/null || true
|
|
50
|
+
git -C "$VOLUME_PATH" remote add host "$REPO"
|
|
51
|
+
git -C "$VOLUME_PATH" fetch --no-tags host "$BRANCH"
|
|
52
|
+
# Review before changing the retained checkout:
|
|
53
|
+
git -C "$VOLUME_PATH" log --oneline --decorate --all -10
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The host repository is an input to this explicit sync operation. Do not add a
|
|
57
|
+
host checkout bind mount to Git mode.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Recovery and troubleshooting
|
|
2
|
+
|
|
3
|
+
[Back to README](../README.md)
|
|
4
|
+
|
|
5
|
+
1. Run `/msb status` and `/msb logs`.
|
|
6
|
+
2. If the state is `unavailable (blocked)`, fix the displayed configuration,
|
|
7
|
+
image, virtualization, or missing-tool error and run `/msb reload`.
|
|
8
|
+
3. If a process died, a later startup or `/msb prune` can remove its labelled
|
|
9
|
+
sandbox after the owner lock is free. The named volume is retained.
|
|
10
|
+
4. If a same-name resource has different managed labels, pi-microsandbox refuses to
|
|
11
|
+
attach or replace it. Remove only a verified managed, unmounted volume with
|
|
12
|
+
`/msb volumes rm NAME --yes`.
|
|
13
|
+
5. On unsupported virtualization hosts, use `PI_MSB_DISABLE=1` for explicit host
|
|
14
|
+
mode or configure `fallback_mode = "host"` knowingly. The latter remains
|
|
15
|
+
visibly distinct from `/msb off`.
|
|
16
|
+
6. For bootstrap failures, use an image that already contains the required
|
|
17
|
+
command list or allow the configured network policy to reach the package
|
|
18
|
+
repositories. Deny mode cannot bootstrap an image missing those commands.
|
|
19
|
+
|
|
20
|
+
For installation prerequisites, see [installation and requirements](getting-started.md). To test a live sandbox from source, see the [live test matrix](development.md#live-test-matrix).
|